draw: handle more TGSI_SEMANTIC_COLOR indices

It could only handle indices 0/1, otherwise what happened was bad (accessing
array out of bounds, no crash but kind of random). This is enough for the gl
state tracker (primary/secondary color) but not enough for some other state
trackers (d3d9 has no limits on the number of color interpolants).
The complexity with color semantics are all due to the front/back mapping (2
outputs in the vs map to one input in the fs) so this isn't extended to
indices > 1 - d3d9 has no use for back colors, therefore this isn't needed and
still only 2 back colors can be handled correctly.

Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
Roland Scheidegger
2017-07-08 00:14:35 +02:00
parent f728435e1f
commit 4db72852a1
3 changed files with 27 additions and 10 deletions
+14 -3
View File
@@ -771,8 +771,9 @@ find_interp(const struct draw_fragment_shader *fs, int *indexed_interp,
int interp;
/* If it's gl_{Front,Back}{,Secondary}Color, pick up the mode
* from the array we've filled before. */
if (semantic_name == TGSI_SEMANTIC_COLOR ||
semantic_name == TGSI_SEMANTIC_BCOLOR) {
if ((semantic_name == TGSI_SEMANTIC_COLOR ||
semantic_name == TGSI_SEMANTIC_BCOLOR) &&
semantic_index < 2) {
interp = indexed_interp[semantic_index];
} else if (semantic_name == TGSI_SEMANTIC_POSITION ||
semantic_name == TGSI_SEMANTIC_CLIPVERTEX) {
@@ -851,7 +852,8 @@ clip_init_state(struct draw_stage *stage)
if (fs) {
for (i = 0; i < fs->info.num_inputs; i++) {
if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
fs->info.input_semantic_index[i] < 2) {
if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR)
indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i];
}
@@ -881,6 +883,15 @@ clip_init_state(struct draw_stage *stage)
clipper->perspect_attribs[clipper->num_perspect_attribs] = i;
clipper->num_perspect_attribs++;
break;
case TGSI_INTERPOLATE_COLOR:
if (draw->rasterizer->flatshade) {
clipper->const_attribs[clipper->num_const_attribs] = i;
clipper->num_const_attribs++;
} else {
clipper->perspect_attribs[clipper->num_perspect_attribs] = i;
clipper->num_perspect_attribs++;
}
break;
default:
assert(interp == -1);
break;
@@ -170,8 +170,9 @@ find_interp(const struct draw_fragment_shader *fs, int *indexed_interp,
int interp;
/* If it's gl_{Front,Back}{,Secondary}Color, pick up the mode
* from the array we've filled before. */
if (semantic_name == TGSI_SEMANTIC_COLOR ||
semantic_name == TGSI_SEMANTIC_BCOLOR) {
if ((semantic_name == TGSI_SEMANTIC_COLOR ||
semantic_name == TGSI_SEMANTIC_BCOLOR) &&
semantic_index < 2) {
interp = indexed_interp[semantic_index];
} else {
/* Otherwise, search in the FS inputs, with a decent default
@@ -216,7 +217,8 @@ static void flatshade_init_state( struct draw_stage *stage )
if (fs) {
for (i = 0; i < fs->info.num_inputs; i++) {
if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
if (fs->info.input_semantic_name[i] == TGSI_SEMANTIC_COLOR &&
fs->info.input_semantic_index[i] < 2) {
if (fs->info.input_interpolate[i] != TGSI_INTERPOLATE_COLOR)
indexed_interp[fs->info.input_semantic_index[i]] = fs->info.input_interpolate[i];
}
@@ -236,7 +238,8 @@ static void flatshade_init_state( struct draw_stage *stage )
info->output_semantic_index[i]);
/* If it's flat, add it to the flat vector. */
if (interp == TGSI_INTERPOLATE_CONSTANT) {
if (interp == TGSI_INTERPOLATE_CONSTANT ||
(interp == TGSI_INTERPOLATE_COLOR && draw->rasterizer->flatshade)) {
flat->flat_attribs[flat->num_flat_attribs] = i;
flat->num_flat_attribs++;
}
@@ -111,18 +111,21 @@ static void twoside_first_tri( struct draw_stage *stage,
twoside->attrib_back0 = -1;
twoside->attrib_back1 = -1;
/* Find which vertex shader outputs are front/back colors */
/*
* Find which vertex shader outputs are front/back colors
* (only first two can be front or back).
*/
for (i = 0; i < vs->info.num_outputs; i++) {
if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_COLOR) {
if (vs->info.output_semantic_index[i] == 0)
twoside->attrib_front0 = i;
else
else if (vs->info.output_semantic_index[i] == 1)
twoside->attrib_front1 = i;
}
if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_BCOLOR) {
if (vs->info.output_semantic_index[i] == 0)
twoside->attrib_back0 = i;
else
else if (vs->info.output_semantic_index[i] == 1)
twoside->attrib_back1 = i;
}
}