mesa: fix gl_DrawID with indirect multi draws using user indirect buffer

The code lowered the draws to direct ones but disregarded gl_DrawID.
We need to pass the draw ID to the driver manually.

gl_DrawID is the 3rd parameter of DrawGallium here.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/5274
Cc: mesa-stable@lists.freedesktop.org

Acked-by: Pierre-Eric Pelloux-Prayer <pierre-eric.pelloux-prayer@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/12533>
This commit is contained in:
Marek Olšák
2021-08-24 13:03:30 -04:00
committed by Marge Bot
parent 1f80cd35cb
commit 614f273ab4
+74 -34
View File
@@ -2499,6 +2499,14 @@ _mesa_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
if (stride == 0)
stride = sizeof(DrawArraysIndirectCommand);
FLUSH_FOR_DRAW(ctx);
_mesa_set_draw_vao(ctx, ctx->Array.VAO,
ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
_mesa_update_state(ctx);
/* From the ARB_draw_indirect spec:
*
* "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the
@@ -2509,35 +2517,43 @@ _mesa_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect,
if (ctx->API == API_OPENGL_COMPAT &&
!ctx->DrawIndirectBuffer) {
if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
"glMultiDrawArraysIndirect"))
if (!_mesa_is_no_error_enabled(ctx) &&
(!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
"glMultiDrawArraysIndirect") ||
!_mesa_validate_DrawArrays(ctx, mode, 1)))
return;
struct pipe_draw_info info;
info.mode = mode;
info.index_size = 0;
info.view_mask = 0;
/* Packed section begin. */
info.primitive_restart = false;
info.has_user_indices = false;
info.index_bounds_valid = false;
info.increment_draw_id = primcount > 1;
info.take_index_buffer_ownership = false;
info.index_bias_varies = false;
/* Packed section end. */
const uint8_t *ptr = (const uint8_t *) indirect;
for (unsigned i = 0; i < primcount; i++) {
DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr;
_mesa_DrawArraysInstancedBaseInstance(mode, cmd->first,
cmd->count, cmd->primCount,
cmd->baseInstance);
if (stride == 0) {
ptr += sizeof(DrawArraysIndirectCommand);
} else {
ptr += stride;
}
info.start_instance = cmd->baseInstance;
info.instance_count = cmd->primCount;
struct pipe_draw_start_count_bias draw;
draw.start = cmd->first;
draw.count = cmd->count;
ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1);
ptr += stride;
}
return;
}
FLUSH_FOR_DRAW(ctx);
_mesa_set_draw_vao(ctx, ctx->Array.VAO,
ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
_mesa_update_state(ctx);
if (!_mesa_is_no_error_enabled(ctx) &&
!_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect,
primcount, stride))
@@ -2555,6 +2571,14 @@ _mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type,
{
GET_CURRENT_CONTEXT(ctx);
FLUSH_FOR_DRAW(ctx);
_mesa_set_draw_vao(ctx, ctx->Array.VAO,
ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
_mesa_update_state(ctx);
/* If <stride> is zero, the array elements are treated as tightly packed. */
if (stride == 0)
stride = sizeof(DrawElementsIndirectCommand);
@@ -2582,32 +2606,48 @@ _mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type,
return;
}
if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
"glMultiDrawArraysIndirect"))
if (!_mesa_is_no_error_enabled(ctx) &&
(!_mesa_valid_draw_indirect_multi(ctx, primcount, stride,
"glMultiDrawArraysIndirect") ||
!_mesa_validate_DrawElements(ctx, mode, 1, type)))
return;
unsigned index_size_shift = get_index_size_shift(type);
struct pipe_draw_info info;
info.mode = mode;
info.index_size = 1 << index_size_shift;
info.view_mask = 0;
/* Packed section begin. */
info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift];
info.has_user_indices = false;
info.index_bounds_valid = false;
info.increment_draw_id = primcount > 1;
info.take_index_buffer_ownership = false;
info.index_bias_varies = false;
/* Packed section end. */
info.restart_index = ctx->Array._RestartIndex[index_size_shift];
const uint8_t *ptr = (const uint8_t *) indirect;
for (unsigned i = 0; i < primcount; i++) {
_mesa_DrawElementsIndirect(mode, type, ptr);
DrawElementsIndirectCommand *cmd = (DrawElementsIndirectCommand*)ptr;
if (stride == 0) {
ptr += sizeof(DrawElementsIndirectCommand);
} else {
ptr += stride;
}
info.index.gl_bo = ctx->Array.VAO->IndexBufferObj;
info.start_instance = cmd->baseInstance;
info.instance_count = cmd->primCount;
struct pipe_draw_start_count_bias draw;
draw.start = cmd->firstIndex;
draw.count = cmd->count;
draw.index_bias = cmd->baseVertex;
ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1);
ptr += stride;
}
return;
}
FLUSH_FOR_DRAW(ctx);
_mesa_set_draw_vao(ctx, ctx->Array.VAO,
ctx->VertexProgram._VPModeInputFilter);
if (ctx->NewState)
_mesa_update_state(ctx);
if (!_mesa_is_no_error_enabled(ctx) &&
!_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect,
primcount, stride))