r600: fixup sparse color exports.
authorDave Airlie <airlied@redhat.com>
Mon, 5 Feb 2018 04:55:07 +0000 (14:55 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 6 Feb 2018 20:16:59 +0000 (06:16 +1000)
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 <sroland@vmware.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/r600_shader.c
src/gallium/drivers/r600/r600_shader.h

index 4c9163c2a7b5ffc847f33ba52bbb42849cdafea2..742ca5babb3c73f9dd645497dda3e8532b7e5de0 100644 (file)
@@ -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) {
index be9b1e9aefc47b00f27a8a5e549bba1fb06ecf13..c3bcb9b77d33d581640a81c6fde4eb8e40f8e79f 100644 (file)
@@ -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++;
index 7fca3f455e86dfb408ce103516985976471342cc..4b23facf6f8f78d8efd08e0529177e97c5d31fad 100644 (file)
@@ -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;