r300g: try to use color varyings for texcoords if max texcoord limit is exceeded

+35 piglits
This commit is contained in:
Marek Olšák 2013-02-02 06:20:25 +01:00
parent 1d3561d877
commit 85efb2fff0
6 changed files with 71 additions and 5 deletions

View File

@ -578,6 +578,7 @@ struct r300_context {
int sprite_coord_enable;
/* Whether two-sided color selection is enabled (AKA light_twoside). */
boolean two_sided_color;
boolean flatshade;
/* Whether fast color clear is enabled. */
boolean cbzb_clear;
/* Whether fragment shader needs to be validated. */

View File

@ -103,7 +103,6 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_BARRIER:
case PIPE_CAP_TGSI_CAN_COMPACT_VARYINGS:
case PIPE_CAP_TGSI_CAN_COMPACT_CONSTANTS:
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
case PIPE_CAP_USER_INDEX_BUFFERS:
case PIPE_CAP_USER_CONSTANT_BUFFERS:
case PIPE_CAP_DEPTH_CLIP_DISABLE: /* XXX implemented, but breaks Regnum Online */
@ -122,6 +121,11 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
case PIPE_CAP_TEXTURE_SWIZZLE:
return util_format_s3tc_enabled ? r300screen->caps.dxtc_swizzle : 1;
/* We don't support color clamping on r500, so that we can use color
* intepolators for generic varyings. */
case PIPE_CAP_VERTEX_COLOR_CLAMPED:
return !is_r500;
/* Supported on r500 only. */
case PIPE_CAP_VERTEX_COLOR_UNCLAMPED:
case PIPE_CAP_MIXED_COLORBUFFER_FORMATS:

View File

@ -42,6 +42,8 @@ struct r300_shader_semantics {
int generic[ATTR_GENERIC_COUNT];
int fog;
int wpos;
int num_generic;
};
static INLINE void r300_shader_semantics_reset(
@ -63,6 +65,8 @@ static INLINE void r300_shader_semantics_reset(
for (i = 0; i < ATTR_GENERIC_COUNT; i++) {
info->generic[i] = ATTR_UNUSED;
}
info->num_generic = 0;
}
#endif

View File

@ -1181,8 +1181,7 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
float point_texcoord_bottom = 0;/* R300_GA_POINT_T0: 0x4204 */
float point_texcoord_right = 1; /* R300_GA_POINT_S1: 0x4208 */
float point_texcoord_top = 0; /* R300_GA_POINT_T1: 0x420c */
boolean vclamp = state->clamp_vertex_color ||
!r300_context(pipe)->screen->caps.is_r500;
boolean vclamp = !r300_context(pipe)->screen->caps.is_r500;
CB_LOCALS;
/* Copy rasterizer state. */
@ -1384,6 +1383,7 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
int last_sprite_coord_enable = r300->sprite_coord_enable;
boolean last_two_sided_color = r300->two_sided_color;
boolean last_msaa_enable = r300->msaa_enable;
boolean last_flatshade = r300->flatshade;
if (r300->draw && rs) {
draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state);
@ -1394,18 +1394,21 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
r300->sprite_coord_enable = rs->rs.sprite_coord_enable;
r300->two_sided_color = rs->rs.light_twoside;
r300->msaa_enable = rs->rs.multisample;
r300->flatshade = rs->rs.flatshade;
} else {
r300->polygon_offset_enabled = FALSE;
r300->sprite_coord_enable = 0;
r300->two_sided_color = FALSE;
r300->msaa_enable = FALSE;
r300->flatshade = FALSE;
}
UPDATE_STATE(state, r300->rs_state);
r300->rs_state.size = RS_STATE_MAIN_SIZE + (r300->polygon_offset_enabled ? 5 : 0);
if (last_sprite_coord_enable != r300->sprite_coord_enable ||
last_two_sided_color != r300->two_sided_color) {
last_two_sided_color != r300->two_sided_color ||
last_flatshade != r300->flatshade) {
r300_mark_atom_dirty(r300, &r300->rs_block_state);
}

View File

@ -316,6 +316,7 @@ static void r300_update_rs_block(struct r300_context *r300)
struct r300_shader_semantics *fs_inputs = &r300_fs(r300)->shader->inputs;
struct r300_rs_block rs = {0};
int i, col_count = 0, tex_count = 0, fp_offset = 0, count, loc = 0, tex_ptr = 0;
int gen_offset = 0;
void (*rX00_rs_col)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
void (*rX00_rs_col_write)(struct r300_rs_block*, int, int, enum r300_rs_col_write_type);
void (*rX00_rs_tex)(struct r300_rs_block*, int, int, enum r300_rs_swizzle);
@ -436,8 +437,60 @@ static void r300_update_rs_block(struct r300_context *r300)
fprintf(stderr, "r300: ERROR: FS input FACE unassigned.\n");
}
/* Re-use color varyings for texcoords if possible.
*
* The colors are interpolated as 20-bit floats (reduced precision),
* Use this hack only if there are too many generic varyings.
* (number of generic varyings + fog + wpos > 8) */
if (r300->screen->caps.is_r500 && !any_bcolor_used && !r300->flatshade &&
fs_inputs->face == ATTR_UNUSED &&
vs_outputs->num_generic + (vs_outputs->fog != ATTR_UNUSED) +
(fs_inputs->wpos != ATTR_UNUSED) > 8) {
for (i = 0; i < ATTR_GENERIC_COUNT && col_count < 2; i++) {
/* Cannot use color varyings for sprite coords. */
if (fs_inputs->generic[i] != ATTR_UNUSED &&
(r300->sprite_coord_enable & (1 << i))) {
break;
}
if (vs_outputs->generic[i] != ATTR_UNUSED) {
/* Set up the color in VAP. */
rs.vap_vsm_vtx_assm |= R300_INPUT_CNTL_COLOR;
rs.vap_out_vtx_fmt[0] |=
R300_VAP_OUTPUT_VTX_FMT_0__COLOR_0_PRESENT << col_count;
stream_loc_notcl[loc++] = 2 + col_count;
/* Rasterize it. */
rX00_rs_col(&rs, col_count, col_count, SWIZ_XYZW);
/* Write it to the FS input register if it's needed by the FS. */
if (fs_inputs->generic[i] != ATTR_UNUSED) {
rX00_rs_col_write(&rs, col_count, fp_offset, WRITE_COLOR);
fp_offset++;
DBG(r300, DBG_RS,
"r300: Rasterized generic %i redirected to color %i and written to FS.\n",
i, col_count);
} else {
DBG(r300, DBG_RS, "r300: Rasterized generic %i redirected to color %i unused.\n",
i, col_count);
}
col_count++;
} else {
/* Skip the FS input register, leave it uninitialized. */
/* If we try to set it to (0,0,0,1), it will lock up. */
if (fs_inputs->generic[i] != ATTR_UNUSED) {
fp_offset++;
DBG(r300, DBG_RS, "r300: FS input generic %i unassigned%s.\n", i);
}
}
}
gen_offset = i;
}
/* Rasterize texture coordinates. */
for (i = 0; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) {
for (i = gen_offset; i < ATTR_GENERIC_COUNT && tex_count < 8; i++) {
boolean sprite_coord = false;
if (fs_inputs->generic[i] != ATTR_UNUSED) {

View File

@ -72,6 +72,7 @@ static void r300_shader_read_vs_outputs(
case TGSI_SEMANTIC_GENERIC:
assert(index < ATTR_GENERIC_COUNT);
vs_outputs->generic[index] = i;
vs_outputs->num_generic++;
break;
case TGSI_SEMANTIC_FOG: