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>
{
if (draw->gs.geometry_shader)
return draw->gs.geometry_shader->viewport_index_output;
- return 0;
+ return draw->vs.vertex_shader->viewport_index_output;
}
/**
{
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;
}
/* 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);
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 );
* 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) {
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 );
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;
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];
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) {
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;
- }
- }
}
}
}