diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c index 0df22931410..6fd25b45b98 100644 --- a/src/gallium/drivers/vc4/vc4_draw.c +++ b/src/gallium/drivers/vc4/vc4_draw.c @@ -331,6 +331,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) vc4_emit_state(pctx); + bool needs_drawarrays_shader_state = false; if ((vc4->dirty & (VC4_DIRTY_VTXBUF | VC4_DIRTY_VTXSTATE | VC4_DIRTY_PRIM_MODE | @@ -342,7 +343,10 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) vc4->prog.vs->uniform_dirty_bits | vc4->prog.fs->uniform_dirty_bits)) || vc4->last_index_bias != info->index_bias) { - vc4_emit_gl_shader_state(vc4, info, 0); + if (info->index_size) + vc4_emit_gl_shader_state(vc4, info, 0); + else + needs_drawarrays_shader_state = true; } vc4->dirty = 0; @@ -392,29 +396,35 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) uint32_t count = info->count; uint32_t start = info->start; uint32_t extra_index_bias = 0; + static const uint32_t max_verts = 65535; + + /* GFXH-515 / SW-5891: The binner emits 16 bit indices for + * drawarrays, which means that if start + count > 64k it + * would truncate the top bits. Work around this by emitting + * a limited number of primitives at a time and reemitting the + * shader state pointing farther down the vertex attribute + * arrays. + * + * To do this properly for line loops or trifans, we'd need to + * make a new VB containing the first vertex plus whatever + * remainder. + */ + if (start + count > max_verts) { + extra_index_bias = start; + start = 0; + needs_drawarrays_shader_state = true; + } while (count) { uint32_t this_count = count; uint32_t step = count; - static const uint32_t max_verts = 65535; - /* GFXH-515 / SW-5891: The binner emits 16 bit indices - * for drawarrays, which means that if start + count > - * 64k it would truncate the top bits. Work around - * this by emitting a limited number of primitives at - * a time and reemitting the shader state pointing - * farther down the vertex attribute arrays. - * - * To do this properly for line loops or trifans, we'd - * need to make a new VB containing the first vertex - * plus whatever remainder. - */ - if (extra_index_bias) { + if (needs_drawarrays_shader_state) { vc4_emit_gl_shader_state(vc4, info, extra_index_bias); } - if (start + count > max_verts) { + if (count > max_verts) { switch (info->mode) { case PIPE_PRIM_POINTS: this_count = step = max_verts; @@ -457,6 +467,7 @@ vc4_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info) count -= step; extra_index_bias += start + step; start = 0; + needs_drawarrays_shader_state = true; } }