aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/ir_clone.cpp1
-rw-r--r--mesalib/src/glsl/linker.cpp52
2 files changed, 53 insertions, 0 deletions
diff --git a/mesalib/src/glsl/ir_clone.cpp b/mesalib/src/glsl/ir_clone.cpp
index e8ac9fbe4..c63615c7e 100644
--- a/mesalib/src/glsl/ir_clone.cpp
+++ b/mesalib/src/glsl/ir_clone.cpp
@@ -51,6 +51,7 @@ ir_variable::clone(void *mem_ctx, struct hash_table *ht) const
var->pixel_center_integer = this->pixel_center_integer;
var->explicit_location = this->explicit_location;
var->has_initializer = this->has_initializer;
+ var->depth_layout = this->depth_layout;
var->num_state_slots = this->num_state_slots;
if (this->state_slots) {
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 0ec773d6c..35270881a 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/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;