CS_LOCALS(r300);
if (fb->nr_cbufs) {
- if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT)
+ if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) {
WRITE_CS_TABLE(blend->cb_noclamp, size);
- else
- WRITE_CS_TABLE(blend->cb_clamp, size);
+ } else {
+ unsigned swz = r300_surface(fb->cbufs[0])->colormask_swizzle;
+ WRITE_CS_TABLE(blend->cb_clamp[swz], size);
+ }
} else {
WRITE_CS_TABLE(blend->cb_no_readwrite, size);
}
case RC_STATE_R300_TEXSCALE_FACTOR:
tex = r300_resource(texstate->sampler_views[constant->u.State[1]]->base.texture);
/* Add a small number to the texture size to work around rounding errors in hw. */
- vec[0] = tex->b.b.b.width0 / (tex->tex.width0 + 0.001f);
- vec[1] = tex->b.b.b.height0 / (tex->tex.height0 + 0.001f);
- vec[2] = tex->b.b.b.depth0 / (tex->tex.depth0 + 0.001f);
+ vec[0] = tex->b.b.width0 / (tex->tex.width0 + 0.001f);
+ vec[1] = tex->b.b.height0 / (tex->tex.height0 + 0.001f);
+ vec[2] = tex->b.b.depth0 / (tex->tex.depth0 + 0.001f);
vec[3] = 1;
break;
struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)state;
struct r300_surface* surf;
unsigned i;
- boolean can_hyperz = r300->rws->get_value(r300->rws, RADEON_VID_CAN_HYPERZ);
uint32_t rb3d_cctl = 0;
CS_LOCALS(r300);
OUT_CS_REG(R300_ZB_DEPTHPITCH, surf->pitch);
OUT_CS_RELOC(surf);
- if (can_hyperz) {
+ if (r300->hyperz_enabled) {
/* HiZ RAM. */
OUT_CS_REG(R300_ZB_HIZ_OFFSET, 0);
OUT_CS_REG(R300_ZB_HIZ_PITCH, surf->pitch_hiz);
struct r300_query *query)
{
struct r300_capabilities* caps = &r300->screen->caps;
+ uint32_t gb_pipes = r300->screen->info.r300_num_gb_pipes;
CS_LOCALS(r300);
- assert(caps->num_frag_pipes);
+ assert(gb_pipes);
- BEGIN_CS(6 * caps->num_frag_pipes + 2);
+ BEGIN_CS(6 * gb_pipes + 2);
/* I'm not so sure I like this switch, but it's hard to be elegant
* when there's so many special cases...
*
* 4-byte offset for each pipe. RV380 and older are special; they have
* only two pipes, and the second pipe's enable is on bit 3, not bit 1,
* so there's a chipset cap for that. */
- switch (caps->num_frag_pipes) {
+ switch (gb_pipes) {
case 4:
/* pipe 3 only */
OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
break;
default:
fprintf(stderr, "r300: Implementation error: Chipset reports %d"
- " pixel pipes!\n", caps->num_frag_pipes);
+ " pixel pipes!\n", gb_pipes);
abort();
}
return;
if (caps->family == CHIP_FAMILY_RV530) {
- if (caps->num_z_pipes == 2)
+ if (r300->screen->info.r300_num_z_pipes == 2)
rv530_emit_query_end_double_z(r300, query);
else
rv530_emit_query_end_single_z(r300, query);
query->num_results += query->num_pipes;
/* XXX grab all the results and reset the counter. */
- if (query->num_results >= query->buffer_size / 4 - 4) {
- query->num_results = (query->buffer_size / 4) / 2;
+ if (query->num_results >= query->buf->size / 4 - 4) {
+ query->num_results = (query->buf->size / 4) / 2;
fprintf(stderr, "r300: Rewinding OQBO...\n");
}
}
void r300_emit_vertex_arrays(struct r300_context* r300, int offset,
boolean indexed, int instance_id)
{
- struct pipe_vertex_buffer *vbuf = r300->vbuf_mgr->vertex_buffer;
- struct pipe_resource **valid_vbuf = r300->vbuf_mgr->real_vertex_buffer;
+ struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
struct pipe_vertex_element *velem = r300->velems->velem;
struct r300_resource *buf;
int i;
}
for (i = 0; i < vertex_array_count; i++) {
- buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]);
+ buf = r300_resource(vbuf[velem[i].vertex_buffer_index].buffer);
OUT_CS_RELOC(buf);
}
} else {
}
for (i = 0; i < vertex_array_count; i++) {
- buf = r300_resource(valid_vbuf[velem[i].vertex_buffer_index]);
+ buf = r300_resource(vbuf[velem[i].vertex_buffer_index].buffer);
OUT_CS_RELOC(buf);
}
}
(r300->vertex_info.size << 8));
OUT_CS(r300->draw_vbo_offset);
OUT_CS(0);
- OUT_CS_RELOC(r300_resource(r300->vbo));
+
+ assert(r300->vbo_cs);
+ cs_winsys->cs_write_reloc(cs_copy, r300->vbo_cs);
+ CS_USED_DW(2);
END_CS;
}
R300_PVS_VF_MAX_VTX_NUM(12) |
(r300screen->caps.is_r500 ? R500_TCL_STATE_OPTIMIZATION : 0));
- /* Emit flow control instructions. */
- if (code->num_fc_ops) {
-
- OUT_CS_REG(R300_VAP_PVS_FLOW_CNTL_OPC, code->fc_ops);
- if (r300screen->caps.is_r500) {
- OUT_CS_REG_SEQ(R500_VAP_PVS_FLOW_CNTL_ADDRS_LW_0, code->num_fc_ops * 2);
- OUT_CS_TABLE(code->fc_op_addrs.r500, code->num_fc_ops * 2);
- } else {
- OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_ADDRS_0, code->num_fc_ops);
- OUT_CS_TABLE(code->fc_op_addrs.r300, code->num_fc_ops);
- }
- OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_LOOP_INDEX_0, code->num_fc_ops);
- OUT_CS_TABLE(code->fc_loop_index, code->num_fc_ops);
+ /* Emit flow control instructions. Even if there are no fc instructions,
+ * we still need to write the registers to make sure they are cleared. */
+ OUT_CS_REG(R300_VAP_PVS_FLOW_CNTL_OPC, code->fc_ops);
+ if (r300screen->caps.is_r500) {
+ OUT_CS_REG_SEQ(R500_VAP_PVS_FLOW_CNTL_ADDRS_LW_0, R300_VS_MAX_FC_OPS * 2);
+ OUT_CS_TABLE(code->fc_op_addrs.r500, R300_VS_MAX_FC_OPS * 2);
+ } else {
+ OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_ADDRS_0, R300_VS_MAX_FC_OPS);
+ OUT_CS_TABLE(code->fc_op_addrs.r300, R300_VS_MAX_FC_OPS);
}
+ OUT_CS_REG_SEQ(R300_VAP_PVS_FLOW_CNTL_LOOP_INDEX_0, R300_VS_MAX_FC_OPS);
+ OUT_CS_TABLE(code->fc_loop_index, R300_VS_MAX_FC_OPS);
END_CS;
}
tex = r300_resource(fb->zsbuf->texture);
BEGIN_CS(size);
+ OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2);
OUT_CS(0);
OUT_CS(tex->tex.hiz_dwords[fb->zsbuf->u.tex.level]);
tex = r300_resource(fb->zsbuf->texture);
BEGIN_CS(size);
+ OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
+ R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2);
OUT_CS(0);
OUT_CS(tex->tex.zmask_dwords[fb->zsbuf->u.tex.level]);
for (i = 0; i < fb->nr_cbufs; i++) {
tex = r300_resource(fb->cbufs[i]->texture);
assert(tex && tex->buf && "cbuf is marked, but NULL!");
- r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, 0,
+ r300->rws->cs_add_reloc(r300->cs, tex->cs_buf,
+ RADEON_USAGE_READWRITE,
r300_surface(fb->cbufs[i])->domain);
}
/* ...depth buffer... */
if (fb->zsbuf) {
tex = r300_resource(fb->zsbuf->texture);
assert(tex && tex->buf && "zsbuf is marked, but NULL!");
- r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, 0,
+ r300->rws->cs_add_reloc(r300->cs, tex->cs_buf,
+ RADEON_USAGE_READWRITE,
r300_surface(fb->zsbuf)->domain);
}
}
}
tex = r300_resource(texstate->sampler_views[i]->base.texture);
- r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, tex->domain, 0);
+ r300->rws->cs_add_reloc(r300->cs, tex->cs_buf, RADEON_USAGE_READ,
+ tex->domain);
}
}
/* ...occlusion query buffer... */
if (r300->query_current)
r300->rws->cs_add_reloc(r300->cs, r300->query_current->cs_buf,
- 0, r300->query_current->domain);
+ RADEON_USAGE_WRITE, RADEON_DOMAIN_GTT);
/* ...vertex buffer for SWTCL path... */
- if (r300->vbo)
- r300->rws->cs_add_reloc(r300->cs, r300_resource(r300->vbo)->cs_buf,
- r300_resource(r300->vbo)->domain, 0);
+ if (r300->vbo_cs)
+ r300->rws->cs_add_reloc(r300->cs, r300->vbo_cs,
+ RADEON_USAGE_READ, RADEON_DOMAIN_GTT);
/* ...vertex buffers for HWTCL path... */
if (do_validate_vertex_buffers && r300->vertex_arrays_dirty) {
- struct pipe_resource **buf = r300->vbuf_mgr->real_vertex_buffer;
- struct pipe_resource **last = r300->vbuf_mgr->real_vertex_buffer +
- r300->vbuf_mgr->nr_real_vertex_buffers;
- for (; buf != last; buf++) {
- if (!*buf)
+ struct pipe_vertex_buffer *vbuf = r300->vertex_buffer;
+ struct pipe_vertex_buffer *last = r300->vertex_buffer +
+ r300->nr_vertex_buffers;
+ struct pipe_resource *buf;
+
+ for (; vbuf != last; vbuf++) {
+ buf = vbuf->buffer;
+ if (!buf)
continue;
- r300->rws->cs_add_reloc(r300->cs, r300_resource(*buf)->cs_buf,
- r300_resource(*buf)->domain, 0);
+ r300->rws->cs_add_reloc(r300->cs, r300_resource(buf)->cs_buf,
+ RADEON_USAGE_READ,
+ r300_resource(buf)->domain);
}
}
/* ...and index buffer for HWTCL path. */
if (index_buffer)
r300->rws->cs_add_reloc(r300->cs, r300_resource(index_buffer)->cs_buf,
- r300_resource(index_buffer)->domain, 0);
+ RADEON_USAGE_READ,
+ r300_resource(index_buffer)->domain);
- /* Now do the validation. */
+ /* Now do the validation (flush is called inside cs_validate on failure). */
if (!r300->rws->cs_validate(r300->cs)) {
/* Ooops, an infinite loop, give up. */
if (flushed)
return FALSE;
- r300_flush(&r300->context, RADEON_FLUSH_ASYNC, NULL);
flushed = TRUE;
goto validate;
}