broadcom/vc5: Fix GPU hang with no vertex elements used by the VS.
authorEric Anholt <eric@anholt.net>
Mon, 23 Oct 2017 17:30:37 +0000 (10:30 -0700)
committerEric Anholt <eric@anholt.net>
Mon, 30 Oct 2017 20:25:45 +0000 (13:25 -0700)
Like VC4, we need to at least have one element set up, but unlike VC4 it
seems we don't need to read it to keep the HW happy.  Fixes GPU hangs with
glsl-no-vertex-attribs.shader_test.

src/gallium/drivers/vc5/vc5_draw.c

index 11d9e92a96be1e45704fc1b6d721073ef7e6b2e0..02333ede5c5ba11b17245d6edf184dd25dc8b362 100644 (file)
@@ -147,10 +147,12 @@ vc5_emit_gl_shader_state(struct vc5_context *vc5,
                                    &vc5->constbuf[PIPE_SHADER_VERTEX],
                                    &vc5->verttex);
 
+        /* See GFXH-930 workaround below */
+        uint32_t num_elements_to_emit = MAX2(vtx->num_elements, 1);
         uint32_t shader_rec_offset =
                 vc5_cl_ensure_space(&job->indirect,
                                     cl_packet_length(GL_SHADER_STATE_RECORD) +
-                                    vtx->num_elements *
+                                    num_elements_to_emit *
                                     cl_packet_length(GL_SHADER_STATE_ATTRIBUTE_RECORD),
                                     32);
 
@@ -187,9 +189,9 @@ vc5_emit_gl_shader_state(struct vc5_context *vc5,
                 shader.coordinate_shader_has_separate_input_and_output_vpm_blocks = true;
                 shader.vertex_shader_has_separate_input_and_output_vpm_blocks = true;
                 shader.coordinate_shader_input_vpm_segment_size =
-                        vc5->prog.cs->prog_data.vs->vpm_input_size;
+                        MAX2(vc5->prog.cs->prog_data.vs->vpm_input_size, 1);
                 shader.vertex_shader_input_vpm_segment_size =
-                        vc5->prog.vs->prog_data.vs->vpm_input_size;
+                        MAX2(vc5->prog.vs->prog_data.vs->vpm_input_size, 1);
 
                 shader.coordinate_shader_output_vpm_segment_size =
                         vc5->prog.cs->prog_data.vs->vpm_output_size;
@@ -240,9 +242,27 @@ vc5_emit_gl_shader_state(struct vc5_context *vc5,
                 cl_emit_prepacked(&job->indirect, &attr_packed);
         }
 
+        if (vtx->num_elements == 0) {
+                /* GFXH-930: At least one attribute must be enabled and read
+                 * by CS and VS.  If we have no attributes being consumed by
+                 * the shader, set up a dummy to be loaded into the VPM.
+                 */
+                cl_emit(&job->indirect, GL_SHADER_STATE_ATTRIBUTE_RECORD, attr) {
+                        /* Valid address of data whose value will be unused. */
+                        attr.address = cl_address(job->indirect.bo, 0);
+
+                        attr.type = ATTRIBUTE_FLOAT;
+                        attr.stride = 0;
+                        attr.vec_size = 1;
+
+                        attr.number_of_values_read_by_coordinate_shader = 1;
+                        attr.number_of_values_read_by_vertex_shader = 1;
+                }
+        }
+
         cl_emit(&job->bcl, GL_SHADER_STATE, state) {
                 state.address = cl_address(job->indirect.bo, shader_rec_offset);
-                state.number_of_attribute_arrays = vtx->num_elements;
+                state.number_of_attribute_arrays = num_elements_to_emit;
         }
 
         vc5_bo_unreference(&cs_uniforms.bo);