diff options
author | Francisco Jerez <[email protected]> | 2016-08-23 11:18:19 -0700 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2016-08-30 16:54:19 -0700 |
commit | 342f945b1320d588e61e4efe1ccc7852a3c8ad9f (patch) | |
tree | f26bb75996fe9aeecdcaf24e52ab28612c02d7b9 | |
parent | cb4b38af41952c2e5ee77253592f0d0833aefd28 (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.cpp | 5 | ||||
-rw-r--r-- | src/mesa/state_tracker/st_program.c | 18 |
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; |