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.c170
1 files changed, 103 insertions, 67 deletions
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 0e5533c790..2ea9fab015 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -41,6 +41,7 @@ void r300_emit_blend_state(struct r300_context* r300, void* state)
{
struct r300_blend_state* blend = (struct r300_blend_state*)state;
CS_LOCALS(r300);
+
BEGIN_CS(8);
OUT_CS_REG(R300_RB3D_ROPCNTL, blend->rop);
OUT_CS_REG_SEQ(R300_RB3D_CBLEND, 3);
@@ -419,8 +420,10 @@ void r300_emit_fb_state(struct r300_context* r300,
OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] |
- r300_translate_colorformat(tex->tex.format), 0,
- RADEON_GEM_DOMAIN_VRAM, 0);
+ r300_translate_colorformat(tex->tex.format) |
+ R300_COLOR_TILE(tex->macrotile) |
+ R300_COLOR_MICROTILE(tex->microtile),
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i),
r300_translate_out_fmt(surf->format));
@@ -443,8 +446,10 @@ void r300_emit_fb_state(struct r300_context* r300,
OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format));
OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
- OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level], 0,
- RADEON_GEM_DOMAIN_VRAM, 0);
+ OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] |
+ R300_DEPTHMACROTILE(tex->macrotile) |
+ R300_DEPTHMICROTILE(tex->microtile),
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
}
END_CS;
@@ -579,19 +584,37 @@ void r300_emit_query_end(struct r300_context* r300)
void r300_emit_rs_state(struct r300_context* r300, void* state)
{
struct r300_rs_state* rs = (struct r300_rs_state*)state;
+ float scale, offset;
CS_LOCALS(r300);
- BEGIN_CS(22);
+ BEGIN_CS(18 + (rs->polygon_offset_enable ? 5 : 0));
OUT_CS_REG(R300_VAP_CNTL_STATUS, rs->vap_control_status);
OUT_CS_REG(R300_GA_POINT_SIZE, rs->point_size);
OUT_CS_REG_SEQ(R300_GA_POINT_MINMAX, 2);
OUT_CS(rs->point_minmax);
OUT_CS(rs->line_control);
- OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 6);
- OUT_CS(rs->depth_scale_front);
- OUT_CS(rs->depth_offset_front);
- OUT_CS(rs->depth_scale_back);
- OUT_CS(rs->depth_offset_back);
+
+ if (rs->polygon_offset_enable) {
+ scale = rs->depth_scale * 12;
+ offset = rs->depth_offset;
+
+ switch (r300->zbuffer_bpp) {
+ case 16:
+ offset *= 4;
+ break;
+ case 24:
+ offset *= 2;
+ break;
+ }
+
+ OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_FRONT_SCALE, 4);
+ OUT_CS_32F(scale);
+ OUT_CS_32F(offset);
+ OUT_CS_32F(scale);
+ OUT_CS_32F(offset);
+ }
+
+ OUT_CS_REG_SEQ(R300_SU_POLY_OFFSET_ENABLE, 2);
OUT_CS(rs->polygon_offset_enable);
OUT_CS(rs->cull_mode);
OUT_CS_REG(R300_GA_LINE_STIPPLE_CONFIG, rs->line_stipple_config);
@@ -641,27 +664,47 @@ void r300_emit_rs_block_state(struct r300_context* r300,
END_CS;
}
-static void r300_emit_scissor_regs(struct r300_context* r300,
- struct r300_scissor_regs* scissor)
+void r300_emit_scissor_state(struct r300_context* r300, void* state)
{
+ unsigned minx, miny, maxx, maxy;
+ 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;
CS_LOCALS(r300);
- BEGIN_CS(3);
- OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
- OUT_CS(scissor->top_left);
- OUT_CS(scissor->bottom_right);
- END_CS;
-}
+ minx = miny = 0;
+ maxx = r300->framebuffer_state.width;
+ maxy = r300->framebuffer_state.height;
-void r300_emit_scissor_state(struct r300_context* r300, void* state)
-{
- struct r300_scissor_state* scissor = (struct r300_scissor_state*)state;
- /* XXX argfl! */
if (((struct r300_rs_state*)r300->rs_state.state)->rs.scissor) {
- r300_emit_scissor_regs(r300, &scissor->scissor);
+ minx = MAX2(minx, scissor->minx);
+ miny = MAX2(miny, scissor->miny);
+ maxx = MIN2(maxx, scissor->maxx);
+ maxy = MIN2(maxy, scissor->maxy);
+ }
+
+ if (r300screen->caps->is_r500) {
+ top_left =
+ (minx << R300_SCISSORS_X_SHIFT) |
+ (miny << R300_SCISSORS_Y_SHIFT);
+ bottom_right =
+ ((maxx - 1) << R300_SCISSORS_X_SHIFT) |
+ ((maxy - 1) << R300_SCISSORS_Y_SHIFT);
} else {
- r300_emit_scissor_regs(r300, &scissor->framebuffer);
+ /* Offset of 1440 in non-R500 chipsets. */
+ top_left =
+ ((minx + 1440) << R300_SCISSORS_X_SHIFT) |
+ ((miny + 1440) << R300_SCISSORS_Y_SHIFT);
+ bottom_right =
+ (((maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
+ (((maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
}
+
+ BEGIN_CS(3);
+ OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
+ OUT_CS(top_left);
+ OUT_CS(bottom_right);
+ END_CS;
}
void r300_emit_texture(struct r300_context* r300,
@@ -680,12 +723,18 @@ void r300_emit_texture(struct r300_context* r300,
filter0 |= R300_TX_WRAP_T(R300_TX_CLAMP_TO_EDGE);
}
- /* determine min/max levels */
- /* the MAX_MIP level is the largest (finest) one */
- max_level = MIN2(sampler->max_lod, tex->tex.last_level);
- min_level = MIN2(sampler->min_lod, max_level);
- format0 |= R300_TX_NUM_LEVELS(max_level);
- filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
+ if (tex->is_npot) {
+ /* NPOT textures don't support mip filter, unfortunately.
+ * This prevents incorrect rendering. */
+ filter0 &= ~R300_TX_MIN_FILTER_MIP_MASK;
+ } else {
+ /* determine min/max levels */
+ /* the MAX_MIP level is the largest (finest) one */
+ max_level = MIN2(sampler->max_lod, tex->tex.last_level);
+ min_level = MIN2(sampler->min_lod, max_level);
+ format0 |= R300_TX_NUM_LEVELS(max_level);
+ filter0 |= R300_TX_MAX_MIP_LEVEL(min_level);
+ }
BEGIN_CS(16);
OUT_CS_REG(R300_TX_FILTER0_0 + (offset * 4), filter0 |
@@ -697,8 +746,10 @@ void r300_emit_texture(struct r300_context* r300,
OUT_CS_REG(R300_TX_FORMAT1_0 + (offset * 4), tex->state.format1);
OUT_CS_REG(R300_TX_FORMAT2_0 + (offset * 4), tex->state.format2);
OUT_CS_REG_SEQ(R300_TX_OFFSET_0 + (offset * 4), 1);
- OUT_CS_RELOC(tex->buffer, 0,
- RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ OUT_CS_RELOC(tex->buffer,
+ R300_TXO_MACRO_TILE(tex->macrotile) |
+ R300_TXO_MICRO_TILE(tex->microtile),
+ RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0, 0);
END_CS;
}
@@ -764,32 +815,6 @@ void r300_emit_aos(struct r300_context* r300, unsigned offset)
END_CS;
}
-#if 0
-void r300_emit_draw_packet(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->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;
-}
-#endif
-
void r300_emit_vertex_format_state(struct r300_context* r300)
{
int i;
@@ -992,14 +1017,23 @@ void r300_emit_dirty_state(struct r300_context* r300)
struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct r300_texture* tex;
struct r300_atom* atom;
- int i, dirty_tex = 0;
+ unsigned i, dwords = 1024;
+ int dirty_tex = 0;
boolean invalid = FALSE;
- /* Check size of CS. */
- /* Make sure we have at least 8*1024 spare dwords. */
+ /* Check the required number of dwords against the space remaining in the
+ * current CS object. If we need more, then flush. */
+
+ foreach(atom, &r300->atom_list) {
+ if (atom->dirty || atom->always_dirty) {
+ dwords += atom->size;
+ }
+ }
+
+ /* Make sure we have at least 2*1024 spare dwords. */
/* XXX It would be nice to know the number of dwords we really need to
* XXX emit. */
- if (!r300->winsys->check_cs(r300->winsys, 8*1024)) {
+ if (!r300->winsys->check_cs(r300->winsys, dwords)) {
r300->context.flush(&r300->context, 0, NULL);
}
@@ -1039,10 +1073,12 @@ validate:
}
}
/* ...occlusion query buffer... */
- if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo,
- 0, RADEON_GEM_DOMAIN_GTT)) {
- r300->context.flush(&r300->context, 0, NULL);
- goto validate;
+ if (r300->dirty_state & R300_NEW_QUERY) {
+ if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo,
+ 0, RADEON_GEM_DOMAIN_GTT)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
}
/* ...and vertex buffer. */
if (r300->vbo) {
@@ -1071,7 +1107,7 @@ validate:
}
foreach(atom, &r300->atom_list) {
- if (atom->dirty) {
+ if (atom->dirty || atom->always_dirty) {
atom->emit(r300, atom->state);
atom->dirty = FALSE;
}