mesa/main: Fix UBO/SSBO ACTIVE_VARIABLES query (ARB_gl_spirv)
When querying MAX_NUM_ACTIVE_VARIABLES, NUM_ACTIVE_VARIABLES and ACTIVE_VARIABLES over SSBO and UBO interfaces, we filter the variables which are active using the variable's name and looking for it in the program resource list. If it is in the program resource list, the variable will be considered active. However due to ARB_gl_spirv where name reflection information is not mandatory, we can use the UBO/SSBO binding and variable offset to filter which variables which are active. v2: use RESOURCE_UBO/UNI macros instead of direct castings, update comment (Alejandro) v3: Change signature of _mesa_program_resource_find_active_variable to simplify calling it. Also, squash the fix for find_binding_offset for arrays of blocks (Arcady) Signed-off-by: Antia Puentes <apuentes@igalia.com> Signed-off-by: Alejandro Piñeiro <apinheiro@igalia.com> Signed-off-by: Arcady Goldmints-Orlov <agoldmints@igalia.com> Reviewed-by: Caio Marcelo de Oliveira Filho <caio.oliveira@intel.com>
This commit is contained in:
parent
161de77e0f
commit
0baa553fab
|
@ -164,10 +164,12 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface,
|
|||
shProg->data->ProgramResourceList[i].Data;
|
||||
GLint block_params = 0;
|
||||
for (unsigned j = 0; j < block->NumUniforms; j++) {
|
||||
const char *iname = block->Uniforms[j].IndexName;
|
||||
struct gl_program_resource *uni =
|
||||
_mesa_program_resource_find_name(shProg, GL_BUFFER_VARIABLE,
|
||||
iname, NULL);
|
||||
_mesa_program_resource_find_active_variable(
|
||||
shProg,
|
||||
GL_BUFFER_VARIABLE,
|
||||
block,
|
||||
j);
|
||||
if (!uni)
|
||||
continue;
|
||||
block_params++;
|
||||
|
|
|
@ -638,6 +638,119 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Find an uniform or buffer variable program resource with an specific offset
|
||||
* inside a block with an specific binding.
|
||||
*
|
||||
* Valid interfaces are GL_BUFFER_VARIABLE and GL_UNIFORM.
|
||||
*/
|
||||
static struct gl_program_resource *
|
||||
program_resource_find_binding_offset(struct gl_shader_program *shProg,
|
||||
GLenum programInterface,
|
||||
const GLuint binding,
|
||||
const GLint offset)
|
||||
{
|
||||
|
||||
/* First we need to get the BLOCK_INDEX from the BUFFER_BINDING */
|
||||
GLenum blockInterface;
|
||||
|
||||
switch (programInterface) {
|
||||
case GL_BUFFER_VARIABLE:
|
||||
blockInterface = GL_SHADER_STORAGE_BLOCK;
|
||||
break;
|
||||
case GL_UNIFORM:
|
||||
blockInterface = GL_UNIFORM_BLOCK;
|
||||
break;
|
||||
default:
|
||||
assert("Invalid program interface");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int block_index = -1;
|
||||
int starting_index = -1;
|
||||
struct gl_program_resource *res = shProg->data->ProgramResourceList;
|
||||
|
||||
/* Blocks are added to the resource list in the same order that they are
|
||||
* added to UniformBlocks/ShaderStorageBlocks. Furthermore, all the blocks
|
||||
* of each type (UBO/SSBO) are contiguous, so we can infer block_index from
|
||||
* the resource list.
|
||||
*/
|
||||
for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) {
|
||||
if (res->Type != blockInterface)
|
||||
continue;
|
||||
|
||||
/* Store the first index where a resource of the specific interface is. */
|
||||
if (starting_index == -1)
|
||||
starting_index = i;
|
||||
|
||||
const struct gl_uniform_block *block = RESOURCE_UBO(res);
|
||||
|
||||
if (block->Binding == binding) {
|
||||
/* For arrays, or arrays of arrays of blocks, we want the resource
|
||||
* for the block with base index. Most properties for members of each
|
||||
* block are inherited from the block with the base index, including
|
||||
* a uniform being active or not.
|
||||
*/
|
||||
block_index = i - starting_index - block->linearized_array_index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (block_index == -1)
|
||||
return NULL;
|
||||
|
||||
/* We now look for the resource corresponding to the uniform or buffer
|
||||
* variable using the BLOCK_INDEX and OFFSET.
|
||||
*/
|
||||
res = shProg->data->ProgramResourceList;
|
||||
for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) {
|
||||
if (res->Type != programInterface)
|
||||
continue;
|
||||
|
||||
const struct gl_uniform_storage *uniform = RESOURCE_UNI(res);
|
||||
|
||||
if (uniform->block_index == block_index && uniform->offset == offset) {
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Checks if an uniform or buffer variable is in the active program resource
|
||||
* list.
|
||||
*
|
||||
* It takes into accout that for variables coming from SPIR-V binaries their
|
||||
* names could not be available (ARB_gl_spirv). In that case, it will use the
|
||||
* the offset and the block binding to locate the resource.
|
||||
*
|
||||
* Valid interfaces are GL_BUFFER_VARIABLE and GL_UNIFORM.
|
||||
*/
|
||||
struct gl_program_resource *
|
||||
_mesa_program_resource_find_active_variable(struct gl_shader_program *shProg,
|
||||
GLenum programInterface,
|
||||
const gl_uniform_block *block,
|
||||
unsigned index)
|
||||
{
|
||||
struct gl_program_resource *res;
|
||||
struct gl_uniform_buffer_variable uni = block->Uniforms[index];
|
||||
|
||||
assert(programInterface == GL_UNIFORM ||
|
||||
programInterface == GL_BUFFER_VARIABLE);
|
||||
|
||||
if (uni.IndexName) {
|
||||
res = _mesa_program_resource_find_name(shProg, programInterface, uni.IndexName,
|
||||
NULL);
|
||||
} else {
|
||||
/* As the resource has no associated name (ARB_gl_spirv),
|
||||
* we can use the UBO/SSBO binding and offset to find it.
|
||||
*/
|
||||
res = program_resource_find_binding_offset(shProg, programInterface,
|
||||
block->Binding, uni.Offset);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static GLuint
|
||||
calc_resource_index(struct gl_shader_program *shProg,
|
||||
struct gl_program_resource *res)
|
||||
|
@ -1039,10 +1152,13 @@ get_buffer_property(struct gl_shader_program *shProg,
|
|||
case GL_NUM_ACTIVE_VARIABLES:
|
||||
*val = 0;
|
||||
for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
|
||||
const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
|
||||
struct gl_program_resource *uni =
|
||||
_mesa_program_resource_find_name(shProg, GL_UNIFORM, iname,
|
||||
NULL);
|
||||
_mesa_program_resource_find_active_variable(
|
||||
shProg,
|
||||
GL_UNIFORM,
|
||||
RESOURCE_UBO(res),
|
||||
i);
|
||||
|
||||
if (!uni)
|
||||
continue;
|
||||
(*val)++;
|
||||
|
@ -1051,10 +1167,13 @@ get_buffer_property(struct gl_shader_program *shProg,
|
|||
case GL_ACTIVE_VARIABLES: {
|
||||
unsigned num_values = 0;
|
||||
for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
|
||||
const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
|
||||
struct gl_program_resource *uni =
|
||||
_mesa_program_resource_find_name(shProg, GL_UNIFORM, iname,
|
||||
NULL);
|
||||
_mesa_program_resource_find_active_variable(
|
||||
shProg,
|
||||
GL_UNIFORM,
|
||||
RESOURCE_UBO(res),
|
||||
i);
|
||||
|
||||
if (!uni)
|
||||
continue;
|
||||
*val++ =
|
||||
|
@ -1075,10 +1194,13 @@ get_buffer_property(struct gl_shader_program *shProg,
|
|||
case GL_NUM_ACTIVE_VARIABLES:
|
||||
*val = 0;
|
||||
for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
|
||||
const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
|
||||
struct gl_program_resource *uni =
|
||||
_mesa_program_resource_find_name(shProg, GL_BUFFER_VARIABLE,
|
||||
iname, NULL);
|
||||
_mesa_program_resource_find_active_variable(
|
||||
shProg,
|
||||
GL_BUFFER_VARIABLE,
|
||||
RESOURCE_UBO(res),
|
||||
i);
|
||||
|
||||
if (!uni)
|
||||
continue;
|
||||
(*val)++;
|
||||
|
@ -1087,10 +1209,13 @@ get_buffer_property(struct gl_shader_program *shProg,
|
|||
case GL_ACTIVE_VARIABLES: {
|
||||
unsigned num_values = 0;
|
||||
for (unsigned i = 0; i < RESOURCE_UBO(res)->NumUniforms; i++) {
|
||||
const char *iname = RESOURCE_UBO(res)->Uniforms[i].IndexName;
|
||||
struct gl_program_resource *uni =
|
||||
_mesa_program_resource_find_name(shProg, GL_BUFFER_VARIABLE,
|
||||
iname, NULL);
|
||||
_mesa_program_resource_find_active_variable(
|
||||
shProg,
|
||||
GL_BUFFER_VARIABLE,
|
||||
RESOURCE_UBO(res),
|
||||
i);
|
||||
|
||||
if (!uni)
|
||||
continue;
|
||||
*val++ =
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
|
||||
#include "glheader.h"
|
||||
#include "main/mtypes.h"
|
||||
#include "compiler/shader_enums.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -296,6 +297,12 @@ extern struct gl_program_resource *
|
|||
_mesa_program_resource_find_index(struct gl_shader_program *shProg,
|
||||
GLenum programInterface, GLuint index);
|
||||
|
||||
extern struct gl_program_resource *
|
||||
_mesa_program_resource_find_active_variable(struct gl_shader_program *shProg,
|
||||
GLenum programInterface,
|
||||
const struct gl_uniform_block *block,
|
||||
unsigned index);
|
||||
|
||||
extern bool
|
||||
_mesa_get_program_resource_name(struct gl_shader_program *shProg,
|
||||
GLenum programInterface, GLuint index,
|
||||
|
|
Loading…
Reference in New Issue