nv30: Emit framebuffer state using state objects
authorPatrice Mandin <pmandin@caramail.com>
Thu, 3 Jul 2008 18:58:31 +0000 (20:58 +0200)
committerPatrice Mandin <pmandin@caramail.com>
Thu, 3 Jul 2008 18:58:31 +0000 (20:58 +0200)
src/gallium/drivers/nv30/nv30_context.h
src/gallium/drivers/nv30/nv30_state.c
src/gallium/drivers/nv30/nv30_state_emit.c
src/gallium/drivers/nv30/nv30_state_fb.c
src/gallium/drivers/nv30/nv30_vbo.c

index dce077b2b4b5d87ec22744a1a0083559312abbdf..4a6c1d2f47ba200c57a6efe1fd996eb55fa23b03 100644 (file)
@@ -99,6 +99,7 @@ struct nv30_state {
        unsigned stipple_enabled;
        unsigned viewport_bypass;
 
+       uint64_t dirty;
        struct nouveau_stateobj *hw[NV30_STATE_MAX];
 };
 
@@ -208,8 +209,10 @@ extern void nv30_fragprog_destroy(struct nv30_context *,
 extern void nv30_fragtex_bind(struct nv30_context *);
 
 /* nv30_state.c and friends */
+extern boolean nv30_state_validate(struct nv30_context *nv30);
 extern void nv30_emit_hw_state(struct nv30_context *nv30);
 extern void nv30_state_tex_update(struct nv30_context *nv30);
+extern struct nv30_state_entry nv30_state_framebuffer;
 
 /* nv30_vbo.c */
 extern boolean nv30_draw_arrays(struct pipe_context *, unsigned mode,
index c1618041bb002c141aaf38c603c8b868e55d95ca..3edfb0874dabbc6649e1cfd781f08d1f07b0855e 100644 (file)
@@ -565,110 +565,9 @@ nv30_set_framebuffer_state(struct pipe_context *pipe,
                           const struct pipe_framebuffer_state *fb)
 {
        struct nv30_context *nv30 = nv30_context(pipe);
-       struct pipe_surface *rt[2], *zeta = NULL;
-       uint32_t rt_enable, rt_format, w = 0, h = 0;
-       int i, colour_format = 0, zeta_format = 0;
-
-       rt_enable = 0;
-       for (i = 0; i < 2; i++) {
-               if (!fb->cbufs[i])
-                       continue;
-
-               if (colour_format) {
-                       assert(w == fb->cbufs[i]->width);
-                       assert(h == fb->cbufs[i]->height);
-                       assert(colour_format == fb->cbufs[i]->format);
-               } else {
-                       w = fb->cbufs[i]->width;
-                       h = fb->cbufs[i]->height;
-                       colour_format = fb->cbufs[i]->format;
-                       rt_enable |= (NV34TCL_RT_ENABLE_COLOR0 << i);
-                       rt[i] = fb->cbufs[i];
-               }
-       }
-
-       if (rt_enable & (NV34TCL_RT_ENABLE_COLOR1 | NV34TCL_RT_ENABLE_COLOR2 |
-                        NV34TCL_RT_ENABLE_COLOR3))
-               rt_enable |= NV34TCL_RT_ENABLE_MRT;
-
-       if (fb->zsbuf) {
-               if (colour_format) {
-                       assert(w == fb->zsbuf->width);
-                       assert(h == fb->zsbuf->height);
-               } else {
-                       w = fb->zsbuf->width;
-                       h = fb->zsbuf->height;
-               }
-
-               zeta_format = fb->zsbuf->format;
-               zeta = fb->zsbuf;
-       }
-
-       rt_format = NV34TCL_RT_FORMAT_TYPE_LINEAR;
-
-       switch (colour_format) {
-       case PIPE_FORMAT_A8R8G8B8_UNORM:
-       case 0:
-               rt_format |= NV34TCL_RT_FORMAT_COLOR_A8R8G8B8;
-               break;
-       case PIPE_FORMAT_R5G6B5_UNORM:
-               rt_format |= NV34TCL_RT_FORMAT_COLOR_R5G6B5;
-               break;
-       default:
-               assert(0);
-       }
-
-       switch (zeta_format) {
-       case PIPE_FORMAT_Z16_UNORM:
-               rt_format |= NV34TCL_RT_FORMAT_ZETA_Z16;
-               break;
-       case PIPE_FORMAT_Z24S8_UNORM:
-       case 0:
-               rt_format |= NV34TCL_RT_FORMAT_ZETA_Z24S8;
-               break;
-       default:
-               assert(0);
-       }
-
-       if (rt_enable & NV34TCL_RT_ENABLE_COLOR0) {
-               uint32_t pitch = rt[0]->stride;
-               if (zeta) {
-                       pitch |= (zeta->stride << 16);
-               } else {
-                       pitch |= (pitch << 16);
-               }
-
-               BEGIN_RING(rankine, NV34TCL_COLOR0_PITCH, 1);
-               OUT_RING  (pitch);
-               nv30->rt[0] = rt[0]->buffer;
-       }
-
-       if (rt_enable & NV34TCL_RT_ENABLE_COLOR1) {
-               BEGIN_RING(rankine, NV34TCL_COLOR1_PITCH, 1);
-               OUT_RING  (rt[1]->stride);
-               nv30->rt[1] = rt[1]->buffer;
-       }
-
-       if (zeta_format)
-       {
-               nv30->zeta = zeta->buffer;
-       }
 
-       nv30->rt_enable = rt_enable;
-       BEGIN_RING(rankine, NV34TCL_RT_ENABLE, 1);
-       OUT_RING  (rt_enable);
-       BEGIN_RING(rankine, NV34TCL_RT_HORIZ, 3);
-       OUT_RING  ((w << 16) | 0);
-       OUT_RING  ((h << 16) | 0);
-       OUT_RING  (rt_format);
-       BEGIN_RING(rankine, NV34TCL_VIEWPORT_HORIZ, 2);
-       OUT_RING  ((w << 16) | 0);
-       OUT_RING  ((h << 16) | 0);
-       BEGIN_RING(rankine, NV34TCL_VIEWPORT_CLIP_HORIZ(0), 2);
-       OUT_RING  (((w - 1) << 16) | 0);
-       OUT_RING  (((h - 1) << 16) | 0);
-       BEGIN_RING(rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
-       OUT_RING  (0);
+       nv30->framebuffer = *fb;
+       nv30->dirty |= NV30_NEW_FB;
 }
 
 static void
index eda2fd45f569e24ff3112f4cef2a3e84188ac95e..9a3954594a751ccff9f495e16d6eb593e808319f 100644 (file)
@@ -1,10 +1,55 @@
 #include "nv30_context.h"
 #include "nv30_state.h"
 
+static struct nv30_state_entry *render_states[] = {
+       &nv30_state_framebuffer,
+       NULL
+};
+
+static void
+nv30_state_do_validate(struct nv30_context *nv30,
+                      struct nv30_state_entry **states)
+{
+       const struct pipe_framebuffer_state *fb = &nv30->framebuffer;
+       unsigned i;
+
+       for (i = 0; i < fb->num_cbufs; i++)
+               fb->cbufs[i]->status = PIPE_SURFACE_STATUS_DEFINED;
+       if (fb->zsbuf)
+               fb->zsbuf->status = PIPE_SURFACE_STATUS_DEFINED;
+
+       while (*states) {
+               struct nv30_state_entry *e = *states;
+
+               if (nv30->dirty & e->dirty.pipe) {
+                       if (e->validate(nv30)) {
+                               nv30->state.dirty |= (1ULL << e->dirty.hw);
+                       }
+               }
+
+               states++;
+       }
+
+/*     TODO: uncomment when finished converting
+       nv30->dirty = 0;
+*/
+}
+
 void
 nv30_emit_hw_state(struct nv30_context *nv30)
 {
-       int i;
+       struct nv30_state *state = &nv30->state;
+       unsigned i;
+       uint64 states;
+
+       for (i = 0, states = state->dirty; states; i++) {
+               if (!(states & (1ULL << i)))
+                       continue;
+               so_ref (state->hw[i], &nv30->screen->state[i]);
+               if (state->hw[i])
+                       so_emit(nv30->nvws, nv30->screen->state[i]);
+               states &= ~(1ULL << i);
+       }
 
        if (nv30->dirty & NV30_NEW_FRAGPROG) {
                nv30_fragprog_bind(nv30, nv30->fragprog.current);
@@ -28,37 +73,7 @@ nv30_emit_hw_state(struct nv30_context *nv30)
 
        nv30->dirty_samplers = 0;
 
-       /* Emit relocs for every referenced buffer.
-        * This is to ensure the bufmgr has an accurate idea of how
-        * the buffer is used.  This isn't very efficient, but we don't
-        * seem to take a significant performance hit.  Will be improved
-        * at some point.  Vertex arrays are emitted by nv30_vbo.c
-        */
-
-       /* Render targets */
-       if (nv30->rt_enable & NV34TCL_RT_ENABLE_COLOR0) {
-               BEGIN_RING(rankine, NV34TCL_DMA_COLOR0, 1);
-               OUT_RELOCo(nv30->rt[0], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-               BEGIN_RING(rankine, NV34TCL_COLOR0_OFFSET, 1);
-               OUT_RELOCl(nv30->rt[0], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       }
-
-       if (nv30->rt_enable & NV34TCL_RT_ENABLE_COLOR1) {
-               BEGIN_RING(rankine, NV34TCL_DMA_COLOR1, 1);
-               OUT_RELOCo(nv30->rt[1], NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-               BEGIN_RING(rankine, NV34TCL_COLOR1_OFFSET, 1);
-               OUT_RELOCl(nv30->rt[1], 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-       }
-
-       if (nv30->zeta) {
-               BEGIN_RING(rankine, NV34TCL_DMA_ZETA, 1);
-               OUT_RELOCo(nv30->zeta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-               BEGIN_RING(rankine, NV34TCL_ZETA_OFFSET, 1);
-               OUT_RELOCl(nv30->zeta, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
-               /* XXX allocate LMA */
-/*             BEGIN_RING(rankine, NV34TCL_LMA_DEPTH_OFFSET, 1);
-               OUT_RING(0);*/
-       }
+       so_emit_reloc_markers(nv30->nvws, state->hw[NV30_STATE_FB]);
 
        /* Texture images, emitted in nv30_fragtex_build */
 #if 0
@@ -83,3 +98,35 @@ nv30_emit_hw_state(struct nv30_context *nv30)
                   NV34TCL_FP_ACTIVE_PROGRAM_DMA1);
 }
 
+boolean
+nv30_state_validate(struct nv30_context *nv30)
+{
+#if 0
+       boolean was_sw = nv30->fallback_swtnl ? TRUE : FALSE;
+
+       if (nv30->render_mode != HW) {
+               /* Don't even bother trying to go back to hw if none
+                * of the states that caused swtnl previously have changed.
+                */
+               if ((nv30->fallback_swtnl & nv30->dirty)
+                               != nv30->fallback_swtnl)
+                       return FALSE;
+
+               /* Attempt to go to hwtnl again */
+               nv30->pipe.flush(&nv30->pipe, 0, NULL);
+               nv30->dirty |= (NV30_NEW_VIEWPORT |
+                               NV30_NEW_VERTPROG |
+                               NV30_NEW_ARRAYS);
+               nv30->render_mode = HW;
+       }
+#endif
+       nv30_state_do_validate(nv30, render_states);
+#if 0
+       if (nv30->fallback_swtnl || nv30->fallback_swrast)
+               return FALSE;
+       
+       if (was_sw)
+               NOUVEAU_ERR("swtnl->hw\n");
+#endif
+       return TRUE;
+}
index a20df9f75d1f591eee76c28b16fe748c335f9c5e..d93e2bb5c897ce79fc996325c6757d0b6aa15302 100644 (file)
@@ -4,7 +4,7 @@ static boolean
 nv30_state_framebuffer_validate(struct nv30_context *nv30)
 {
        struct pipe_framebuffer_state *fb = &nv30->framebuffer;
-       struct pipe_surface *rt[4], *zeta = NULL;
+       struct pipe_surface *rt[2], *zeta = NULL;
        uint32_t rt_enable, rt_format;
        int i, colour_format = 0, zeta_format = 0;
        struct nouveau_stateobj *so = so_new(64, 10);
@@ -23,8 +23,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
                }
        }
 
-       if (rt_enable & (NV34TCL_RT_ENABLE_COLOR1 | NV34TCL_RT_ENABLE_COLOR2 |
-                        NV34TCL_RT_ENABLE_COLOR3))
+       if (rt_enable & NV34TCL_RT_ENABLE_COLOR1)
                rt_enable |= NV34TCL_RT_ENABLE_MRT;
 
        if (fb->zsbuf) {
@@ -86,31 +85,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
                          NOUVEAU_BO_LOW, 0, 0);
                so_data  (so, rt[1]->stride);
        }
-/*
-       if (rt_enable & NV34TCL_RT_ENABLE_COLOR2) {
-               so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR2, 1);
-               so_reloc (so, rt[2]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
-                         nv30->nvws->channel->vram->handle,
-                         nv30->nvws->channel->gart->handle);
-               so_method(so, nv30->screen->rankine, NV34TCL_COLOR2_OFFSET, 1);
-               so_reloc (so, rt[2]->buffer, rt[2]->offset, rt_flags |
-                         NOUVEAU_BO_LOW, 0, 0);
-               so_method(so, nv30->screen->rankine, NV34TCL_COLOR2_PITCH, 1);
-               so_data  (so, rt[2]->pitch * rt[2]->cpp);
-       }
 
-       if (rt_enable & NV34TCL_RT_ENABLE_COLOR3) {
-               so_method(so, nv30->screen->rankine, NV34TCL_DMA_COLOR3, 1);
-               so_reloc (so, rt[3]->buffer, 0, rt_flags | NOUVEAU_BO_OR,
-                         nv30->nvws->channel->vram->handle,
-                         nv30->nvws->channel->gart->handle);
-               so_method(so, nv30->screen->rankine, NV34TCL_COLOR3_OFFSET, 1);
-               so_reloc (so, rt[3]->buffer, rt[3]->offset, rt_flags |
-                         NOUVEAU_BO_LOW, 0, 0);
-               so_method(so, nv30->screen->rankine, NV34TCL_COLOR3_PITCH, 1);
-               so_data  (so, rt[3]->pitch * rt[3]->cpp);
-       }
-*/
        if (zeta_format) {
                so_method(so, nv30->screen->rankine, NV34TCL_DMA_ZETA, 1);
                so_reloc (so, zeta->buffer, 0, rt_flags | NOUVEAU_BO_OR,
@@ -119,8 +94,7 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
                so_method(so, nv30->screen->rankine, NV34TCL_ZETA_OFFSET, 1);
                so_reloc (so, zeta->buffer, zeta->offset, rt_flags |
                          NOUVEAU_BO_LOW, 0, 0);
-               /*so_method(so, nv30->screen->rankine, NV34TCL_ZETA_PITCH, 1);
-               so_data  (so, zeta->pitch * zeta->cpp);*/
+               /* TODO: allocate LMA depth buffer */
        }
 
        so_method(so, nv30->screen->rankine, NV34TCL_RT_ENABLE, 1);
@@ -137,6 +111,9 @@ nv30_state_framebuffer_validate(struct nv30_context *nv30)
        so_data  (so, ((h - 1) << 16) | 0);
        so_method(so, nv30->screen->rankine, 0x1d88, 1);
        so_data  (so, (1 << 12) | h);
+       /* Wonder why this is needed, context should all be set to zero on init */
+       so_method(so, nv30->screen->rankine, NV34TCL_VIEWPORT_TX_ORIGIN, 1);
+       so_data  (so, 0);
 
        so_ref(so, &nv30->state.hw[NV30_STATE_FB]);
        return TRUE;
index 359e443bb1c6f8f8d844cba8e76e74bf962e47ec..d23164eb485eab3adac4c0b788172ba2c0692f02 100644 (file)
@@ -154,6 +154,8 @@ nv30_vbo_validate_state(struct nv30_context *nv30,
 {
        unsigned inputs;
 
+       nv30_state_validate(nv30);
+
        nv30_emit_hw_state(nv30);
 
        if (nv30->dirty & NV30_NEW_ARRAYS) {