broadcom/vc5: Fix up the NIR types of FS outputs generated by NIR-to-TGSI.
authorEric Anholt <eric@anholt.net>
Wed, 21 Mar 2018 19:05:54 +0000 (12:05 -0700)
committerEric Anholt <eric@anholt.net>
Wed, 21 Mar 2018 21:02:34 +0000 (14:02 -0700)
Unfortunately TGSI doesn't record the type of the FS output like GLSL
does, but VC5's TLB writes depend on the output's base type.  Just record
the type in the key at variant compile time when we've got a TGSI input
and then fix it up.

Fixes KHR-GLES3.packed_pixels.pbo_rectangle.rgba32i/ui and apparently a
GPU hang that breaks most tests that come after it.

src/broadcom/compiler/v3d_compiler.h
src/broadcom/compiler/vir.c
src/gallium/drivers/vc5/vc5_context.h
src/gallium/drivers/vc5/vc5_program.c

index df81f0757e2bb5a5fa1a5f32a6aa29720489b0dc..207e29733aa2c05a68383548e55c9a3fe9967e88 100644 (file)
@@ -336,6 +336,11 @@ struct v3d_fs_key {
         uint8_t swap_color_rb;
         /* Mask of which render targets need to be written as 32-bit floats */
         uint8_t f32_color_rb;
+        /* Masks of which render targets need to be written as ints/uints.
+         * Used by gallium to work around lost information in TGSI.
+         */
+        uint8_t int_color_rb;
+        uint8_t uint_color_rb;
         uint8_t alpha_test_func;
         uint8_t logicop_func;
         uint32_t point_sprite_mask;
index 05f557fbcd0218fd10c5f4f55a5331c9855198f3..ff9405e6c120d41e2a979451ad70e9841018fca3 100644 (file)
@@ -756,6 +756,36 @@ v3d_set_fs_prog_data_inputs(struct v3d_compile *c,
         }
 }
 
+static void
+v3d_fixup_fs_output_types(struct v3d_compile *c)
+{
+        nir_foreach_variable(var, &c->s->outputs) {
+                uint32_t mask = 0;
+
+                switch (var->data.location) {
+                case FRAG_RESULT_COLOR:
+                        mask = ~0;
+                        break;
+                case FRAG_RESULT_DATA0:
+                case FRAG_RESULT_DATA1:
+                case FRAG_RESULT_DATA2:
+                case FRAG_RESULT_DATA3:
+                        mask = 1 << (var->data.location - FRAG_RESULT_DATA0);
+                        break;
+                }
+
+                if (c->fs_key->int_color_rb & mask) {
+                        var->type =
+                                glsl_vector_type(GLSL_TYPE_INT,
+                                                 glsl_get_components(var->type));
+                } else if (c->fs_key->uint_color_rb & mask) {
+                        var->type =
+                                glsl_vector_type(GLSL_TYPE_UINT,
+                                                 glsl_get_components(var->type));
+                }
+        }
+}
+
 uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler,
                          struct v3d_fs_key *key,
                          struct v3d_fs_prog_data *prog_data,
@@ -768,6 +798,9 @@ uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler,
 
         c->fs_key = key;
 
+        if (key->int_color_rb || key->uint_color_rb)
+                v3d_fixup_fs_output_types(c);
+
         v3d_lower_nir(c);
 
         if (key->light_twoside)
index 28b2e165a9d7d8d1c7546ff2c8bfdfddc97c1f90..1ab5a6b1532ce8eeca4c9c7d50bb807ee16eb2cf 100644 (file)
@@ -132,6 +132,13 @@ struct vc5_uncompiled_shader {
         struct v3d_varying_slot *tf_outputs;
         uint16_t tf_specs[PIPE_MAX_SO_BUFFERS];
         uint32_t num_tf_specs;
+
+        /**
+         * Flag for if the NIR in this shader originally came from TGSI.  If
+         * so, we need to do some fixups at compile time, due to missing
+         * information in TGSI that exists in NIR.
+         */
+        bool was_tgsi;
 };
 
 struct vc5_compiled_shader {
index ae3850a64b370bb4921924eb080ddca375801a5d..87c21abe8b1236fabdc86583a5218a1be34b32a8 100644 (file)
@@ -170,6 +170,8 @@ vc5_shader_state_create(struct pipe_context *pctx,
                         fprintf(stderr, "\n");
                 }
                 s = tgsi_to_nir(cso->tokens, &v3d_nir_options);
+
+                so->was_tgsi = true;
         }
 
         NIR_PASS_V(s, nir_opt_global_to_local);
@@ -414,6 +416,13 @@ vc5_update_compiled_fs(struct vc5_context *vc5, uint8_t prim_mode)
                     desc->channel[0].size == 32) {
                         key->f32_color_rb |= 1 << i;
                 }
+
+                if (vc5->prog.bind_fs->was_tgsi) {
+                        if (util_format_is_pure_uint(cbuf->format))
+                                key->uint_color_rb |= 1 << i;
+                        else if (util_format_is_pure_sint(cbuf->format))
+                                key->int_color_rb |= 1 << i;
+                }
         }
 
         if (key->is_points) {