summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/glsl/linker.cpp52
-rw-r--r--src/mesa/main/mtypes.h3
-rw-r--r--src/mesa/program/ir_to_mesa.cpp29
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp23
4 files changed, 61 insertions, 46 deletions
diff --git a/src/glsl/linker.cpp b/src/glsl/linker.cpp
index 0ec773d6cd2..35270881af5 100644
--- a/src/glsl/linker.cpp
+++ b/src/glsl/linker.cpp
@@ -1876,6 +1876,57 @@ store_tfeedback_info(struct gl_context *ctx, struct gl_shader_program *prog,
}
/**
+ * Store the gl_FragDepth layout in the gl_shader_program struct.
+ */
+static void
+store_fragdepth_layout(struct gl_shader_program *prog)
+{
+ if (prog->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) {
+ return;
+ }
+
+ struct exec_list *ir = prog->_LinkedShaders[MESA_SHADER_FRAGMENT]->ir;
+
+ /* We don't look up the gl_FragDepth symbol directly because if
+ * gl_FragDepth is not used in the shader, it's removed from the IR.
+ * However, the symbol won't be removed from the symbol table.
+ *
+ * We're only interested in the cases where the variable is NOT removed
+ * from the IR.
+ */
+ foreach_list(node, ir) {
+ ir_variable *const var = ((ir_instruction *) node)->as_variable();
+
+ if (var == NULL || var->mode != ir_var_out) {
+ continue;
+ }
+
+ if (strcmp(var->name, "gl_FragDepth") == 0) {
+ switch (var->depth_layout) {
+ case ir_depth_layout_none:
+ prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE;
+ return;
+ case ir_depth_layout_any:
+ prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY;
+ return;
+ case ir_depth_layout_greater:
+ prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER;
+ return;
+ case ir_depth_layout_less:
+ prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS;
+ return;
+ case ir_depth_layout_unchanged:
+ prog->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED;
+ return;
+ default:
+ assert(0);
+ return;
+ }
+ }
+ }
+}
+
+/**
* Validate the resources used by a program versus the implementation limits
*/
static bool
@@ -2177,6 +2228,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
update_array_sizes(prog);
link_assign_uniform_locations(prog);
+ store_fragdepth_layout(prog);
if (!check_resources(ctx, prog))
goto done;
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 285ec0783da..b3427dac17d 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -2218,6 +2218,9 @@ struct gl_shader_program
/** Post-link transform feedback info. */
struct gl_transform_feedback_info LinkedTransformFeedback;
+ /** Post-link gl_FragDepth layout for ARB_conservative_depth. */
+ enum gl_frag_depth_layout FragDepthLayout;
+
/** Geometry shader state - copied into gl_geometry_program at link time */
struct {
GLint VerticesOut;
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 5cee8377811..5a68fc51d08 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -685,29 +685,6 @@ ir_to_mesa_visitor::visit(ir_variable *ir)
fp->OriginUpperLeft = ir->origin_upper_left;
fp->PixelCenterInteger = ir->pixel_center_integer;
-
- } else if (strcmp(ir->name, "gl_FragDepth") == 0) {
- struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
- switch (ir->depth_layout) {
- case ir_depth_layout_none:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE;
- break;
- case ir_depth_layout_any:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY;
- break;
- case ir_depth_layout_greater:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER;
- break;
- case ir_depth_layout_less:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS;
- break;
- case ir_depth_layout_unchanged:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED;
- break;
- default:
- assert(0);
- break;
- }
}
if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {
@@ -3222,6 +3199,12 @@ get_mesa_program(struct gl_context *ctx,
do_set_program_inouts(shader->ir, prog, shader->Type == GL_FRAGMENT_SHADER);
count_resources(prog);
+ /* Set the gl_FragDepth layout. */
+ if (target == GL_FRAGMENT_PROGRAM_ARB) {
+ struct gl_fragment_program *fp = (struct gl_fragment_program *)prog;
+ fp->FragDepthLayout = shader_program->FragDepthLayout;
+ }
+
_mesa_reference_program(ctx, &shader->Program, prog);
if ((ctx->Shader.Flags & GLSL_NO_OPT) == 0) {
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 0bf6766f72d..929c7af01ce 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -1017,29 +1017,6 @@ glsl_to_tgsi_visitor::visit(ir_variable *ir)
fp->OriginUpperLeft = ir->origin_upper_left;
fp->PixelCenterInteger = ir->pixel_center_integer;
-
- } else if (strcmp(ir->name, "gl_FragDepth") == 0) {
- struct gl_fragment_program *fp = (struct gl_fragment_program *)this->prog;
- switch (ir->depth_layout) {
- case ir_depth_layout_none:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_NONE;
- break;
- case ir_depth_layout_any:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_ANY;
- break;
- case ir_depth_layout_greater:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_GREATER;
- break;
- case ir_depth_layout_less:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_LESS;
- break;
- case ir_depth_layout_unchanged:
- fp->FragDepthLayout = FRAG_DEPTH_LAYOUT_UNCHANGED;
- break;
- default:
- assert(0);
- break;
- }
}
if (ir->mode == ir_var_uniform && strncmp(ir->name, "gl_", 3) == 0) {