summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2018-02-05 14:55:07 +1000
committerDave Airlie <[email protected]>2018-02-07 06:16:59 +1000
commit6c691081a183aec51d5305592b9fa391ebb447ab (patch)
tree2106e3a506145803ac9c4efbfaf6d50457c1857f /src
parent2d5b5d267e1b0997ebe9fe7bcc06f6b79af48e43 (diff)
r600: fixup sparse color exports.
If we have gaps in the shader mask we have to have 0x1 in them according to a comment in radeonsi, and this is required to fix the test at least on cayman. We also need to record the highest one written to write to the ps exports reg. This fixes: KHR-GL45.enhanced_layouts.fragment_data_location_api Reviewed-by: Roland Scheidegger <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c2
-rw-r--r--src/gallium/drivers/r600/r600_shader.c10
-rw-r--r--src/gallium/drivers/r600/r600_shader.h1
3 files changed, 12 insertions, 1 deletions
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 4c9163c2a7b..742ca5babb3 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -3369,7 +3369,7 @@ void evergreen_update_ps_state(struct pipe_context *ctx, struct r600_pipe_shader
exports_ps |= 1;
}
- num_cout = rshader->nr_ps_color_exports;
+ num_cout = rshader->ps_export_highest + 1;
exports_ps |= S_02884C_EXPORT_COLORS(num_cout);
if (!exports_ps) {
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index be9b1e9aefc..c3bcb9b77d3 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -3876,6 +3876,16 @@ static int r600_shader_from_tgsi(struct r600_context *rctx,
output[j].type = V_SQ_CF_ALLOC_EXPORT_WORD0_SQ_EXPORT_PIXEL;
shader->nr_ps_color_exports++;
shader->ps_color_export_mask |= (0xf << (shader->output[i].sid * 4));
+
+ /* If the i-th target format is set, all previous target formats must
+ * be non-zero to avoid hangs. - from radeonsi, seems to apply to eg as well.
+ */
+ if (shader->output[i].sid > 0)
+ for (unsigned x = 0; x < shader->output[i].sid; x++)
+ shader->ps_color_export_mask |= (1 << (x*4));
+
+ if (shader->output[i].sid > shader->ps_export_highest)
+ shader->ps_export_highest = shader->output[i].sid;
if (shader->fs_write_all && (rscreen->b.chip_class >= EVERGREEN)) {
for (k = 1; k < max_color_exports; k++) {
j++;
diff --git a/src/gallium/drivers/r600/r600_shader.h b/src/gallium/drivers/r600/r600_shader.h
index 7fca3f455e8..4b23facf6f8 100644
--- a/src/gallium/drivers/r600/r600_shader.h
+++ b/src/gallium/drivers/r600/r600_shader.h
@@ -85,6 +85,7 @@ struct r600_shader {
/* Real number of ps color exports compiled in the bytecode */
unsigned nr_ps_color_exports;
unsigned ps_color_export_mask;
+ unsigned ps_export_highest;
/* bit n is set if the shader writes gl_ClipDistance[n] */
unsigned cc_dist_mask;
unsigned clip_dist_write;