summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/shader_query.cpp
diff options
context:
space:
mode:
authorTapani Pälli <tapani.palli@intel.com>2015-10-14 11:01:29 +0300
committerTapani Pälli <tapani.palli@intel.com>2015-10-14 12:39:04 +0300
commitac257f1070add308004c5c79a8acfdef5a6778da (patch)
treec96909bb7a58ded70ca27961e004c4767e899e2d /src/mesa/main/shader_query.cpp
parentb76159b09617a07b9e3d53d64d31d4835702827f (diff)
downloadexternal_mesa3d-ac257f1070add308004c5c79a8acfdef5a6778da.zip
external_mesa3d-ac257f1070add308004c5c79a8acfdef5a6778da.tar.gz
external_mesa3d-ac257f1070add308004c5c79a8acfdef5a6778da.tar.bz2
glsl: calculate TOP_LEVEL_ARRAY_SIZE and STRIDE when adding resources
Patch moves existing calculation code from shader_query.cpp to happen during program resource list creation. No Piglit or CTS regressions were observed during testing. Signed-off-by: Tapani Pälli <tapani.palli@intel.com> Reviewed-by: Samuel Iglesias Gonsálvez <siglesias@igalia.com>
Diffstat (limited to 'src/mesa/main/shader_query.cpp')
-rw-r--r--src/mesa/main/shader_query.cpp244
1 files changed, 2 insertions, 242 deletions
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 50b44fa..8182d3d 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -839,244 +839,6 @@ program_resource_location(struct gl_shader_program *shProg,
}
}
-static char*
-get_top_level_name(const char *name)
-{
- const char *first_dot = strchr(name, '.');
- const char *first_square_bracket = strchr(name, '[');
- int name_size = 0;
- /* From ARB_program_interface_query spec:
- *
- * "For the property TOP_LEVEL_ARRAY_SIZE, a single integer identifying the
- * number of active array elements of the top-level shader storage block
- * member containing to the active variable is written to <params>. If the
- * top-level block member is not declared as an array, the value one is
- * written to <params>. If the top-level block member is an array with no
- * declared size, the value zero is written to <params>.
- */
-
- /* The buffer variable is on top level.*/
- if (!first_square_bracket && !first_dot)
- name_size = strlen(name);
- else if ((!first_square_bracket ||
- (first_dot && first_dot < first_square_bracket)))
- name_size = first_dot - name;
- else
- name_size = first_square_bracket - name;
-
- return strndup(name, name_size);
-}
-
-static char*
-get_var_name(const char *name)
-{
- const char *first_dot = strchr(name, '.');
-
- if (!first_dot)
- return strdup(name);
-
- return strndup(first_dot+1, strlen(first_dot) - 1);
-}
-
-static bool
-is_top_level_shader_storage_block_member(const char* name,
- const char* interface_name,
- const char* field_name)
-{
- bool result = false;
-
- /* If the given variable is already a top-level shader storage
- * block member, then return array_size = 1.
- * We could have two possibilities: if we have an instanced
- * shader storage block or not instanced.
- *
- * For the first, we check create a name as it was in top level and
- * compare it with the real name. If they are the same, then
- * the variable is already at top-level.
- *
- * Full instanced name is: interface name + '.' + var name +
- * NULL character
- */
- int name_length = strlen(interface_name) + 1 + strlen(field_name) + 1;
- char *full_instanced_name = (char *) calloc(name_length, sizeof(char));
- if (!full_instanced_name) {
- fprintf(stderr, "%s: Cannot allocate space for name\n", __func__);
- return false;
- }
-
- snprintf(full_instanced_name, name_length, "%s.%s",
- interface_name, field_name);
-
- /* Check if its top-level shader storage block member of an
- * instanced interface block, or of a unnamed interface block.
- */
- if (strcmp(name, full_instanced_name) == 0 ||
- strcmp(name, field_name) == 0)
- result = true;
-
- free(full_instanced_name);
- return result;
-}
-
-static GLint
-program_resource_top_level_array_size(struct gl_shader_program *shProg,
- struct gl_program_resource *res,
- const char *name)
-{
- int block_index = RESOURCE_UNI(res)->block_index;
- int array_size = -1;
- char *var_name = get_top_level_name(name);
- char *interface_name =
- get_top_level_name(shProg->BufferInterfaceBlocks[block_index].Name);
-
- if (strcmp(var_name, interface_name) == 0) {
- /* Deal with instanced array of SSBOs */
- char *temp_name = get_var_name(name);
- free(var_name);
- var_name = get_top_level_name(temp_name);
- free(temp_name);
- }
-
- for (unsigned i = 0; i < shProg->NumShaders; i++) {
- if (shProg->Shaders[i] == NULL)
- continue;
-
- const gl_shader *stage = shProg->Shaders[i];
- foreach_in_list(ir_instruction, node, stage->ir) {
- ir_variable *var = node->as_variable();
- if (!var || !var->get_interface_type() ||
- var->data.mode != ir_var_shader_storage)
- continue;
-
- const glsl_type *interface = var->get_interface_type();
-
- if (strcmp(interface_name, interface->name) != 0)
- continue;
-
- for (unsigned i = 0; i < interface->length; i++) {
- const glsl_struct_field *field = &interface->fields.structure[i];
- if (strcmp(field->name, var_name) != 0)
- continue;
- /* From GL_ARB_program_interface_query spec:
- *
- * "For the property TOP_LEVEL_ARRAY_SIZE, a single integer
- * identifying the number of active array elements of the top-level
- * shader storage block member containing to the active variable is
- * written to <params>. If the top-level block member is not
- * declared as an array, the value one is written to <params>. If
- * the top-level block member is an array with no declared size,
- * the value zero is written to <params>.
- */
- if (is_top_level_shader_storage_block_member(name,
- interface_name,
- var_name))
- array_size = 1;
- else if (field->type->is_unsized_array())
- array_size = 0;
- else if (field->type->is_array())
- array_size = field->type->length;
- else
- array_size = 1;
-
- goto found_top_level_array_size;
- }
- }
- }
-found_top_level_array_size:
- free(interface_name);
- free(var_name);
- return array_size;
-}
-
-static GLint
-program_resource_top_level_array_stride(struct gl_shader_program *shProg,
- struct gl_program_resource *res,
- const char *name)
-{
- int block_index = RESOURCE_UNI(res)->block_index;
- int array_stride = -1;
- char *var_name = get_top_level_name(name);
- char *interface_name =
- get_top_level_name(shProg->BufferInterfaceBlocks[block_index].Name);
-
- if (strcmp(var_name, interface_name) == 0) {
- /* Deal with instanced array of SSBOs */
- char *temp_name = get_var_name(name);
- free(var_name);
- var_name = get_top_level_name(temp_name);
- free(temp_name);
- }
-
- for (unsigned i = 0; i < shProg->NumShaders; i++) {
- if (shProg->Shaders[i] == NULL)
- continue;
-
- const gl_shader *stage = shProg->Shaders[i];
- foreach_in_list(ir_instruction, node, stage->ir) {
- ir_variable *var = node->as_variable();
- if (!var || !var->get_interface_type() ||
- var->data.mode != ir_var_shader_storage)
- continue;
-
- const glsl_type *interface = var->get_interface_type();
-
- if (strcmp(interface_name, interface->name) != 0) {
- continue;
- }
-
- for (unsigned i = 0; i < interface->length; i++) {
- const glsl_struct_field *field = &interface->fields.structure[i];
- if (strcmp(field->name, var_name) != 0)
- continue;
- /* From GL_ARB_program_interface_query:
- *
- * "For the property TOP_LEVEL_ARRAY_STRIDE, a single integer
- * identifying the stride between array elements of the top-level
- * shader storage block member containing the active variable is
- * written to <params>. For top-level block members declared as
- * arrays, the value written is the difference, in basic machine
- * units, between the offsets of the active variable for
- * consecutive elements in the top-level array. For top-level
- * block members not declared as an array, zero is written to
- * <params>."
- */
- if (field->type->is_array()) {
- const enum glsl_matrix_layout matrix_layout =
- glsl_matrix_layout(field->matrix_layout);
- bool row_major = matrix_layout == GLSL_MATRIX_LAYOUT_ROW_MAJOR;
- const glsl_type *array_type = field->type->fields.array;
-
- if (is_top_level_shader_storage_block_member(name,
- interface_name,
- var_name)) {
- array_stride = 0;
- goto found_top_level_array_stride;
- }
- if (interface->interface_packing != GLSL_INTERFACE_PACKING_STD430) {
- if (array_type->is_record() || array_type->is_array()) {
- array_stride = array_type->std140_size(row_major);
- array_stride = glsl_align(array_stride, 16);
- } else {
- unsigned element_base_align = 0;
- element_base_align = array_type->std140_base_alignment(row_major);
- array_stride = MAX2(element_base_align, 16);
- }
- } else {
- array_stride = array_type->std430_array_stride(row_major);
- }
- } else {
- array_stride = 0;
- }
- goto found_top_level_array_stride;
- }
- }
- }
-found_top_level_array_stride:
- free(interface_name);
- free(var_name);
- return array_stride;
-}
-
/**
* Function implements following location queries:
* glGetUniformLocation
@@ -1444,14 +1206,12 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
case GL_TOP_LEVEL_ARRAY_SIZE:
VALIDATE_TYPE(GL_BUFFER_VARIABLE);
- *val = program_resource_top_level_array_size(shProg, res,
- _mesa_program_resource_name(res));
+ *val = RESOURCE_UNI(res)->top_level_array_size;
return 1;
case GL_TOP_LEVEL_ARRAY_STRIDE:
VALIDATE_TYPE(GL_BUFFER_VARIABLE);
- *val = program_resource_top_level_array_stride(shProg, res,
- _mesa_program_resource_name(res));
+ *val = RESOURCE_UNI(res)->top_level_array_stride;
return 1;
/* GL_ARB_tessellation_shader */