glsl: Propagate depth layout qualifier from AST to IR
authorChad Versace <chad.versace@intel.com>
Thu, 27 Jan 2011 09:40:26 +0000 (01:40 -0800)
committerChad Versace <chad.versace@intel.com>
Thu, 27 Jan 2011 00:37:44 +0000 (16:37 -0800)
src/glsl/ast_to_hir.cpp
src/glsl/ir.cpp
src/glsl/ir.h

index 34d61b8e752b04cbdb96426cc0fdb5b018e41fa5..df11a30c1acdd9638c868ada2eff2f8453eeb981 100644 (file)
@@ -2009,6 +2009,40 @@ apply_type_qualifier_to_variable(const struct ast_type_qualifier *qual,
       }
    }
 
+   /* Layout qualifiers for gl_FragDepth, which are enabled by extension
+    * AMD_conservative_depth.
+    */
+   int depth_layout_count = qual->flags.q.depth_any
+      + qual->flags.q.depth_greater
+      + qual->flags.q.depth_less
+      + qual->flags.q.depth_unchanged;
+   if (depth_layout_count > 0
+       && !state->AMD_conservative_depth_enable) {
+       _mesa_glsl_error(loc, state,
+                        "extension GL_AMD_conservative_depth must be enabled "
+                       "to use depth layout qualifiers");
+   } else if (depth_layout_count > 0
+              && strcmp(var->name, "gl_FragDepth") != 0) {
+       _mesa_glsl_error(loc, state,
+                        "depth layout qualifiers can be applied only to "
+                        "gl_FragDepth");
+   } else if (depth_layout_count > 1
+              && strcmp(var->name, "gl_FragDepth") == 0) {
+      _mesa_glsl_error(loc, state,
+                       "at most one depth layout qualifier can be applied to "
+                       "gl_FragDepth");
+   }
+   if (qual->flags.q.depth_any)
+      var->depth_layout = ir_depth_layout_any;
+   else if (qual->flags.q.depth_greater)
+      var->depth_layout = ir_depth_layout_greater;
+   else if (qual->flags.q.depth_less)
+      var->depth_layout = ir_depth_layout_less;
+   else if (qual->flags.q.depth_unchanged)
+       var->depth_layout = ir_depth_layout_unchanged;
+   else
+       var->depth_layout = ir_depth_layout_none;
+
    if (var->type->is_array() && state->language_version != 110) {
       var->array_lvalue = true;
    }
@@ -2599,6 +2633,36 @@ ast_declarator_list::hir(exec_list *instructions,
                    && earlier->type == var->type
                    && earlier->mode == var->mode) {
            earlier->interpolation = var->interpolation;
+
+         /* Layout qualifiers for gl_FragDepth. */
+         } else if (state->AMD_conservative_depth_enable
+                    && strcmp(var->name, "gl_FragDepth") == 0
+                    && earlier->type == var->type
+                    && earlier->mode == var->mode) {
+
+            /** From the AMD_conservative_depth spec:
+             *     Within any shader, the first redeclarations of gl_FragDepth
+             *     must appear before any use of gl_FragDepth.
+             */
+            if (earlier->used) {
+               _mesa_glsl_error(&loc, state,
+                                "the first redeclaration of gl_FragDepth "
+                                "must appear before any use of gl_FragDepth");
+            }
+
+            /* Prevent inconsistent redeclaration of depth layout qualifier. */
+            if (earlier->depth_layout != ir_depth_layout_none
+                && earlier->depth_layout != var->depth_layout) {
+               _mesa_glsl_error(&loc, state,
+                                "gl_FragDepth: depth layout is declared here "
+                                "as '%s, but it was previously declared as "
+                                "'%s'",
+                                depth_layout_string(var->depth_layout),
+                                depth_layout_string(earlier->depth_layout));
+            }
+
+            earlier->depth_layout = var->depth_layout;
+
         } else {
            YYLTYPE loc = this->get_location();
            _mesa_glsl_error(&loc, state, "`%s' redeclared", decl->identifier);
index b3676d5707626701a52b2b9b50651d6be37cffa5..b4ceb5bba14b62f12369b42351b60242f44a7ffe 100644 (file)
@@ -1341,6 +1341,7 @@ ir_variable::ir_variable(const struct glsl_type *type, const char *name,
    this->constant_value = NULL;
    this->origin_upper_left = false;
    this->pixel_center_integer = false;
+   this->depth_layout = ir_depth_layout_none;
    this->used = false;
 
    if (type && type->base_type == GLSL_TYPE_SAMPLER)
index 7399df40385e8ef34e4f4aa1bd870b9e405a9011..8d5056aa1a485d14febd2748d7530d95a85d0641 100644 (file)
@@ -353,6 +353,14 @@ public:
    unsigned pixel_center_integer:1;
    /*@}*/
 
+   /**
+    * \brief Layout qualifier for gl_FragDepth.
+    *
+    * This is not equal to \c ir_depth_layout_none if and only if this
+    * variable is \c gl_FragDepth and a layout qualifier is specified.
+    */
+   ir_depth_layout depth_layout;
+
    /**
     * Was the location explicitly set in the shader?
     *