From: Iago Toral Quiroga Date: Mon, 9 Mar 2015 14:17:03 +0000 (+0100) Subject: i965: Do not render primitives in non-zero streams then TF is disabled X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=2042a2f961a07e04eaca0347e42859c249325531;p=mesa.git i965: Do not render primitives in non-zero streams then TF is disabled Haswell hardware seems to ignore Render Stream Select bits from 3DSTATE_STREAMOUT packet when the SOL stage is disabled even if the PRM says otherwise. Because of this, all primitives are sent down the pipeline for rasterization, which is wrong. If SOL is enabled, Render Stream Select is honored and primitives bound to non-zero streams are discarded after stream output. Since the only purpose of primives sent to non-zero streams is to be recorded by transform feedback, we can simply discard all geometry bound to non-zero streams then transform feedback is disabled to prevent it from ever reaching the rasterization stage. Notice that this patch introduces a small change in the behavior we get when a geometry shader emits more vertices than the maximum declared: before, a vertex that was emitted to a non-zero stream when TF was disabled would still count for the purposes of checking that we don't exceed the maximum number of output vertices declared by the shader. With this change, these vertices are completely ignored and won't increase the output vertex count, making more room for other (hopefully more useful) vertices. Fixes piglit test arb_gpu_shader5-emitstreamvertex_nodraw on Haswell and Broadwell. v2 (Ken): Drop is_haswell check in favor of doing this unconditionally. Broadwell needs the workaround as well, and it doesn't hurt to do it in general. Also tweak comments - the Haswell PRM does actually mention this ("Command Reference: Instructions" page 797). Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83962 Reviewed-by: Kenneth Graunke Cc: mesa-stable@lists.freedesktop.org --- diff --git a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp index 2002ffd6428..18a44be7370 100644 --- a/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp +++ b/src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp @@ -476,6 +476,19 @@ vec4_gs_visitor::visit(ir_emit_vertex *ir) { this->current_annotation = "emit vertex: safety check"; + /* Haswell and later hardware ignores the "Render Stream Select" bits + * from the 3DSTATE_STREAMOUT packet when the SOL stage is disabled, + * and instead sends all primitives down the pipeline for rasterization. + * If the SOL stage is enabled, "Render Stream Select" is honored and + * primitives bound to non-zero streams are discarded after stream output. + * + * Since the only purpose of primives sent to non-zero streams is to + * be recorded by transform feedback, we can simply discard all geometry + * bound to these streams when transform feedback is disabled. + */ + if (ir->stream_id() > 0 && shader_prog->TransformFeedback.NumVarying == 0) + return; + /* To ensure that we don't output more vertices than the shader specified * using max_vertices, do the logic inside a conditional of the form "if * (vertex_count < MAX)"