Module: Mesa Branch: main Commit: 3ebd6498c4f6a1430231b9ef5bca93fc6d538d1e URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=3ebd6498c4f6a1430231b9ef5bca93fc6d538d1e
Author: Pavel Asyutchenko <[email protected]> Date: Wed Oct 6 23:27:50 2021 +0300 llvmpipe: fix gl_FragColor and gl_LastFragData[0] combination Signed-off-by: Pavel Asyutchenko <[email protected]> Reviewed-by: Dave Airlie <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13252> --- src/gallium/drivers/llvmpipe/lp_state_fs.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 553bd5c85b1..976d14a3224 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -1091,7 +1091,7 @@ generate_fs_loop(struct gallivm_state *gallivm, LLVMBuildStore(builder, out, ptr); } - + bool has_cbuf0_write = false; /* Color write - per fragment sample */ for (attrib = 0; attrib < shader->info.base.num_outputs; ++attrib) { @@ -1099,6 +1099,21 @@ generate_fs_loop(struct gallivm_state *gallivm, if ((shader->info.base.output_semantic_name[attrib] == TGSI_SEMANTIC_COLOR) && ((cbuf < key->nr_cbufs) || (cbuf == 1 && dual_source_blend))) { + if (cbuf == 0 && shader->info.base.properties[TGSI_PROPERTY_FS_COLOR0_WRITES_ALL_CBUFS]) { + /* XXX: there is an edge case with FB fetch where gl_FragColor and gl_LastFragData[0] + * are used together. This creates both FRAG_RESULT_COLOR and FRAG_RESULT_DATA* output + * variables. This loop then writes to cbuf 0 twice, owerwriting the correct value + * from gl_FragColor with some garbage. This case is excercised in one of deqp tests. + * A similar bug can happen if gl_SecondaryFragColorEXT and gl_LastFragData[1] + * are mixed in the same fashion... + * This workaround will break if gl_LastFragData[0] goes in outputs list before + * gl_FragColor. This doesn't seem to happen though. + */ + if (has_cbuf0_write) + continue; + has_cbuf0_write = true; + } + for(chan = 0; chan < TGSI_NUM_CHANNELS; ++chan) { if(outputs[attrib][chan]) { /* XXX: just initialize outputs to point at colors[] and
