summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAntia Puentes <[email protected]>2018-12-18 11:55:04 +0100
committerAlejandro Piñeiro <[email protected]>2019-07-12 23:42:41 +0200
commit0baa553fab5cfbee3410ca9f311e2bf61ccec5d4 (patch)
tree9c22ca7ddc146d63e7db9eadd017ea4eaea77064 /src
parent161de77e0feeab365f1a53464cb60eb3608ebe2e (diff)
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 <[email protected]> Signed-off-by: Alejandro Piñeiro <[email protected]> Signed-off-by: Arcady Goldmints-Orlov <[email protected]> Reviewed-by: Caio Marcelo de Oliveira Filho <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/mesa/main/program_resource.c8
-rw-r--r--src/mesa/main/shader_query.cpp149
-rw-r--r--src/mesa/main/shaderapi.h7
3 files changed, 149 insertions, 15 deletions
diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c
index fedd1f183ce..c85988d21ff 100644
--- a/src/mesa/main/program_resource.c
+++ b/src/mesa/main/program_resource.c
@@ -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++;
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index e9b39b7ff8f..000e2a16ea7 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -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++ =
diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h
index a8227ecc969..73fa90bbae9 100644
--- a/src/mesa/main/shaderapi.h
+++ b/src/mesa/main/shaderapi.h
@@ -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,