diff options
Diffstat (limited to 'src/mesa/main/program_resource.c')
-rw-r--r-- | src/mesa/main/program_resource.c | 189 |
1 files changed, 93 insertions, 96 deletions
diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c index d857b84e60d..23d2b4d2da0 100644 --- a/src/mesa/main/program_resource.c +++ b/src/mesa/main/program_resource.c @@ -28,10 +28,11 @@ #include "main/mtypes.h" #include "main/shaderapi.h" #include "main/shaderobj.h" +#include "main/context.h" #include "program_resource.h" - +#include "ir_uniform.h" static bool -supported_interface_enum(GLenum iface) +supported_interface_enum(struct gl_context *ctx, GLenum iface) { switch (iface) { case GL_UNIFORM: @@ -42,17 +43,21 @@ supported_interface_enum(GLenum iface) case GL_ATOMIC_COUNTER_BUFFER: return true; case GL_VERTEX_SUBROUTINE: - case GL_TESS_CONTROL_SUBROUTINE: - case GL_TESS_EVALUATION_SUBROUTINE: - case GL_GEOMETRY_SUBROUTINE: case GL_FRAGMENT_SUBROUTINE: - case GL_COMPUTE_SUBROUTINE: case GL_VERTEX_SUBROUTINE_UNIFORM: - case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: - case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: - case GL_GEOMETRY_SUBROUTINE_UNIFORM: case GL_FRAGMENT_SUBROUTINE_UNIFORM: + return _mesa_has_shader_subroutine(ctx); + case GL_GEOMETRY_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + return _mesa_has_geometry_shaders(ctx) && _mesa_has_shader_subroutine(ctx); + case GL_COMPUTE_SUBROUTINE: case GL_COMPUTE_SUBROUTINE_UNIFORM: + return _mesa_has_compute_shaders(ctx) && _mesa_has_shader_subroutine(ctx); + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + return _mesa_has_tessellation(ctx) && _mesa_has_shader_subroutine(ctx); case GL_BUFFER_VARIABLE: case GL_SHADER_STORAGE_BLOCK: default: @@ -79,9 +84,9 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, } /* Validate interface. */ - if (!supported_interface_enum(programInterface)) { + if (!supported_interface_enum(ctx, programInterface)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s)", - _mesa_lookup_enum_by_nr(programInterface)); + _mesa_enum_to_string(programInterface)); return; } @@ -96,8 +101,8 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, if (programInterface == GL_ATOMIC_COUNTER_BUFFER) { _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s pname %s)", - _mesa_lookup_enum_by_nr(programInterface), - _mesa_lookup_enum_by_nr(pname)); + _mesa_enum_to_string(programInterface), + _mesa_enum_to_string(pname)); return; } /* Name length consists of base name, 3 additional chars '[0]' if @@ -138,15 +143,40 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, default: _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(%s pname %s)", - _mesa_lookup_enum_by_nr(programInterface), - _mesa_lookup_enum_by_nr(pname)); + _mesa_enum_to_string(programInterface), + _mesa_enum_to_string(pname)); }; break; case GL_MAX_NUM_COMPATIBLE_SUBROUTINES: + switch (programInterface) { + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: { + for (i = 0, *params = 0; i < shProg->NumProgramResourceList; i++) { + if (shProg->ProgramResourceList[i].Type == programInterface) { + struct gl_uniform_storage *uni = + (struct gl_uniform_storage *) + shProg->ProgramResourceList[i].Data; + *params = MAX2(*params, uni->num_compatible_subroutines); + } + } + break; + } + + default: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(%s pname %s)", + _mesa_enum_to_string(programInterface), + _mesa_enum_to_string(pname)); + } + break; default: _mesa_error(ctx, GL_INVALID_OPERATION, "glGetProgramInterfaceiv(pname %s)", - _mesa_lookup_enum_by_nr(pname)); + _mesa_enum_to_string(pname)); } } @@ -173,32 +203,12 @@ is_xfb_marker(const char *str) return false; } -/** - * Checks if given name index is legal for GetProgramResourceIndex, - * check is written to be compatible with GL_ARB_array_of_arrays. - */ -static bool -valid_program_resource_index_name(const GLchar *name) -{ - const char *array = strstr(name, "["); - const char *close = strrchr(name, ']'); - - /* Not array, no need for the check. */ - if (!array) - return true; - - /* Last array index has to be zero. */ - if (!close || *--close != '0') - return false; - - return true; -} - GLuint GLAPIENTRY _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, const GLchar *name) { GET_CURRENT_CONTEXT(ctx); + unsigned array_index = 0; struct gl_program_resource *res; struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, @@ -206,6 +216,11 @@ _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, if (!shProg || !name) return GL_INVALID_INDEX; + if (!supported_interface_enum(ctx, programInterface)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)", + _mesa_enum_to_string(programInterface)); + return GL_INVALID_INDEX; + } /* * For the interface TRANSFORM_FEEDBACK_VARYING, the value INVALID_INDEX * should be returned when querying the index assigned to the special names @@ -217,24 +232,33 @@ _mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, return GL_INVALID_INDEX; switch (programInterface) { + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_VERTEX_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: case GL_PROGRAM_INPUT: case GL_PROGRAM_OUTPUT: case GL_UNIFORM: case GL_TRANSFORM_FEEDBACK_VARYING: - /* Validate name syntax for array variables */ - if (!valid_program_resource_index_name(name)) - return GL_INVALID_INDEX; - /* fall-through */ case GL_UNIFORM_BLOCK: - res = _mesa_program_resource_find_name(shProg, programInterface, name); - if (!res) + res = _mesa_program_resource_find_name(shProg, programInterface, name, + &array_index); + if (!res || array_index > 0) return GL_INVALID_INDEX; return _mesa_program_resource_index(shProg, res); case GL_ATOMIC_COUNTER_BUFFER: default: _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceIndex(%s)", - _mesa_lookup_enum_by_nr(programInterface)); + _mesa_enum_to_string(programInterface)); } return GL_INVALID_INDEX; @@ -250,19 +274,13 @@ _mesa_GetProgramResourceName(GLuint program, GLenum programInterface, _mesa_lookup_shader_program_err(ctx, program, "glGetProgramResourceName"); - /* Set user friendly return values in case of errors. */ - if (name) - *name = '\0'; - if (length) - *length = 0; - if (!shProg || !name) return; if (programInterface == GL_ATOMIC_COUNTER_BUFFER || - !supported_interface_enum(programInterface)) { + !supported_interface_enum(ctx, programInterface)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceName(%s)", - _mesa_lookup_enum_by_nr(programInterface)); + _mesa_enum_to_string(programInterface)); return; } @@ -300,36 +318,6 @@ _mesa_GetProgramResourceiv(GLuint program, GLenum programInterface, propCount, props, bufSize, length, params); } -/** - * Function verifies syntax of given name for GetProgramResourceLocation - * and GetProgramResourceLocationIndex for the following cases: - * - * "array element portion of a string passed to GetProgramResourceLocation - * or GetProgramResourceLocationIndex must not have, a "+" sign, extra - * leading zeroes, or whitespace". - * - * Check is written to be compatible with GL_ARB_array_of_arrays. - */ -static bool -invalid_array_element_syntax(const GLchar *name) -{ - char *first = strchr(name, '['); - char *last = strrchr(name, '['); - - if (!first) - return false; - - /* No '+' or ' ' allowed anywhere. */ - if (strchr(first, '+') || strchr(first, ' ')) - return true; - - /* Check that last array index is 0. */ - if (last[1] == '0' && last[2] != ']') - return true; - - return false; -} - static struct gl_shader_program * lookup_linked_program(GLuint program, const char *caller) { @@ -356,7 +344,7 @@ _mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface, struct gl_shader_program *shProg = lookup_linked_program(program, "glGetProgramResourceLocation"); - if (!shProg || !name || invalid_array_element_syntax(name)) + if (!shProg || !name) return -1; /* Validate programInterface. */ @@ -366,24 +354,33 @@ _mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface, case GL_PROGRAM_OUTPUT: break; - /* For reference valid cases requiring additional extension support: - * GL_ARB_shader_subroutine - * GL_ARB_tessellation_shader - * GL_ARB_compute_shader - */ case GL_VERTEX_SUBROUTINE_UNIFORM: - case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: - case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: - case GL_GEOMETRY_SUBROUTINE_UNIFORM: case GL_FRAGMENT_SUBROUTINE_UNIFORM: + if (!_mesa_has_shader_subroutine(ctx)) + goto fail; + break; + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + if (!_mesa_has_geometry_shaders(ctx) || !_mesa_has_shader_subroutine(ctx)) + goto fail; + break; case GL_COMPUTE_SUBROUTINE_UNIFORM: - + if (!_mesa_has_compute_shaders(ctx) || !_mesa_has_shader_subroutine(ctx)) + goto fail; + break; + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + if (!_mesa_has_tessellation(ctx) || !_mesa_has_shader_subroutine(ctx)) + goto fail; + break; default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)", - _mesa_lookup_enum_by_nr(programInterface), name); + goto fail; } return _mesa_program_resource_location(shProg, programInterface, name); +fail: + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocation(%s %s)", + _mesa_enum_to_string(programInterface), name); + return -1; } /** @@ -397,7 +394,7 @@ _mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, struct gl_shader_program *shProg = lookup_linked_program(program, "glGetProgramResourceLocationIndex"); - if (!shProg || !name || invalid_array_element_syntax(name)) + if (!shProg || !name) return -1; /* From the GL_ARB_program_interface_query spec: @@ -408,7 +405,7 @@ _mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, if (programInterface != GL_PROGRAM_OUTPUT) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramResourceLocationIndex(%s)", - _mesa_lookup_enum_by_nr(programInterface)); + _mesa_enum_to_string(programInterface)); return -1; } |