nvc0: don't enable early-z if alpha test is enabled
authorChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sun, 13 Mar 2011 12:05:14 +0000 (13:05 +0100)
committerChristoph Bumiller <e0425955@student.tuwien.ac.at>
Sun, 13 Mar 2011 12:23:54 +0000 (13:23 +0100)
Depth values are also written before the shader is executed, so if
early tests are enabled, fragments that failed the alpha test were
modifying the depth buffer, but they shouldn't.

src/gallium/drivers/nvc0/nvc0_context.h
src/gallium/drivers/nvc0/nvc0_shader_state.c
src/gallium/drivers/nvc0/nvc0_state.c
src/gallium/drivers/nvc0/nvc0_state_validate.c

index 67c5a1287b1b50da86f69d9c2a6a63b4a587e3a9..aac358e142b82755249968f93947fe08cc28c505 100644 (file)
@@ -79,6 +79,7 @@ struct nvc0_context {
       uint32_t instance_base;
       int32_t index_bias;
       boolean prim_restart;
+      boolean early_z;
       uint8_t num_vtxbufs;
       uint8_t num_vtxelts;
       uint8_t num_textures[5];
index 79b5f3d81cc9f26c93d438e00d40c622a0702540..7294eaa222e1b074cd859d358e612c959c966207 100644 (file)
@@ -111,8 +111,6 @@ nvc0_fragprog_validate(struct nvc0_context *nvc0)
          return;
    nvc0_program_update_context_state(nvc0, fp, 4);
 
-   BEGIN_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), 1);
-   OUT_RING  (chan, fp->fp.early_z);
    BEGIN_RING(chan, RING_3D(SP_SELECT(5)), 2);
    OUT_RING  (chan, 0x51);
    OUT_RING  (chan, fp->code_base);
index bbcac3938f5dd2394df7411fa7f4dff8acf844cf..1815fe88a9b8681eaf6d9b46cc8a8165227a8ecc 100644 (file)
@@ -276,14 +276,11 @@ nvc0_zsa_state_create(struct pipe_context *pipe,
 
    so->pipe = *cso;
 
-   SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask);
-   SB_BEGIN_3D(so, DEPTH_TEST_ENABLE, 1);
+   SB_IMMED_3D(so, DEPTH_TEST_ENABLE, cso->depth.enabled);
    if (cso->depth.enabled) {
-      SB_DATA    (so, 1);
+      SB_IMMED_3D(so, DEPTH_WRITE_ENABLE, cso->depth.writemask);
       SB_BEGIN_3D(so, DEPTH_TEST_FUNC, 1);
       SB_DATA    (so, nvgl_comparison_op(cso->depth.func));
-   } else {
-      SB_DATA    (so, 0);
    }
 
    if (cso->stencil[0].enabled) {
@@ -315,15 +312,12 @@ nvc0_zsa_state_create(struct pipe_context *pipe,
    if (cso->stencil[0].enabled) {
       SB_IMMED_3D(so, STENCIL_TWO_SIDE_ENABLE, 0);
    }
-    
-   SB_BEGIN_3D(so, ALPHA_TEST_ENABLE, 1);
+
+   SB_IMMED_3D(so, ALPHA_TEST_ENABLE, cso->alpha.enabled);
    if (cso->alpha.enabled) {
-      SB_DATA    (so, 1);
       SB_BEGIN_3D(so, ALPHA_TEST_REF, 2);
       SB_DATA    (so, fui(cso->alpha.ref_value));
       SB_DATA    (so, nvgl_comparison_op(cso->alpha.func));
-   } else {
-      SB_DATA    (so, 0);
    }
 
    assert(so->size < (sizeof(so->state) / sizeof(so->state[0])));
index c37a070bc68d5c8b94c4234221b0417e2bd37431..4daa968de5a01b6f513c4f9135760b8410600988 100644 (file)
@@ -387,6 +387,20 @@ nvc0_constbufs_validate(struct nvc0_context *nvc0)
    }
 }
 
+static void
+nvc0_validate_derived_1(struct nvc0_context *nvc0)
+{
+   struct nouveau_channel *chan = nvc0->screen->base.channel;
+   boolean early_z;
+
+   early_z = nvc0->fragprog->fp.early_z && !nvc0->zsa->pipe.alpha.enabled;
+
+   if (early_z != nvc0->state.early_z) {
+      nvc0->state.early_z = early_z;
+      IMMED_RING(chan, RING_3D(EARLY_FRAGMENT_TESTS), early_z);
+   }
+}
+
 static struct state_validate {
     void (*func)(struct nvc0_context *);
     uint32_t states;
@@ -406,6 +420,7 @@ static struct state_validate {
     { nvc0_tevlprog_validate,      NVC0_NEW_TEVLPROG },
     { nvc0_gmtyprog_validate,      NVC0_NEW_GMTYPROG },
     { nvc0_fragprog_validate,      NVC0_NEW_FRAGPROG },
+    { nvc0_validate_derived_1,     NVC0_NEW_FRAGPROG | NVC0_NEW_ZSA },
     { nvc0_constbufs_validate,     NVC0_NEW_CONSTBUF },
     { nvc0_validate_textures,      NVC0_NEW_TEXTURES },
     { nvc0_validate_samplers,      NVC0_NEW_SAMPLERS },