summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorRoland Scheidegger <[email protected]>2017-07-08 00:14:35 +0200
committerRoland Scheidegger <[email protected]>2017-07-08 06:02:18 +0200
commit4db72852a16fc4a2a559255f9965e1d02e4f2b9c (patch)
treec1870ee4f833acadd2288f2befe9f641e2ea87e9 /src/gallium
parentf728435e1f872af3efcd6b9215e8d722d35090cc (diff)
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 <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_clip.c17
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_flatshade.c11
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_twoside.c9
3 files changed, 27 insertions, 10 deletions
diff --git a/src/gallium/auxiliary/draw/draw_pipe_clip.c b/src/gallium/auxiliary/draw/draw_pipe_clip.c
index cf2b41738bf..4cfa54b2e17 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_clip.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_clip.c
@@ -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;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
index cd285e6f97c..2830435b993 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_flatshade.c
@@ -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++;
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_twoside.c b/src/gallium/auxiliary/draw/draw_pipe_twoside.c
index 52d87c6b291..7e76835f12e 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_twoside.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_twoside.c
@@ -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;
}
}