summaryrefslogtreecommitdiff
path: root/src/gallium/drivers/r300/r300_emit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gallium/drivers/r300/r300_emit.c')
-rw-r--r--src/gallium/drivers/r300/r300_emit.c122
1 files changed, 100 insertions, 22 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 01bac5f759..caeb73a8ed 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -163,6 +163,7 @@ void r300_emit_fb_state(struct r300_context* r300,
BEGIN_CS((8 * fb->nr_cbufs) + (fb->zsbuf ? 8 : 0) + 4);
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!");
pixpitch = tex->stride / tex->tex.block.size;
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
@@ -177,7 +178,8 @@ void r300_emit_fb_state(struct r300_context* r300,
if (fb->zsbuf) {
tex = (struct r300_texture*)fb->zsbuf->texture;
- pixpitch = (tex->stride / tex->tex.block.size);
+ assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
+ pixpitch = tex->stride / tex->tex.block.size;
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
@@ -234,7 +236,7 @@ void r300_emit_rs_block_state(struct r300_context* r300,
}
for (i = 0; i < 8; i++) {
OUT_CS(rs->ip[i]);
- debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]);
+ /* debug_printf("ip %d: 0x%08x\n", i, rs->ip[i]); */
}
OUT_CS_REG_SEQ(R300_RS_COUNT, 2);
@@ -248,11 +250,11 @@ void r300_emit_rs_block_state(struct r300_context* r300,
}
for (i = 0; i < 8; i++) {
OUT_CS(rs->inst[i]);
- debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]);
+ /* debug_printf("inst %d: 0x%08x\n", i, rs->inst[i]); */
}
- debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count,
- rs->inst_count);
+ /* debug_printf("count: 0x%08x inst_count: 0x%08x\n", rs->count,
+ * rs->inst_count); */
END_CS;
}
@@ -296,6 +298,30 @@ void r300_emit_texture(struct r300_context* r300,
END_CS;
}
+void r300_emit_vertex_buffer(struct r300_context* r300)
+{
+ CS_LOCALS(r300);
+
+ debug_printf("r300: Preparing vertex buffer %p for render, "
+ "vertex size %d\n", r300->vbo,
+ r300->vertex_info.vinfo.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.vinfo.size |
+ (r300->vertex_info.vinfo.size << 8));
+ OUT_CS(r300->vbo_offset);
+ OUT_CS_RELOC(r300->vbo, 0, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_CS;
+}
+
void r300_emit_vertex_format_state(struct r300_context* r300)
{
int i;
@@ -310,22 +336,22 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
OUT_CS_REG_SEQ(R300_VAP_OUTPUT_VTX_FMT_0, 2);
OUT_CS(r300->vertex_info.vinfo.hwfmt[2]);
OUT_CS(r300->vertex_info.vinfo.hwfmt[3]);
- for (i = 0; i < 4; i++) {
- debug_printf("hwfmt%d: 0x%08x\n", i,
- r300->vertex_info.vinfo.hwfmt[i]);
- }
+ /* for (i = 0; i < 4; i++) {
+ * debug_printf("hwfmt%d: 0x%08x\n", i,
+ * r300->vertex_info.vinfo.hwfmt[i]);
+ * } */
OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_0, 8);
for (i = 0; i < 8; i++) {
OUT_CS(r300->vertex_info.vap_prog_stream_cntl[i]);
- debug_printf("prog_stream_cntl%d: 0x%08x\n", i,
- r300->vertex_info.vap_prog_stream_cntl[i]);
+ /* debug_printf("prog_stream_cntl%d: 0x%08x\n", i,
+ * r300->vertex_info.vap_prog_stream_cntl[i]); */
}
OUT_CS_REG_SEQ(R300_VAP_PROG_STREAM_CNTL_EXT_0, 8);
for (i = 0; i < 8; i++) {
OUT_CS(r300->vertex_info.vap_prog_stream_cntl_ext[i]);
- debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i,
- r300->vertex_info.vap_prog_stream_cntl_ext[i]);
+ /* debug_printf("prog_stream_cntl_ext%d: 0x%08x\n", i,
+ * r300->vertex_info.vap_prog_stream_cntl_ext[i]); */
}
END_CS;
}
@@ -403,7 +429,11 @@ void r300_emit_viewport_state(struct r300_context* r300,
OUT_CS_32F(viewport->zscale);
OUT_CS_32F(viewport->zoffset);
- OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
+ if (r300->rs_state->enable_vte) {
+ OUT_CS_REG(R300_VAP_VTE_CNTL, viewport->vte_control);
+ } else {
+ OUT_CS_REG(R300_VAP_VTE_CNTL, 0);
+ }
END_CS;
}
@@ -421,23 +451,66 @@ void r300_flush_textures(struct r300_context* r300)
void r300_emit_dirty_state(struct r300_context* r300)
{
struct r300_screen* r300screen = r300_screen(r300->context.screen);
- int i;
- int dirty_tex = 0;
+ struct r300_texture* tex;
+ int i, dirty_tex = 0;
+ boolean invalid = FALSE;
- if (!(r300->dirty_hw)) {
+ if (!(r300->dirty_state)) {
return;
}
r300_update_derived_state(r300);
/* XXX check size */
- struct r300_texture* fb_tex =
- (struct r300_texture*)r300->framebuffer_state.cbufs[0];
- r300->winsys->add_buffer(r300->winsys, fb_tex->buffer,
- 0, RADEON_GEM_DOMAIN_VRAM);
+validate:
+ /* Color buffers... */
+ for (i = 0; i < r300->framebuffer_state.nr_cbufs; i++) {
+ tex = (struct r300_texture*)r300->framebuffer_state.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)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ }
+ /* ...depth buffer... */
+ if (r300->framebuffer_state.zsbuf) {
+ tex = (struct r300_texture*)r300->framebuffer_state.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)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ }
+ /* ...textures... */
+ for (i = 0; i < r300->texture_count; i++) {
+ tex = r300->textures[i];
+ assert(tex && tex->buffer && "texture is marked, but NULL!");
+ if (!r300->winsys->add_buffer(r300->winsys, tex->buffer,
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ }
+ /* ...and vertex buffer. */
+ if (r300->vbo) {
+ if (!r300->winsys->add_buffer(r300->winsys, r300->vbo,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
+ } else {
+ debug_printf("No VBO while emitting dirty state!\n");
+ }
if (r300->winsys->validate(r300->winsys)) {
- /* XXX */
r300->context.flush(&r300->context, 0, NULL);
+ if (invalid) {
+ /* Well, hell. */
+ exit(1);
+ }
+ invalid = TRUE;
+ goto validate;
}
if (r300->dirty_state & R300_NEW_BLEND) {
@@ -519,4 +592,9 @@ void r300_emit_dirty_state(struct r300_context* r300)
r300_emit_vertex_format_state(r300);
r300->dirty_state &= ~R300_NEW_VERTEX_FORMAT;
}
+
+ /* Finally, emit the VBO. */
+ r300_emit_vertex_buffer(r300);
+
+ r300->dirty_hw++;
}