mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-02-08 23:00:28 +01:00
mesa: separate shader program object from shader object.
Currently a callback delete_shader_cb is used for deleting shader and shader program objects. Mesa detaches all attached shaders in _mesa_free_shader_program_data when deleting shader program objects. However it is likely that these shaders have been freed in _mesa_free_shader, which will result in unexpected behaviour. This fix uses a single callback for shader program objects and deletes shader program objects before shader objects.
This commit is contained in:
parent
0da03c0aa9
commit
3ffd11f71d
3 changed files with 21 additions and 13 deletions
|
|
@ -444,6 +444,7 @@ alloc_shared_state( GLcontext *ctx )
|
|||
ss->ArrayObjects = _mesa_NewHashTable();
|
||||
|
||||
#if FEATURE_ARB_shader_objects
|
||||
ss->ShaderProgramObjects = _mesa_NewHashTable();
|
||||
ss->ShaderObjects = _mesa_NewHashTable();
|
||||
#endif
|
||||
|
||||
|
|
@ -523,6 +524,8 @@ cleanup:
|
|||
_mesa_DeleteHashTable (ss->ArrayObjects);
|
||||
|
||||
#if FEATURE_ARB_shader_objects
|
||||
if (ss->ShaderProgramObjects)
|
||||
_mesa_DeleteHashTable (ss->ShaderProgramObjects);
|
||||
if (ss->ShaderObjects)
|
||||
_mesa_DeleteHashTable (ss->ShaderObjects);
|
||||
#endif
|
||||
|
|
@ -631,14 +634,17 @@ delete_shader_cb(GLuint id, void *data, void *userData)
|
|||
{
|
||||
GLcontext *ctx = (GLcontext *) userData;
|
||||
struct gl_shader *sh = (struct gl_shader *) data;
|
||||
if (sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER) {
|
||||
_mesa_free_shader(ctx, sh);
|
||||
}
|
||||
else {
|
||||
struct gl_shader_program *shProg = (struct gl_shader_program *) data;
|
||||
ASSERT(shProg->Type == GL_SHADER_PROGRAM_MESA);
|
||||
_mesa_free_shader_program(ctx, shProg);
|
||||
}
|
||||
assert(sh->Type == GL_FRAGMENT_SHADER || sh->Type == GL_VERTEX_SHADER);
|
||||
_mesa_free_shader(ctx, sh);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_shader_program_cb(GLuint id, void *data, void *userData)
|
||||
{
|
||||
GLcontext *ctx = (GLcontext *) userData;
|
||||
struct gl_shader_program *shProg = (struct gl_shader_program *) data;
|
||||
assert(shProg->Type == GL_SHADER_PROGRAM_MESA);
|
||||
_mesa_free_shader_program(ctx, shProg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -721,6 +727,8 @@ free_shared_state( GLcontext *ctx, struct gl_shared_state *ss )
|
|||
_mesa_DeleteHashTable(ss->ArrayObjects);
|
||||
|
||||
#if FEATURE_ARB_shader_objects
|
||||
_mesa_HashDeleteAll(ss->ShaderProgramObjects, delete_shader_program_cb, ctx);
|
||||
_mesa_DeleteHashTable(ss->ShaderProgramObjects);
|
||||
_mesa_HashDeleteAll(ss->ShaderObjects, delete_shader_cb, ctx);
|
||||
_mesa_DeleteHashTable(ss->ShaderObjects);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -2202,8 +2202,8 @@ struct gl_shared_state
|
|||
#endif
|
||||
|
||||
#if FEATURE_ARB_shader_objects
|
||||
/** Table of both gl_shader and gl_shader_program objects */
|
||||
struct _mesa_HashTable *ShaderObjects;
|
||||
struct _mesa_HashTable *ShaderProgramObjects;
|
||||
#endif
|
||||
|
||||
#if FEATURE_EXT_framebuffer_object
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ _mesa_reference_shader_program(GLcontext *ctx,
|
|||
deleteFlag = (old->RefCount == 0);
|
||||
|
||||
if (deleteFlag) {
|
||||
_mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name);
|
||||
_mesa_HashRemove(ctx->Shared->ShaderProgramObjects, old->Name);
|
||||
_mesa_free_shader_program(ctx, old);
|
||||
}
|
||||
|
||||
|
|
@ -204,7 +204,7 @@ _mesa_lookup_shader_program(GLcontext *ctx, GLuint name)
|
|||
struct gl_shader_program *shProg;
|
||||
if (name) {
|
||||
shProg = (struct gl_shader_program *)
|
||||
_mesa_HashLookup(ctx->Shared->ShaderObjects, name);
|
||||
_mesa_HashLookup(ctx->Shared->ShaderProgramObjects, name);
|
||||
/* Note that both gl_shader and gl_shader_program objects are kept
|
||||
* in the same hash table. Check the object's type to be sure it's
|
||||
* what we're expecting.
|
||||
|
|
@ -536,10 +536,10 @@ _mesa_create_program(GLcontext *ctx)
|
|||
GLuint name;
|
||||
struct gl_shader_program *shProg;
|
||||
|
||||
name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1);
|
||||
name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderProgramObjects, 1);
|
||||
shProg = _mesa_new_shader_program(ctx, name);
|
||||
|
||||
_mesa_HashInsert(ctx->Shared->ShaderObjects, name, shProg);
|
||||
_mesa_HashInsert(ctx->Shared->ShaderProgramObjects, name, shProg);
|
||||
|
||||
assert(shProg->RefCount == 1);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue