diff options
-rw-r--r-- | src/gallium/drivers/r300/r300_context.h | 13 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_emit.c | 6 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_state.c | 34 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_state_derived.c | 40 | ||||
-rw-r--r-- | src/gallium/drivers/r300/r300_state_invariant.c | 13 |
5 files changed, 85 insertions, 21 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index d8bed53a6d5..6ab10c874dd 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -106,6 +106,16 @@ struct r300_rs_state { uint32_t color_control; /* R300_GA_COLOR_CONTROL: 0x4278 */ uint32_t polygon_mode; /* R300_GA_POLY_MODE: 0x4288 */ uint32_t clip_rule; /* R300_SC_CLIP_RULE: 0x43D0 */ + + /* Specifies top of Raster pipe specific enable controls, + * i.e. texture coordinates stuffing for points, lines, triangles */ + uint32_t stuffing_enable; /* R300_GB_ENABLE: 0x4008 */ + + /* Point sprites texture coordinates, 0: lower left, 1: upper right */ + float point_texcoord_left; /* R300_GA_POINT_S0: 0x4200 */ + float point_texcoord_bottom; /* R300_GA_POINT_T0: 0x4204 */ + float point_texcoord_right; /* R300_GA_POINT_S1: 0x4208 */ + float point_texcoord_top; /* R300_GA_POINT_T1: 0x420c */ }; struct r300_rs_block { @@ -420,6 +430,9 @@ struct r300_context { /* Whether the two-sided stencil ref value is different for front and * back faces, and fallback should be used for r3xx-r4xx. */ boolean stencil_ref_bf_fallback; + /* Point sprites texcoord index, 1 bit per texcoord */ + int sprite_coord_enable; + /* upload managers */ struct u_upload_mgr *upload_vb; struct u_upload_mgr *upload_ib; diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index 637b0adbff6..dd02eae70f9 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -748,6 +748,12 @@ void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state) OUT_CS_REG(R300_GA_LINE_STIPPLE_VALUE, rs->line_stipple_value); OUT_CS_REG(R300_GA_POLY_MODE, rs->polygon_mode); OUT_CS_REG(R300_SC_CLIP_RULE, rs->clip_rule); + OUT_CS_REG(R300_GB_ENABLE, rs->stuffing_enable); + OUT_CS_REG_SEQ(R300_GA_POINT_S0, 4); + OUT_CS_32F(rs->point_texcoord_left); + OUT_CS_32F(rs->point_texcoord_bottom); + OUT_CS_32F(rs->point_texcoord_right); + OUT_CS_32F(rs->point_texcoord_top); END_CS; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index f1a062333a6..f5ece395532 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -757,6 +757,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe, const struct pipe_rasterizer_state* state) { struct r300_rs_state* rs = CALLOC_STRUCT(r300_rs_state); + int i; /* Copy rasterizer state for Draw. */ rs->rs = *state; @@ -851,6 +852,30 @@ static void* r300_create_rs_state(struct pipe_context* pipe, rs->clip_rule = state->scissor ? 0xAAAA : 0xFFFF; + /* Point sprites */ + if (state->sprite_coord_enable) { + rs->stuffing_enable = R300_GB_POINT_STUFF_ENABLE; + for (i = 0; i < 8; i++) { + if (state->sprite_coord_enable & (1 << i)) + rs->stuffing_enable |= + R300_GB_TEX_STR << (R300_GB_TEX0_SOURCE_SHIFT + (i*2)); + } + + rs->point_texcoord_left = 0.0f; + rs->point_texcoord_right = 1.0f; + + switch (state->sprite_coord_mode) { + case PIPE_SPRITE_COORD_UPPER_LEFT: + rs->point_texcoord_top = 0.0f; + rs->point_texcoord_bottom = 1.0f; + break; + case PIPE_SPRITE_COORD_LOWER_LEFT: + rs->point_texcoord_top = 1.0f; + rs->point_texcoord_bottom = 0.0f; + break; + } + } + return (void*)rs; } @@ -859,6 +884,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) { struct r300_context* r300 = r300_context(pipe); struct r300_rs_state* rs = (struct r300_rs_state*)state; + int last_sprite_coord_enable = r300->sprite_coord_enable; if (r300->draw) { draw_flush(r300->draw); @@ -867,12 +893,18 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state) if (rs) { r300->polygon_offset_enabled = rs->rs.offset_cw || rs->rs.offset_ccw; + r300->sprite_coord_enable = rs->rs.sprite_coord_enable; } else { r300->polygon_offset_enabled = FALSE; + r300->sprite_coord_enable = 0; } UPDATE_STATE(state, r300->rs_state); - r300->rs_state.size = 19 + (r300->polygon_offset_enabled ? 5 : 0); + r300->rs_state.size = 26 + (r300->polygon_offset_enabled ? 5 : 0); + + if (last_sprite_coord_enable != r300->sprite_coord_enable) { + r300->rs_block_state.dirty = TRUE; + } } /* Free rasterizer state. */ diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index 86c5277263a..ddf7285731e 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -37,6 +37,12 @@ /* r300_state_derived: Various bits of state which are dependent upon * currently bound CSO data. */ +enum r300_rs_swizzle { + SWIZ_XYZW = 0, + SWIZ_X001, + SWIZ_XY01, +}; + static void r300_draw_emit_attrib(struct r300_context* r300, enum attrib_emit emit, enum interp_mode interp, @@ -180,14 +186,20 @@ static void r300_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) } static void r300_rs_tex(struct r300_rs_block* rs, int id, int ptr, - boolean swizzle_X001) + enum r300_rs_swizzle swiz) { - if (swizzle_X001) { + if (swiz == SWIZ_X001) { rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | R300_RS_SEL_S(R300_RS_SEL_C0) | R300_RS_SEL_T(R300_RS_SEL_K0) | R300_RS_SEL_R(R300_RS_SEL_K0) | R300_RS_SEL_Q(R300_RS_SEL_K1); + } else if (swiz == SWIZ_XY01) { + rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | + R300_RS_SEL_S(R300_RS_SEL_C0) | + R300_RS_SEL_T(R300_RS_SEL_C1) | + R300_RS_SEL_R(R300_RS_SEL_K0) | + R300_RS_SEL_Q(R300_RS_SEL_K1); } else { rs->ip[id] |= R300_RS_TEX_PTR(ptr*4) | R300_RS_SEL_S(R300_RS_SEL_C0) | @@ -223,15 +235,20 @@ static void r500_rs_col_write(struct r300_rs_block* rs, int id, int fp_offset) } static void r500_rs_tex(struct r300_rs_block* rs, int id, int ptr, - boolean swizzle_X001) + enum r300_rs_swizzle swiz) { int rs_tex_comp = ptr*4; - if (swizzle_X001) { + if (swiz == SWIZ_X001) { rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | R500_RS_SEL_T(R500_RS_IP_PTR_K0) | R500_RS_SEL_R(R500_RS_IP_PTR_K0) | R500_RS_SEL_Q(R500_RS_IP_PTR_K1); + } else if (swiz == SWIZ_XY01) { + rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | + R500_RS_SEL_T(rs_tex_comp + 1) | + R500_RS_SEL_R(R500_RS_IP_PTR_K0) | + R500_RS_SEL_Q(R500_RS_IP_PTR_K1); } else { rs->ip[id] |= R500_RS_SEL_S(rs_tex_comp) | R500_RS_SEL_T(rs_tex_comp + 1) | @@ -260,7 +277,7 @@ static void r300_update_rs_block(struct r300_context* r300, int i, col_count = 0, tex_count = 0, fp_offset = 0, count; void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean); void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); - void (*rX00_rs_tex)(struct r300_rs_block*, int, int, boolean); + void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle); void (*rX00_rs_tex_write)(struct r300_rs_block*, int, int); boolean any_bcolor_used = vs_outputs->bcolor[0] != ATTR_UNUSED || vs_outputs->bcolor[1] != ATTR_UNUSED; @@ -302,14 +319,19 @@ static void r300_update_rs_block(struct r300_context* r300, /* Rasterize texture coordinates. */ for (i = 0; i < ATTR_GENERIC_COUNT; i++) { - if (vs_outputs->generic[i] != ATTR_UNUSED) { + bool sprite_coord = !!(r300->sprite_coord_enable & (1 << i)); + + if (vs_outputs->generic[i] != ATTR_UNUSED || sprite_coord) { /* Always rasterize if it's written by the VS, * otherwise it locks up. */ - rX00_rs_tex(&rs, tex_count, tex_count, FALSE); + rX00_rs_tex(&rs, tex_count, tex_count, + sprite_coord ? SWIZ_XY01 : SWIZ_XYZW); /* Write it to the FS input register if it's used by the FS. */ if (fs_inputs->generic[i] != ATTR_UNUSED) { rX00_rs_tex_write(&rs, tex_count, fp_offset); + if (sprite_coord) + debug_printf("r300: SpriteCoord (generic index %i) is being written to reg %i\n", i, fp_offset); fp_offset++; } tex_count++; @@ -326,7 +348,7 @@ static void r300_update_rs_block(struct r300_context* r300, if (vs_outputs->fog != ATTR_UNUSED) { /* Always rasterize if it's written by the VS, * otherwise it locks up. */ - rX00_rs_tex(&rs, tex_count, tex_count, TRUE); + rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_X001); /* Write it to the FS input register if it's used by the FS. */ if (fs_inputs->fog != ATTR_UNUSED) { @@ -345,7 +367,7 @@ static void r300_update_rs_block(struct r300_context* r300, /* Rasterize WPOS. */ /* If the FS doesn't need it, it's not written by the VS. */ if (vs_outputs->wpos != ATTR_UNUSED && fs_inputs->wpos != ATTR_UNUSED) { - rX00_rs_tex(&rs, tex_count, tex_count, FALSE); + rX00_rs_tex(&rs, tex_count, tex_count, SWIZ_XYZW); rX00_rs_tex_write(&rs, tex_count, fp_offset); fp_offset++; diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c index a8cd2f5b315..ffb175febf1 100644 --- a/src/gallium/drivers/r300/r300_state_invariant.c +++ b/src/gallium/drivers/r300/r300_state_invariant.c @@ -44,13 +44,9 @@ void r300_emit_invariant_state(struct r300_context* r300, struct r300_capabilities* caps = &r300_screen(r300->context.screen)->caps; CS_LOCALS(r300); - BEGIN_CS(14 + (caps->has_tcl ? 2: 0)); + BEGIN_CS(12 + (caps->has_tcl ? 2: 0)); /*** Graphics Backend (GB) ***/ - /* Various GB enables */ - OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE | - R300_GB_LINE_STUFF_ENABLE | - R300_GB_TRIANGLE_STUFF_ENABLE); /* Subpixel multisampling for AA * These are commented out because glisse's CS checker doesn't like them. * I presume these will be re-enabled later. @@ -78,7 +74,7 @@ void r300_emit_invariant_state(struct r300_context* r300, END_CS; /* XXX unsorted stuff from surface_fill */ - BEGIN_CS(42 + (caps->has_tcl ? 7 : 0) + + BEGIN_CS(38 + (caps->has_tcl ? 7 : 0) + (caps->family >= CHIP_FAMILY_RV350 ? 4 : 0)); if (caps->has_tcl) { @@ -90,11 +86,6 @@ void r300_emit_invariant_state(struct r300_context* r300, OUT_CS_32F(1.0); OUT_CS_32F(1.0); } - /* XXX point tex stuffing */ - OUT_CS_REG_SEQ(R300_GA_POINT_S0, 1); - OUT_CS_32F(0.0); - OUT_CS_REG_SEQ(R300_GA_POINT_S1, 1); - OUT_CS_32F(1.0); /* XXX line tex stuffing */ OUT_CS_REG_SEQ(R300_GA_LINE_S0, 1); OUT_CS_32F(0.0); |