OSDN Git Service

broadcom/vc5: Emit proper flatshading code for glShadeModel(GL_FLAT).
authorEric Anholt <eric@anholt.net>
Wed, 27 Dec 2017 23:12:37 +0000 (15:12 -0800)
committerEric Anholt <eric@anholt.net>
Wed, 3 Jan 2018 22:25:23 +0000 (14:25 -0800)
In updating the simulator, behavior changed slightly so that our old code
wasn't getting glxgears's flatshading interpolated right.  Emit flat
shading code just like we would for a normal flat-shaded varying, by
passing a flag in the shader key for glShadeModel(GL_FLAT) state and
customizing the color inputs based on that.

src/broadcom/compiler/nir_to_vir.c
src/broadcom/compiler/v3d_compiler.h
src/broadcom/compiler/vir.c
src/gallium/drivers/vc5/vc5_emit.c
src/gallium/drivers/vc5/vc5_program.c
src/gallium/drivers/vc5/vc5_state.c

index 77d460c..394e20d 100644 (file)
@@ -614,16 +614,22 @@ emit_fragment_varying(struct v3d_compile *c, nir_variable *var,
         switch (var->data.interpolation) {
         case INTERP_MODE_NONE:
                 /* If a gl_FrontColor or gl_BackColor input has no interp
-                 * qualifier, then flag it for glShadeModel() handling by the
-                 * driver.
+                 * qualifier, then if we're using glShadeModel(GL_FLAT) it
+                 * needs to be flat shaded.
                  */
                 switch (var->data.location) {
                 case VARYING_SLOT_COL0:
                 case VARYING_SLOT_COL1:
                 case VARYING_SLOT_BFC0:
                 case VARYING_SLOT_BFC1:
-                        BITSET_SET(c->shade_model_flags, i);
-                        break;
+                        if (c->fs_key->shade_model_flat) {
+                                BITSET_SET(c->flat_shade_flags, i);
+                                vir_MOV_dest(c, c->undef, vary);
+                                return vir_MOV(c, r5);
+                        } else {
+                                return vir_FADD(c, vir_FMUL(c, vary,
+                                                            c->payload_w), r5);
+                        }
                 default:
                         break;
                 }
index 7cb2e59..99d58e7 100644 (file)
@@ -317,6 +317,7 @@ struct v3d_fs_key {
         bool sample_alpha_to_coverage;
         bool sample_alpha_to_one;
         bool clamp_color;
+        bool shade_model_flat;
         uint8_t nr_cbufs;
         uint8_t swap_color_rb;
         /* Mask of which render targets need to be written as 32-bit floats */
@@ -417,17 +418,11 @@ struct v3d_compile {
         uint32_t uniforms_array_size;
 
         /* Booleans for whether the corresponding QFILE_VARY[i] is
-         * flat-shaded.  This doesn't count gl_FragColor flat-shading, which is
-         * controlled by shader->color_inputs and rasterizer->flatshade in the
-         * gallium driver.
+         * flat-shaded.  This includes gl_FragColor flat-shading, which is
+         * customized based on the shademodel_flat shader key.
          */
         BITSET_WORD flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
 
-        /* Booleans for whether the corresponding QFILE_VARY[i] uses the
-         * default glShadeModel() behavior.
-         */
-        BITSET_WORD shade_model_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
-
         struct v3d_ubo_range *ubo_ranges;
         bool *ubo_range_used;
         uint32_t ubo_ranges_array_size;
@@ -574,14 +569,9 @@ struct v3d_fs_prog_data {
 
         struct v3d_varying_slot input_slots[V3D_MAX_FS_INPUTS];
 
-        /* Bitmask for whether the corresponding input is flat-shaded,
-         * independent of rasterizer (gl_FragColor) flat-shading.
+        /* Bitmask for whether the corresponding input is flat-shaded.
          */
         BITSET_WORD flat_shade_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
-        /* Bitmask for whether the corresponding input uses the default
-         * glShadeModel() behavior.
-         */
-        BITSET_WORD shade_model_flags[BITSET_WORDS(V3D_MAX_FS_INPUTS)];
 
         bool writes_z;
         bool discard;
index d95a150..2589c7f 100644 (file)
@@ -716,8 +716,6 @@ v3d_set_fs_prog_data_inputs(struct v3d_compile *c,
 
         memcpy(prog_data->flat_shade_flags, c->flat_shade_flags,
                sizeof(c->flat_shade_flags));
-        memcpy(prog_data->shade_model_flags, c->shade_model_flags,
-               sizeof(c->shade_model_flags));
 }
 
 uint64_t *v3d_compile_fs(const struct v3d_compiler *compiler,
index 413059e..3914a34 100644 (file)
@@ -507,11 +507,6 @@ vc5_emit_state(struct pipe_context *pctx)
 
                         flags.flat_shade_flags_for_varyings_v024 =
                                 vc5->prog.fs->prog_data.fs->flat_shade_flags[0] & 0xfffff;
-
-                        if (vc5->rasterizer->base.flatshade) {
-                                flags.flat_shade_flags_for_varyings_v024 |=
-                                        vc5->prog.fs->prog_data.fs->shade_model_flags[0] & 0xfffff;
-                        }
                 }
         }
 
index 4232d6a..2fbd839 100644 (file)
@@ -390,6 +390,7 @@ vc5_update_compiled_fs(struct vc5_context *vc5, uint8_t prim_mode)
         }
 
         key->light_twoside = vc5->rasterizer->base.light_twoside;
+        key->shade_model_flat = vc5->rasterizer->base.flatshade;
 
         struct vc5_compiled_shader *old_fs = vc5->prog.fs;
         vc5->prog.fs = vc5_get_compiled_shader(vc5, &key->base);
@@ -399,11 +400,8 @@ vc5_update_compiled_fs(struct vc5_context *vc5, uint8_t prim_mode)
         vc5->dirty |= VC5_DIRTY_COMPILED_FS;
 
         if (old_fs &&
-            (vc5->prog.fs->prog_data.fs->flat_shade_flags !=
-             old_fs->prog_data.fs->flat_shade_flags ||
-             (vc5->rasterizer->base.flatshade &&
-              vc5->prog.fs->prog_data.fs->shade_model_flags !=
-              old_fs->prog_data.fs->shade_model_flags))) {
+            vc5->prog.fs->prog_data.fs->flat_shade_flags !=
+            old_fs->prog_data.fs->flat_shade_flags) {
                 vc5->dirty |= VC5_DIRTY_FLAT_SHADE_FLAGS;
         }
 
index 8bc575f..a3ae2b3 100644 (file)
@@ -272,13 +272,6 @@ static void
 vc5_rasterizer_state_bind(struct pipe_context *pctx, void *hwcso)
 {
         struct vc5_context *vc5 = vc5_context(pctx);
-        struct vc5_rasterizer_state *rast = hwcso;
-
-        if (vc5->rasterizer && rast &&
-            vc5->rasterizer->base.flatshade != rast->base.flatshade) {
-                vc5->dirty |= VC5_DIRTY_FLAT_SHADE_FLAGS;
-        }
-
         vc5->rasterizer = hwcso;
         vc5->dirty |= VC5_DIRTY_RASTERIZER;
 }