diff options
author | Timothy Arceri <[email protected]> | 2016-06-30 14:55:40 +1000 |
---|---|---|
committer | Timothy Arceri <[email protected]> | 2016-06-30 16:51:25 +1000 |
commit | 1fb8c6df884c2a17cf980c4ea32db4c214903b55 (patch) | |
tree | a21b0de699816ce28de37dd61531a025cc984114 /src/mesa/main | |
parent | 378f07ccb5bff7857d87a4fe5dff0b5e83f99895 (diff) |
glsl/mesa: split gl_shader in two
There are two distinctly different uses of this struct. The first
is to store GL shader objects. The second is to store information
about a shader stage thats been linked.
The two uses actually share few fields and there is clearly confusion
about their use. For example the linked shaders map one to one with
a program so can simply be destroyed along with the program. However
previously we were calling reference counting on the linked shaders.
We were also creating linked shaders with a name even though it
is always 0 and called the driver version of the _mesa_new_shader()
function unnecessarily for GL shader objects.
Acked-by: Iago Toral Quiroga <[email protected]>
Diffstat (limited to 'src/mesa/main')
-rw-r--r-- | src/mesa/main/api_validate.c | 6 | ||||
-rw-r--r-- | src/mesa/main/dd.h | 3 | ||||
-rw-r--r-- | src/mesa/main/ff_fragment_shader.cpp | 2 | ||||
-rw-r--r-- | src/mesa/main/mtypes.h | 143 | ||||
-rw-r--r-- | src/mesa/main/shader_query.cpp | 2 | ||||
-rw-r--r-- | src/mesa/main/shaderapi.c | 19 | ||||
-rw-r--r-- | src/mesa/main/shaderobj.c | 32 | ||||
-rw-r--r-- | src/mesa/main/shaderobj.h | 7 | ||||
-rw-r--r-- | src/mesa/main/uniform_query.cpp | 4 | ||||
-rw-r--r-- | src/mesa/main/uniforms.c | 2 |
10 files changed, 180 insertions, 40 deletions
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c index 8efbf50c092..c0962241f84 100644 --- a/src/mesa/main/api_validate.c +++ b/src/mesa/main/api_validate.c @@ -207,7 +207,8 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) GLenum mode_before_gs = mode; if (tes) { - struct gl_shader *tes_sh = tes->_LinkedShaders[MESA_SHADER_TESS_EVAL]; + struct gl_linked_shader *tes_sh = + tes->_LinkedShaders[MESA_SHADER_TESS_EVAL]; if (tes_sh->TessEval.PointMode) mode_before_gs = GL_POINTS; else if (tes_sh->TessEval.PrimitiveMode == GL_ISOLINES) @@ -324,7 +325,8 @@ _mesa_valid_prim_mode(struct gl_context *ctx, GLenum mode, const char *name) else if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]) { struct gl_shader_program *tes = ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; - struct gl_shader *tes_sh = tes->_LinkedShaders[MESA_SHADER_TESS_EVAL]; + struct gl_linked_shader *tes_sh = + tes->_LinkedShaders[MESA_SHADER_TESS_EVAL]; if (tes_sh->TessEval.PointMode) pass = ctx->TransformFeedback.Mode == GL_POINTS; else if (tes_sh->TessEval.PrimitiveMode == GL_ISOLINES) diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index f918bb6f717..4891e2a3728 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -783,8 +783,7 @@ struct dd_function_table { * \name GLSL-related functions (ARB extensions and OpenGL 2.x) */ /*@{*/ - struct gl_shader *(*NewShader)(struct gl_context *ctx, - GLuint name, gl_shader_stage stage); + struct gl_linked_shader *(*NewShader)(gl_shader_stage stage); void (*UseProgram)(struct gl_context *ctx, struct gl_shader_program *shProg); /*@}*/ diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp index d0def7c5f70..f90d31ae7e9 100644 --- a/src/mesa/main/ff_fragment_shader.cpp +++ b/src/mesa/main/ff_fragment_shader.cpp @@ -1203,7 +1203,7 @@ create_new_program(struct gl_context *ctx, struct state_key *key) _mesa_glsl_parse_state *state; p.mem_ctx = ralloc_context(NULL); - p.shader = ctx->Driver.NewShader(ctx, 0, MESA_SHADER_FRAGMENT); + p.shader = _mesa_new_shader(ctx, 0, MESA_SHADER_FRAGMENT); p.shader->ir = new(p.shader) exec_list; state = new(p.shader) _mesa_glsl_parse_state(ctx, MESA_SHADER_FRAGMENT, p.shader); diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 73ae55d83eb..fdd445f6857 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -2235,30 +2235,13 @@ struct gl_subroutine_function }; /** - * A GLSL vertex or fragment shader object. + * A linked GLSL shader object. */ -struct gl_shader +struct gl_linked_shader { - /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB || - * GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER. - * Must be the first field. - */ - GLenum Type; gl_shader_stage Stage; - GLuint Name; /**< AKA the handle */ - GLint RefCount; /**< Reference count */ - GLchar *Label; /**< GL_KHR_debug */ - GLboolean DeletePending; - GLboolean CompileStatus; - bool IsES; /**< True if this shader uses GLSL ES */ - - GLuint SourceChecksum; /**< for debug/logging purposes */ - const GLchar *Source; /**< Source code string */ struct gl_program *Program; /**< Post-compile assembly code */ - GLchar *InfoLog; - - unsigned Version; /**< GLSL version used for linking */ /** * \name Sampler tracking @@ -2450,6 +2433,126 @@ struct gl_shader struct gl_subroutine_function *SubroutineFunctions; }; +/** + * A GLSL shader object. + */ +struct gl_shader +{ + /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB || + * GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER. + * Must be the first field. + */ + GLenum Type; + gl_shader_stage Stage; + GLuint Name; /**< AKA the handle */ + GLint RefCount; /**< Reference count */ + GLchar *Label; /**< GL_KHR_debug */ + GLboolean DeletePending; + GLboolean CompileStatus; + bool IsES; /**< True if this shader uses GLSL ES */ + + GLuint SourceChecksum; /**< for debug/logging purposes */ + const GLchar *Source; /**< Source code string */ + + GLchar *InfoLog; + + unsigned Version; /**< GLSL version used for linking */ + + struct exec_list *ir; + struct glsl_symbol_table *symbols; + + bool uses_builtin_functions; + bool uses_gl_fragcoord; + bool redeclares_gl_fragcoord; + bool ARB_fragment_coord_conventions_enable; + + /** + * Fragment shader state from GLSL 1.50 layout qualifiers. + */ + bool origin_upper_left; + bool pixel_center_integer; + + struct { + /** Global xfb_stride out qualifier if any */ + GLuint BufferStride[MAX_FEEDBACK_BUFFERS]; + } TransformFeedback; + + /** + * Tessellation Control shader state from layout qualifiers. + */ + struct { + /** + * 0 - vertices not declared in shader, or + * 1 .. GL_MAX_PATCH_VERTICES + */ + GLint VerticesOut; + } TessCtrl; + + /** + * Tessellation Evaluation shader state from layout qualifiers. + */ + struct { + /** + * GL_TRIANGLES, GL_QUADS, GL_ISOLINES or PRIM_UNKNOWN if it's not set + * in this shader. + */ + GLenum PrimitiveMode; + /** + * GL_EQUAL, GL_FRACTIONAL_ODD, GL_FRACTIONAL_EVEN, or 0 if it's not set + * in this shader. + */ + GLenum Spacing; + /** + * GL_CW, GL_CCW, or 0 if it's not set in this shader. + */ + GLenum VertexOrder; + /** + * 1, 0, or -1 if it's not set in this shader. + */ + int PointMode; + } TessEval; + + /** + * Geometry shader state from GLSL 1.50 layout qualifiers. + */ + struct { + GLint VerticesOut; + /** + * 0 - Invocations count not declared in shader, or + * 1 .. MAX_GEOMETRY_SHADER_INVOCATIONS + */ + GLint Invocations; + /** + * GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, or + * GL_TRIANGLES_ADJACENCY, or PRIM_UNKNOWN if it's not set in this + * shader. + */ + GLenum InputType; + /** + * GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP, or PRIM_UNKNOWN if + * it's not set in this shader. + */ + GLenum OutputType; + } Geom; + + /** + * Whether early fragment tests are enabled as defined by + * ARB_shader_image_load_store. + */ + bool EarlyFragmentTests; + + /** + * Compute shader state from ARB_compute_shader layout qualifiers. + */ + struct { + /** + * Size specified using local_size_{x,y,z}, or all 0's to indicate that + * it's not set in this shader. + */ + unsigned LocalSize[3]; + } Comp; +}; + struct gl_uniform_buffer_variable { @@ -2834,7 +2937,7 @@ struct gl_shader_program * \c MESA_SHADER_* defines. Entries for non-existent stages will be * \c NULL. */ - struct gl_shader *_LinkedShaders[MESA_SHADER_STAGES]; + struct gl_linked_shader *_LinkedShaders[MESA_SHADER_STAGES]; /** List of all active resources after linking. */ struct gl_program_resource *ProgramResourceList; diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 5956ce4976d..b5e1a44417f 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -1264,7 +1264,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg, return 1; case GL_COMPATIBLE_SUBROUTINES: { const struct gl_uniform_storage *uni; - struct gl_shader *sh; + struct gl_linked_shader *sh; unsigned count, i; int j; diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 142e75089df..962b42e62ae 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -2175,7 +2175,8 @@ _mesa_copy_linked_program_data(gl_shader_stage type, case MESA_SHADER_TESS_EVAL: { struct gl_tess_eval_program *dst_tep = (struct gl_tess_eval_program *) dst; - struct gl_shader *tes_sh = src->_LinkedShaders[MESA_SHADER_TESS_EVAL]; + struct gl_linked_shader *tes_sh = + src->_LinkedShaders[MESA_SHADER_TESS_EVAL]; dst_tep->PrimitiveMode = tes_sh->TessEval.PrimitiveMode; dst_tep->Spacing = tes_sh->TessEval.Spacing; @@ -2187,7 +2188,8 @@ _mesa_copy_linked_program_data(gl_shader_stage type, } case MESA_SHADER_GEOMETRY: { struct gl_geometry_program *dst_gp = (struct gl_geometry_program *) dst; - struct gl_shader *geom_sh = src->_LinkedShaders[MESA_SHADER_GEOMETRY]; + struct gl_linked_shader *geom_sh = + src->_LinkedShaders[MESA_SHADER_GEOMETRY]; dst_gp->VerticesIn = src->Geom.VerticesIn; dst_gp->VerticesOut = geom_sh->Geom.VerticesOut; @@ -2420,7 +2422,7 @@ _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, GET_CURRENT_CONTEXT(ctx); const char *api_name = "glGetActiveSubroutineUniformiv"; struct gl_shader_program *shProg; - struct gl_shader *sh; + struct gl_linked_shader *sh; gl_shader_stage stage; struct gl_program_resource *res; const struct gl_uniform_storage *uni; @@ -2585,7 +2587,7 @@ _mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, GET_CURRENT_CONTEXT(ctx); const char *api_name = "glUniformSubroutinesuiv"; struct gl_shader_program *shProg; - struct gl_shader *sh; + struct gl_linked_shader *sh; gl_shader_stage stage; int i; @@ -2683,7 +2685,7 @@ _mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location, GET_CURRENT_CONTEXT(ctx); const char *api_name = "glGetUniformSubroutineuiv"; struct gl_shader_program *shProg; - struct gl_shader *sh; + struct gl_linked_shader *sh; gl_shader_stage stage; if (!_mesa_has_shader_subroutine(ctx)) { @@ -2730,7 +2732,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype, GET_CURRENT_CONTEXT(ctx); const char *api_name = "glGetProgramStageiv"; struct gl_shader_program *shProg; - struct gl_shader *sh; + struct gl_linked_shader *sh; gl_shader_stage stage; if (!_mesa_has_shader_subroutine(ctx)) { @@ -2812,7 +2814,8 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype, } static int -find_compat_subroutine(struct gl_shader *sh, const struct glsl_type *type) +find_compat_subroutine(struct gl_linked_shader *sh, + const struct glsl_type *type) { int i, j; @@ -2827,7 +2830,7 @@ find_compat_subroutine(struct gl_shader *sh, const struct glsl_type *type) } static void -_mesa_shader_init_subroutine_defaults(struct gl_shader *sh) +_mesa_shader_init_subroutine_defaults(struct gl_linked_shader *sh) { int i, j; diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index f3d5c2ee5ba..93fdc669f2f 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -99,7 +99,6 @@ _mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader) /** * Allocate a new gl_shader object, initialize it. - * Called via ctx->Driver.NewShader() */ struct gl_shader * _mesa_new_shader(struct gl_context *ctx, GLuint name, gl_shader_stage stage) @@ -116,6 +115,22 @@ _mesa_new_shader(struct gl_context *ctx, GLuint name, gl_shader_stage stage) /** + * Allocate a new gl_linked_shader object. + * Called via ctx->Driver.NewShader() + */ +struct gl_linked_shader * +_mesa_new_linked_shader(gl_shader_stage stage) +{ + struct gl_linked_shader *shader; + shader = rzalloc(NULL, struct gl_linked_shader); + if (shader) { + shader->Stage = stage; + } + return shader; +} + + +/** * Delete a shader object. */ void @@ -123,6 +138,17 @@ _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh) { free((void *)sh->Source); free(sh->Label); + ralloc_free(sh); +} + + +/** + * Delete a shader object. + */ +void +_mesa_delete_linked_shader(struct gl_context *ctx, + struct gl_linked_shader *sh) +{ _mesa_reference_program(ctx, &sh->Program, NULL); ralloc_free(sh); } @@ -360,7 +386,7 @@ _mesa_free_shader_program_data(struct gl_context *ctx, for (sh = 0; sh < MESA_SHADER_STAGES; sh++) { if (shProg->_LinkedShaders[sh] != NULL) { - _mesa_delete_shader(ctx, shProg->_LinkedShaders[sh]); + _mesa_delete_linked_shader(ctx, shProg->_LinkedShaders[sh]); shProg->_LinkedShaders[sh] = NULL; } } @@ -436,6 +462,6 @@ _mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name, void _mesa_init_shader_object_functions(struct dd_function_table *driver) { - driver->NewShader = _mesa_new_shader; + driver->NewShader = _mesa_new_linked_shader; driver->LinkShader = _mesa_ir_link_shader; } diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h index 3abd597a58c..f331db11664 100644 --- a/src/mesa/main/shaderobj.h +++ b/src/mesa/main/shaderobj.h @@ -82,9 +82,16 @@ _mesa_init_shader(struct gl_context *ctx, struct gl_shader *shader); extern struct gl_shader * _mesa_new_shader(struct gl_context *ctx, GLuint name, gl_shader_stage type); +extern struct gl_linked_shader * +_mesa_new_linked_shader(gl_shader_stage type); + extern void _mesa_delete_shader(struct gl_context *ctx, struct gl_shader *sh); +extern void +_mesa_delete_linked_shader(struct gl_context *ctx, + struct gl_linked_shader *sh); + extern struct gl_shader_program * _mesa_lookup_shader_program(struct gl_context *ctx, GLuint name); diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index 127f097fe1f..67375a17f48 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -824,7 +824,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, if (uni->type->is_sampler()) { bool flushed = false; for (int i = 0; i < MESA_SHADER_STAGES; i++) { - struct gl_shader *const sh = shProg->_LinkedShaders[i]; + struct gl_linked_shader *const sh = shProg->_LinkedShaders[i]; /* If the shader stage doesn't use the sampler uniform, skip this. */ @@ -876,7 +876,7 @@ _mesa_uniform(struct gl_context *ctx, struct gl_shader_program *shProg, if (uni->type->is_image()) { for (int i = 0; i < MESA_SHADER_STAGES; i++) { if (uni->opaque[i].active) { - struct gl_shader *sh = shProg->_LinkedShaders[i]; + struct gl_linked_shader *sh = shProg->_LinkedShaders[i]; for (int j = 0; j < count; j++) sh->ImageUnits[uni->opaque[i].index + offset + j] = diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c index d02f92ee0a5..3921644892c 100644 --- a/src/mesa/main/uniforms.c +++ b/src/mesa/main/uniforms.c @@ -68,7 +68,7 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg, struct gl_program *prog) { GLbitfield mask = prog->SamplersUsed; - struct gl_shader *shader = + struct gl_linked_shader *shader = shProg->_LinkedShaders[_mesa_program_enum_to_shader_stage(prog->Target)]; assert(shader); |