Mesa (master): r300g: Atomize framebuffers.

Corbin Simpson csimpson at kemper.freedesktop.org
Thu Jan 28 11:07:54 UTC 2010


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

Author: Corbin Simpson <MostAwesomeDude at gmail.com>
Date:   Wed Jan 27 21:31:36 2010 -0800

r300g: Atomize framebuffers.

There might be some optimizations possible here...

---

 src/gallium/drivers/r300/r300_blit.c    |   12 ++++++----
 src/gallium/drivers/r300/r300_context.c |    1 +
 src/gallium/drivers/r300/r300_context.h |    5 +--
 src/gallium/drivers/r300/r300_emit.c    |   36 +++++++++++++++---------------
 src/gallium/drivers/r300/r300_emit.h    |    3 +-
 src/gallium/drivers/r300/r300_state.c   |   18 ++++++++++++---
 6 files changed, 43 insertions(+), 32 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 11c21e0..cdedb30 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -73,13 +73,15 @@ void r300_clear(struct pipe_context* pipe,
      */
 
     struct r300_context* r300 = r300_context(pipe);
+    struct pipe_framebuffer_state* fb =
+        (struct pipe_framebuffer_state*)r300->fb_state.state;
 
     r300_blitter_save_states(r300);
 
     util_blitter_clear(r300->blitter,
-                       r300->framebuffer_state.width,
-                       r300->framebuffer_state.height,
-                       r300->framebuffer_state.nr_cbufs,
+                       fb->width,
+                       fb->height,
+                       fb->nr_cbufs,
                        buffers, rgba, depth, stencil);
 }
 
