v3d: Store the actual mask of color buffers present in the key.
authorEric Anholt <eric@anholt.net>
Fri, 1 Feb 2019 21:13:48 +0000 (13:13 -0800)
committerEric Anholt <eric@anholt.net>
Tue, 5 Feb 2019 23:42:04 +0000 (15:42 -0800)
If you only bound rt 1+, we'd still emit a write to the rt0 that isn't
present (noticed while debugging an
ext_framebuffer_multisample-alpha-to-coverage-no-draw-buffer-zero
regression in another change).

src/broadcom/compiler/nir_to_vir.c
src/broadcom/compiler/v3d_compiler.h
src/gallium/drivers/v3d/v3d_program.c

index a5e75f650e8927fae92e71fb10231efa65f123e6..d983f91e71847a6b4d0640f57f7a594f07b1245c 100644 (file)
@@ -1129,8 +1129,8 @@ emit_frag_end(struct v3d_compile *c)
         */
 
         bool has_any_tlb_color_write = false;
-        for (int rt = 0; rt < c->fs_key->nr_cbufs; rt++) {
-                if (c->output_color_var[rt])
+        for (int rt = 0; rt < V3D_MAX_DRAW_BUFFERS; rt++) {
+                if (c->fs_key->cbufs & (1 << rt) && c->output_color_var[rt])
                         has_any_tlb_color_write = true;
         }
 
@@ -1194,8 +1194,8 @@ emit_frag_end(struct v3d_compile *c)
          * uniform setup
          */
 
-        for (int rt = 0; rt < c->fs_key->nr_cbufs; rt++) {
-                if (!c->output_color_var[rt])
+        for (int rt = 0; rt < V3D_MAX_DRAW_BUFFERS; rt++) {
+                if (!(c->fs_key->cbufs & (1 << rt)) || !c->output_color_var[rt])
                         continue;
 
                 nir_variable *var = c->output_color_var[rt];
index 127b04136d18584a695406926361ca9b998168a9..cea26484a8fcb7582282cbc77e4f99a39fce2bfe 100644 (file)
@@ -357,7 +357,8 @@ struct v3d_fs_key {
         bool sample_alpha_to_one;
         bool clamp_color;
         bool shade_model_flat;
-        uint8_t nr_cbufs;
+        /* Mask of which color render targets are present. */
+        uint8_t cbufs;
         uint8_t swap_color_rb;
         /* Mask of which render targets need to be written as 32-bit floats */
         uint8_t f32_color_rb;
index 61ae1f259815769e9904bc6b3ab60bd5efcc7372..30769047a9617801563634f51edfb3b1ec298ada 100644 (file)
@@ -199,11 +199,10 @@ v3d_shader_precompile(struct v3d_context *v3d,
 
                 nir_foreach_variable(var, &s->outputs) {
                         if (var->data.location == FRAG_RESULT_COLOR) {
-                                key.nr_cbufs = 1;
+                                key.cbufs |= 1 << 0;
                         } else if (var->data.location >= FRAG_RESULT_DATA0) {
-                                key.nr_cbufs = MAX2(key.nr_cbufs,
-                                                    var->data.location -
-                                                    FRAG_RESULT_DATA0 + 1);
+                                key.cbufs |= 1 << (var->data.location -
+                                                   FRAG_RESULT_DATA0);
                         }
                 }
 
@@ -526,17 +525,19 @@ v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode)
                 key->alpha_test_func = v3d->zsa->base.alpha.func;
         }
 
-        /* gl_FragColor's propagation to however many bound color buffers
-         * there are means that the buffer count needs to be in the key.
-         */
-        key->nr_cbufs = v3d->framebuffer.nr_cbufs;
         key->swap_color_rb = v3d->swap_color_rb;
 
-        for (int i = 0; i < key->nr_cbufs; i++) {
+        for (int i = 0; i < v3d->framebuffer.nr_cbufs; i++) {
                 struct pipe_surface *cbuf = v3d->framebuffer.cbufs[i];
                 if (!cbuf)
                         continue;
 
+                /* gl_FragColor's propagation to however many bound color
+                 * buffers there are means that the shader compile needs to
+                 * know what buffers are present.
+                 */
+                key->cbufs |= 1 << i;
+
                 const struct util_format_description *desc =
                         util_format_description(cbuf->format);