X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=inline;f=src%2Fmesa%2Fmain%2Fshaderapi.c;h=d40a35376701a04caccba8860f70f29cbe030cf3;hb=aab0ea935290cdbf6c74e4d001d4bbc8178fc14a;hp=6650613d28d76ea3cca3dec505b71568a807aa94;hpb=4293a12c7f0d4fd7ac3a278570f3fe55fc4433a6;p=mesa.git diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 6650613d28d..d40a3537670 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -45,12 +45,13 @@ #include "main/mtypes.h" #include "main/shaderapi.h" #include "main/shaderobj.h" +#include "main/uniforms.h" #include "program/program.h" #include "program/prog_parameter.h" -#include "program/prog_uniform.h" #include "ralloc.h" #include #include "../glsl/glsl_parser_extras.h" +#include "../glsl/ir_uniform.h" /** Define this to enable shader substitution (see below) */ #define SHADER_SUBST 0 @@ -82,6 +83,8 @@ get_shader_flags(void) flags |= GLSL_UNIFORMS; if (strstr(env, "useprog")) flags |= GLSL_USE_PROG; + if (strstr(env, "errors")) + flags |= GLSL_REPORT_ERRORS; } return flags; @@ -102,6 +105,7 @@ _mesa_init_shader_state(struct gl_context *ctx) memset(&options, 0, sizeof(options)); options.MaxUnrollIterations = 32; + options.MaxIfDepth = UINT_MAX; /* Default pragma settings */ options.DefaultPragmas.Optimize = GL_TRUE; @@ -124,68 +128,12 @@ _mesa_free_shader_state(struct gl_context *ctx) NULL); _mesa_reference_shader_program(ctx, &ctx->Shader.CurrentFragmentProgram, NULL); + _mesa_reference_shader_program(ctx, &ctx->Shader._CurrentFragmentProgram, + NULL); _mesa_reference_shader_program(ctx, &ctx->Shader.ActiveProgram, NULL); } -/** - * Return the size of the given GLSL datatype, in floats (components). - */ -GLint -_mesa_sizeof_glsl_type(GLenum type) -{ - switch (type) { - case GL_FLOAT: - case GL_INT: - case GL_BOOL: - case GL_SAMPLER_1D: - case GL_SAMPLER_2D: - case GL_SAMPLER_3D: - case GL_SAMPLER_CUBE: - case GL_SAMPLER_1D_SHADOW: - case GL_SAMPLER_2D_SHADOW: - case GL_SAMPLER_2D_RECT_ARB: - case GL_SAMPLER_2D_RECT_SHADOW_ARB: - case GL_SAMPLER_1D_ARRAY_EXT: - case GL_SAMPLER_2D_ARRAY_EXT: - case GL_SAMPLER_1D_ARRAY_SHADOW_EXT: - case GL_SAMPLER_2D_ARRAY_SHADOW_EXT: - case GL_SAMPLER_CUBE_SHADOW_EXT: - return 1; - case GL_FLOAT_VEC2: - case GL_INT_VEC2: - case GL_UNSIGNED_INT_VEC2: - case GL_BOOL_VEC2: - return 2; - case GL_FLOAT_VEC3: - case GL_INT_VEC3: - case GL_UNSIGNED_INT_VEC3: - case GL_BOOL_VEC3: - return 3; - case GL_FLOAT_VEC4: - case GL_INT_VEC4: - case GL_UNSIGNED_INT_VEC4: - case GL_BOOL_VEC4: - return 4; - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT2x3: - case GL_FLOAT_MAT2x4: - return 8; /* two float[4] vectors */ - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT3x2: - case GL_FLOAT_MAT3x4: - return 12; /* three float[4] vectors */ - case GL_FLOAT_MAT4: - case GL_FLOAT_MAT4x2: - case GL_FLOAT_MAT4x3: - return 16; /* four float[4] vectors */ - default: - _mesa_problem(NULL, "Invalid type in _mesa_sizeof_glsl_type()"); - return 1; - } -} - - /** * Copy string from to , up to maxLength characters, returning * length of in . @@ -220,18 +168,12 @@ static bool validate_shader_target(const struct gl_context *ctx, GLenum type) { switch (type) { -#if FEATURE_ARB_fragment_shader case GL_FRAGMENT_SHADER: return ctx->Extensions.ARB_fragment_shader; -#endif -#if FEATURE_ARB_vertex_shader case GL_VERTEX_SHADER: return ctx->Extensions.ARB_vertex_shader; -#endif -#if FEATURE_ARB_geometry_shader4 case GL_GEOMETRY_SHADER_ARB: - return ctx->Extensions.ARB_geometry_shader4; -#endif + return _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; default: return false; } @@ -323,98 +265,6 @@ attach_shader(struct gl_context *ctx, GLuint program, GLuint shader) } -static GLint -get_attrib_location(struct gl_context *ctx, GLuint program, const GLchar *name) -{ - struct gl_shader_program *shProg - = _mesa_lookup_shader_program_err(ctx, program, "glGetAttribLocation"); - - if (!shProg) { - return -1; - } - - if (!shProg->LinkStatus) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetAttribLocation(program not linked)"); - return -1; - } - - if (!name) - return -1; - - if (shProg->VertexProgram) { - const struct gl_program_parameter_list *attribs = - shProg->VertexProgram->Base.Attributes; - if (attribs) { - GLint i = _mesa_lookup_parameter_index(attribs, -1, name); - if (i >= 0) { - return attribs->Parameters[i].StateIndexes[0]; - } - } - } - return -1; -} - - -static void -bind_attrib_location(struct gl_context *ctx, GLuint program, GLuint index, - const GLchar *name) -{ - struct gl_shader_program *shProg; - const GLint size = -1; /* unknown size */ - GLint i, oldIndex; - GLenum datatype = GL_FLOAT_VEC4; - - shProg = _mesa_lookup_shader_program_err(ctx, program, - "glBindAttribLocation"); - if (!shProg) { - return; - } - - if (!name) - return; - - if (strncmp(name, "gl_", 3) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindAttribLocation(illegal name)"); - return; - } - - if (index >= ctx->Const.VertexProgram.MaxAttribs) { - _mesa_error(ctx, GL_INVALID_VALUE, "glBindAttribLocation(index)"); - return; - } - - if (shProg->LinkStatus) { - /* get current index/location for the attribute */ - oldIndex = get_attrib_location(ctx, program, name); - } - else { - oldIndex = -1; - } - - /* this will replace the current value if it's already in the list */ - i = _mesa_add_attribute(shProg->Attributes, name, size, datatype, index); - if (i < 0) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindAttribLocation"); - return; - } - - /* - * Note that this attribute binding won't go into effect until - * glLinkProgram is called again. - */ -} - - -static void -bind_frag_data_location(struct gl_context *ctx, GLuint program, - GLuint colorNumber, const GLchar *name) -{ - _mesa_problem(ctx, "bind_frag_data_location() not implemented yet"); -} - - static GLuint create_shader(struct gl_context *ctx, GLenum type) { @@ -473,10 +323,12 @@ delete_shader_program(struct gl_context *ctx, GLuint name) if (!shProg) return; - shProg->DeletePending = GL_TRUE; + if (!shProg->DeletePending) { + shProg->DeletePending = GL_TRUE; - /* effectively, decr shProg's refcount */ - _mesa_reference_shader_program(ctx, &shProg, NULL); + /* effectively, decr shProg's refcount */ + _mesa_reference_shader_program(ctx, &shProg, NULL); + } } @@ -489,10 +341,12 @@ delete_shader(struct gl_context *ctx, GLuint shader) if (!sh) return; - sh->DeletePending = GL_TRUE; + if (!sh->DeletePending) { + sh->DeletePending = GL_TRUE; - /* effectively, decr sh's refcount */ - _mesa_reference_shader(ctx, &sh, NULL); + /* effectively, decr sh's refcount */ + _mesa_reference_shader(ctx, &sh, NULL); + } } @@ -518,7 +372,7 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader) _mesa_reference_shader(ctx, &shProg->Shaders[i], NULL); /* alloc new, smaller array */ - newList = (struct gl_shader **) + newList = malloc((n - 1) * sizeof(struct gl_shader *)); if (!newList) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glDetachShader"); @@ -564,38 +418,6 @@ detach_shader(struct gl_context *ctx, GLuint program, GLuint shader) } -static void -get_active_attrib(struct gl_context *ctx, GLuint program, GLuint index, - GLsizei maxLength, GLsizei *length, GLint *size, - GLenum *type, GLchar *nameOut) -{ - const struct gl_program_parameter_list *attribs = NULL; - struct gl_shader_program *shProg; - - shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetActiveAttrib"); - if (!shProg) - return; - - if (shProg->VertexProgram) - attribs = shProg->VertexProgram->Base.Attributes; - - if (!attribs || index >= attribs->NumParameters) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetActiveAttrib(index)"); - return; - } - - _mesa_copy_string(nameOut, maxLength, length, - attribs->Parameters[index].Name); - - if (size) - *size = attribs->Parameters[index].Size - / _mesa_sizeof_glsl_type(attribs->Parameters[index].DataType); - - if (type) - *type = attribs->Parameters[index].DataType; -} - - /** * Return list of shaders attached to shader program. */ @@ -616,16 +438,6 @@ get_attached_shaders(struct gl_context *ctx, GLuint program, GLsizei maxCount, } -static GLint -get_frag_data_location(struct gl_context *ctx, GLuint program, - const GLchar *name) -{ - _mesa_problem(ctx, "get_frag_data_location() not implemented yet"); - return -1; -} - - - /** * glGetHandleARB() - return ID/name of currently bound shader program. */ @@ -653,79 +465,135 @@ get_handle(struct gl_context *ctx, GLenum pname) static void get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *params) { - const struct gl_program_parameter_list *attribs; struct gl_shader_program *shProg = _mesa_lookup_shader_program(ctx, program); + /* Is transform feedback available in this context? + */ + const bool has_xfb = + (ctx->API == API_OPENGL && ctx->Extensions.EXT_transform_feedback) + || ctx->API == API_OPENGL_CORE + || _mesa_is_gles3(ctx); + + /* Are geometry shaders available in this context? + */ + const bool has_gs = + _mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_geometry_shader4; + + /* Are uniform buffer objects available in this context? + */ + const bool has_ubo = + (ctx->API == API_OPENGL && ctx->Extensions.ARB_uniform_buffer_object) + || ctx->API == API_OPENGL_CORE + || _mesa_is_gles3(ctx); + if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, "glGetProgramiv(program)"); return; } - if (shProg->VertexProgram) - attribs = shProg->VertexProgram->Base.Attributes; - else - attribs = NULL; - switch (pname) { case GL_DELETE_STATUS: *params = shProg->DeletePending; - break; + return; case GL_LINK_STATUS: *params = shProg->LinkStatus; - break; + return; case GL_VALIDATE_STATUS: *params = shProg->Validated; - break; + return; case GL_INFO_LOG_LENGTH: *params = shProg->InfoLog ? strlen(shProg->InfoLog) + 1 : 0; - break; + return; case GL_ATTACHED_SHADERS: *params = shProg->NumShaders; - break; + return; case GL_ACTIVE_ATTRIBUTES: - *params = attribs ? attribs->NumParameters : 0; - break; + *params = _mesa_count_active_attribs(shProg); + return; case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH: - *params = _mesa_longest_parameter_name(attribs, PROGRAM_INPUT) + 1; - break; + *params = _mesa_longest_attribute_name_length(shProg); + return; case GL_ACTIVE_UNIFORMS: - *params = shProg->Uniforms ? shProg->Uniforms->NumUniforms : 0; - break; - case GL_ACTIVE_UNIFORM_MAX_LENGTH: - *params = _mesa_longest_uniform_name(shProg->Uniforms); - if (*params > 0) - (*params)++; /* add one for terminating zero */ - break; - case GL_PROGRAM_BINARY_LENGTH_OES: - *params = 0; - break; -#if FEATURE_EXT_transform_feedback + *params = shProg->NumUserUniformStorage; + return; + case GL_ACTIVE_UNIFORM_MAX_LENGTH: { + unsigned i; + GLint max_len = 0; + + for (i = 0; i < shProg->NumUserUniformStorage; i++) { + /* Add one for the terminating NUL character. + */ + const GLint len = strlen(shProg->UniformStorage[i].name) + 1; + + if (len > max_len) + max_len = len; + } + + *params = max_len; + return; + } case GL_TRANSFORM_FEEDBACK_VARYINGS: + if (!has_xfb) + break; *params = shProg->TransformFeedback.NumVarying; - break; + return; case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + if (!has_xfb) + break; *params = longest_feedback_varying_name(shProg) + 1; - break; + return; case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: + if (!has_xfb) + break; *params = shProg->TransformFeedback.BufferMode; - break; -#endif -#if FEATURE_ARB_geometry_shader4 + return; case GL_GEOMETRY_VERTICES_OUT_ARB: + if (!has_gs) + break; *params = shProg->Geom.VerticesOut; - break; + return; case GL_GEOMETRY_INPUT_TYPE_ARB: + if (!has_gs) + break; *params = shProg->Geom.InputType; - break; + return; case GL_GEOMETRY_OUTPUT_TYPE_ARB: + if (!has_gs) + break; *params = shProg->Geom.OutputType; - break; -#endif - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname)"); return; + case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: { + unsigned i; + GLint max_len = 0; + + if (!has_ubo) + break; + + for (i = 0; i < shProg->NumUniformBlocks; i++) { + /* Add one for the terminating NUL character. + */ + const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1; + + if (len > max_len) + max_len = len; + } + + *params = max_len; + return; + } + case GL_ACTIVE_UNIFORM_BLOCKS: + if (!has_ubo) + break; + + *params = shProg->NumUniformBlocks; + return; + default: + break; } + + _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramiv(pname=%s)", + _mesa_lookup_enum_by_nr(pname)); } @@ -809,7 +677,8 @@ get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, /** - * Set/replace shader source code. + * Set/replace shader source code. A helper function used by + * glShaderSource[ARB] and glCreateShaderProgramEXT. */ static void shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source) @@ -821,9 +690,7 @@ shader_source(struct gl_context *ctx, GLuint shader, const GLchar *source) return; /* free old shader source string and install new one */ - if (sh->Source) { - free((void *) sh->Source); - } + free((void *)sh->Source); sh->Source = source; sh->CompileStatus = GL_FALSE; #ifdef DEBUG @@ -854,6 +721,12 @@ compile_shader(struct gl_context *ctx, GLuint shaderObj) * compilation was successful. */ _mesa_glsl_compile_shader(ctx, sh); + + if (sh->CompileStatus == GL_FALSE && + (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) { + _mesa_debug(ctx, "Error compiling shader %u:\n%s\n", + sh->Name, sh->InfoLog); + } } @@ -876,7 +749,7 @@ link_program(struct gl_context *ctx, GLuint program) || shProg == ctx->Shader.CurrentGeometryProgram || shProg == ctx->Shader.CurrentFragmentProgram)) { _mesa_error(ctx, GL_INVALID_OPERATION, - "glLinkProgram(transform feedback active"); + "glLinkProgram(transform feedback active)"); return; } @@ -884,6 +757,12 @@ link_program(struct gl_context *ctx, GLuint program) _mesa_glsl_link_shader(ctx, shProg); + if (shProg->LinkStatus == GL_FALSE && + (ctx->Shader.Flags & GLSL_REPORT_ERRORS)) { + _mesa_debug(ctx, "Error linking program %u:\n%s\n", + shProg->Name, shProg->InfoLog); + } + /* debug code */ if (0) { GLuint i; @@ -929,10 +808,15 @@ print_shader_info(const struct gl_shader_program *shProg) shProg->Shaders[i]->Name, shProg->Shaders[i]->SourceChecksum); } - if (shProg->VertexProgram) - printf(" vert prog %u\n", shProg->VertexProgram->Base.Id); - if (shProg->FragmentProgram) - printf(" frag prog %u\n", shProg->FragmentProgram->Base.Id); + if (shProg->_LinkedShaders[MESA_SHADER_VERTEX]) + printf(" vert prog %u\n", + shProg->_LinkedShaders[MESA_SHADER_VERTEX]->Program->Id); + if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]) + printf(" frag prog %u\n", + shProg->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program->Id); + if (shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]) + printf(" geom prog %u\n", + shProg->_LinkedShaders[MESA_SHADER_GEOMETRY]->Program->Id); } @@ -963,7 +847,6 @@ use_shader_program(struct gl_context *ctx, GLenum type, struct gl_shader_program **target; switch (type) { -#if FEATURE_ARB_vertex_shader case GL_VERTEX_SHADER: target = &ctx->Shader.CurrentVertexProgram; if ((shProg == NULL) @@ -971,8 +854,6 @@ use_shader_program(struct gl_context *ctx, GLenum type, shProg = NULL; } break; -#endif -#if FEATURE_ARB_geometry_shader4 case GL_GEOMETRY_SHADER_ARB: target = &ctx->Shader.CurrentGeometryProgram; if ((shProg == NULL) @@ -980,8 +861,6 @@ use_shader_program(struct gl_context *ctx, GLenum type, shProg = NULL; } break; -#endif -#if FEATURE_ARB_fragment_shader case GL_FRAGMENT_SHADER: target = &ctx->Shader.CurrentFragmentProgram; if ((shProg == NULL) @@ -989,13 +868,33 @@ use_shader_program(struct gl_context *ctx, GLenum type, shProg = NULL; } break; -#endif default: return false; } if (*target != shProg) { FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS); + + /* If the shader is also bound as the current rendering shader, unbind + * it from that binding point as well. This ensures that the correct + * semantics of glDeleteProgram are maintained. + */ + switch (type) { + case GL_VERTEX_SHADER: + /* Empty for now. */ + break; + case GL_GEOMETRY_SHADER_ARB: + /* Empty for now. */ + break; + case GL_FRAGMENT_SHADER: + if (*target == ctx->Shader._CurrentFragmentProgram) { + _mesa_reference_shader_program(ctx, + &ctx->Shader._CurrentFragmentProgram, + NULL); + } + break; + } + _mesa_reference_shader_program(ctx, target, shProg); return true; } @@ -1019,59 +918,6 @@ _mesa_use_program(struct gl_context *ctx, struct gl_shader_program *shProg) } -/** - * Validate a program's samplers. - * Specifically, check that there aren't two samplers of different types - * pointing to the same texture unit. - * \return GL_TRUE if valid, GL_FALSE if invalid - */ -static GLboolean -validate_samplers(const struct gl_program *prog, char *errMsg) -{ - static const char *targetName[] = { - "TEXTURE_2D_ARRAY", - "TEXTURE_1D_ARRAY", - "TEXTURE_CUBE", - "TEXTURE_3D", - "TEXTURE_RECT", - "TEXTURE_2D", - "TEXTURE_1D", - }; - GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS]; - GLbitfield samplersUsed = prog->SamplersUsed; - GLuint i; - - assert(Elements(targetName) == NUM_TEXTURE_TARGETS); - - if (samplersUsed == 0x0) - return GL_TRUE; - - for (i = 0; i < Elements(targetUsed); i++) - targetUsed[i] = -1; - - /* walk over bits which are set in 'samplers' */ - while (samplersUsed) { - GLuint unit; - gl_texture_index target; - GLint sampler = _mesa_ffs(samplersUsed) - 1; - assert(sampler >= 0); - assert(sampler < MAX_TEXTURE_IMAGE_UNITS); - unit = prog->SamplerUnits[sampler]; - target = prog->SamplerTargets[sampler]; - if (targetUsed[unit] != -1 && targetUsed[unit] != (int) target) { - _mesa_snprintf(errMsg, 100, - "Texture unit %d is accessed both as %s and %s", - unit, targetName[targetUsed[unit]], targetName[target]); - return GL_FALSE; - } - targetUsed[unit] = target; - samplersUsed ^= (1 << sampler); - } - - return GL_TRUE; -} - - /** * Do validation of the given shader program. * \param errMsg returns error message if validation fails. @@ -1081,9 +927,6 @@ static GLboolean validate_shader_program(const struct gl_shader_program *shProg, char *errMsg) { - const struct gl_vertex_program *vp = shProg->VertexProgram; - const struct gl_fragment_program *fp = shProg->FragmentProgram; - if (!shProg->LinkStatus) { return GL_FALSE; } @@ -1108,12 +951,8 @@ validate_shader_program(const struct gl_shader_program *shProg, * Check: any two active samplers in the current program object are of * different types, but refer to the same texture image unit, */ - if (vp && !validate_samplers(&vp->Base, errMsg)) { - return GL_FALSE; - } - if (fp && !validate_samplers(&fp->Base, errMsg)) { + if (!_mesa_sampler_uniforms_are_valid(shProg, errMsg, 100)) return GL_FALSE; - } return GL_TRUE; } @@ -1126,7 +965,7 @@ static void validate_program(struct gl_context *ctx, GLuint program) { struct gl_shader_program *shProg; - char errMsg[100]; + char errMsg[100] = ""; shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram"); if (!shProg) { @@ -1161,25 +1000,6 @@ _mesa_AttachShader(GLuint program, GLuint shader) } -void GLAPIENTRY -_mesa_BindAttribLocationARB(GLhandleARB program, GLuint index, - const GLcharARB *name) -{ - GET_CURRENT_CONTEXT(ctx); - bind_attrib_location(ctx, program, index, name); -} - - -/* GL_EXT_gpu_shader4, GL3 */ -void GLAPIENTRY -_mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, - const GLchar *name) -{ - GET_CURRENT_CONTEXT(ctx); - bind_frag_data_location(ctx, program, colorNumber, name); -} - - void GLAPIENTRY _mesa_CompileShaderARB(GLhandleARB shaderObj) { @@ -1288,16 +1108,6 @@ _mesa_DetachShader(GLuint program, GLuint shader) } -void GLAPIENTRY -_mesa_GetActiveAttribARB(GLhandleARB program, GLuint index, - GLsizei maxLength, GLsizei * length, GLint * size, - GLenum * type, GLcharARB * name) -{ - GET_CURRENT_CONTEXT(ctx); - get_active_attrib(ctx, program, index, maxLength, length, size, type, name); -} - - void GLAPIENTRY _mesa_GetAttachedObjectsARB(GLhandleARB container, GLsizei maxCount, GLsizei * count, GLhandleARB * obj) @@ -1316,24 +1126,6 @@ _mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, } -GLint GLAPIENTRY -_mesa_GetAttribLocationARB(GLhandleARB program, const GLcharARB * name) -{ - GET_CURRENT_CONTEXT(ctx); - return get_attrib_location(ctx, program, name); -} - - -/* GL_EXT_gpu_shader4, GL3 */ -GLint GLAPIENTRY -_mesa_GetFragDataLocation(GLuint program, const GLchar *name) -{ - GET_CURRENT_CONTEXT(ctx); - return get_frag_data_location(ctx, program, name); -} - - - void GLAPIENTRY _mesa_GetInfoLogARB(GLhandleARB object, GLsizei maxLength, GLsizei * length, GLcharARB * infoLog) @@ -1480,7 +1272,7 @@ read_shader(const char *fname) return NULL; } - buffer = (char *) malloc(max); + buffer = malloc(max); len = fread(buffer, 1, max, f); buffer[len] = 0; @@ -1517,7 +1309,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, * This array holds offsets of where the appropriate string ends, thus the * last element will be set to the total length of the source code. */ - offsets = (GLint *) malloc(count * sizeof(GLint)); + offsets = malloc(count * sizeof(GLint)); if (offsets == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); return; @@ -1526,7 +1318,8 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, for (i = 0; i < count; i++) { if (string[i] == NULL) { free((GLvoid *) offsets); - _mesa_error(ctx, GL_INVALID_OPERATION, "glShaderSourceARB(null string)"); + _mesa_error(ctx, GL_INVALID_OPERATION, + "glShaderSourceARB(null string)"); return; } if (length == NULL || length[i] < 0) @@ -1543,7 +1336,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, * valgrind warnings in the parser/grammer code. */ totalLength = offsets[count - 1] + 2; - source = (GLcharARB *) malloc(totalLength * sizeof(GLcharARB)); + source = malloc(totalLength * sizeof(GLcharARB)); if (source == NULL) { free((GLvoid *) offsets); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderSourceARB"); @@ -1577,7 +1370,7 @@ _mesa_ShaderSourceARB(GLhandleARB shaderObj, GLsizei count, free(source); source = newSource; } - } + } shader_source(ctx, shaderObj, source); @@ -1599,7 +1392,9 @@ _mesa_UseProgramObjectARB(GLhandleARB program) struct gl_transform_feedback_object *obj = ctx->TransformFeedback.CurrentObject; - if (obj->Active) { + ASSERT_OUTSIDE_BEGIN_END(ctx); + + if (obj->Active && !obj->Paused) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUseProgram(transform feedback active)"); return; @@ -1713,11 +1508,8 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, #endif /* FEATURE_ES2 */ -#if FEATURE_ARB_geometry_shader4 - void GLAPIENTRY -_mesa_ProgramParameteriARB(GLuint program, GLenum pname, - GLint value) +_mesa_ProgramParameteriARB(GLuint program, GLenum pname, GLint value) { struct gl_shader_program *shProg; GET_CURRENT_CONTEXT(ctx); @@ -1732,7 +1524,7 @@ _mesa_ProgramParameteriARB(GLuint program, GLenum pname, switch (pname) { case GL_GEOMETRY_VERTICES_OUT_ARB: if (value < 1 || - (unsigned) value > ctx->Const.GeometryProgram.MaxGeometryOutputVertices) { + (unsigned) value > ctx->Const.MaxGeometryOutputVertices) { _mesa_error(ctx, GL_INVALID_VALUE, "glProgramParameteri(GL_GEOMETRY_VERTICES_OUT_ARB=%d", value); @@ -1777,8 +1569,6 @@ _mesa_ProgramParameteriARB(GLuint program, GLenum pname, } } -#endif - void _mesa_use_shader_program(struct gl_context *ctx, GLenum type, struct gl_shader_program *shProg) @@ -1789,18 +1579,25 @@ _mesa_use_shader_program(struct gl_context *ctx, GLenum type, ctx->Driver.UseProgram(ctx, shProg); } + +/** + * For GL_EXT_separate_shader_objects + */ void GLAPIENTRY _mesa_UseShaderProgramEXT(GLenum type, GLuint program) { GET_CURRENT_CONTEXT(ctx); struct gl_shader_program *shProg = NULL; + ASSERT_OUTSIDE_BEGIN_END(ctx); + if (!validate_shader_target(ctx, type)) { _mesa_error(ctx, GL_INVALID_ENUM, "glUseShaderProgramEXT(type)"); return; } - if (ctx->TransformFeedback.CurrentObject->Active) { + if (ctx->TransformFeedback.CurrentObject->Active && + !ctx->TransformFeedback.CurrentObject->Paused) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUseShaderProgramEXT(transform feedback is active)"); return; @@ -1822,6 +1619,10 @@ _mesa_UseShaderProgramEXT(GLenum type, GLuint program) _mesa_use_shader_program(ctx, type, shProg); } + +/** + * For GL_EXT_separate_shader_objects + */ void GLAPIENTRY _mesa_ActiveProgramEXT(GLuint program) { @@ -1834,6 +1635,10 @@ _mesa_ActiveProgramEXT(GLuint program) return; } + +/** + * For GL_EXT_separate_shader_objects + */ GLuint GLAPIENTRY _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string) { @@ -1882,25 +1687,29 @@ _mesa_CreateShaderProgramEXT(GLenum type, const GLchar *string) * Plug in shader-related functions into API dispatch table. */ void -_mesa_init_shader_dispatch(struct _glapi_table *exec) +_mesa_init_shader_dispatch(const struct gl_context *ctx, + struct _glapi_table *exec) { #if FEATURE_GL /* GL_ARB_vertex/fragment_shader */ - SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB); - SET_GetHandleARB(exec, _mesa_GetHandleARB); - SET_DetachObjectARB(exec, _mesa_DetachObjectARB); - SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB); + if (ctx->API != API_OPENGLES2) { + SET_DeleteObjectARB(exec, _mesa_DeleteObjectARB); + SET_GetHandleARB(exec, _mesa_GetHandleARB); + SET_DetachObjectARB(exec, _mesa_DetachObjectARB); + SET_CreateShaderObjectARB(exec, _mesa_CreateShaderObjectARB); + SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB); + SET_AttachObjectARB(exec, _mesa_AttachObjectARB); + SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB); + SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB); + SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB); + SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB); + } + SET_ShaderSourceARB(exec, _mesa_ShaderSourceARB); SET_CompileShaderARB(exec, _mesa_CompileShaderARB); - SET_CreateProgramObjectARB(exec, _mesa_CreateProgramObjectARB); - SET_AttachObjectARB(exec, _mesa_AttachObjectARB); SET_LinkProgramARB(exec, _mesa_LinkProgramARB); SET_UseProgramObjectARB(exec, _mesa_UseProgramObjectARB); SET_ValidateProgramARB(exec, _mesa_ValidateProgramARB); - SET_GetObjectParameterfvARB(exec, _mesa_GetObjectParameterfvARB); - SET_GetObjectParameterivARB(exec, _mesa_GetObjectParameterivARB); - SET_GetInfoLogARB(exec, _mesa_GetInfoLogARB); - SET_GetAttachedObjectsARB(exec, _mesa_GetAttachedObjectsARB); SET_GetShaderSourceARB(exec, _mesa_GetShaderSourceARB); /* OpenGL 2.0 */ @@ -1918,28 +1727,37 @@ _mesa_init_shader_dispatch(struct _glapi_table *exec) SET_IsProgram(exec, _mesa_IsProgram); SET_IsShader(exec, _mesa_IsShader); -#if FEATURE_ARB_vertex_shader + /* GL_ARB_vertex_shader */ SET_BindAttribLocationARB(exec, _mesa_BindAttribLocationARB); SET_GetActiveAttribARB(exec, _mesa_GetActiveAttribARB); SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB); -#endif -#if FEATURE_ARB_geometry_shader4 - SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB); -#endif + if (ctx->API != API_OPENGLES2) { + SET_ProgramParameteriARB(exec, _mesa_ProgramParameteriARB); - SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT); - SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT); - SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT); + SET_UseShaderProgramEXT(exec, _mesa_UseShaderProgramEXT); + SET_ActiveProgramEXT(exec, _mesa_ActiveProgramEXT); + SET_CreateShaderProgramEXT(exec, _mesa_CreateShaderProgramEXT); + } /* GL_EXT_gpu_shader4 / GL 3.0 */ - SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation); - SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation); + if (ctx->API != API_OPENGLES2) { + SET_BindFragDataLocationEXT(exec, _mesa_BindFragDataLocation); + } + if (ctx->API != API_OPENGLES2 || _mesa_is_gles3(ctx)) { + SET_GetFragDataLocationEXT(exec, _mesa_GetFragDataLocation); + } /* GL_ARB_ES2_compatibility */ SET_ReleaseShaderCompiler(exec, _mesa_ReleaseShaderCompiler); SET_GetShaderPrecisionFormat(exec, _mesa_GetShaderPrecisionFormat); + SET_ShaderBinary(exec, _mesa_ShaderBinary); + /* GL_ARB_blend_func_extended */ + if (ctx->API != API_OPENGLES2) { + SET_BindFragDataLocationIndexed(exec, _mesa_BindFragDataLocationIndexed); + SET_GetFragDataIndex(exec, _mesa_GetFragDataIndex); + } #endif /* FEATURE_GL */ }