return 0;
}
+ _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
sh = ctx->Driver.NewShader(ctx, name, type);
- _mesa_HashInsert(ctx->Shared->ShaderObjects, name, sh);
+ _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh);
+ _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
return name;
}
GLuint name;
struct gl_shader_program *shProg;
+ _mesa_HashLockMutex(ctx->Shared->ShaderObjects);
+
name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
shProg = _mesa_new_shader_program(name);
- _mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
+ _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg);
assert(shProg->RefCount == 1);
+ _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects);
+
return name;
}
for (i = 0; i < shProg->NumUniformBlocks; i++) {
/* Add one for the terminating NUL character.
*/
- const GLint len = strlen(shProg->UniformBlocks[i]->Name) + 1;
+ const GLint len = strlen(shProg->UniformBlocks[i].Name) + 1;
if (len > max_len)
max_len = len;
/* free old shader source string and install new one */
free((void *)sh->Source);
sh->Source = source;
- sh->CompileStatus = GL_FALSE;
#ifdef DEBUG
sh->SourceChecksum = _mesa_str_checksum(sh->Source);
#endif
if ((shProg != NULL) && (shProg->_LinkedShaders[stage] == NULL))
shProg = NULL;
+ if (shProg)
+ _mesa_shader_program_init_subroutine_defaults(shProg);
+
if (*target != shProg) {
/* Program is current, flush it */
if (shTarget == ctx->_Shader) {
use_shader_program(ctx, i, shProg, &ctx->Shader);
_mesa_active_program(ctx, shProg, "glUseProgram");
- _mesa_shader_program_init_subroutine_defaults(shProg);
if (ctx->Driver.UseProgram)
ctx->Driver.UseProgram(ctx, shProg);
}
switch (type) {
case MESA_SHADER_VERTEX:
dst->ClipDistanceArraySize = src->Vert.ClipDistanceArraySize;
+ dst->CullDistanceArraySize = src->Vert.CullDistanceArraySize;
break;
case MESA_SHADER_TESS_CTRL: {
struct gl_tess_ctrl_program *dst_tcp =
dst_tep->VertexOrder = src->TessEval.VertexOrder;
dst_tep->PointMode = src->TessEval.PointMode;
dst->ClipDistanceArraySize = src->TessEval.ClipDistanceArraySize;
+ dst->CullDistanceArraySize = src->TessEval.CullDistanceArraySize;
break;
}
case MESA_SHADER_GEOMETRY: {
dst_gp->InputType = src->Geom.InputType;
dst_gp->OutputType = src->Geom.OutputType;
dst->ClipDistanceArraySize = src->Geom.ClipDistanceArraySize;
+ dst->CullDistanceArraySize = src->Geom.CullDistanceArraySize;
dst_gp->UsesEndPrimitive = src->Geom.UsesEndPrimitive;
dst_gp->UsesStreams = src->Geom.UsesStreams;
break;
resource_type = _mesa_shader_stage_to_subroutine(stage);
res = _mesa_program_resource_find_name(shProg, resource_type, name, NULL);
if (!res) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
return -1;
}
return;
}
+ if (index >= sh->NumSubroutineUniforms) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "%s: invalid index greater than GL_ACTIVE_SUBROUTINE_UNIFORMS", api_name);
+ return;
+ }
+
switch (pname) {
case GL_NUM_COMPATIBLE_SUBROUTINES: {
res = _mesa_program_resource_find_index(shProg, resource_type, index);
res = _mesa_program_resource_find_index(shProg, resource_type, index);
if (res) {
values[0] = strlen(_mesa_program_resource_name(res)) + 1
- + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);;
+ + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0);
}
break;
default:
values[0] = sh->NumSubroutineUniformRemapTable;
break;
case GL_ACTIVE_SUBROUTINE_UNIFORMS:
- values[0] = sh->NumSubroutineUniformTypes;
+ values[0] = sh->NumSubroutineUniforms;
break;
case GL_ACTIVE_SUBROUTINE_MAX_LENGTH:
{