From 4b6d6642d2c64ce67d65ead480fb99104a7e2d3a Mon Sep 17 00:00:00 2001 From: Roland Scheidegger Date: Tue, 18 Nov 2014 22:46:00 +0100 Subject: [PATCH] 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 --- src/gallium/auxiliary/draw/draw_context.c | 4 ++-- src/gallium/auxiliary/draw/draw_llvm.c | 6 +++++- .../draw/draw_pt_fetch_shade_pipeline_llvm.c | 6 +++--- src/gallium/auxiliary/draw/draw_pt_post_vs.c | 2 +- src/gallium/auxiliary/draw/draw_vs.c | 4 +++- src/gallium/auxiliary/draw/draw_vs.h | 1 + src/gallium/auxiliary/tgsi/tgsi_scan.c | 15 ++++++--------- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/gallium/auxiliary/draw/draw_context.c b/src/gallium/auxiliary/draw/draw_context.c index bb8c03c36f9..f46f8b42038 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 1c265603663..a2e6112009a 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 49341ffd9fd..cc837366ae9 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 9279cd17613..71a7d3918e9 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 dc50870b267..f24354e9d51 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 79dbfb71549..1d54e7ef298 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]; diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c index 42bc61eeb4c..a23bb4067aa 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_scan.c +++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c @@ -232,6 +232,12 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->num_written_culldistance += util_bitcount(fulldecl->Declaration.UsageMask); } + else if (semName == TGSI_SEMANTIC_VIEWPORT_INDEX) { + info->writes_viewport_index = TRUE; + } + else if (semName == TGSI_SEMANTIC_LAYER) { + info->writes_layer = TRUE; + } } if (procType == TGSI_PROCESSOR_FRAGMENT) { @@ -248,15 +254,6 @@ tgsi_scan_shader(const struct tgsi_token *tokens, info->writes_edgeflag = TRUE; } } - - if (procType == TGSI_PROCESSOR_GEOMETRY) { - if (semName == TGSI_SEMANTIC_VIEWPORT_INDEX) { - info->writes_viewport_index = TRUE; - } - else if (semName == TGSI_SEMANTIC_LAYER) { - info->writes_layer = TRUE; - } - } } } } -- 2.30.2