radeonsi: implement TC L2 write-back (flush) without cache invalidation
[mesa.git] / src / gallium / drivers / nouveau / nv50 / nv50_shader_state.c
index 23263945bdc8bcf8ffa2f050edcd085d0ec0a98f..d234748a0a0c011ccb07307a71a8061b83291baf 100644 (file)
@@ -174,6 +174,42 @@ nv50_fragprog_validate(struct nv50_context *nv50)
    struct nv50_program *fp = nv50->fragprog;
    struct pipe_rasterizer_state *rast = &nv50->rast->pipe;
 
+   if (nv50->zsa && nv50->zsa->pipe.alpha.enabled) {
+      struct pipe_framebuffer_state *fb = &nv50->framebuffer;
+      bool blendable = fb->nr_cbufs == 0 || !fb->cbufs[0] ||
+         nv50->screen->base.base.is_format_supported(
+               &nv50->screen->base.base,
+               fb->cbufs[0]->format,
+               fb->cbufs[0]->texture->target,
+               fb->cbufs[0]->texture->nr_samples,
+               PIPE_BIND_BLENDABLE);
+      /* If we already have alphatest code, we have to keep updating
+       * it. However we only have to have different code if the current RT0 is
+       * non-blendable. Otherwise we just set it to always pass and use the
+       * hardware alpha test.
+       */
+      if (fp->fp.alphatest || !blendable) {
+         uint8_t alphatest = PIPE_FUNC_ALWAYS + 1;
+         if (!blendable)
+            alphatest = nv50->zsa->pipe.alpha.func + 1;
+         if (!fp->fp.alphatest)
+            nv50_program_destroy(nv50, fp);
+         else if (fp->mem && fp->fp.alphatest != alphatest)
+            nouveau_heap_free(&fp->mem);
+
+         fp->fp.alphatest = alphatest;
+      }
+   } else if (fp->fp.alphatest && fp->fp.alphatest != PIPE_FUNC_ALWAYS + 1) {
+      /* Alpha test is disabled but we have a shader where it's filled
+       * in. Make sure to reset the function to 'always', otherwise it'll end
+       * up discarding fragments incorrectly.
+       */
+      if (fp->mem)
+         nouveau_heap_free(&fp->mem);
+
+      fp->fp.alphatest = PIPE_FUNC_ALWAYS + 1;
+   }
+
    if (fp->fp.force_persample_interp != rast->force_persample_interp) {
       /* Force the program to be reuploaded, which will trigger interp fixups
        * to get applied