diff options
Diffstat (limited to 'src/gallium/drivers/r300/r300_emit.c')
-rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 168 |
1 files changed, 94 insertions, 74 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index addb28bded..15bcf8907f 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -32,6 +32,7 @@ #include "r300_emit.h" #include "r300_fs.h" #include "r300_screen.h" +#include "r300_screen_buffer.h" #include "r300_vs.h" void r300_emit_blend_state(struct r300_context* r300, @@ -144,10 +145,8 @@ static const float * get_shader_constant( struct rc_constant * constant, struct r300_constant_buffer * externals) { - struct r300_viewport_state* viewport = - (struct r300_viewport_state*)r300->viewport_state.state; - struct r300_textures_state* texstate = - (struct r300_textures_state*)r300->textures_state.state; + struct r300_viewport_state* viewport = r300->viewport_state.state; + struct r300_textures_state* texstate = r300->textures_state.state; static float vec[4] = { 0.0, 0.0, 0.0, 1.0 }; struct pipe_texture *tex; @@ -163,7 +162,7 @@ static const float * get_shader_constant( /* Factor for converting rectangle coords to * normalized coords. Should only show up on non-r500. */ case RC_STATE_R300_TEXRECT_FACTOR: - tex = &texstate->textures[constant->u.State[1]]->tex; + tex = texstate->fragment_sampler_views[constant->u.State[1]]->texture; vec[0] = 1.0 / tex->width0; vec[1] = 1.0 / tex->height0; break; @@ -187,13 +186,13 @@ static const float * get_shader_constant( break; default: - debug_printf("r300: Implementation error: " + fprintf(stderr, "r300: Implementation error: " "Unknown RC_CONSTANT type %d\n", constant->u.State[0]); } break; default: - debug_printf("r300: Implementation error: " + fprintf(stderr, "r300: Implementation error: " "Unhandled constant type %d\n", constant->Type); } @@ -415,10 +414,10 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) assert(tex && tex->buffer && "cbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1); - OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); - OUT_CS_RELOC(tex->buffer, tex->fb_state.colorpitch[surf->level], + OUT_CS_TEX_RELOC(tex, tex->fb_state.colorpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), tex->fb_state.us_out_fmt); @@ -434,12 +433,12 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) assert(tex && tex->buffer && "zsbuf is marked, but NULL!"); OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1); - OUT_CS_RELOC(tex->buffer, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); + OUT_CS_TEX_RELOC(tex, surf->offset, 0, RADEON_GEM_DOMAIN_VRAM, 0); OUT_CS_REG(R300_ZB_FORMAT, tex->fb_state.zb_format); OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); - OUT_CS_RELOC(tex->buffer, tex->fb_state.depthpitch[surf->level], + OUT_CS_TEX_RELOC(tex, tex->fb_state.depthpitch[surf->level], 0, RADEON_GEM_DOMAIN_VRAM, 0); } @@ -448,7 +447,7 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state) END_CS; } -static void r300_emit_query_start(struct r300_context *r300) +void r300_emit_query_start(struct r300_context *r300) { struct r300_capabilities *caps = r300_screen(r300->context.screen)->caps; struct r300_query *query = r300->query_current; @@ -491,13 +490,13 @@ static void r300_emit_query_finish(struct r300_context *r300, /* pipe 3 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 3); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3), 0, RADEON_GEM_DOMAIN_GTT, 0); case 3: /* pipe 2 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 2); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2), 0, RADEON_GEM_DOMAIN_GTT, 0); case 2: /* pipe 1 only */ @@ -505,19 +504,19 @@ static void r300_emit_query_finish(struct r300_context *r300, OUT_CS_REG(R300_SU_REG_DEST, 1 << (caps->high_second_pipe ? 3 : 1)); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1), 0, RADEON_GEM_DOMAIN_GTT, 0); case 1: /* pipe 0 only */ OUT_CS_REG(R300_SU_REG_DEST, 1 << 0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0), 0, RADEON_GEM_DOMAIN_GTT, 0); break; default: - debug_printf("r300: Implementation error: Chipset reports %d" + fprintf(stderr, "r300: Implementation error: Chipset reports %d" " pixel pipes!\n", caps->num_frag_pipes); - assert(0); + abort(); } /* And, finally, reset it to normal... */ @@ -533,7 +532,7 @@ static void rv530_emit_query_single(struct r300_context *r300, BEGIN_CS(8); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -546,10 +545,10 @@ static void rv530_emit_query_double(struct r300_context *r300, BEGIN_CS(14); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset, 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1); OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1); - OUT_CS_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); + OUT_CS_BUF_RELOC(r300->oqbo, query->offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0); OUT_CS_REG(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL); END_CS; } @@ -675,7 +674,7 @@ void r300_emit_scissor_state(struct r300_context* r300, maxx = fb->width; maxy = fb->height; - if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) { + if (r300->scissor_enabled) { minx = MAX2(minx, scissor->minx); miny = MAX2(miny, scissor->miny); maxx = MIN2(maxx, scissor->maxx); @@ -747,8 +746,9 @@ void r300_emit_textures_state(struct r300_context *r300, OUT_CS_REG(R300_TX_FORMAT2_0 + (i * 4), texstate->format[2]); OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (i * 4), 1); - OUT_CS_RELOC(allstate->textures[i]->buffer, texstate->tile_config, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); + OUT_CS_TEX_RELOC((struct r300_texture *)allstate->fragment_sampler_views[i]->texture, + texstate->tile_config, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0); } } END_CS; @@ -757,9 +757,9 @@ void r300_emit_textures_state(struct r300_context *r300, void r300_emit_aos(struct r300_context* r300, unsigned offset) { struct pipe_vertex_buffer *vb1, *vb2, *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; int i; - unsigned size1, size2, aos_count = r300->vertex_element_count; + unsigned size1, size2, aos_count = r300->velems->count; unsigned packet_size = (aos_count * 3 + 1) / 2; CS_LOCALS(r300); @@ -788,12 +788,36 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset) } for (i = 0; i < aos_count; i++) { - OUT_CS_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, - RADEON_GEM_DOMAIN_GTT, 0, 0); + OUT_CS_BUF_RELOC_NO_OFFSET(vbuf[velem[i].vertex_buffer_index].buffer, + RADEON_GEM_DOMAIN_GTT, 0, 0); } END_CS; } +void r300_emit_vertex_buffer(struct r300_context* r300) +{ + CS_LOCALS(r300); + + DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, " + "vertex size %d\n", r300->vbo, + r300->vertex_info.size); + /* Set the pointer to our vertex buffer. The emitted values are this: + * PACKET3 [3D_LOAD_VBPNTR] + * COUNT [1] + * FORMAT [size | stride << 8] + * OFFSET [offset into BO] + * VBPNTR [relocated BO] + */ + BEGIN_CS(7); + OUT_CS_PKT3(R300_PACKET3_3D_LOAD_VBPNTR, 3); + OUT_CS(1); + OUT_CS(r300->vertex_info.size | + (r300->vertex_info.size << 8)); + OUT_CS(r300->vbo_offset); + OUT_CS_BUF_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0); + END_CS; +} + void r300_emit_vertex_stream_state(struct r300_context* r300, unsigned size, void* state) { @@ -867,12 +891,6 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) CS_LOCALS(r300); - if (!r300screen->caps->has_tcl) { - debug_printf("r300: Implementation error: emit_vertex_shader called," - " but has_tcl is FALSE!\n"); - return; - } - BEGIN_CS(size); /* R300_VAP_PVS_CODE_CNTL_0 * R300_VAP_PVS_CONST_CNTL @@ -902,28 +920,19 @@ void r300_emit_vs_state(struct r300_context* r300, unsigned size, void* state) void r300_emit_vs_constant_buffer(struct r300_context* r300, struct rc_constant_list* constants) { - int i; struct r300_screen* r300screen = r300_screen(r300->context.screen); + unsigned i; CS_LOCALS(r300); - if (!r300screen->caps->has_tcl) { - debug_printf("r300: Implementation error: emit_vertex_shader called," - " but has_tcl is FALSE!\n"); - return; - } - - if (constants->Count == 0) - return; - BEGIN_CS(constants->Count * 4 + 3); OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, (r300screen->caps->is_r500 ? R500_PVS_CONST_START : R300_PVS_CONST_START)); OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->Count * 4); for (i = 0; i < constants->Count; i++) { - const float * data = get_shader_constant(r300, - &constants->Constants[i], - &r300->shader_constants[PIPE_SHADER_VERTEX]); + const float *data = get_shader_constant(r300, + &constants->Constants[i], + &r300->shader_constants[PIPE_SHADER_VERTEX]); OUT_CS_32F(data[0]); OUT_CS_32F(data[1]); OUT_CS_32F(data[2]); @@ -980,21 +989,27 @@ void r300_emit_buffer_validate(struct r300_context *r300, (struct r300_textures_state*)r300->textures_state.state; struct r300_texture* tex; struct pipe_vertex_buffer *vbuf = r300->vertex_buffer; - struct pipe_vertex_element *velem = r300->vertex_element; + struct pipe_vertex_element *velem = r300->velems->velem; struct pipe_buffer *pbuf; unsigned i; boolean invalid = FALSE; + /* upload buffers first */ + if (r300->any_user_vbs) { + r300_upload_user_buffers(r300); + r300->any_user_vbs = false; + } + /* Clean out BOs. */ - r300->winsys->reset_bos(r300->winsys); + r300->rws->reset_bos(r300->rws); validate: /* Color buffers... */ 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)) { + if (!r300_add_texture(r300->rws, tex, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } @@ -1003,66 +1018,67 @@ validate: 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)) { + if (!r300_add_texture(r300->rws, tex, + 0, RADEON_GEM_DOMAIN_VRAM)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...textures... */ for (i = 0; i < texstate->count; i++) { - tex = texstate->textures[i]; - if (!tex || !texstate->sampler_states[i]) + if (!(texstate->tx_enable & (1 << i))) { continue; - if (!r300->winsys->add_buffer(r300->winsys, tex->buffer, - RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { + } + + tex = (struct r300_texture*)texstate->fragment_sampler_views[i]->texture; + if (!r300_add_texture(r300->rws, tex, + RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...occlusion query buffer... */ if (r300->dirty_state & R300_NEW_QUERY) { - if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo, - 0, RADEON_GEM_DOMAIN_GTT)) { + if (!r300_add_buffer(r300->rws, r300->oqbo, + 0, RADEON_GEM_DOMAIN_GTT)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...vertex buffer for SWTCL path... */ if (r300->vbo) { - if (!r300->winsys->add_buffer(r300->winsys, r300->vbo, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300_add_buffer(r300->rws, r300->vbo, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } /* ...vertex buffers for HWTCL path... */ if (do_validate_vertex_buffers) { - for (i = 0; i < r300->vertex_element_count; i++) { + for (i = 0; i < r300->velems->count; i++) { pbuf = vbuf[velem[i].vertex_buffer_index].buffer; - if (!r300->winsys->add_buffer(r300->winsys, pbuf, - RADEON_GEM_DOMAIN_GTT, 0)) { - r300->context.flush(&r300->context, 0, NULL); + if (!r300_add_buffer(r300->rws, pbuf, + RADEON_GEM_DOMAIN_GTT, 0)) { + r300->context.flush(&r300->context, 0, NULL); goto validate; } } } /* ...and index buffer for HWTCL path. */ if (index_buffer) { - if (!r300->winsys->add_buffer(r300->winsys, index_buffer, - RADEON_GEM_DOMAIN_GTT, 0)) { + if (!r300_add_buffer(r300->rws, index_buffer, + RADEON_GEM_DOMAIN_GTT, 0)) { r300->context.flush(&r300->context, 0, NULL); goto validate; } } - - if (!r300->winsys->validate(r300->winsys)) { + if (!r300->rws->validate(r300->rws)) { r300->context.flush(&r300->context, 0, NULL); if (invalid) { /* Well, hell. */ - debug_printf("r300: Stuck in validation loop, gonna quit now."); - exit(1); + fprintf(stderr, "r300: Stuck in validation loop, gonna quit now.\n"); + abort(); } invalid = TRUE; goto validate; @@ -1127,7 +1143,9 @@ void r300_emit_dirty_state(struct r300_context* r300) if (r300->dirty_state & R300_NEW_VERTEX_SHADER_CONSTANTS) { struct r300_vertex_shader* vs = r300->vs_state.state; - r300_emit_vs_constant_buffer(r300, &vs->code.constants); + if (vs->code.constants.Count) { + r300_emit_vs_constant_buffer(r300, &vs->code.constants); + } r300->dirty_state &= ~R300_NEW_VERTEX_SHADER_CONSTANTS; } @@ -1135,8 +1153,10 @@ void r300_emit_dirty_state(struct r300_context* r300) assert(r300->dirty_state == 0); */ - /* Finally, emit the VBO. */ - /* r300_emit_vertex_buffer(r300); */ + /* Emit the VBO for SWTCL. */ + if (!r300screen->caps->has_tcl) { + r300_emit_vertex_buffer(r300); + } r300->dirty_hw++; } |