i965: Use 32 bit u_bit_scan for vertex attribute setup.
authorMathias Fröhlich <mathias.froehlich@web.de>
Sat, 20 Apr 2019 05:57:12 +0000 (07:57 +0200)
committerMarge Bot <eric+marge@anholt.net>
Tue, 10 Mar 2020 14:28:37 +0000 (14:28 +0000)
The vertex array object contains 32 vertex arrays. By that we cannot
reference more then these in the vertex shader inputs. So, we can use
the 32 bits u_bit_scan function to iterate the vertex shader inputs
and place an assert that only these are present. Also place an other
assert that the vertex array setup in i965 does not overrun the
enabled array in brw_context::vs::enabled.

v2: Style fixes.

Reviewed-by: Matt Turner <mattst88@gmail.com>
Signed-off-by: Mathias Fröhlich <Mathias.Froehlich@web.de>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/308>

src/mesa/drivers/dri/i965/brw_draw_upload.c

index 5e2643371f0283a7b357571a26cd64d22ba27129..3f4d9a9948ed139e605b1074f2ff8c1f3bd613c9 100644 (file)
@@ -461,9 +461,11 @@ brw_prepare_vertices(struct brw_context *brw)
    /* BRW_NEW_VS_PROG_DATA */
    const struct brw_vs_prog_data *vs_prog_data =
       brw_vs_prog_data(brw->vs.base.prog_data);
-   GLbitfield64 vs_inputs =
+   const uint64_t vs_inputs64 =
       nir_get_single_slot_attribs_mask(vs_prog_data->inputs_read,
                                        vp->DualSlotInputs);
+   assert((vs_inputs64 & ~(uint64_t)VERT_BIT_ALL) == 0);
+   unsigned vs_inputs = (unsigned)vs_inputs64;
    const unsigned char *ptr = NULL;
    GLuint interleaved = 0;
    unsigned int min_index = brw->vb.min_index + brw->basevertex;
@@ -491,15 +493,15 @@ brw_prepare_vertices(struct brw_context *brw)
 
    /* Accumulate the list of enabled arrays. */
    brw->vb.nr_enabled = 0;
-   while (vs_inputs) {
-      const unsigned index = ffsll(vs_inputs) - 1;
-      assert(index < 64);
 
-      struct brw_vertex_element *input = &brw->vb.inputs[index];
-      input->is_dual_slot = (vp->DualSlotInputs & BITFIELD64_BIT(index)) != 0;
-      vs_inputs &= ~BITFIELD64_BIT(index);
+   unsigned mask = vs_inputs;
+   while (mask) {
+      const gl_vert_attrib attr = u_bit_scan(&mask);
+      struct brw_vertex_element *input = &brw->vb.inputs[attr];
+      input->is_dual_slot = (vp->DualSlotInputs & BITFIELD64_BIT(attr)) != 0;
       brw->vb.enabled[brw->vb.nr_enabled++] = input;
    }
+   assert(brw->vb.nr_enabled <= VERT_ATTRIB_MAX);
 
    if (brw->vb.nr_enabled == 0)
       return;