From b9ae570bab5d0fefef93a9f6808603971304a74d Mon Sep 17 00:00:00 2001 From: Corbin Simpson Date: Wed, 27 Jan 2010 21:31:36 -0800 Subject: [PATCH] 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 11c21e071bd..cdedb302209 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 694452a3898..9837530a7ac 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 c4c137d6f85..3f461640a03 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 8c5b1607d0e..f1d32764fdb 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 c6dbc5af1e3..6b96d9b57c0 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 b1c9aebd280..1b920563a5f 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: -- 2.30.2