| @@ -76,6 +76,7 @@ static void r300_destroy_context(struct pipe_context* context) | |||
| FREE(r300->blend_color_state.state); | |||
| FREE(r300->clip_state.state); | |||
| FREE(r300->fb_state.state); | |||
| FREE(r300->gpu_flush.state); | |||
| FREE(r300->rs_block_state.state); | |||
| FREE(r300->scissor_state.state); | |||
| FREE(r300->textures_state.state); | |||
| @@ -120,6 +121,7 @@ static void r300_setup_atoms(struct r300_context* r300) | |||
| /* XXX unsorted. */ | |||
| R300_INIT_ATOM(invariant_state, 71); | |||
| /* RB3D (unpipelined), ZB (unpipelined), US, SC. */ | |||
| R300_INIT_ATOM(gpu_flush, 9); | |||
| R300_INIT_ATOM(fb_state, 0); | |||
| R300_INIT_ATOM(ztop_state, 2); | |||
| R300_INIT_ATOM(dsa_state, is_r500 ? 8 : 6); | |||
| @@ -157,6 +159,7 @@ static void r300_setup_atoms(struct r300_context* r300) | |||
| r300->blend_color_state.state = CALLOC_STRUCT(r300_blend_color_state); | |||
| r300->clip_state.state = CALLOC_STRUCT(r300_clip_state); | |||
| r300->fb_state.state = CALLOC_STRUCT(pipe_framebuffer_state); | |||
| r300->gpu_flush.state = CALLOC_STRUCT(pipe_framebuffer_state); | |||
| r300->rs_block_state.state = CALLOC_STRUCT(r300_rs_block); | |||
| r300->scissor_state.state = CALLOC_STRUCT(pipe_scissor_state); | |||
| r300->textures_state.state = CALLOC_STRUCT(r300_textures_state); | |||
| @@ -180,16 +183,20 @@ static void r300_setup_atoms(struct r300_context* r300) | |||
| * call and we must initialize the command buffers somehow. */ | |||
| static void r300_init_states(struct pipe_context *pipe) | |||
| { | |||
| struct r300_context *r300 = r300_context(pipe); | |||
| struct pipe_blend_color bc = {{0}}; | |||
| struct pipe_clip_state cs = {{{0}}}; | |||
| struct pipe_scissor_state ss = {0}; | |||
| struct r300_clip_state *clip = | |||
| (struct r300_clip_state*)r300_context(pipe)->clip_state.state; | |||
| (struct r300_clip_state*)r300->clip_state.state; | |||
| struct r300_gpu_flush *gpuflush = | |||
| (struct r300_gpu_flush*)r300->gpu_flush.state; | |||
| CB_LOCALS; | |||
| pipe->set_blend_color(pipe, &bc); | |||
| pipe->set_scissor_state(pipe, &ss); | |||
| /* Initialize the clip state. */ | |||
| if (r300_context(pipe)->screen->caps.has_tcl) { | |||
| pipe->set_clip_state(pipe, &cs); | |||
| } else { | |||
| @@ -197,6 +204,25 @@ static void r300_init_states(struct pipe_context *pipe) | |||
| OUT_CB_REG(R300_VAP_CLIP_CNTL, R300_CLIP_DISABLE); | |||
| END_CB; | |||
| } | |||
| /* Initialize the GPU flush. */ | |||
| { | |||
| BEGIN_CB(gpuflush->cb_flush_clean, 6); | |||
| /* Flush and free renderbuffer caches. */ | |||
| OUT_CB_REG(R300_RB3D_DSTCACHE_CTLSTAT, | |||
| R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | | |||
| R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); | |||
| OUT_CB_REG(R300_ZB_ZCACHE_CTLSTAT, | |||
| R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | | |||
| R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); | |||
| /* Wait until the GPU is idle. | |||
| * This fixes random pixels sometimes appearing probably caused | |||
| * by incomplete rendering. */ | |||
| OUT_CB_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); | |||
| END_CB; | |||
| } | |||
| } | |||
| struct pipe_context* r300_create_context(struct pipe_screen* screen, | |||
| @@ -98,6 +98,10 @@ struct r300_dsa_state { | |||
| boolean two_sided_stencil_ref; | |||
| }; | |||
| struct r300_gpu_flush { | |||
| uint32_t cb_flush_clean[6]; | |||
| }; | |||
| struct r300_rs_state { | |||
| /* Original rasterizer state. */ | |||
| struct pipe_rasterizer_state rs; | |||
| @@ -461,6 +465,8 @@ struct r300_context { | |||
| struct r300_atom pvs_flush; | |||
| /* Texture cache invalidate. */ | |||
| struct r300_atom texture_cache_inval; | |||
| /* GPU flush. */ | |||
| struct r300_atom gpu_flush; | |||
| /* Invariant state. This must be emitted to get the engine started. */ | |||
| struct r300_atom invariant_state; | |||
| @@ -267,11 +267,11 @@ void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo | |||
| END_CS; | |||
| } | |||
| void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) | |||
| void r300_emit_gpu_flush(struct r300_context *r300, unsigned size, void *state) | |||
| { | |||
| struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; | |||
| struct r300_surface* surf; | |||
| unsigned i; | |||
| struct r300_gpu_flush *gpuflush = (struct r300_gpu_flush*)state; | |||
| struct pipe_framebuffer_state* fb = | |||
| (struct pipe_framebuffer_state*)r300->fb_state.state; | |||
| CS_LOCALS(r300); | |||
| BEGIN_CS(size); | |||
| @@ -290,18 +290,19 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) | |||
| ((fb->height + 1440-1) << R300_SCISSORS_Y_SHIFT)); | |||
| } | |||
| /* Flush and free renderbuffer caches. */ | |||
| OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, | |||
| R300_RB3D_DSTCACHE_CTLSTAT_DC_FREE_FREE_3D_TAGS | | |||
| R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D); | |||
| OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT, | |||
| R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE | | |||
| R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE); | |||
| /* Wait until the GPU is idle. | |||
| * This fixes random pixels sometimes appearing probably caused | |||
| * by incomplete rendering. */ | |||
| OUT_CS_REG(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN); | |||
| /* Flush CB & ZB caches and wait until the 3D engine is idle and clean. */ | |||
| OUT_CS_TABLE(gpuflush->cb_flush_clean, 6); | |||
| END_CS; | |||
| } | |||
| void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) | |||
| { | |||
| struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state; | |||
| struct r300_surface* surf; | |||
| unsigned i; | |||
| CS_LOCALS(r300); | |||
| BEGIN_CS(size); | |||
| /* XXX unpipelined regs | |||
| rb3d_aaresolve_ctl | |||
| @@ -59,6 +59,8 @@ void r500_emit_fs_rc_constant_state(struct r300_context* r300, unsigned size, vo | |||
| void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state); | |||
| void r300_emit_gpu_flush(struct r300_context *r300, unsigned size, void *state); | |||
| void r300_emit_query_start(struct r300_context *r300, unsigned size, void *state); | |||
| void r300_emit_query_end(struct r300_context* r300); | |||
| @@ -686,6 +686,7 @@ static void | |||
| draw_flush(r300->draw); | |||
| } | |||
| r300->gpu_flush.dirty = TRUE; | |||
| r300->fb_state.dirty = TRUE; | |||
| /* If nr_cbufs is changed from zero to non-zero or vice versa... */ | |||
| @@ -703,7 +704,7 @@ static void | |||
| memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); | |||
| r300->fb_state.size = | |||
| 16 + | |||
| 7 + | |||
| (8 * state->nr_cbufs) + | |||
| (state->zsbuf ? (r300->screen->caps.has_hiz ? 22 : 18) : 0); | |||