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 in Haswell. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=83962 --- src/mesa/drivers/dri/i965/brw_vec4_gs_visitor.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) 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 2002ffd..01d8073 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,22 @@ vec4_gs_visitor::visit(ir_emit_vertex *ir) { this->current_annotation = "emit vertex: safety check"; + /* 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 these streams when transform feedback is disabled. + */ + if (brw->is_haswell && + ir->stream_id() > 0 && + this->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)" -- 1.9.1 _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev