1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2019 Red Hat. 3bf215546Sopenharmony_ci * Copyright © 2022 Collabora, LTD 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci * IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "vk_alloc.h" 26bf215546Sopenharmony_ci#include "vk_cmd_enqueue_entrypoints.h" 27bf215546Sopenharmony_ci#include "vk_command_buffer.h" 28bf215546Sopenharmony_ci#include "vk_device.h" 29bf215546Sopenharmony_ci#include "vk_pipeline_layout.h" 30bf215546Sopenharmony_ci#include "vk_util.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 33bf215546Sopenharmony_civk_cmd_enqueue_CmdDrawMultiEXT(VkCommandBuffer commandBuffer, 34bf215546Sopenharmony_ci uint32_t drawCount, 35bf215546Sopenharmony_ci const VkMultiDrawInfoEXT *pVertexInfo, 36bf215546Sopenharmony_ci uint32_t instanceCount, 37bf215546Sopenharmony_ci uint32_t firstInstance, 38bf215546Sopenharmony_ci uint32_t stride) 39bf215546Sopenharmony_ci{ 40bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer); 41bf215546Sopenharmony_ci 42bf215546Sopenharmony_ci struct vk_cmd_queue_entry *cmd = 43bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, sizeof(*cmd), 8, 44bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 45bf215546Sopenharmony_ci if (!cmd) 46bf215546Sopenharmony_ci return; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci cmd->type = VK_CMD_DRAW_MULTI_EXT; 49bf215546Sopenharmony_ci list_addtail(&cmd->cmd_link, &cmd_buffer->cmd_queue.cmds); 50bf215546Sopenharmony_ci 51bf215546Sopenharmony_ci cmd->u.draw_multi_ext.draw_count = drawCount; 52bf215546Sopenharmony_ci if (pVertexInfo) { 53bf215546Sopenharmony_ci unsigned i = 0; 54bf215546Sopenharmony_ci cmd->u.draw_multi_ext.vertex_info = 55bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 56bf215546Sopenharmony_ci sizeof(*cmd->u.draw_multi_ext.vertex_info) * drawCount, 8, 57bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 58bf215546Sopenharmony_ci 59bf215546Sopenharmony_ci vk_foreach_multi_draw(draw, i, pVertexInfo, drawCount, stride) { 60bf215546Sopenharmony_ci memcpy(&cmd->u.draw_multi_ext.vertex_info[i], draw, 61bf215546Sopenharmony_ci sizeof(*cmd->u.draw_multi_ext.vertex_info)); 62bf215546Sopenharmony_ci } 63bf215546Sopenharmony_ci } 64bf215546Sopenharmony_ci cmd->u.draw_multi_ext.instance_count = instanceCount; 65bf215546Sopenharmony_ci cmd->u.draw_multi_ext.first_instance = firstInstance; 66bf215546Sopenharmony_ci cmd->u.draw_multi_ext.stride = stride; 67bf215546Sopenharmony_ci} 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 70bf215546Sopenharmony_civk_cmd_enqueue_CmdDrawMultiIndexedEXT(VkCommandBuffer commandBuffer, 71bf215546Sopenharmony_ci uint32_t drawCount, 72bf215546Sopenharmony_ci const VkMultiDrawIndexedInfoEXT *pIndexInfo, 73bf215546Sopenharmony_ci uint32_t instanceCount, 74bf215546Sopenharmony_ci uint32_t firstInstance, 75bf215546Sopenharmony_ci uint32_t stride, 76bf215546Sopenharmony_ci const int32_t *pVertexOffset) 77bf215546Sopenharmony_ci{ 78bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer); 79bf215546Sopenharmony_ci 80bf215546Sopenharmony_ci struct vk_cmd_queue_entry *cmd = 81bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, sizeof(*cmd), 8, 82bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 83bf215546Sopenharmony_ci if (!cmd) 84bf215546Sopenharmony_ci return; 85bf215546Sopenharmony_ci 86bf215546Sopenharmony_ci cmd->type = VK_CMD_DRAW_MULTI_INDEXED_EXT; 87bf215546Sopenharmony_ci list_addtail(&cmd->cmd_link, &cmd_buffer->cmd_queue.cmds); 88bf215546Sopenharmony_ci 89bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.draw_count = drawCount; 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci if (pIndexInfo) { 92bf215546Sopenharmony_ci unsigned i = 0; 93bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.index_info = 94bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 95bf215546Sopenharmony_ci sizeof(*cmd->u.draw_multi_indexed_ext.index_info) * drawCount, 8, 96bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 97bf215546Sopenharmony_ci 98bf215546Sopenharmony_ci vk_foreach_multi_draw_indexed(draw, i, pIndexInfo, drawCount, stride) { 99bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.index_info[i].firstIndex = draw->firstIndex; 100bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.index_info[i].indexCount = draw->indexCount; 101bf215546Sopenharmony_ci if (pVertexOffset == NULL) 102bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.index_info[i].vertexOffset = draw->vertexOffset; 103bf215546Sopenharmony_ci } 104bf215546Sopenharmony_ci } 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.instance_count = instanceCount; 107bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.first_instance = firstInstance; 108bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.stride = stride; 109bf215546Sopenharmony_ci 110bf215546Sopenharmony_ci if (pVertexOffset) { 111bf215546Sopenharmony_ci cmd->u.draw_multi_indexed_ext.vertex_offset = 112bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 113bf215546Sopenharmony_ci sizeof(*cmd->u.draw_multi_indexed_ext.vertex_offset), 8, 114bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ci memcpy(cmd->u.draw_multi_indexed_ext.vertex_offset, pVertexOffset, 117bf215546Sopenharmony_ci sizeof(*cmd->u.draw_multi_indexed_ext.vertex_offset)); 118bf215546Sopenharmony_ci } 119bf215546Sopenharmony_ci} 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 122bf215546Sopenharmony_civk_cmd_enqueue_CmdPushDescriptorSetKHR(VkCommandBuffer commandBuffer, 123bf215546Sopenharmony_ci VkPipelineBindPoint pipelineBindPoint, 124bf215546Sopenharmony_ci VkPipelineLayout layout, 125bf215546Sopenharmony_ci uint32_t set, 126bf215546Sopenharmony_ci uint32_t descriptorWriteCount, 127bf215546Sopenharmony_ci const VkWriteDescriptorSet *pDescriptorWrites) 128bf215546Sopenharmony_ci{ 129bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer); 130bf215546Sopenharmony_ci struct vk_cmd_push_descriptor_set_khr *pds; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci struct vk_cmd_queue_entry *cmd = 133bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, sizeof(*cmd), 8, 134bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 135bf215546Sopenharmony_ci if (!cmd) 136bf215546Sopenharmony_ci return; 137bf215546Sopenharmony_ci 138bf215546Sopenharmony_ci pds = &cmd->u.push_descriptor_set_khr; 139bf215546Sopenharmony_ci 140bf215546Sopenharmony_ci cmd->type = VK_CMD_PUSH_DESCRIPTOR_SET_KHR; 141bf215546Sopenharmony_ci list_addtail(&cmd->cmd_link, &cmd_buffer->cmd_queue.cmds); 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci pds->pipeline_bind_point = pipelineBindPoint; 144bf215546Sopenharmony_ci pds->layout = layout; 145bf215546Sopenharmony_ci pds->set = set; 146bf215546Sopenharmony_ci pds->descriptor_write_count = descriptorWriteCount; 147bf215546Sopenharmony_ci 148bf215546Sopenharmony_ci if (pDescriptorWrites) { 149bf215546Sopenharmony_ci pds->descriptor_writes = 150bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 151bf215546Sopenharmony_ci sizeof(*pds->descriptor_writes) * descriptorWriteCount, 8, 152bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 153bf215546Sopenharmony_ci memcpy(pds->descriptor_writes, 154bf215546Sopenharmony_ci pDescriptorWrites, 155bf215546Sopenharmony_ci sizeof(*pds->descriptor_writes) * descriptorWriteCount); 156bf215546Sopenharmony_ci 157bf215546Sopenharmony_ci for (unsigned i = 0; i < descriptorWriteCount; i++) { 158bf215546Sopenharmony_ci switch (pds->descriptor_writes[i].descriptorType) { 159bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLER: 160bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER: 161bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE: 162bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE: 163bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 164bf215546Sopenharmony_ci pds->descriptor_writes[i].pImageInfo = 165bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 166bf215546Sopenharmony_ci sizeof(VkDescriptorImageInfo) * pds->descriptor_writes[i].descriptorCount, 8, 167bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 168bf215546Sopenharmony_ci memcpy((VkDescriptorImageInfo *)pds->descriptor_writes[i].pImageInfo, 169bf215546Sopenharmony_ci pDescriptorWrites[i].pImageInfo, 170bf215546Sopenharmony_ci sizeof(VkDescriptorImageInfo) * pds->descriptor_writes[i].descriptorCount); 171bf215546Sopenharmony_ci break; 172bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER: 173bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER: 174bf215546Sopenharmony_ci pds->descriptor_writes[i].pTexelBufferView = 175bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 176bf215546Sopenharmony_ci sizeof(VkBufferView) * pds->descriptor_writes[i].descriptorCount, 8, 177bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 178bf215546Sopenharmony_ci memcpy((VkBufferView *)pds->descriptor_writes[i].pTexelBufferView, 179bf215546Sopenharmony_ci pDescriptorWrites[i].pTexelBufferView, 180bf215546Sopenharmony_ci sizeof(VkBufferView) * pds->descriptor_writes[i].descriptorCount); 181bf215546Sopenharmony_ci break; 182bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER: 183bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER: 184bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC: 185bf215546Sopenharmony_ci case VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC: 186bf215546Sopenharmony_ci default: 187bf215546Sopenharmony_ci pds->descriptor_writes[i].pBufferInfo = 188bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 189bf215546Sopenharmony_ci sizeof(VkDescriptorBufferInfo) * pds->descriptor_writes[i].descriptorCount, 8, 190bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 191bf215546Sopenharmony_ci memcpy((VkDescriptorBufferInfo *)pds->descriptor_writes[i].pBufferInfo, 192bf215546Sopenharmony_ci pDescriptorWrites[i].pBufferInfo, 193bf215546Sopenharmony_ci sizeof(VkDescriptorBufferInfo) * pds->descriptor_writes[i].descriptorCount); 194bf215546Sopenharmony_ci break; 195bf215546Sopenharmony_ci } 196bf215546Sopenharmony_ci } 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci} 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_cistatic void 201bf215546Sopenharmony_ciunref_pipeline_layout(struct vk_cmd_queue *queue, 202bf215546Sopenharmony_ci struct vk_cmd_queue_entry *cmd) 203bf215546Sopenharmony_ci{ 204bf215546Sopenharmony_ci struct vk_command_buffer *cmd_buffer = 205bf215546Sopenharmony_ci container_of(queue, struct vk_command_buffer, cmd_queue); 206bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_pipeline_layout, layout, 207bf215546Sopenharmony_ci cmd->u.bind_descriptor_sets.layout); 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci assert(cmd->type == VK_CMD_BIND_DESCRIPTOR_SETS); 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci vk_pipeline_layout_unref(cmd_buffer->base.device, layout); 212bf215546Sopenharmony_ci} 213bf215546Sopenharmony_ci 214bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 215bf215546Sopenharmony_civk_cmd_enqueue_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, 216bf215546Sopenharmony_ci VkPipelineBindPoint pipelineBindPoint, 217bf215546Sopenharmony_ci VkPipelineLayout layout, 218bf215546Sopenharmony_ci uint32_t firstSet, 219bf215546Sopenharmony_ci uint32_t descriptorSetCount, 220bf215546Sopenharmony_ci const VkDescriptorSet* pDescriptorSets, 221bf215546Sopenharmony_ci uint32_t dynamicOffsetCount, 222bf215546Sopenharmony_ci const uint32_t *pDynamicOffsets) 223bf215546Sopenharmony_ci{ 224bf215546Sopenharmony_ci VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer); 225bf215546Sopenharmony_ci 226bf215546Sopenharmony_ci struct vk_cmd_queue_entry *cmd = 227bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, sizeof(*cmd), 8, 228bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 229bf215546Sopenharmony_ci if (!cmd) 230bf215546Sopenharmony_ci return; 231bf215546Sopenharmony_ci 232bf215546Sopenharmony_ci cmd->type = VK_CMD_BIND_DESCRIPTOR_SETS; 233bf215546Sopenharmony_ci list_addtail(&cmd->cmd_link, &cmd_buffer->cmd_queue.cmds); 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci /* We need to hold a reference to the descriptor set as long as this 236bf215546Sopenharmony_ci * command is in the queue. Otherwise, it may get deleted out from under 237bf215546Sopenharmony_ci * us before the command is replayed. 238bf215546Sopenharmony_ci */ 239bf215546Sopenharmony_ci vk_pipeline_layout_ref(vk_pipeline_layout_from_handle(layout)); 240bf215546Sopenharmony_ci cmd->u.bind_descriptor_sets.layout = layout; 241bf215546Sopenharmony_ci cmd->driver_free_cb = unref_pipeline_layout; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci cmd->u.bind_descriptor_sets.pipeline_bind_point = pipelineBindPoint; 244bf215546Sopenharmony_ci cmd->u.bind_descriptor_sets.first_set = firstSet; 245bf215546Sopenharmony_ci cmd->u.bind_descriptor_sets.descriptor_set_count = descriptorSetCount; 246bf215546Sopenharmony_ci if (pDescriptorSets) { 247bf215546Sopenharmony_ci cmd->u.bind_descriptor_sets.descriptor_sets = 248bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 249bf215546Sopenharmony_ci sizeof(*cmd->u.bind_descriptor_sets.descriptor_sets) * descriptorSetCount, 8, 250bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 251bf215546Sopenharmony_ci 252bf215546Sopenharmony_ci memcpy(cmd->u.bind_descriptor_sets.descriptor_sets, pDescriptorSets, 253bf215546Sopenharmony_ci sizeof(*cmd->u.bind_descriptor_sets.descriptor_sets) * descriptorSetCount); 254bf215546Sopenharmony_ci } 255bf215546Sopenharmony_ci cmd->u.bind_descriptor_sets.dynamic_offset_count = dynamicOffsetCount; 256bf215546Sopenharmony_ci if (pDynamicOffsets) { 257bf215546Sopenharmony_ci cmd->u.bind_descriptor_sets.dynamic_offsets = 258bf215546Sopenharmony_ci vk_zalloc(cmd_buffer->cmd_queue.alloc, 259bf215546Sopenharmony_ci sizeof(*cmd->u.bind_descriptor_sets.dynamic_offsets) * dynamicOffsetCount, 8, 260bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 261bf215546Sopenharmony_ci 262bf215546Sopenharmony_ci memcpy(cmd->u.bind_descriptor_sets.dynamic_offsets, pDynamicOffsets, 263bf215546Sopenharmony_ci sizeof(*cmd->u.bind_descriptor_sets.dynamic_offsets) * dynamicOffsetCount); 264bf215546Sopenharmony_ci } 265bf215546Sopenharmony_ci} 266