[Mesa-dev] [PATCH 02/84] st/nine: Move core of device clear to nine_state

Axel Davy axel.davy at ens.fr
Wed Dec 7 22:54:35 UTC 2016


Part of the refactor to move all gallium calls to
nine_state.c, and have all internal states required
for those calls in nine_context.

Signed-off-by: Axel Davy <axel.davy at ens.fr>
---
 src/gallium/state_trackers/nine/device9.c    | 130 +--------------------
 src/gallium/state_trackers/nine/nine_state.c | 166 +++++++++++++++++++++++++--
 src/gallium/state_trackers/nine/nine_state.h |   5 +-
 3 files changed, 160 insertions(+), 141 deletions(-)

diff --git a/src/gallium/state_trackers/nine/device9.c b/src/gallium/state_trackers/nine/device9.c
index be1e7dc..7e6d3b3 100644
--- a/src/gallium/state_trackers/nine/device9.c
+++ b/src/gallium/state_trackers/nine/device9.c
@@ -1927,16 +1927,7 @@ NineDevice9_Clear( struct NineDevice9 *This,
                    float Z,
                    DWORD Stencil )
 {
-    const int sRGB = This->state.rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
-    struct pipe_surface *cbuf, *zsbuf;
-    struct pipe_context *pipe = This->pipe;
     struct NineSurface9 *zsbuf_surf = This->state.ds;
-    struct NineSurface9 *rt;
-    unsigned bufs = 0;
-    unsigned r, i;
-    union pipe_color_union rgba;
-    unsigned rt_mask = 0;
-    D3DRECT rect;
 
     DBG("This=%p Count=%u pRects=%p Flags=%x Color=%08x Z=%f Stencil=%x\n",
         This, Count, pRects, Flags, Color, Z, Stencil);
@@ -1957,126 +1948,7 @@ NineDevice9_Clear( struct NineDevice9 *This,
         Count = 0;
 #endif
 
-    nine_update_state_framebuffer_clear(This);
-
-    if (Flags & D3DCLEAR_TARGET) bufs |= PIPE_CLEAR_COLOR;
-    /* Ignore Z buffer if not bound */
-    if (This->context.pipe.fb.zsbuf != NULL) {
-        if (Flags & D3DCLEAR_ZBUFFER) bufs |= PIPE_CLEAR_DEPTH;
-        if (Flags & D3DCLEAR_STENCIL) bufs |= PIPE_CLEAR_STENCIL;
-    }
-    if (!bufs)
-        return D3D_OK;
-    d3dcolor_to_pipe_color_union(&rgba, Color);
-
-    rect.x1 = This->state.viewport.X;
-    rect.y1 = This->state.viewport.Y;
-    rect.x2 = This->state.viewport.Width + rect.x1;
-    rect.y2 = This->state.viewport.Height + rect.y1;
-
-    /* Both rectangles apply, which is weird, but that's D3D9. */
-    if (This->state.rs[D3DRS_SCISSORTESTENABLE]) {
-        rect.x1 = MAX2(rect.x1, This->state.scissor.minx);
-        rect.y1 = MAX2(rect.y1, This->state.scissor.miny);
-        rect.x2 = MIN2(rect.x2, This->state.scissor.maxx);
-        rect.y2 = MIN2(rect.y2, This->state.scissor.maxy);
-    }
-
-    if (Count) {
-        /* Maybe apps like to specify a large rect ? */
-        if (pRects[0].x1 <= rect.x1 && pRects[0].x2 >= rect.x2 &&
-            pRects[0].y1 <= rect.y1 && pRects[0].y2 >= rect.y2) {
-            DBG("First rect covers viewport.\n");
-            Count = 0;
-            pRects = NULL;
-        }
-    }
-
-    if (rect.x1 >= This->context.pipe.fb.width || rect.y1 >= This->context.pipe.fb.height)
-        return D3D_OK;
-
-    for (i = 0; i < This->caps.NumSimultaneousRTs; ++i) {
-        if (This->state.rt[i] && This->state.rt[i]->desc.Format != D3DFMT_NULL)
-            rt_mask |= 1 << i;
-    }
-
-    /* fast path, clears everything at once */
-    if (!Count &&
-        (!(bufs & PIPE_CLEAR_COLOR) || (rt_mask == This->context.rt_mask)) &&
-        rect.x1 == 0 && rect.y1 == 0 &&
-        /* Case we clear only render target. Check clear region vs rt. */
-        ((!(bufs & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
-         rect.x2 >= This->context.pipe.fb.width &&
-         rect.y2 >= This->context.pipe.fb.height) ||
-        /* Case we clear depth buffer (and eventually rt too).
-         * depth buffer size is always >= rt size. Compare to clear region */
-        ((bufs & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
-         rect.x2 >= zsbuf_surf->desc.Width &&
-         rect.y2 >= zsbuf_surf->desc.Height))) {
-        DBG("Clear fast path\n");
-        pipe->clear(pipe, bufs, &rgba, Z, Stencil);
-        return D3D_OK;
-    }
-
-    if (!Count) {
-        Count = 1;
-        pRects = ▭
-    }
-
-    for (i = 0; i < This->caps.NumSimultaneousRTs; ++i) {
-        rt = This->state.rt[i];
-        if (!rt || rt->desc.Format == D3DFMT_NULL ||
-            !(bufs & PIPE_CLEAR_COLOR))
-            continue; /* save space, compiler should hoist this */
-        cbuf = NineSurface9_GetSurface(rt, sRGB);
-        for (r = 0; r < Count; ++r) {
-            /* Don't trust users to pass these in the right order. */
-            unsigned x1 = MIN2(pRects[r].x1, pRects[r].x2);
-            unsigned y1 = MIN2(pRects[r].y1, pRects[r].y2);
-            unsigned x2 = MAX2(pRects[r].x1, pRects[r].x2);
-            unsigned y2 = MAX2(pRects[r].y1, pRects[r].y2);
-#ifndef NINE_LAX
-            /* Drop negative rectangles (like wine expects). */
-            if (pRects[r].x1 > pRects[r].x2) continue;
-            if (pRects[r].y1 > pRects[r].y2) continue;
-#endif
-
-            x1 = MAX2(x1, rect.x1);
-            y1 = MAX2(y1, rect.y1);
-            x2 = MIN3(x2, rect.x2, rt->desc.Width);
-            y2 = MIN3(y2, rect.y2, rt->desc.Height);
-
-            DBG("Clearing (%u..%u)x(%u..%u)\n", x1, x2, y1, y2);
-            pipe->clear_render_target(pipe, cbuf, &rgba,
-                                      x1, y1, x2 - x1, y2 - y1, false);
-        }
-    }
-    if (!(bufs & PIPE_CLEAR_DEPTHSTENCIL))
-        return D3D_OK;
-
-    bufs &= PIPE_CLEAR_DEPTHSTENCIL;
-
-    for (r = 0; r < Count; ++r) {
-        unsigned x1 = MIN2(pRects[r].x1, pRects[r].x2);
-        unsigned y1 = MIN2(pRects[r].y1, pRects[r].y2);
-        unsigned x2 = MAX2(pRects[r].x1, pRects[r].x2);
-        unsigned y2 = MAX2(pRects[r].y1, pRects[r].y2);
-#ifndef NINE_LAX
-        /* Drop negative rectangles. */
-        if (pRects[r].x1 > pRects[r].x2) continue;
-        if (pRects[r].y1 > pRects[r].y2) continue;
-#endif
-
-        x1 = MIN2(x1, rect.x1);
-        y1 = MIN2(y1, rect.y1);
-        x2 = MIN3(x2, rect.x2, zsbuf_surf->desc.Width);
-        y2 = MIN3(y2, rect.y2, zsbuf_surf->desc.Height);
-
-        zsbuf = NineSurface9_GetSurface(zsbuf_surf, 0);
-        assert(zsbuf);
-        pipe->clear_depth_stencil(pipe, zsbuf, bufs, Z, Stencil,
-                                  x1, y1, x2 - x1, y2 - y1, false);
-    }
+    nine_context_clear_fb(This, Count, pRects, Flags, Color, Z, Stencil);
     return D3D_OK;
 }
 
diff --git a/src/gallium/state_trackers/nine/nine_state.c b/src/gallium/state_trackers/nine/nine_state.c
index aabe180..46b301d 100644
--- a/src/gallium/state_trackers/nine/nine_state.c
+++ b/src/gallium/state_trackers/nine/nine_state.c
@@ -1006,17 +1006,6 @@ update_managed_buffers(struct NineDevice9 *device)
     }
 }
 
-void
-nine_update_state_framebuffer_clear(struct NineDevice9 *device)
-{
-    struct nine_state *state = &device->state;
-
-    validate_textures(device);
-
-    if (state->changed.group & NINE_STATE_FB)
-        update_framebuffer(device, TRUE);
-}
-
 boolean
 nine_update_state(struct NineDevice9 *device)
 {
@@ -1132,6 +1121,161 @@ nine_update_state(struct NineDevice9 *device)
     return TRUE;
 }
 
+static void
+nine_update_state_framebuffer_clear(struct NineDevice9 *device)
+{
+    struct nine_state *state = &device->state;
+
+    validate_textures(device);
+
+    if (state->changed.group & NINE_STATE_FB)
+        update_framebuffer(device, TRUE);
+}
+
+/* Checks were already done before the call */
+void
+nine_context_clear_fb(struct NineDevice9 *device,
+              DWORD Count,
+              const D3DRECT *pRects,
+              DWORD Flags,
+              D3DCOLOR Color,
+              float Z,
+              DWORD Stencil)
+{
+    const int sRGB = device->state.rs[D3DRS_SRGBWRITEENABLE] ? 1 : 0;
+    struct pipe_surface *cbuf, *zsbuf;
+    struct pipe_context *pipe = device->pipe;
+    struct NineSurface9 *zsbuf_surf = device->state.ds;
+    struct NineSurface9 *rt;
+    unsigned bufs = 0;
+    unsigned r, i;
+    union pipe_color_union rgba;
+    unsigned rt_mask = 0;
+    D3DRECT rect;
+
+    nine_update_state_framebuffer_clear(device);
+
+    if (Flags & D3DCLEAR_TARGET) bufs |= PIPE_CLEAR_COLOR;
+    /* Ignore Z buffer if not bound */
+    if (device->context.pipe.fb.zsbuf != NULL) {
+        if (Flags & D3DCLEAR_ZBUFFER) bufs |= PIPE_CLEAR_DEPTH;
+        if (Flags & D3DCLEAR_STENCIL) bufs |= PIPE_CLEAR_STENCIL;
+    }
+    if (!bufs)
+        return;
+    d3dcolor_to_pipe_color_union(&rgba, Color);
+
+    rect.x1 = device->state.viewport.X;
+    rect.y1 = device->state.viewport.Y;
+    rect.x2 = device->state.viewport.Width + rect.x1;
+    rect.y2 = device->state.viewport.Height + rect.y1;
+
+    /* Both rectangles apply, which is weird, but that's D3D9. */
+    if (device->state.rs[D3DRS_SCISSORTESTENABLE]) {
+        rect.x1 = MAX2(rect.x1, device->state.scissor.minx);
+        rect.y1 = MAX2(rect.y1, device->state.scissor.miny);
+        rect.x2 = MIN2(rect.x2, device->state.scissor.maxx);
+        rect.y2 = MIN2(rect.y2, device->state.scissor.maxy);
+    }
+
+    if (Count) {
+        /* Maybe apps like to specify a large rect ? */
+        if (pRects[0].x1 <= rect.x1 && pRects[0].x2 >= rect.x2 &&
+            pRects[0].y1 <= rect.y1 && pRects[0].y2 >= rect.y2) {
+            DBG("First rect covers viewport.\n");
+            Count = 0;
+            pRects = NULL;
+        }
+    }
+
+    if (rect.x1 >= device->context.pipe.fb.width || rect.y1 >= device->context.pipe.fb.height)
+        return;
+
+    for (i = 0; i < device->caps.NumSimultaneousRTs; ++i) {
+        if (device->state.rt[i] && device->state.rt[i]->desc.Format != D3DFMT_NULL)
+            rt_mask |= 1 << i;
+    }
+
+    /* fast path, clears everything at once */
+    if (!Count &&
+        (!(bufs & PIPE_CLEAR_COLOR) || (rt_mask == device->context.rt_mask)) &&
+        rect.x1 == 0 && rect.y1 == 0 &&
+        /* Case we clear only render target. Check clear region vs rt. */
+        ((!(bufs & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
+         rect.x2 >= device->context.pipe.fb.width &&
+         rect.y2 >= device->context.pipe.fb.height) ||
+        /* Case we clear depth buffer (and eventually rt too).
+         * depth buffer size is always >= rt size. Compare to clear region */
+        ((bufs & (PIPE_CLEAR_DEPTH | PIPE_CLEAR_STENCIL)) &&
+         rect.x2 >= zsbuf_surf->desc.Width &&
+         rect.y2 >= zsbuf_surf->desc.Height))) {
+        DBG("Clear fast path\n");
+        pipe->clear(pipe, bufs, &rgba, Z, Stencil);
+        return;
+    }
+
+    if (!Count) {
+        Count = 1;
+        pRects = ▭
+    }
+
+    for (i = 0; i < device->caps.NumSimultaneousRTs; ++i) {
+        rt = device->state.rt[i];
+        if (!rt || rt->desc.Format == D3DFMT_NULL ||
+            !(bufs & PIPE_CLEAR_COLOR))
+            continue; /* save space, compiler should hoist this */
+        cbuf = NineSurface9_GetSurface(rt, sRGB);
+        for (r = 0; r < Count; ++r) {
+            /* Don't trust users to pass these in the right order. */
+            unsigned x1 = MIN2(pRects[r].x1, pRects[r].x2);
+            unsigned y1 = MIN2(pRects[r].y1, pRects[r].y2);
+            unsigned x2 = MAX2(pRects[r].x1, pRects[r].x2);
+            unsigned y2 = MAX2(pRects[r].y1, pRects[r].y2);
+#ifndef NINE_LAX
+            /* Drop negative rectangles (like wine expects). */
+            if (pRects[r].x1 > pRects[r].x2) continue;
+            if (pRects[r].y1 > pRects[r].y2) continue;
+#endif
+
+            x1 = MAX2(x1, rect.x1);
+            y1 = MAX2(y1, rect.y1);
+            x2 = MIN3(x2, rect.x2, rt->desc.Width);
+            y2 = MIN3(y2, rect.y2, rt->desc.Height);
+
+            DBG("Clearing (%u..%u)x(%u..%u)\n", x1, x2, y1, y2);
+            pipe->clear_render_target(pipe, cbuf, &rgba,
+                                      x1, y1, x2 - x1, y2 - y1, false);
+        }
+    }
+    if (!(bufs & PIPE_CLEAR_DEPTHSTENCIL))
+        return;
+
+    bufs &= PIPE_CLEAR_DEPTHSTENCIL;
+
+    for (r = 0; r < Count; ++r) {
+        unsigned x1 = MIN2(pRects[r].x1, pRects[r].x2);
+        unsigned y1 = MIN2(pRects[r].y1, pRects[r].y2);
+        unsigned x2 = MAX2(pRects[r].x1, pRects[r].x2);
+        unsigned y2 = MAX2(pRects[r].y1, pRects[r].y2);
+#ifndef NINE_LAX
+        /* Drop negative rectangles. */
+        if (pRects[r].x1 > pRects[r].x2) continue;
+        if (pRects[r].y1 > pRects[r].y2) continue;
+#endif
+
+        x1 = MIN2(x1, rect.x1);
+        y1 = MIN2(y1, rect.y1);
+        x2 = MIN3(x2, rect.x2, zsbuf_surf->desc.Width);
+        y2 = MIN3(y2, rect.y2, zsbuf_surf->desc.Height);
+
+        zsbuf = NineSurface9_GetSurface(zsbuf_surf, 0);
+        assert(zsbuf);
+        pipe->clear_depth_stencil(pipe, zsbuf, bufs, Z, Stencil,
+                                  x1, y1, x2 - x1, y2 - y1, false);
+    }
+    return;
+}
+
 /* State defaults */
 
 static const DWORD nine_render_state_defaults[NINED3DRS_LAST + 1] =
diff --git a/src/gallium/state_trackers/nine/nine_state.h b/src/gallium/state_trackers/nine/nine_state.h
index 885ea6b..bb1064a 100644
--- a/src/gallium/state_trackers/nine/nine_state.h
+++ b/src/gallium/state_trackers/nine/nine_state.h
@@ -266,8 +266,11 @@ extern const uint32_t nine_render_states_vertex[(NINED3DRS_COUNT + 31) / 32];
 
 struct NineDevice9;
 
-void nine_update_state_framebuffer_clear(struct NineDevice9 *);
 boolean nine_update_state(struct NineDevice9 *);
+void
+nine_context_clear_fb(struct NineDevice9 *device, DWORD Count,
+                      const D3DRECT *pRects, DWORD Flags,
+                      D3DCOLOR Color, float Z, DWORD Stencil);
 
 void nine_state_restore_non_cso(struct NineDevice9 *device);
 void nine_state_set_defaults(struct NineDevice9 *, const D3DCAPS9 *,
-- 
2.10.2



More information about the mesa-dev mailing list