vc4: Fix fallback to quad clears of depth in GLX.
authorEric Anholt <eric@anholt.net>
Wed, 5 Oct 2016 21:10:30 +0000 (14:10 -0700)
committerEric Anholt <eric@anholt.net>
Fri, 7 Oct 2016 01:09:24 +0000 (18:09 -0700)
The fix in the vc4-jobs series ended up triggering the fallback path on
GLX apps that use depth but not stencil.

src/gallium/drivers/vc4/vc4_context.c
src/gallium/drivers/vc4/vc4_draw.c
src/gallium/drivers/vc4/vc4_resource.c
src/gallium/drivers/vc4/vc4_resource.h

index b780b13c90f4a40531b4cff71a34a37114ee81ef..974df8a1da2b435cef7a0f8104f069c53a160144 100644 (file)
@@ -70,6 +70,10 @@ static void
 vc4_invalidate_resource(struct pipe_context *pctx, struct pipe_resource *prsc)
 {
         struct vc4_context *vc4 = vc4_context(pctx);
+        struct vc4_resource *rsc = vc4_resource(prsc);
+
+        rsc->initialized_buffers = 0;
+
         struct hash_entry *entry = _mesa_hash_table_search(vc4->write_jobs,
                                                            prsc);
         if (!entry)
index e4d617958660f5072a3517f960129e405fc3b4cb..49f9479c247ae39ed3f53ac7b233c1217157a4a5 100644 (file)
@@ -444,11 +444,21 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
          */
         assert(start_draw_calls_queued == job->draw_calls_queued);
 
-        if (vc4->zsa && vc4->zsa->base.depth.enabled) {
-                job->resolve |= PIPE_CLEAR_DEPTH;
+        if (vc4->zsa && vc4->framebuffer.zsbuf) {
+                struct vc4_resource *rsc =
+                        vc4_resource(vc4->framebuffer.zsbuf->texture);
+
+                if (vc4->zsa->base.depth.enabled) {
+                        job->resolve |= PIPE_CLEAR_DEPTH;
+                        rsc->initialized_buffers = PIPE_CLEAR_DEPTH;
+                }
+
+                if (vc4->zsa->base.stencil[0].enabled) {
+                        job->resolve |= PIPE_CLEAR_STENCIL;
+                        rsc->initialized_buffers |= PIPE_CLEAR_STENCIL;
+                }
         }
-        if (vc4->zsa && vc4->zsa->base.stencil[0].enabled)
-                job->resolve |= PIPE_CLEAR_STENCIL;
+
         job->resolve |= PIPE_CLEAR_COLOR0;
 
         if (vc4_debug & VC4_DEBUG_ALWAYS_FLUSH)
@@ -482,38 +492,50 @@ vc4_clear(struct pipe_context *pctx, unsigned buffers,
                 job = vc4_get_job_for_fbo(vc4);
         }
 
-        /* Clearing ZS will clear both Z and stencil, so if we're trying to
-         * clear just one then we need to draw a quad to do it instead.
-         */
-        if ((buffers & PIPE_CLEAR_DEPTHSTENCIL) != 0 &&
-            (buffers & PIPE_CLEAR_DEPTHSTENCIL) != PIPE_CLEAR_DEPTHSTENCIL &&
-            util_format_is_depth_and_stencil(vc4->framebuffer.zsbuf->format)) {
-                perf_debug("Partial clear of Z+stencil buffer, drawing a quad "
-                           "instead of fast clearing\n");
-                vc4_blitter_save(vc4);
-                util_blitter_clear(vc4->blitter,
-                                   vc4->framebuffer.width,
-                                   vc4->framebuffer.height,
-                                   1,
-                                   buffers & PIPE_CLEAR_DEPTHSTENCIL,
-                                   NULL, depth, stencil);
-                buffers &= ~PIPE_CLEAR_DEPTHSTENCIL;
-                if (!buffers)
-                        return;
-        }
-
         if (buffers & PIPE_CLEAR_COLOR0) {
+                struct vc4_resource *rsc =
+                        vc4_resource(vc4->framebuffer.cbufs[0]->texture);
+
                 job->clear_color[0] = job->clear_color[1] =
                         pack_rgba(vc4->framebuffer.cbufs[0]->format,
                                   color->f);
+                rsc->initialized_buffers |= (buffers & PIPE_CLEAR_COLOR0);
         }
 
         if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
+                struct vc4_resource *rsc =
+                        vc4_resource(vc4->framebuffer.zsbuf->texture);
+                unsigned zsclear = buffers & PIPE_CLEAR_DEPTHSTENCIL;
+
+                /* Clearing ZS will clear both Z and stencil, so if we're
+                 * trying to clear just one then we need to draw a quad to do
+                 * it instead.
+                 */
+                if ((zsclear == PIPE_CLEAR_DEPTH ||
+                     zsclear == PIPE_CLEAR_STENCIL) &&
+                    (rsc->initialized_buffers & ~zsclear) &&
+                    util_format_is_depth_and_stencil(vc4->framebuffer.zsbuf->format)) {
+                        perf_debug("Partial clear of Z+stencil buffer, "
+                                   "drawing a quad instead of fast clearing\n");
+                        vc4_blitter_save(vc4);
+                        util_blitter_clear(vc4->blitter,
+                                           vc4->framebuffer.width,
+                                           vc4->framebuffer.height,
+                                           1,
+                                           zsclear,
+                                           NULL, depth, stencil);
+                        buffers &= ~zsclear;
+                        if (!buffers)
+                                return;
+                }
+
                 /* Though the depth buffer is stored with Z in the high 24,
                  * for this field we just need to store it in the low 24.
                  */
                 job->clear_depth = util_pack_z(PIPE_FORMAT_Z24X8_UNORM, depth);
                 job->clear_stencil = stencil;
+
+                rsc->initialized_buffers |= zsclear;
         }
 
         job->draw_min_x = 0;
index 5f8b6b0f7152f1c85184d71424f61f39068361df..4168079cd866df8c3d91df5a4affce042893e6aa 100644 (file)
@@ -193,8 +193,10 @@ vc4_resource_transfer_map(struct pipe_context *pctx,
                         vc4_flush_jobs_writing_resource(vc4, prsc);
         }
 
-        if (usage & PIPE_TRANSFER_WRITE)
+        if (usage & PIPE_TRANSFER_WRITE) {
                 rsc->writes++;
+                rsc->initialized_buffers = ~0;
+        }
 
         trans = slab_alloc(&vc4->transfer_pool);
         if (!trans)
index b275050da2083673356ffcd828f9fdfa75a0000f..27aa4e87282f698f264d659a9a46e07a889b7051 100644 (file)
@@ -70,6 +70,17 @@ struct vc4_resource {
          */
         uint64_t writes;
 
+        /**
+         * Bitmask of PIPE_CLEAR_COLOR0, PIPE_CLEAR_DEPTH, PIPE_CLEAR_STENCIL
+         * for which parts of the resource are defined.
+         *
+         * Used for avoiding fallback to quad clears for clearing just depth,
+         * when the stencil contents have never been initialized.  Note that
+         * we're lazy and fields not present in the buffer (DEPTH in a color
+         * buffer) may get marked.
+         */
+        uint32_t initialized_buffers;
+
         /**
          * Resource containing the non-GL_TEXTURE_BASE_LEVEL-rebased texture
          * contents, or the 4-byte index buffer.