mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-09 06:48:06 +02:00
radv: fix draw calls with 0-sized index buffers and robustness on NAVI10
The correct workaround is to bind an internal index buffer to handle robustness2 correctly. Fixes dEQP-VK.robustness.index_access.* in CTS 1.3.5.0 on NAVI10. Cc: mesa-stable Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21471>
This commit is contained in:
parent
b1c19498c6
commit
c356f1b4ed
1 changed files with 35 additions and 20 deletions
|
|
@ -7937,6 +7937,25 @@ radv_emit_userdata_task(struct radv_cmd_buffer *cmd_buffer, uint32_t x, uint32_t
|
|||
radv_emit_userdata_task_ib_only(cmd_buffer, ib_va, first_task ? 8 : 0);
|
||||
}
|
||||
|
||||
/* Bind an internal index buffer for GPUs that hang with 0-sized index buffers to handle robustness2
|
||||
* which requires 0 for out-of-bounds access.
|
||||
*/
|
||||
static void
|
||||
radv_handle_zero_index_buffer_bug(struct radv_cmd_buffer *cmd_buffer, uint64_t *index_va,
|
||||
uint32_t *remaining_indexes)
|
||||
{
|
||||
const uint32_t zero = 0;
|
||||
uint32_t offset;
|
||||
|
||||
if (!radv_cmd_buffer_upload_data(cmd_buffer, sizeof(uint32_t), &zero, &offset)) {
|
||||
vk_command_buffer_set_error(&cmd_buffer->vk, VK_ERROR_OUT_OF_HOST_MEMORY);
|
||||
return;
|
||||
}
|
||||
|
||||
*index_va = radv_buffer_get_va(cmd_buffer->upload.upload_bo) + offset;
|
||||
*remaining_indexes = 1;
|
||||
}
|
||||
|
||||
ALWAYS_INLINE static void
|
||||
radv_emit_draw_packets_indexed(struct radv_cmd_buffer *cmd_buffer,
|
||||
const struct radv_draw_info *info,
|
||||
|
|
@ -7957,18 +7976,17 @@ radv_emit_draw_packets_indexed(struct radv_cmd_buffer *cmd_buffer,
|
|||
if (vertexOffset) {
|
||||
radv_emit_userdata_vertex(cmd_buffer, info, *vertexOffset);
|
||||
vk_foreach_multi_draw_indexed(draw, i, minfo, drawCount, stride) {
|
||||
const uint32_t remaining_indexes = MAX2(state->max_index_count, draw->firstIndex) - draw->firstIndex;
|
||||
uint32_t remaining_indexes = MAX2(state->max_index_count, draw->firstIndex) - draw->firstIndex;
|
||||
uint64_t index_va = state->index_va + draw->firstIndex * index_size;
|
||||
|
||||
/* Skip draw calls with 0-sized index buffers if the GPU can't handle them */
|
||||
/* Handle draw calls with 0-sized index buffers if the GPU can't support them. */
|
||||
if (!remaining_indexes &&
|
||||
cmd_buffer->device->physical_device->rad_info.has_zero_index_buffer_bug)
|
||||
continue;
|
||||
radv_handle_zero_index_buffer_bug(cmd_buffer, &index_va, &remaining_indexes);
|
||||
|
||||
if (i > 0)
|
||||
radeon_set_sh_reg(cs, state->graphics_pipeline->vtx_base_sgpr + sizeof(uint32_t), i);
|
||||
|
||||
const uint64_t index_va = state->index_va + draw->firstIndex * index_size;
|
||||
|
||||
if (!state->render.view_mask) {
|
||||
radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va, remaining_indexes, draw->indexCount, false);
|
||||
} else {
|
||||
|
|
@ -7981,12 +7999,13 @@ radv_emit_draw_packets_indexed(struct radv_cmd_buffer *cmd_buffer,
|
|||
}
|
||||
} else {
|
||||
vk_foreach_multi_draw_indexed(draw, i, minfo, drawCount, stride) {
|
||||
const uint32_t remaining_indexes = MAX2(state->max_index_count, draw->firstIndex) - draw->firstIndex;
|
||||
uint32_t remaining_indexes = MAX2(state->max_index_count, draw->firstIndex) - draw->firstIndex;
|
||||
uint64_t index_va = state->index_va + draw->firstIndex * index_size;
|
||||
|
||||
/* Skip draw calls with 0-sized index buffers if the GPU can't handle them */
|
||||
/* Handle draw calls with 0-sized index buffers if the GPU can't support them. */
|
||||
if (!remaining_indexes &&
|
||||
cmd_buffer->device->physical_device->rad_info.has_zero_index_buffer_bug)
|
||||
continue;
|
||||
radv_handle_zero_index_buffer_bug(cmd_buffer, &index_va, &remaining_indexes);
|
||||
|
||||
if (i > 0) {
|
||||
if (state->last_vertex_offset != draw->vertexOffset)
|
||||
|
|
@ -7996,8 +8015,6 @@ radv_emit_draw_packets_indexed(struct radv_cmd_buffer *cmd_buffer,
|
|||
} else
|
||||
radv_emit_userdata_vertex(cmd_buffer, info, draw->vertexOffset);
|
||||
|
||||
const uint64_t index_va = state->index_va + draw->firstIndex * index_size;
|
||||
|
||||
if (!state->render.view_mask) {
|
||||
radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va, remaining_indexes, draw->indexCount, false);
|
||||
} else {
|
||||
|
|
@ -8028,14 +8045,13 @@ radv_emit_draw_packets_indexed(struct radv_cmd_buffer *cmd_buffer,
|
|||
|
||||
radv_emit_userdata_vertex(cmd_buffer, info, *vertexOffset);
|
||||
vk_foreach_multi_draw_indexed(draw, i, minfo, drawCount, stride) {
|
||||
const uint32_t remaining_indexes = MAX2(state->max_index_count, draw->firstIndex) - draw->firstIndex;
|
||||
uint32_t remaining_indexes = MAX2(state->max_index_count, draw->firstIndex) - draw->firstIndex;
|
||||
uint64_t index_va = state->index_va + draw->firstIndex * index_size;
|
||||
|
||||
/* Skip draw calls with 0-sized index buffers if the GPU can't handle them */
|
||||
/* Handle draw calls with 0-sized index buffers if the GPU can't support them. */
|
||||
if (!remaining_indexes &&
|
||||
cmd_buffer->device->physical_device->rad_info.has_zero_index_buffer_bug)
|
||||
continue;
|
||||
|
||||
const uint64_t index_va = state->index_va + draw->firstIndex * index_size;
|
||||
radv_handle_zero_index_buffer_bug(cmd_buffer, &index_va, &remaining_indexes);
|
||||
|
||||
if (!state->render.view_mask) {
|
||||
radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va, remaining_indexes, draw->indexCount, can_eop && i < drawCount - 1);
|
||||
|
|
@ -8049,19 +8065,18 @@ radv_emit_draw_packets_indexed(struct radv_cmd_buffer *cmd_buffer,
|
|||
}
|
||||
} else {
|
||||
vk_foreach_multi_draw_indexed(draw, i, minfo, drawCount, stride) {
|
||||
const uint32_t remaining_indexes = MAX2(state->max_index_count, draw->firstIndex) - draw->firstIndex;
|
||||
uint32_t remaining_indexes = MAX2(state->max_index_count, draw->firstIndex) - draw->firstIndex;
|
||||
uint64_t index_va = state->index_va + draw->firstIndex * index_size;
|
||||
|
||||
/* Skip draw calls with 0-sized index buffers if the GPU can't handle them */
|
||||
/* Handle draw calls with 0-sized index buffers if the GPU can't support them. */
|
||||
if (!remaining_indexes &&
|
||||
cmd_buffer->device->physical_device->rad_info.has_zero_index_buffer_bug)
|
||||
continue;
|
||||
radv_handle_zero_index_buffer_bug(cmd_buffer, &index_va, &remaining_indexes);
|
||||
|
||||
const VkMultiDrawIndexedInfoEXT *next = (const VkMultiDrawIndexedInfoEXT*)(i < drawCount - 1 ? ((uint8_t*)draw + stride) : NULL);
|
||||
const bool offset_changes = next && next->vertexOffset != draw->vertexOffset;
|
||||
radv_emit_userdata_vertex(cmd_buffer, info, draw->vertexOffset);
|
||||
|
||||
const uint64_t index_va = state->index_va + draw->firstIndex * index_size;
|
||||
|
||||
if (!state->render.view_mask) {
|
||||
radv_cs_emit_draw_indexed_packet(cmd_buffer, index_va, remaining_indexes, draw->indexCount, can_eop && !offset_changes && i < drawCount - 1);
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue