summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorTimothy Arceri <[email protected]>2016-06-30 14:55:40 +1000
committerTimothy Arceri <[email protected]>2016-06-30 16:51:25 +1000
commit1fb8c6df884c2a17cf980c4ea32db4c214903b55 (patch)
treea21b0de699816ce28de37dd61531a025cc984114 /src/mesa/main
parent378f07ccb5bff7857d87a4fe5dff0b5e83f99895 (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.c6
-rw-r--r--src/mesa/main/dd.h3
-rw-r--r--src/mesa/main/ff_fragment_shader.cpp2
-rw-r--r--src/mesa/main/mtypes.h143
-rw-r--r--src/mesa/main/shader_query.cpp2
-rw-r--r--src/mesa/main/shaderapi.c19
-rw-r--r--src/mesa/main/shaderobj.c32
-rw-r--r--src/mesa/main/shaderobj.h7
-rw-r--r--src/mesa/main/uniform_query.cpp4
-rw-r--r--src/mesa/main/uniforms.c2
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);