summaryrefslogtreecommitdiffstats
path: root/src/mesa/main/shader_query.cpp
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2015-04-20 10:27:58 +1000
committerDave Airlie <[email protected]>2015-07-23 17:25:49 +1000
commit0a18f160159b93c57943e5cb4d9d9a78a5b72996 (patch)
tree4aae990fc95f4ffa72f8ccbd97eeec30bc123674 /src/mesa/main/shader_query.cpp
parent60266863d80bb2af94fa5c189ccd23ee20607ea9 (diff)
program_resource: add subroutine support (v3.1)
This fleshes out the ARB_program_query support for the APIs that ARB_shader_subroutine introduces, leaving some TODOs for later addition. v2: reworked for lots of the ARB_program_interface_query entry points and tests v3: use common function to test for subroutine support v3.1: add tess, fix missing breaks Acked-by: Kenneth Graunke <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src/mesa/main/shader_query.cpp')
-rw-r--r--src/mesa/main/shader_query.cpp101
1 files changed, 101 insertions, 0 deletions
diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp
index 59b9396f19b..3e52a098a67 100644
--- a/src/mesa/main/shader_query.cpp
+++ b/src/mesa/main/shader_query.cpp
@@ -61,6 +61,7 @@ DECL_RESOURCE_FUNC(UBO, gl_uniform_block);
DECL_RESOURCE_FUNC(UNI, gl_uniform_storage);
DECL_RESOURCE_FUNC(ATC, gl_active_atomic_buffer);
DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_varying_info);
+DECL_RESOURCE_FUNC(SUB, gl_subroutine_function);
void GLAPIENTRY
_mesa_BindAttribLocation(GLhandleARB program, GLuint index,
@@ -497,6 +498,20 @@ _mesa_program_resource_name(struct gl_program_resource *res)
return RESOURCE_VAR(res)->name;
case GL_UNIFORM:
return RESOURCE_UNI(res)->name;
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ return RESOURCE_UNI(res)->name + MESA_SUBROUTINE_PREFIX_LEN;
+ case GL_VERTEX_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
+ return RESOURCE_SUB(res)->name;
default:
assert(!"support for resource type not implemented");
}
@@ -515,7 +530,19 @@ _mesa_program_resource_array_size(struct gl_program_resource *res)
case GL_PROGRAM_OUTPUT:
return RESOURCE_VAR(res)->data.max_array_access;
case GL_UNIFORM:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
return RESOURCE_UNI(res)->array_elements;
+ case GL_VERTEX_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
case GL_ATOMIC_COUNTER_BUFFER:
case GL_UNIFORM_BLOCK:
return 0;
@@ -571,6 +598,18 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg,
case GL_TRANSFORM_FEEDBACK_VARYING:
case GL_UNIFORM_BLOCK:
case GL_UNIFORM:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ case GL_VERTEX_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
if (strncmp(rname, name, baselen) == 0) {
/* Basename match, check if array or struct. */
if (name[baselen] == '\0' ||
@@ -651,6 +690,18 @@ _mesa_program_resource_find_index(struct gl_shader_program *shProg,
case GL_PROGRAM_INPUT:
case GL_PROGRAM_OUTPUT:
case GL_UNIFORM:
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ case GL_VERTEX_SUBROUTINE:
+ case GL_GEOMETRY_SUBROUTINE:
+ case GL_FRAGMENT_SUBROUTINE:
+ case GL_COMPUTE_SUBROUTINE:
+ case GL_TESS_CONTROL_SUBROUTINE:
+ case GL_TESS_EVALUATION_SUBROUTINE:
if (++idx == (int) index)
return res;
break;
@@ -740,6 +791,8 @@ program_resource_location(struct gl_shader_program *shProg,
{
unsigned index, offset;
int array_index = -1;
+ long offset_ret;
+ const GLchar *base_name_end;
if (res->Type == GL_PROGRAM_INPUT || res->Type == GL_PROGRAM_OUTPUT) {
array_index = array_index_of_resource(res, name);
@@ -780,6 +833,14 @@ program_resource_location(struct gl_shader_program *shProg,
/* location in remap table + array element offset */
return RESOURCE_UNI(res)->remap_location + offset;
+ case GL_VERTEX_SUBROUTINE_UNIFORM:
+ case GL_GEOMETRY_SUBROUTINE_UNIFORM:
+ case GL_FRAGMENT_SUBROUTINE_UNIFORM:
+ case GL_COMPUTE_SUBROUTINE_UNIFORM:
+ case GL_TESS_CONTROL_SUBROUTINE_UNIFORM:
+ case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM:
+ offset_ret = parse_program_resource_name(name, &base_name_end);
+ return RESOURCE_UNI(res)->remap_location + ((offset_ret != -1) ? offset_ret : 0);
default:
return -1;
}
@@ -1048,6 +1109,46 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg,
goto invalid_operation;
*val = RESOURCE_VAR(res)->data.index;
return 1;
+
+ case GL_NUM_COMPATIBLE_SUBROUTINES:
+ if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM &&
+ res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM &&
+ res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
+ res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
+ res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
+ res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
+ goto invalid_operation;
+ *val = RESOURCE_UNI(res)->num_compatible_subroutines;
+ return 1;
+ case GL_COMPATIBLE_SUBROUTINES: {
+ const struct gl_uniform_storage *uni;
+ struct gl_shader *sh;
+ unsigned count, i;
+ int j;
+
+ if (res->Type != GL_VERTEX_SUBROUTINE_UNIFORM &&
+ res->Type != GL_FRAGMENT_SUBROUTINE_UNIFORM &&
+ res->Type != GL_GEOMETRY_SUBROUTINE_UNIFORM &&
+ res->Type != GL_COMPUTE_SUBROUTINE_UNIFORM &&
+ res->Type != GL_TESS_CONTROL_SUBROUTINE_UNIFORM &&
+ res->Type != GL_TESS_EVALUATION_SUBROUTINE_UNIFORM)
+ goto invalid_operation;
+ uni = RESOURCE_UNI(res);
+
+ sh = shProg->_LinkedShaders[_mesa_shader_stage_from_subroutine_uniform(res->Type)];
+ count = 0;
+ for (i = 0; i < sh->NumSubroutineFunctions; i++) {
+ struct gl_subroutine_function *fn = &sh->SubroutineFunctions[i];
+ for (j = 0; j < fn->num_compat_types; j++) {
+ if (fn->types[j] == uni->type) {
+ val[count++] = i;
+ break;
+ }
+ }
+ }
+ return count;
+ }
+ /* GL_ARB_tessellation_shader */
case GL_IS_PER_PATCH:
switch (res->Type) {
case GL_PROGRAM_INPUT: