summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorMarek Olšák <[email protected]>2013-02-02 06:20:25 +0100
committerMarek Olšák <[email protected]>2013-02-06 14:45:22 +0100
commit85efb2fff0d4de56c31e414fd05a37d212211da1 (patch)
treef90174f00111de86f6f1cf34dd381c2e68144a9d /src/gallium
parent1d3561d877c8294ffccfd6765268f32dc9ae62cf (diff)
r300g: try to use color varyings for texcoords if max texcoord limit is exceeded
+35 piglits
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/r300/r300_context.h1
-rw-r--r--src/gallium/drivers/r300/r300_screen.c6
-rw-r--r--src/gallium/drivers/r300/r300_shader_semantics.h4
-rw-r--r--src/gallium/drivers/r300/r300_state.c9
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c55
-rw-r--r--src/gallium/drivers/r300/r300_vs.c1
6 files changed, 71 insertions, 5 deletions
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 32b71eda4ee..d88ba3f7ed7 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -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. */
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 01f782c4a27..ebc8a2e958d 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -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:
diff --git a/src/gallium/drivers/r300/r300_shader_semantics.h b/src/gallium/drivers/r300/r300_shader_semantics.h
index 4be23e64ce7..b756048c6c7 100644
--- a/src/gallium/drivers/r300/r300_shader_semantics.h
+++ b/src/gallium/drivers/r300/r300_shader_semantics.h
@@ -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
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 15ce3e00c07..19c7d4eb322 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -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);
}
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 3ccf396b741..1013557bde9 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -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) {
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index ea0621e2d3e..33612a322f7 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -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: