Mesa (master): r300g: Account for CS space used per atom.

Corbin Simpson csimpson at kemper.freedesktop.org
Wed Jan 13 09:46:23 UTC 2010


Module: Mesa
Branch: master
Commit: aeb34b248903f98559209db4f095d1096ecb580a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=aeb34b248903f98559209db4f095d1096ecb580a

Author: Corbin Simpson <MostAwesomeDude at gmail.com>
Date:   Wed Jan 13 01:41:31 2010 -0800

r300g: Account for CS space used per atom.

Oh yeah, those atoms are startin' to pay off. The main obstacle now
for OA playability is the absurdly low default mouse sensitivity, IMO.
Not totally smooth yet, but getting there.

---

 src/gallium/drivers/r300/r300_context.c |   36 +++++++++++++++++++-----------
 src/gallium/drivers/r300/r300_context.h |    9 +++++++
 src/gallium/drivers/r300/r300_emit.c    |   18 ++++++++++++---
 src/gallium/drivers/r300/r300_state.c   |   10 +++++++-
 4 files changed, 55 insertions(+), 18 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 98a5bb8..5e4f655 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -110,23 +110,33 @@ static void r300_flush_cb(void *data)
     cs_context_copy->context.flush(&cs_context_copy->context, 0, NULL);
 }
 
-#define R300_INIT_ATOM(name) \
-    r300->name##_state.state = NULL; \
-    r300->name##_state.emit = r300_emit_##name##_state; \
-    r300->name##_state.dirty = FALSE; \
-    insert_at_tail(&r300->atom_list, &r300->name##_state);
+#define R300_INIT_ATOM(atomname, atomsize) \
+    r300->atomname##_state.name = #atomname; \
+    r300->atomname##_state.state = NULL; \
+    r300->atomname##_state.size = atomsize; \
+    r300->atomname##_state.emit = r300_emit_##atomname##_state; \
+    r300->atomname##_state.dirty = FALSE; \
+    insert_at_tail(&r300->atom_list, &r300->atomname##_state);
 
 static void r300_setup_atoms(struct r300_context* r300)
 {
+    /* Create the actual atom list.
+     *
+     * Each atom is examined and emitted in the order it appears here, which
+     * can affect performance and conformance if not handled with care.
+     *
+     * Some atoms never change size, others change every emit. This is just
+     * an upper bound on each atom, to keep the emission machinery from
+     * underallocating space. */
     make_empty_list(&r300->atom_list);
-    R300_INIT_ATOM(ztop);
-    R300_INIT_ATOM(blend);
-    R300_INIT_ATOM(blend_color);
-    R300_INIT_ATOM(clip);
-    R300_INIT_ATOM(dsa);
-    R300_INIT_ATOM(rs);
-    R300_INIT_ATOM(scissor);
-    R300_INIT_ATOM(viewport);
+    R300_INIT_ATOM(ztop, 2);
+    R300_INIT_ATOM(blend, 8);
+    R300_INIT_ATOM(blend_color, 3);
+    R300_INIT_ATOM(clip, 29);
+    R300_INIT_ATOM(dsa, 8);
+    R300_INIT_ATOM(rs, 22);
+    R300_INIT_ATOM(scissor, 3);
+    R300_INIT_ATOM(viewport, 9);
 }
 
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 7e5de40..682b917 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -36,10 +36,19 @@ struct r300_fragment_shader;
 struct r300_vertex_shader;
 
 struct r300_atom {
+    /* List pointers. */
     struct r300_atom *prev, *next;
+    /* Name, for debugging. */
+    const char* name;
+    /* Opaque state. */
     void* state;
+    /* Emit the state to the context. */
     void (*emit)(struct r300_context*, void*);
+    /* Upper bound on number of dwords to emit. */
+    unsigned size;
+    /* Whether this atom should be emitted. */
     boolean dirty;
+    /* Another dirty flag that is never automatically cleared. */
     boolean always_dirty;
 };
 
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index ba04bd0..9f93327 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -41,6 +41,7 @@ void r300_emit_blend_state(struct r300_context* r300, void* state)
 {
     struct r300_blend_state* blend = (struct r300_blend_state*)state;
     CS_LOCALS(r300);
+
     BEGIN_CS(8);
     OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop);
     OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3);
@@ -992,14 +993,23 @@ void r300_emit_dirty_state(struct r300_context* r300)
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     struct r300_texture* tex;
     struct r300_atom* atom;
-    int i, dirty_tex = 0;
+    unsigned i, dwords = 1024;
+    int dirty_tex = 0;
     boolean invalid = FALSE;
 
-    /* Check size of CS. */
-    /* Make sure we have at least 8*1024 spare dwords. */
+    /* Check the required number of dwords against the space remaining in the
+     * current CS object. If we need more, then flush. */
+
+    foreach(atom, &r300->atom_list) {
+        if (atom->dirty || atom->always_dirty) {
+            dwords += atom->size;
+        }
+    }
+
+    /* Make sure we have at least 2*1024 spare dwords. */
     /* XXX It would be nice to know the number of dwords we really need to
      * XXX emit. */
-    if (!r300->winsys->check_cs(r300->winsys, 8*1024)) {
+    if (!r300->winsys->check_cs(r300->winsys, dwords)) {
         r300->context.flush(&r300->context, 0, NULL);
     }
 
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 00f1b23..281ff68 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -340,6 +340,7 @@ static void r300_set_blend_color(struct pipe_context* pipe,
                                  const struct pipe_blend_color* color)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_screen* r300screen = r300_screen(pipe->screen);
     struct r300_blend_color_state* state =
         (struct r300_blend_color_state*)r300->blend_color_state.state;
     union util_color uc;
@@ -355,6 +356,7 @@ static void r300_set_blend_color(struct pipe_context* pipe,
         float_to_fixed10(color->color[2]) |
         (float_to_fixed10(color->color[1]) << 16);
 
+    r300->blend_color_state.size = r300screen->caps->is_r500 ? 3 : 2;
     r300->blend_color_state.dirty = TRUE;
 }
 
@@ -365,11 +367,14 @@ static void r300_set_clip_state(struct pipe_context* pipe,
 
     if (r300_screen(pipe->screen)->caps->has_tcl) {
         memcpy(r300->clip_state.state, state, sizeof(struct pipe_clip_state));
-        r300->clip_state.dirty = TRUE;
+        r300->clip_state.size = 29;
     } else {
         draw_flush(r300->draw);
         draw_set_clip_state(r300->draw, state);
+        r300->clip_state.size = 2;
     }
+
+    r300->clip_state.dirty = TRUE;
 }
 
 /* Create a new depth, stencil, and alpha state based on the CSO dsa state.
@@ -462,8 +467,10 @@ static void r300_bind_dsa_state(struct pipe_context* pipe,
                                 void* state)
 {
     struct r300_context* r300 = r300_context(pipe);
+    struct r300_screen* r300screen = r300_screen(pipe->screen);
 
     r300->dsa_state.state = state;
+    r300->dsa_state.size = r300screen->caps->is_r500 ? 8 : 6;
     r300->dsa_state.dirty = TRUE;
 }
 
@@ -839,6 +846,7 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
 
     memcpy(r300->scissor_state.state, state,
         sizeof(struct pipe_scissor_state));
+
     r300->scissor_state.dirty = TRUE;
 }
 




More information about the mesa-commit mailing list