summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrancisco Jerez <[email protected]>2016-08-23 11:18:19 -0700
committerFrancisco Jerez <[email protected]>2016-08-30 16:54:19 -0700
commit342f945b1320d588e61e4efe1ccc7852a3c8ad9f (patch)
treef26bb75996fe9aeecdcaf24e52ab28612c02d7b9
parentcb4b38af41952c2e5ee77253592f0d0833aefd28 (diff)
st/glsl_to_tgsi: Use SecondaryOutputsWritten to determine dual-source fragment outputs.
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 <[email protected]>
-rw-r--r--src/mesa/state_tracker/st_glsl_to_tgsi.cpp5
-rw-r--r--src/mesa/state_tracker/st_program.c18
2 files changed, 15 insertions, 8 deletions
diff --git a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index b7e47dbc21b..507a7826e38 100644
--- a/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -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);
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index 03a685c4db6..429d0c9eb6d 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -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;