mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
v3dv: implement VK_EXT_multi_draw
Implement the Vulkan extension VK_EXT_multi_draw. It was tested with deqp-vk -n dEQP-VK.draw.*multi_draw*. Signed-off-by: Maíra Canal <mcanal@igalia.com> Reviewed-by: Iago Toral Quiroga <itoral@igalia.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26138>
This commit is contained in:
parent
794b0496e9
commit
4d95b4861e
7 changed files with 104 additions and 2 deletions
|
|
@ -582,7 +582,7 @@ Khronos extensions that are not part of any Vulkan version:
|
|||
VK_EXT_memory_budget DONE (anv, hasvk, lvp, radv, tu, v3dv, vn)
|
||||
VK_EXT_memory_priority DONE (lvp, radv)
|
||||
VK_EXT_mesh_shader DONE (anv/gfx12.5+, lvp, radv)
|
||||
VK_EXT_multi_draw DONE (anv, hasvk, lvp, radv, tu, vn)
|
||||
VK_EXT_multi_draw DONE (anv, hasvk, lvp, radv, tu, vn, v3dv)
|
||||
VK_EXT_multisampled_render_to_single_sampled DONE (lvp)
|
||||
VK_EXT_nested_command_buffer DONE (lvp)
|
||||
VK_EXT_non_seamless_cube_map DONE (anv, hasvk, lvp, nvk, radv, tu, vn)
|
||||
|
|
|
|||
|
|
@ -3359,6 +3359,10 @@ ntq_emit_intrinsic(struct v3d_compile *c, nir_intrinsic_instr *instr)
|
|||
ntq_store_def(c, &instr->def, 0, vir_MOV(c, c->vid));
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_draw_id:
|
||||
ntq_store_def(c, &instr->def, 0, vir_uniform(c, QUNIFORM_DRAW_ID, 0));
|
||||
break;
|
||||
|
||||
case nir_intrinsic_load_tlb_color_v3d:
|
||||
vir_emit_tlb_color_read(c, instr);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -345,6 +345,11 @@ enum quniform_contents {
|
|||
QUNIFORM_INLINE_UBO_1,
|
||||
QUNIFORM_INLINE_UBO_2,
|
||||
QUNIFORM_INLINE_UBO_3,
|
||||
|
||||
/**
|
||||
* Current value of DrawIndex for Multidraw
|
||||
*/
|
||||
QUNIFORM_DRAW_ID,
|
||||
};
|
||||
|
||||
static inline uint32_t v3d_unit_data_create(uint32_t unit, uint32_t value)
|
||||
|
|
|
|||
|
|
@ -2336,6 +2336,7 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
const bool has_new_push_constants = dirty_uniform_state & V3DV_CMD_DIRTY_PUSH_CONSTANTS;
|
||||
const bool has_new_descriptors = dirty_uniform_state & V3DV_CMD_DIRTY_DESCRIPTOR_SETS;
|
||||
const bool has_new_view_index = dirty_uniform_state & V3DV_CMD_DIRTY_VIEW_INDEX;
|
||||
const bool has_new_draw_id = dirty_uniform_state & V3DV_CMD_DIRTY_DRAW_ID;
|
||||
|
||||
/* VK_SHADER_STAGE_FRAGMENT_BIT */
|
||||
const bool has_new_descriptors_fs =
|
||||
|
|
@ -2403,6 +2404,7 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
|
||||
const bool needs_vs_update = has_new_viewport ||
|
||||
has_new_view_index ||
|
||||
has_new_draw_id ||
|
||||
has_new_pipeline ||
|
||||
has_new_push_constants_vs ||
|
||||
has_new_descriptors_vs;
|
||||
|
|
@ -2422,6 +2424,7 @@ update_gfx_uniform_state(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
}
|
||||
|
||||
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_VIEW_INDEX;
|
||||
cmd_buffer->state.dirty &= ~V3DV_CMD_DIRTY_DRAW_ID;
|
||||
}
|
||||
|
||||
/* This stores command buffer state that we might be about to stomp for
|
||||
|
|
@ -2913,7 +2916,8 @@ v3dv_cmd_buffer_emit_pre_draw(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
V3DV_CMD_DIRTY_PUSH_CONSTANTS |
|
||||
V3DV_CMD_DIRTY_DESCRIPTOR_SETS |
|
||||
V3DV_CMD_DIRTY_VIEWPORT |
|
||||
V3DV_CMD_DIRTY_VIEW_INDEX);
|
||||
V3DV_CMD_DIRTY_VIEW_INDEX |
|
||||
V3DV_CMD_DIRTY_DRAW_ID);
|
||||
|
||||
if (dirty_uniform_state)
|
||||
update_gfx_uniform_state(cmd_buffer, dirty_uniform_state);
|
||||
|
|
@ -3030,6 +3034,35 @@ v3dv_CmdDraw(VkCommandBuffer commandBuffer,
|
|||
cmd_buffer_draw(cmd_buffer, &info);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
v3dv_CmdDrawMultiEXT(VkCommandBuffer commandBuffer,
|
||||
uint32_t drawCount,
|
||||
const VkMultiDrawInfoEXT *pVertexInfo,
|
||||
uint32_t instanceCount,
|
||||
uint32_t firstInstance,
|
||||
uint32_t stride)
|
||||
|
||||
{
|
||||
if (drawCount == 0 || instanceCount == 0)
|
||||
return;
|
||||
|
||||
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
|
||||
uint32_t i = 0;
|
||||
vk_foreach_multi_draw(draw, i, pVertexInfo, drawCount, stride) {
|
||||
cmd_buffer->state.draw_id = i;
|
||||
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DRAW_ID;
|
||||
|
||||
struct v3dv_draw_info info = {};
|
||||
info.vertex_count = draw->vertexCount;
|
||||
info.instance_count = instanceCount;
|
||||
info.first_instance = firstInstance;
|
||||
info.first_vertex = draw->firstVertex;
|
||||
|
||||
cmd_buffer_draw(cmd_buffer, &info);
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
v3dv_CmdDrawIndexed(VkCommandBuffer commandBuffer,
|
||||
uint32_t indexCount,
|
||||
|
|
@ -3064,6 +3097,48 @@ v3dv_CmdDrawIndexed(VkCommandBuffer commandBuffer,
|
|||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
v3dv_CmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer,
|
||||
uint32_t drawCount,
|
||||
const VkMultiDrawIndexedInfoEXT *pIndexInfo,
|
||||
uint32_t instanceCount,
|
||||
uint32_t firstInstance,
|
||||
uint32_t stride,
|
||||
const int32_t *pVertexOffset)
|
||||
{
|
||||
if (drawCount == 0 || instanceCount == 0)
|
||||
return;
|
||||
|
||||
V3DV_FROM_HANDLE(v3dv_cmd_buffer, cmd_buffer, commandBuffer);
|
||||
|
||||
uint32_t i = 0;
|
||||
vk_foreach_multi_draw_indexed(draw, i, pIndexInfo, drawCount, stride) {
|
||||
uint32_t vertex_count = draw->indexCount * instanceCount;
|
||||
int32_t vertexOffset = pVertexOffset ? *pVertexOffset : draw->vertexOffset;
|
||||
|
||||
cmd_buffer->state.draw_id = i;
|
||||
cmd_buffer->state.dirty |= V3DV_CMD_DIRTY_DRAW_ID;
|
||||
|
||||
struct v3dv_render_pass *pass = cmd_buffer->state.pass;
|
||||
if (likely(!pass->multiview_enabled)) {
|
||||
v3dv_cmd_buffer_emit_pre_draw(cmd_buffer, true, false, vertex_count);
|
||||
v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw_indexed)
|
||||
(cmd_buffer, draw->indexCount, instanceCount,
|
||||
draw->firstIndex, vertexOffset, firstInstance);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint32_t view_mask = pass->subpasses[cmd_buffer->state.subpass_idx].view_mask;
|
||||
while (view_mask) {
|
||||
cmd_buffer_set_view_index(cmd_buffer, u_bit_scan(&view_mask));
|
||||
v3dv_cmd_buffer_emit_pre_draw(cmd_buffer, true, false, vertex_count);
|
||||
v3dv_X(cmd_buffer->device, cmd_buffer_emit_draw_indexed)
|
||||
(cmd_buffer, draw->indexCount, instanceCount,
|
||||
draw->firstIndex, vertexOffset, firstInstance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
v3dv_CmdDrawIndirect(VkCommandBuffer commandBuffer,
|
||||
VkBuffer _buffer,
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ get_device_extensions(const struct v3dv_physical_device *device,
|
|||
.EXT_index_type_uint8 = true,
|
||||
.EXT_line_rasterization = true,
|
||||
.EXT_memory_budget = true,
|
||||
.EXT_multi_draw = true,
|
||||
.EXT_physical_device_drm = true,
|
||||
.EXT_pipeline_creation_cache_control = true,
|
||||
.EXT_pipeline_creation_feedback = true,
|
||||
|
|
@ -436,6 +437,9 @@ get_features(const struct v3dv_physical_device *physical_device,
|
|||
|
||||
/* VK_EXT_pipeline_robustness */
|
||||
.pipelineRobustness = true,
|
||||
|
||||
/* VK_EXT_multi_draw */
|
||||
.multiDraw = true,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -1736,6 +1740,12 @@ v3dv_GetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice,
|
|||
VK_PIPELINE_ROBUSTNESS_IMAGE_BEHAVIOR_DEVICE_DEFAULT_EXT;
|
||||
break;
|
||||
}
|
||||
case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MULTI_DRAW_PROPERTIES_EXT: {
|
||||
VkPhysicalDeviceMultiDrawPropertiesEXT *properties =
|
||||
(VkPhysicalDeviceMultiDrawPropertiesEXT *)ext;
|
||||
properties->maxMultiDrawCount = 2048;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
v3dv_debug_ignored_stype(ext->sType);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1091,6 +1091,7 @@ enum v3dv_cmd_dirty_bits {
|
|||
V3DV_CMD_DIRTY_VIEW_INDEX = 1 << 17,
|
||||
V3DV_CMD_DIRTY_COLOR_WRITE_ENABLE = 1 << 18,
|
||||
V3DV_CMD_DIRTY_DEPTH_BOUNDS = 1 << 19,
|
||||
V3DV_CMD_DIRTY_DRAW_ID = 1 << 20,
|
||||
};
|
||||
|
||||
struct v3dv_dynamic_state {
|
||||
|
|
@ -1530,6 +1531,9 @@ struct v3dv_cmd_buffer_state {
|
|||
/* Current view index for multiview rendering */
|
||||
uint32_t view_index;
|
||||
|
||||
/* Current draw ID for multidraw */
|
||||
uint32_t draw_id;
|
||||
|
||||
/* Used to flag OOM conditions during command buffer recording */
|
||||
bool oom;
|
||||
|
||||
|
|
|
|||
|
|
@ -657,6 +657,10 @@ v3dv_write_uniforms_wg_offsets(struct v3dv_cmd_buffer *cmd_buffer,
|
|||
cl_aligned_u32(&uniforms, pipeline->spill.size_per_thread);
|
||||
break;
|
||||
|
||||
case QUNIFORM_DRAW_ID:
|
||||
cl_aligned_u32(&uniforms, job->cmd_buffer->state.draw_id);
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("unsupported quniform_contents uniform type\n");
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue