summaryrefslogtreecommitdiffstats
path: root/src/gallium/auxiliary/draw
diff options
context:
space:
mode:
authorRoland Scheidegger <sroland@vmware.com>2014-11-18 22:46:00 +0100
committerRoland Scheidegger <sroland@vmware.com>2014-11-19 18:35:30 +0100
commit4b6d6642d2c64ce67d65ead480fb99104a7e2d3a (patch)
treeacea1eac94a65c073a4545c0a15960d524a14b21 /src/gallium/auxiliary/draw
parent9460cd39e8c74a6a8aba7e5c57bb4929ab135c29 (diff)
downloadexternal_mesa3d-4b6d6642d2c64ce67d65ead480fb99104a7e2d3a.zip
external_mesa3d-4b6d6642d2c64ce67d65ead480fb99104a7e2d3a.tar.gz
external_mesa3d-4b6d6642d2c64ce67d65ead480fb99104a7e2d3a.tar.bz2
draw: fixes for vertex shaders outputting layer or viewport index
Mostly add a couple cases so we don't just check gs for this. There's only one gotcha, the built-in vp transform in the llvm vs can't handle it (this would be fixable though non-trivial due to vp index being non-constant for the SoA outputs, but we don't use it if there's a gs neither - the whole clip/vp transform integration there is suboptimal). Reviewed-by: Jose Fonseca <jfonseca@vmware.com>
Diffstat (limited to 'src/gallium/auxiliary/draw')
-rw-r--r--src/gallium/auxiliary/draw/draw_context.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c6
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_post_vs.c2
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.c4
-rw-r--r--src/gallium/auxiliary/draw/draw_vs.h1
6 files changed, 15 insertions, 8 deletions
diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c
index bb8c03c..f46f8b4 100644
--- a/src/gallium/auxiliary/draw/draw_context.c
+++ b/src/gallium/auxiliary/draw/draw_context.c
@@ -806,7 +806,7 @@ draw_current_shader_viewport_index_output(const struct draw_context *draw)
{
if (draw->gs.geometry_shader)
return draw->gs.geometry_shader->viewport_index_output;
- return 0;
+ return draw->vs.vertex_shader->viewport_index_output;
}
/**
@@ -818,7 +818,7 @@ draw_current_shader_uses_viewport_index(const struct draw_context *draw)
{
if (draw->gs.geometry_shader)
return draw->gs.geometry_shader->info.writes_viewport_index;
- return FALSE;
+ return draw->vs.vertex_shader->info.writes_viewport_index;
}
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 1c26560..a2e6112 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -1522,8 +1522,12 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant,
/* If geometry shader is present we need to skip both the viewport
* transformation and clipping otherwise the inputs to the geometry
* shader will be incorrect.
+ * The code can't handle vp transform when vs writes vp index neither
+ * (though this would be fixable here, but couldn't just broadcast
+ * the values).
*/
- const boolean bypass_viewport = key->has_gs || key->bypass_viewport;
+ const boolean bypass_viewport = key->has_gs || key->bypass_viewport ||
+ llvm->draw->vs.vertex_shader->info.writes_viewport_index;
const boolean enable_cliptest = !key->has_gs && (key->clip_xy ||
key->clip_z ||
key->clip_user);
diff --git a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
index 49341ff..cc83736 100644
--- a/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_pt_fetch_shade_pipeline_llvm.c
@@ -169,8 +169,7 @@ llvm_middle_end_prepare( struct draw_pt_middle_end *middle,
draw_pt_so_emit_prepare( fpme->so_emit, gs == NULL );
if (!(opt & PT_PIPELINE)) {
- draw_pt_emit_prepare( fpme->emit,
- out_prim,
+ draw_pt_emit_prepare( fpme->emit, out_prim,
max_vertices );
*max_vertices = MAX2( *max_vertices, 4096 );
@@ -442,7 +441,8 @@ llvm_pipeline_generic(struct draw_pt_middle_end *middle,
* will try to access non-existent position output.
*/
if (draw_current_shader_position_output(draw) != -1) {
- if ((opt & PT_SHADE) && gshader) {
+ if ((opt & PT_SHADE) && (gshader ||
+ draw->vs.vertex_shader->info.writes_viewport_index)) {
clipped = draw_pt_post_vs_run( fpme->post_vs, vert_info, prim_info );
}
if (clipped) {
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 9279cd1..71a7d39 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -117,7 +117,7 @@ dot4(const float *a, const float *b)
boolean draw_pt_post_vs_run( struct pt_post_vs *pvs,
- struct draw_vertex_info *info,
+ struct draw_vertex_info *info,
const struct draw_prim_info *prim_info )
{
return pvs->run( pvs, info, prim_info );
diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c
index dc50870..f24354e 100644
--- a/src/gallium/auxiliary/draw/draw_vs.c
+++ b/src/gallium/auxiliary/draw/draw_vs.c
@@ -85,7 +85,9 @@ draw_create_vertex_shader(struct draw_context *draw,
vs->info.output_semantic_index[i] == 0) {
found_clipvertex = TRUE;
vs->clipvertex_output = i;
- } else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
+ } else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_VIEWPORT_INDEX)
+ vs->viewport_index_output = i;
+ else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_CLIPDIST) {
debug_assert(vs->info.output_semantic_index[i] <
PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT);
vs->clipdistance_output[vs->info.output_semantic_index[i]] = i;
diff --git a/src/gallium/auxiliary/draw/draw_vs.h b/src/gallium/auxiliary/draw/draw_vs.h
index 79dbfb7..1d54e7e 100644
--- a/src/gallium/auxiliary/draw/draw_vs.h
+++ b/src/gallium/auxiliary/draw/draw_vs.h
@@ -110,6 +110,7 @@ struct draw_vertex_shader {
struct tgsi_shader_info info;
unsigned position_output;
+ unsigned viewport_index_output;
unsigned edgeflag_output;
unsigned clipvertex_output;
unsigned clipdistance_output[PIPE_MAX_CLIP_OR_CULL_DISTANCE_ELEMENT_COUNT];