mirror of
https://gitee.com/openharmony/third_party_mesa3d
synced 2024-11-25 08:20:34 +00:00
mesa/subroutines: start adding per-context subroutine index support (v1.1)
One piece of ARB_shader_subroutine I ignored was the fact that it needs to store the subroutine index data per context and not per shader program. There is one CTS test that tests this: GL45-CTS.shader_subroutine.multiple_contexts However the test only does a write to context and readback, it never renders using the values, so this is enough to fix the test however not enough to do what the spec says. So with this patch the info is now stored per context, but it gets updated into the program at UseProgram and when the values are inserted into the context, which won't help if multiple contexts are in use in multiple threads. v1.1: cleanups and nit-picks (Andres) Signed-off-by: Dave Airlie <airlied@redhat.com> Reviewed-by: Andres Gomez <agomez@igalia.com>
This commit is contained in:
parent
27d20ee264
commit
4566aaaa5b
@ -4314,6 +4314,15 @@ struct gl_atomic_buffer_binding
|
||||
GLsizeiptr Size;
|
||||
};
|
||||
|
||||
/**
|
||||
* Shader subroutines storage
|
||||
*/
|
||||
struct gl_subroutine_index_binding
|
||||
{
|
||||
GLuint NumIndex;
|
||||
GLuint *IndexPtr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Mesa rendering context.
|
||||
*
|
||||
@ -4552,6 +4561,7 @@ struct gl_context
|
||||
*/
|
||||
struct gl_image_unit ImageUnits[MAX_IMAGE_UNITS];
|
||||
|
||||
struct gl_subroutine_index_binding SubroutineIndex[MESA_SHADER_STAGES];
|
||||
/*@}*/
|
||||
|
||||
struct gl_meta_state *Meta; /**< for "meta" operations */
|
||||
|
@ -469,7 +469,7 @@ _mesa_bind_pipeline(struct gl_context *ctx,
|
||||
FLUSH_VERTICES(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
|
||||
|
||||
for (i = 0; i < MESA_SHADER_STAGES; i++)
|
||||
_mesa_shader_program_init_subroutine_defaults(ctx->_Shader->CurrentProgram[i]);
|
||||
_mesa_shader_program_init_subroutine_defaults(ctx, ctx->_Shader->CurrentProgram[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +65,7 @@
|
||||
#define PATH_MAX _MAX_PATH
|
||||
#endif
|
||||
|
||||
static void _mesa_shader_write_subroutine_index(struct gl_context *ctx, struct gl_linked_shader *sh);
|
||||
/**
|
||||
* Return mask of GLSL_x flags by examining the MESA_GLSL env var.
|
||||
*/
|
||||
@ -1208,7 +1209,7 @@ use_shader_program(struct gl_context *ctx, gl_shader_stage stage,
|
||||
shProg = NULL;
|
||||
|
||||
if (shProg)
|
||||
_mesa_shader_program_init_subroutine_defaults(shProg);
|
||||
_mesa_shader_program_init_subroutine_defaults(ctx, shProg);
|
||||
|
||||
if (*target != shProg) {
|
||||
/* Program is current, flush it */
|
||||
@ -2648,27 +2649,15 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count,
|
||||
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", api_name);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx->SubroutineIndex[sh->Stage].IndexPtr[j] = indices[j];
|
||||
}
|
||||
i += uni_count;
|
||||
} while(i < count);
|
||||
|
||||
FLUSH_VERTICES(ctx, _NEW_PROGRAM_CONSTANTS);
|
||||
i = 0;
|
||||
do {
|
||||
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
|
||||
if (uni == NULL) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
int uni_count = uni->array_elements ? uni->array_elements : 1;
|
||||
|
||||
memcpy(&uni->storage[0], &indices[i],
|
||||
sizeof(GLuint) * uni_count);
|
||||
|
||||
_mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
|
||||
i += uni_count;
|
||||
} while(i < count);
|
||||
_mesa_shader_write_subroutine_index(ctx, sh);
|
||||
}
|
||||
|
||||
|
||||
@ -2710,12 +2699,7 @@ _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location,
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[location];
|
||||
int offset = location - uni->opaque[stage].index;
|
||||
memcpy(params, &uni->storage[offset],
|
||||
sizeof(GLuint));
|
||||
}
|
||||
*params = ctx->SubroutineIndex[sh->Stage].IndexPtr[location];
|
||||
}
|
||||
|
||||
|
||||
@ -2824,29 +2808,63 @@ find_compat_subroutine(struct gl_linked_shader *sh,
|
||||
}
|
||||
|
||||
static void
|
||||
_mesa_shader_init_subroutine_defaults(struct gl_linked_shader *sh)
|
||||
_mesa_shader_write_subroutine_index(struct gl_context *ctx,
|
||||
struct gl_linked_shader *sh)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) {
|
||||
if (sh->NumSubroutineUniformRemapTable == 0)
|
||||
return;
|
||||
|
||||
i = 0;
|
||||
do {
|
||||
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
|
||||
int uni_count;
|
||||
int val;
|
||||
|
||||
if (!uni)
|
||||
if (!uni) {
|
||||
i++;
|
||||
continue;
|
||||
uni_count = uni->array_elements ? uni->array_elements : 1;
|
||||
val = find_compat_subroutine(sh, uni->type);
|
||||
}
|
||||
|
||||
for (j = 0; j < uni_count; j++)
|
||||
uni_count = uni->array_elements ? uni->array_elements : 1;
|
||||
for (j = 0; j < uni_count; j++) {
|
||||
val = ctx->SubroutineIndex[sh->Stage].IndexPtr[i + j];
|
||||
memcpy(&uni->storage[j], &val, sizeof(int));
|
||||
}
|
||||
|
||||
_mesa_propagate_uniforms_to_driver_storage(uni, 0, uni_count);
|
||||
i += uni_count;
|
||||
} while(i < sh->NumSubroutineUniformRemapTable);
|
||||
}
|
||||
|
||||
static void
|
||||
_mesa_shader_init_subroutine_defaults(struct gl_context *ctx,
|
||||
struct gl_linked_shader *sh)
|
||||
{
|
||||
int i;
|
||||
struct gl_subroutine_index_binding *binding = &ctx->SubroutineIndex[sh->Stage];
|
||||
if (binding->NumIndex != sh->NumSubroutineUniformRemapTable) {
|
||||
binding->IndexPtr = realloc(binding->IndexPtr,
|
||||
sh->NumSubroutineUniformRemapTable * (sizeof(GLuint)));
|
||||
binding->NumIndex = sh->NumSubroutineUniformRemapTable;
|
||||
}
|
||||
|
||||
for (i = 0; i < sh->NumSubroutineUniformRemapTable; i++) {
|
||||
struct gl_uniform_storage *uni = sh->SubroutineUniformRemapTable[i];
|
||||
|
||||
if (!uni)
|
||||
continue;
|
||||
|
||||
binding->IndexPtr[i] = find_compat_subroutine(sh, uni->type);
|
||||
}
|
||||
|
||||
_mesa_shader_write_subroutine_index(ctx, sh);
|
||||
}
|
||||
|
||||
void
|
||||
_mesa_shader_program_init_subroutine_defaults(struct gl_shader_program *shProg)
|
||||
_mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx,
|
||||
struct gl_shader_program *shProg)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -2857,6 +2875,6 @@ _mesa_shader_program_init_subroutine_defaults(struct gl_shader_program *shProg)
|
||||
if (!shProg->_LinkedShaders[i])
|
||||
continue;
|
||||
|
||||
_mesa_shader_init_subroutine_defaults(shProg->_LinkedShaders[i]);
|
||||
_mesa_shader_init_subroutine_defaults(ctx, shProg->_LinkedShaders[i]);
|
||||
}
|
||||
}
|
||||
|
@ -286,7 +286,8 @@ _mesa_PatchParameterfv(GLenum pname, const GLfloat *values);
|
||||
|
||||
/* GL_ARB_shader_subroutine */
|
||||
void
|
||||
_mesa_shader_program_init_subroutine_defaults(struct gl_shader_program *shProg);
|
||||
_mesa_shader_program_init_subroutine_defaults(struct gl_context *ctx,
|
||||
struct gl_shader_program *shProg);
|
||||
|
||||
extern GLint GLAPIENTRY
|
||||
_mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype,
|
||||
|
Loading…
Reference in New Issue
Block a user