@@ -97,7 +99,7 @@ void r300_surface_copy(struct pipe_context* pipe,
      * is really transparent. The states will be restored by the blitter once
      * copying is done. */
     r300_blitter_save_states(r300);
-    util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+    util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
 
     util_blitter_save_fragment_sampler_states(
         r300->blitter, r300->sampler_count, (void**)r300->sampler_states);
@@ -121,7 +123,7 @@ void r300_surface_fill(struct pipe_context* pipe,
     struct r300_context* r300 = r300_context(pipe);
 
     r300_blitter_save_states(r300);
-    util_blitter_save_framebuffer(r300->blitter, &r300->framebuffer_state);
+    util_blitter_save_framebuffer(r300->blitter, r300->fb_state.state);
 
     util_blitter_fill(r300->blitter,
                       dst, dstx, dsty, width, height, value);
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 694452a..9837530 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -118,6 +118,7 @@ static void r300_setup_atoms(struct r300_context* r300)
     R300_INIT_ATOM(blend_color, 3);
     R300_INIT_ATOM(clip, 29);
     R300_INIT_ATOM(dsa, 8);
+    R300_INIT_ATOM(fb, 56);
     R300_INIT_ATOM(rs, 25);
     R300_INIT_ATOM(scissor, 3);
     R300_INIT_ATOM(viewport, 9);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index c4c137d..3f46164 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -139,7 +139,6 @@ struct r300_ztop_state {
     uint32_t z_buffer_top;      /* R300_ZB_ZTOP: 0x4f14 */
 };
 
-#define R300_NEW_FRAMEBUFFERS    0x00000010
 #define R300_NEW_FRAGMENT_SHADER 0x00000020
 #define R300_NEW_FRAGMENT_SHADER_CONSTANTS    0x00000040
 #define R300_NEW_SAMPLER         0x00000200
@@ -288,8 +287,8 @@ struct r300_context {
     struct r300_atom dsa_state;
     /* Fragment shader. */
     struct r300_fragment_shader* fs;
-    /* Framebuffer state. We currently don't need our own version of this. */
-    struct pipe_framebuffer_state framebuffer_state;
+    /* Framebuffer state. */
+    struct r300_atom fb_state;
     /* Rasterizer state. */
     struct r300_atom rs_state;
     /* RS block state. */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 8c5b160..f1d3276 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -38,12 +38,14 @@
 void r300_emit_blend_state(struct r300_context* r300, void* state)
 {
     struct r300_blend_state* blend = (struct r300_blend_state*)state;
+    struct pipe_framebuffer_state* fb =
+        (struct pipe_framebuffer_state*)r300->fb_state.state;
     CS_LOCALS(r300);
 
     BEGIN_CS(8);
     OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop);
     OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3);
-    if (r300->framebuffer_state.nr_cbufs) {
+    if (fb->nr_cbufs) {
         OUT_CS(blend->blend_control);
         OUT_CS(blend->alpha_blend_control);
         OUT_CS(blend->color_channel_mask);
@@ -110,6 +112,8 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state)
 {
     struct r300_dsa_state* dsa = (struct r300_dsa_state*)state;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
+    struct pipe_framebuffer_state* fb =
+        (struct pipe_framebuffer_state*)r300->fb_state.state;
     CS_LOCALS(r300);
 
     BEGIN_CS(r300screen->caps->is_r500 ? 8 : 6);
@@ -122,7 +126,7 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state)
 
     OUT_CS_REG_SEQ(R300_ZB_CNTL, 3);
 
-    if (r300->framebuffer_state.zsbuf) {
+    if (fb->zsbuf) {
         OUT_CS(dsa->z_buffer_control);
         OUT_CS(dsa->z_stencil_control);
     } else {
@@ -382,17 +386,14 @@ void r500_emit_fs_constant_buffer(struct r300_context* r300,
     END_CS;
 }
 
-void r300_emit_fb_state(struct r300_context* r300,
-                        struct pipe_framebuffer_state* fb)
+void r300_emit_fb_state(struct r300_context* r300, void* state)
 {
+    struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state;
     struct r300_texture* tex;
     struct pipe_surface* surf;
     int i;
     CS_LOCALS(r300);
 
-    /* Shouldn't fail unless there is a bug in the state tracker. */
-    assert(fb->nr_cbufs <= 4);
-
     BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) +
              (fb->zsbuf ? 10 : 0) + 6);
 
@@ -671,11 +672,13 @@ void r300_emit_scissor_state(struct r300_context* r300, void* state)
     uint32_t top_left, bottom_right;
     struct r300_screen* r300screen = r300_screen(r300->context.screen);
     struct pipe_scissor_state* scissor = (struct pipe_scissor_state*)state;
+    struct pipe_framebuffer_state* fb =
+        (struct pipe_framebuffer_state*)r300->fb_state.state;
     CS_LOCALS(r300);
 
     minx = miny = 0;
-    maxx = r300->framebuffer_state.width;
-    maxy = r300->framebuffer_state.height;
+    maxx = fb->width;
+    maxy = fb->height;
 
     if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) {
         minx = MAX2(minx, scissor->minx);
@@ -1009,6 +1012,8 @@ static void r300_flush_pvs(struct r300_context* r300)
 
 void r300_emit_buffer_validate(struct r300_context *r300)
 {
+    struct pipe_framebuffer_state* fb =
+        (struct pipe_framebuffer_state*)r300->fb_state.state;
     struct r300_texture* tex;
     unsigned i;
     boolean invalid = FALSE;
@@ -1018,8 +1023,8 @@ void r300_emit_buffer_validate(struct r300_context *r300)
 
 validate:
     /* Color buffers... */
-    for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) {
-        tex = (struct r300_texture*)r300->framebuffer_state.cbufs[i]->texture;
+    for (i = 0; i < fb->nr_cbufs; i++) {
+        tex = (struct r300_texture*)fb->cbufs[i]->texture;
         assert(tex && tex->buffer && "cbuf is marked, but NULL!");
         if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
                     0, RADEON_GEM_DOMAIN_VRAM)) {
@@ -1028,8 +1033,8 @@ validate:
         }
     }
     /* ...depth buffer... */
-    if (r300->framebuffer_state.zsbuf) {
-        tex = (struct r300_texture*)r300->framebuffer_state.zsbuf->texture;
+    if (fb->zsbuf) {
+        tex = (struct r300_texture*)fb->zsbuf->texture;
         assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
         if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
                     0, RADEON_GEM_DOMAIN_VRAM)) {
@@ -1135,11 +1140,6 @@ void r300_emit_dirty_state(struct r300_context* r300)
         r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER_CONSTANTS;
     }
 
-    if (r300->dirty_state & R300_NEW_FRAMEBUFFERS) {
-        r300_emit_fb_state(r300, &r300->framebuffer_state);
-        r300->dirty_state &= ~R300_NEW_FRAMEBUFFERS;
-    }
-
     /* Samplers and textures are tracked separately but emitted together. */
     if (r300->dirty_state &
             (R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES)) {
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index c6dbc5a..6b96d9b 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -51,8 +51,7 @@ void r500_emit_fragment_program_code(struct r300_context* r300,
 void r500_emit_fs_constant_buffer(struct r300_context* r300,
                                   struct rc_constant_list* constants);
 
-void r300_emit_fb_state(struct r300_context* r300,
-                        struct pipe_framebuffer_state* fb);
+void r300_emit_fb_state(struct r300_context* r300, void* state);
 
 void r300_emit_query_begin(struct r300_context* r300,
                            struct r300_query* query);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index b1c9aeb..1b92056 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -487,20 +487,30 @@ static void
     struct r300_context* r300 = r300_context(pipe);
     uint32_t zbuffer_bpp = 0;
 
+    r300->fb_state.size = (10 * state->nr_cbufs) +
+        (2 * (4 - state->nr_cbufs)) +
+        (state->zsbuf ? 10 : 0) + 6;
+
+    if (state->nr_cbufs > 4) {
+        debug_printf("r300: Implementation error: Too many MRTs in %s, "
+            "refusing to bind framebuffer state!\n", __FUNCTION__);
+        return;
+    }
+
     if (r300->draw) {
         draw_flush(r300->draw);
     }
 
-    r300->framebuffer_state = *state;
+    r300->fb_state.state = state;
 
     /* Don't rely on the order of states being set for the first time. */
-    r300->dirty_state |= R300_NEW_FRAMEBUFFERS;
-
+    /* XXX wait what */
     r300->blend_state.dirty = TRUE;
     r300->dsa_state.dirty = TRUE;
+    r300->fb_state.dirty = TRUE;
     r300->scissor_state.dirty = TRUE;
 
-    /* Polyfon offset depends on the zbuffer bit depth. */
+    /* Polygon offset depends on the zbuffer bit depth. */
     if (state->zsbuf && r300->polygon_offset_enabled) {
         switch (util_format_get_blocksize(state->zsbuf->texture->format)) {
             case 2:




More information about the mesa-commit mailing list