st/glsl_to_tgsi: Use SecondaryOutputsWritten to determine dual-source fragment outputs.
authorFrancisco Jerez <currojerez@riseup.net>
Tue, 23 Aug 2016 18:18:19 +0000 (11:18 -0700)
committerFrancisco Jerez <currojerez@riseup.net>
Tue, 30 Aug 2016 23:54:19 +0000 (16:54 -0700)
Currently the mesa state tracker relies on there being two bits set
per dual-source output in the gl_program::OutputsWritten bitset, but
that only worked due to a GLSL front-end bug that caused it to set the
OutputsWritten bit for both location and location+1 even though at the
GLSL level the primary and secondary color outputs used for
dual-source blending have the same location.  Fix it by extending
outputMapping[] to 2*FRAG_RESULT_MAX elements in order to represent a
mapping from a (location, index) pair to its TGSI output, which should
also make it slightly easier to add support for dual-source blending
in combination with multiple render targets in the long run.

No Piglit regressions on llvmpipe.

Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
src/mesa/state_tracker/st_glsl_to_tgsi.cpp
src/mesa/state_tracker/st_program.c

index b7e47dbc21bb71c1fce16d77734c1ae9f75ddb2f..507a7826e38e1e17835b778aba0483f0592848bf 100644 (file)
@@ -2419,7 +2419,8 @@ glsl_to_tgsi_visitor::visit(ir_dereference_variable *ir)
             entry = new(mem_ctx) variable_storage(var,
                                                   PROGRAM_OUTPUT,
                                                   var->data.location
-                                                  + var->data.index);
+                                                  + FRAG_RESULT_MAX *
+                                                    var->data.index);
          }
          this->variables.push_tail(entry);
          break;
@@ -5367,7 +5368,7 @@ dst_register(struct st_translate *t, gl_register_file file, unsigned index,
    case PROGRAM_OUTPUT:
       if (!array_id) {
          if (t->procType == PIPE_SHADER_FRAGMENT)
-            assert(index < FRAG_RESULT_MAX);
+            assert(index < 2 * FRAG_RESULT_MAX);
          else if (t->procType == PIPE_SHADER_TESS_CTRL ||
                   t->procType == PIPE_SHADER_TESS_EVAL)
             assert(index < VARYING_SLOT_TESS_MAX);
index 03a685c4db6b070c5ac99bfb779f3eb2e1fe523e..429d0c9eb6dcdbe08c375e56ac4139c6d8f7652e 100644 (file)
@@ -586,7 +586,9 @@ bool
 st_translate_fragment_program(struct st_context *st,
                               struct st_fragment_program *stfp)
 {
-   GLuint outputMapping[FRAG_RESULT_MAX];
+   GLuint outputMapping[2 * FRAG_RESULT_MAX] =
+      { 0 /* XXX - Avoid temporary regression due to bogus OutputsWritten
+           *       bitset. */ };
    GLuint inputMapping[VARYING_SLOT_MAX];
    GLuint inputSlotToAttr[VARYING_SLOT_MAX];
    GLuint interpMode[PIPE_MAX_SHADER_INPUTS];  /* XXX size? */
@@ -810,9 +812,13 @@ st_translate_fragment_program(struct st_context *st,
       }
 
       /* handle remaining outputs (color) */
-      for (attr = 0; attr < FRAG_RESULT_MAX; attr++) {
-         if (outputsWritten & BITFIELD64_BIT(attr)) {
-            switch (attr) {
+      for (attr = 0; attr < ARRAY_SIZE(outputMapping); attr++) {
+         const GLbitfield64 written = attr < FRAG_RESULT_MAX ? outputsWritten :
+            stfp->Base.Base.SecondaryOutputsWritten;
+         const unsigned loc = attr % FRAG_RESULT_MAX;
+
+         if (written & BITFIELD64_BIT(loc)) {
+            switch (loc) {
             case FRAG_RESULT_DEPTH:
             case FRAG_RESULT_STENCIL:
             case FRAG_RESULT_SAMPLE_MASK:
@@ -822,8 +828,8 @@ st_translate_fragment_program(struct st_context *st,
             case FRAG_RESULT_COLOR:
                write_all = GL_TRUE; /* fallthrough */
             default:
-               assert(attr == FRAG_RESULT_COLOR ||
-                      (FRAG_RESULT_DATA0 <= attr && attr < FRAG_RESULT_MAX));
+               assert(loc == FRAG_RESULT_COLOR ||
+                      (FRAG_RESULT_DATA0 <= loc && loc < FRAG_RESULT_MAX));
                fs_output_semantic_name[fs_num_outputs] = TGSI_SEMANTIC_COLOR;
                fs_output_semantic_index[fs_num_outputs] = numColors;
                outputMapping[attr] = fs_num_outputs;