mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-19 02:48:07 +02:00
kk: Enable VK_EXT_multi_draw
Issues a draw for each entry, reusing as much setup as possible. Reviewed-by: Aitor Camacho <aitor@lunarg.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41399>
This commit is contained in:
parent
e95626b62a
commit
20d1fdf7eb
3 changed files with 101 additions and 1 deletions
|
|
@ -662,7 +662,7 @@ Khronos extensions that are not part of any Vulkan version:
|
|||
VK_EXT_memory_budget DONE (anv, hasvk, lvp, nvk, panvk, radv, tu, v3dv, vn)
|
||||
VK_EXT_memory_priority DONE (lvp, radv)
|
||||
VK_EXT_mesh_shader DONE (anv/gfx12.5+, lvp, radv, vn)
|
||||
VK_EXT_multi_draw DONE (anv, hasvk, hk, lvp, nvk, radv, tu, vn, v3dv)
|
||||
VK_EXT_multi_draw DONE (anv, hasvk, hk, kk, lvp, nvk, radv, tu, vn, v3dv)
|
||||
VK_EXT_multisampled_render_to_single_sampled DONE (lvp, vn, panvk, tu)
|
||||
VK_EXT_mutable_descriptor_type DONE (anv, hk, kk, lvp, nvk, panvk/v9+, radv, tu, vn)
|
||||
VK_EXT_nested_command_buffer DONE (anv, lvp, nvk, panvk/v10+, radv, tu, vn)
|
||||
|
|
|
|||
|
|
@ -1092,6 +1092,50 @@ kk_CmdDraw(VkCommandBuffer commandBuffer, uint32_t vertexCount,
|
|||
kk_draw(cmd, data);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
kk_CmdDrawMultiEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
|
||||
const VkMultiDrawInfoEXT *pVertexInfo,
|
||||
uint32_t instanceCount, uint32_t firstInstance,
|
||||
uint32_t stride)
|
||||
{
|
||||
/* Metal validation dislikes empty calls */
|
||||
if (instanceCount == 0)
|
||||
return;
|
||||
|
||||
VK_FROM_HANDLE(kk_cmd_buffer, cmd, commandBuffer);
|
||||
|
||||
const struct vk_dynamic_graphics_state *dyn =
|
||||
&cmd->vk.dynamic_graphics_state;
|
||||
|
||||
struct kk_draw_data data = {
|
||||
.count[1] = instanceCount,
|
||||
.first_instance = firstInstance,
|
||||
.prim = vk_topology_to_mesa(dyn->ia.primitive_topology),
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < drawCount; ++i) {
|
||||
/* Metal validation dislikes empty calls */
|
||||
if (pVertexInfo->vertexCount > 0) {
|
||||
/* TODO_KOSMICKRISP
|
||||
* Move this to a separate buffer from the root so we don't have to upload
|
||||
* it every single loop. Pass it to the kk_draw call as a parameter that
|
||||
* will later be uploaded.
|
||||
*/
|
||||
cmd->state.gfx.descriptors.root_dirty = true;
|
||||
cmd->state.gfx.descriptors.root.draw.draw_id = i;
|
||||
|
||||
data.count[0] = pVertexInfo->vertexCount;
|
||||
data.first_vertex = pVertexInfo->firstVertex;
|
||||
kk_draw(cmd, data);
|
||||
}
|
||||
|
||||
pVertexInfo = ((void *)pVertexInfo) + stride;
|
||||
}
|
||||
/* TODO_KOSMICKRISP Remove once above is done */
|
||||
cmd->state.gfx.descriptors.root_dirty = true;
|
||||
cmd->state.gfx.descriptors.root.draw.draw_id = 0;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
kk_CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
|
||||
uint32_t instanceCount, uint32_t firstIndex,
|
||||
|
|
@ -1124,6 +1168,58 @@ kk_CmdDrawIndexed(VkCommandBuffer commandBuffer, uint32_t indexCount,
|
|||
kk_draw(cmd, data);
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
kk_CmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, uint32_t drawCount,
|
||||
const VkMultiDrawIndexedInfoEXT *pIndexInfo,
|
||||
uint32_t instanceCount, uint32_t firstInstance,
|
||||
uint32_t stride, const int32_t *pVertexOffset)
|
||||
{
|
||||
/* Metal validation dislikes empty calls */
|
||||
if (instanceCount == 0)
|
||||
return;
|
||||
|
||||
VK_FROM_HANDLE(kk_cmd_buffer, cmd, commandBuffer);
|
||||
|
||||
const struct vk_dynamic_graphics_state *dyn =
|
||||
&cmd->vk.dynamic_graphics_state;
|
||||
|
||||
struct kk_draw_data data = {
|
||||
.count[1] = instanceCount,
|
||||
.index_buffer = cmd->state.gfx.index.handle,
|
||||
.index_buffer_offset = cmd->state.gfx.index.offset,
|
||||
.index_buffer_range_B =
|
||||
cmd->state.gfx.index.size - cmd->state.gfx.index.offset,
|
||||
.first_instance = firstInstance,
|
||||
.prim = vk_topology_to_mesa(dyn->ia.primitive_topology),
|
||||
.index_size = cmd->state.gfx.index.bytes_per_index,
|
||||
.indexed = true,
|
||||
};
|
||||
|
||||
for (uint32_t i = 0; i < drawCount; ++i) {
|
||||
/* Metal validation dislikes empty calls */
|
||||
if (pIndexInfo->indexCount > 0) {
|
||||
/* TODO_KOSMICKRISP
|
||||
* Move this to a separate buffer from the root so we don't have to upload
|
||||
* it every single loop. Pass it to the kk_draw call as a parameter that
|
||||
* will later be uploaded.
|
||||
*/
|
||||
cmd->state.gfx.descriptors.root_dirty = true;
|
||||
cmd->state.gfx.descriptors.root.draw.draw_id = i;
|
||||
|
||||
data.count[0] = pIndexInfo->indexCount;
|
||||
data.first_index = pIndexInfo->firstIndex;
|
||||
data.first_vertex = pVertexOffset != NULL ? *pVertexOffset :
|
||||
pIndexInfo->vertexOffset;
|
||||
kk_draw(cmd, data);
|
||||
}
|
||||
|
||||
pIndexInfo = ((void *)pIndexInfo) + stride;
|
||||
}
|
||||
/* TODO_KOSMICKRISP Remove once above is done */
|
||||
cmd->state.gfx.descriptors.root_dirty = true;
|
||||
cmd->state.gfx.descriptors.root.draw.draw_id = 0;
|
||||
}
|
||||
|
||||
VKAPI_ATTR void VKAPI_CALL
|
||||
kk_CmdDrawIndirect(VkCommandBuffer commandBuffer, VkBuffer _buffer,
|
||||
VkDeviceSize offset, uint32_t drawCount, uint32_t stride)
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ kk_get_device_extensions(const struct kk_instance *instance,
|
|||
.EXT_external_memory_metal = true,
|
||||
.EXT_image_2d_view_of_3d = true,
|
||||
.EXT_load_store_op_none = true,
|
||||
.EXT_multi_draw = true,
|
||||
.EXT_mutable_descriptor_type = true,
|
||||
.EXT_shader_atomic_float = true,
|
||||
.EXT_shader_replicated_composites = true,
|
||||
|
|
@ -325,6 +326,9 @@ kk_get_device_features(
|
|||
.image2DViewOf3D = true,
|
||||
.sampler2DViewOf3D = true,
|
||||
|
||||
/* VK_EXT_multi_draw */
|
||||
.multiDraw = true,
|
||||
|
||||
/* VK_EXT_shader_replicated_composites */
|
||||
.shaderReplicatedComposites = true,
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue