diff --git a/src/virtio/vulkan/vn_common.h b/src/virtio/vulkan/vn_common.h index ffa6a3ee5bd..bd7f4fcce15 100644 --- a/src/virtio/vulkan/vn_common.h +++ b/src/virtio/vulkan/vn_common.h @@ -73,6 +73,7 @@ struct vn_shader_module; struct vn_pipeline_layout; struct vn_pipeline_cache; struct vn_pipeline; +struct vn_command_pool; struct vn_command_buffer; struct vn_cs_encoder; diff --git a/src/virtio/vulkan/vn_device.c b/src/virtio/vulkan/vn_device.c index 23b7fc742ff..b8aae8dbb15 100644 --- a/src/virtio/vulkan/vn_device.c +++ b/src/virtio/vulkan/vn_device.c @@ -6590,3 +6590,1262 @@ vn_DestroyPipeline(VkDevice device, vn_object_base_fini(&pipeline->base); vk_free(alloc, pipeline); } + +/* command pool commands */ + +VkResult +vn_CreateCommandPool(VkDevice device, + const VkCommandPoolCreateInfo *pCreateInfo, + const VkAllocationCallbacks *pAllocator, + VkCommandPool *pCommandPool) +{ + struct vn_device *dev = vn_device_from_handle(device); + const VkAllocationCallbacks *alloc = + pAllocator ? pAllocator : &dev->base.base.alloc; + + struct vn_command_pool *pool = + vk_zalloc(alloc, sizeof(*pool), VN_DEFAULT_ALIGN, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!pool) + return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + + vn_object_base_init(&pool->base, VK_OBJECT_TYPE_COMMAND_POOL, &dev->base); + + pool->allocator = *alloc; + list_inithead(&pool->command_buffers); + + VkCommandPool pool_handle = vn_command_pool_to_handle(pool); + vn_async_vkCreateCommandPool(dev->instance, device, pCreateInfo, NULL, + &pool_handle); + + *pCommandPool = pool_handle; + + return VK_SUCCESS; +} + +void +vn_DestroyCommandPool(VkDevice device, + VkCommandPool commandPool, + const VkAllocationCallbacks *pAllocator) +{ + struct vn_device *dev = vn_device_from_handle(device); + struct vn_command_pool *pool = vn_command_pool_from_handle(commandPool); + const VkAllocationCallbacks *alloc; + + if (!pool) + return; + + alloc = pAllocator ? pAllocator : &pool->allocator; + + vn_async_vkDestroyCommandPool(dev->instance, device, commandPool, NULL); + + list_for_each_entry_safe (struct vn_command_buffer, cmd, + &pool->command_buffers, head) { + vn_cs_encoder_fini(&cmd->cs); + vn_object_base_fini(&cmd->base); + vk_free(alloc, cmd); + } + + vn_object_base_fini(&pool->base); + vk_free(alloc, pool); +} + +VkResult +vn_ResetCommandPool(VkDevice device, + VkCommandPool commandPool, + VkCommandPoolResetFlags flags) +{ + struct vn_device *dev = vn_device_from_handle(device); + struct vn_command_pool *pool = vn_command_pool_from_handle(commandPool); + + list_for_each_entry_safe (struct vn_command_buffer, cmd, + &pool->command_buffers, head) { + vn_cs_encoder_reset(&cmd->cs); + cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL; + } + + vn_async_vkResetCommandPool(dev->instance, device, commandPool, flags); + + return VK_SUCCESS; +} + +void +vn_TrimCommandPool(VkDevice device, + VkCommandPool commandPool, + VkCommandPoolTrimFlags flags) +{ + struct vn_device *dev = vn_device_from_handle(device); + + vn_async_vkTrimCommandPool(dev->instance, device, commandPool, flags); +} + +/* command buffer commands */ + +VkResult +vn_AllocateCommandBuffers(VkDevice device, + const VkCommandBufferAllocateInfo *pAllocateInfo, + VkCommandBuffer *pCommandBuffers) +{ + struct vn_device *dev = vn_device_from_handle(device); + struct vn_command_pool *pool = + vn_command_pool_from_handle(pAllocateInfo->commandPool); + const VkAllocationCallbacks *alloc = &pool->allocator; + + for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; i++) { + struct vn_command_buffer *cmd = + vk_zalloc(alloc, sizeof(*cmd), VN_DEFAULT_ALIGN, + VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); + if (!cmd) { + for (uint32_t j = 0; j < i; j++) { + cmd = vn_command_buffer_from_handle(pCommandBuffers[j]); + vn_cs_encoder_fini(&cmd->cs); + list_del(&cmd->head); + vk_free(alloc, cmd); + } + memset(pCommandBuffers, 0, + sizeof(*pCommandBuffers) * pAllocateInfo->commandBufferCount); + return vn_error(dev->instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + vn_object_base_init(&cmd->base, VK_OBJECT_TYPE_COMMAND_BUFFER, + &dev->base); + cmd->device = dev; + + list_addtail(&cmd->head, &pool->command_buffers); + + cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL; + vn_cs_encoder_init_indirect(&cmd->cs, dev->instance, 16 * 1024); + + VkCommandBuffer cmd_handle = vn_command_buffer_to_handle(cmd); + pCommandBuffers[i] = cmd_handle; + } + + vn_async_vkAllocateCommandBuffers(dev->instance, device, pAllocateInfo, + pCommandBuffers); + + return VK_SUCCESS; +} + +void +vn_FreeCommandBuffers(VkDevice device, + VkCommandPool commandPool, + uint32_t commandBufferCount, + const VkCommandBuffer *pCommandBuffers) +{ + struct vn_device *dev = vn_device_from_handle(device); + struct vn_command_pool *pool = vn_command_pool_from_handle(commandPool); + const VkAllocationCallbacks *alloc = &pool->allocator; + + vn_async_vkFreeCommandBuffers(dev->instance, device, commandPool, + commandBufferCount, pCommandBuffers); + + for (uint32_t i = 0; i < commandBufferCount; i++) { + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(pCommandBuffers[i]); + + if (!cmd) + continue; + + vn_cs_encoder_fini(&cmd->cs); + list_del(&cmd->head); + + vn_object_base_fini(&cmd->base); + vk_free(alloc, cmd); + } +} + +VkResult +vn_ResetCommandBuffer(VkCommandBuffer commandBuffer, + VkCommandBufferResetFlags flags) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + + vn_cs_encoder_reset(&cmd->cs); + cmd->state = VN_COMMAND_BUFFER_STATE_INITIAL; + + vn_async_vkResetCommandBuffer(cmd->device->instance, commandBuffer, flags); + + return VK_SUCCESS; +} + +VkResult +vn_BeginCommandBuffer(VkCommandBuffer commandBuffer, + const VkCommandBufferBeginInfo *pBeginInfo) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + struct vn_instance *instance = cmd->device->instance; + size_t cmd_size; + + vn_cs_encoder_reset(&cmd->cs); + + cmd_size = vn_sizeof_vkBeginCommandBuffer(commandBuffer, pBeginInfo); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) { + cmd->state = VN_COMMAND_BUFFER_STATE_INVALID; + return vn_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + vn_encode_vkBeginCommandBuffer(&cmd->cs, 0, commandBuffer, pBeginInfo); + + cmd->state = VN_COMMAND_BUFFER_STATE_RECORDING; + + return VK_SUCCESS; +} + +VkResult +vn_EndCommandBuffer(VkCommandBuffer commandBuffer) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + struct vn_instance *instance = cmd->device->instance; + size_t cmd_size; + + cmd_size = vn_sizeof_vkEndCommandBuffer(commandBuffer); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) { + cmd->state = VN_COMMAND_BUFFER_STATE_INVALID; + return vn_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + vn_encode_vkEndCommandBuffer(&cmd->cs, 0, commandBuffer); + vn_cs_encoder_commit(&cmd->cs); + + if (vn_cs_encoder_get_fatal(&cmd->cs)) { + cmd->state = VN_COMMAND_BUFFER_STATE_INVALID; + return vn_error(instance, VK_ERROR_OUT_OF_HOST_MEMORY); + } + + vn_instance_wait_roundtrip(instance, cmd->cs.current_buffer_roundtrip); + mtx_lock(&instance->ring.mutex); + VkResult result = + vn_instance_ring_submit_locked(instance, &cmd->cs, NULL, NULL); + mtx_unlock(&instance->ring.mutex); + if (result != VK_SUCCESS) { + cmd->state = VN_COMMAND_BUFFER_STATE_INVALID; + return vn_error(instance, result); + } + + vn_cs_encoder_reset(&cmd->cs); + + cmd->state = VN_COMMAND_BUFFER_STATE_EXECUTABLE; + + return VK_SUCCESS; +} + +void +vn_CmdBindPipeline(VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipeline pipeline) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = + vn_sizeof_vkCmdBindPipeline(commandBuffer, pipelineBindPoint, pipeline); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdBindPipeline(&cmd->cs, 0, commandBuffer, pipelineBindPoint, + pipeline); +} + +void +vn_CmdSetViewport(VkCommandBuffer commandBuffer, + uint32_t firstViewport, + uint32_t viewportCount, + const VkViewport *pViewports) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdSetViewport(commandBuffer, firstViewport, + viewportCount, pViewports); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetViewport(&cmd->cs, 0, commandBuffer, firstViewport, + viewportCount, pViewports); +} + +void +vn_CmdSetScissor(VkCommandBuffer commandBuffer, + uint32_t firstScissor, + uint32_t scissorCount, + const VkRect2D *pScissors) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdSetScissor(commandBuffer, firstScissor, + scissorCount, pScissors); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetScissor(&cmd->cs, 0, commandBuffer, firstScissor, + scissorCount, pScissors); +} + +void +vn_CmdSetLineWidth(VkCommandBuffer commandBuffer, float lineWidth) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdSetLineWidth(commandBuffer, lineWidth); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetLineWidth(&cmd->cs, 0, commandBuffer, lineWidth); +} + +void +vn_CmdSetDepthBias(VkCommandBuffer commandBuffer, + float depthBiasConstantFactor, + float depthBiasClamp, + float depthBiasSlopeFactor) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = + vn_sizeof_vkCmdSetDepthBias(commandBuffer, depthBiasConstantFactor, + depthBiasClamp, depthBiasSlopeFactor); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetDepthBias(&cmd->cs, 0, commandBuffer, + depthBiasConstantFactor, depthBiasClamp, + depthBiasSlopeFactor); +} + +void +vn_CmdSetBlendConstants(VkCommandBuffer commandBuffer, + const float blendConstants[4]) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdSetBlendConstants(commandBuffer, blendConstants); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetBlendConstants(&cmd->cs, 0, commandBuffer, + blendConstants); +} + +void +vn_CmdSetDepthBounds(VkCommandBuffer commandBuffer, + float minDepthBounds, + float maxDepthBounds) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdSetDepthBounds(commandBuffer, minDepthBounds, + maxDepthBounds); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetDepthBounds(&cmd->cs, 0, commandBuffer, minDepthBounds, + maxDepthBounds); +} + +void +vn_CmdSetStencilCompareMask(VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t compareMask) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdSetStencilCompareMask(commandBuffer, faceMask, + compareMask); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetStencilCompareMask(&cmd->cs, 0, commandBuffer, faceMask, + compareMask); +} + +void +vn_CmdSetStencilWriteMask(VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t writeMask) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = + vn_sizeof_vkCmdSetStencilWriteMask(commandBuffer, faceMask, writeMask); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetStencilWriteMask(&cmd->cs, 0, commandBuffer, faceMask, + writeMask); +} + +void +vn_CmdSetStencilReference(VkCommandBuffer commandBuffer, + VkStencilFaceFlags faceMask, + uint32_t reference) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = + vn_sizeof_vkCmdSetStencilReference(commandBuffer, faceMask, reference); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetStencilReference(&cmd->cs, 0, commandBuffer, faceMask, + reference); +} + +void +vn_CmdBindDescriptorSets(VkCommandBuffer commandBuffer, + VkPipelineBindPoint pipelineBindPoint, + VkPipelineLayout layout, + uint32_t firstSet, + uint32_t descriptorSetCount, + const VkDescriptorSet *pDescriptorSets, + uint32_t dynamicOffsetCount, + const uint32_t *pDynamicOffsets) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdBindDescriptorSets( + commandBuffer, pipelineBindPoint, layout, firstSet, descriptorSetCount, + pDescriptorSets, dynamicOffsetCount, pDynamicOffsets); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdBindDescriptorSets(&cmd->cs, 0, commandBuffer, + pipelineBindPoint, layout, firstSet, + descriptorSetCount, pDescriptorSets, + dynamicOffsetCount, pDynamicOffsets); +} + +void +vn_CmdBindIndexBuffer(VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkIndexType indexType) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdBindIndexBuffer(commandBuffer, buffer, offset, + indexType); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdBindIndexBuffer(&cmd->cs, 0, commandBuffer, buffer, offset, + indexType); +} + +void +vn_CmdBindVertexBuffers(VkCommandBuffer commandBuffer, + uint32_t firstBinding, + uint32_t bindingCount, + const VkBuffer *pBuffers, + const VkDeviceSize *pOffsets) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdBindVertexBuffers( + commandBuffer, firstBinding, bindingCount, pBuffers, pOffsets); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdBindVertexBuffers(&cmd->cs, 0, commandBuffer, firstBinding, + bindingCount, pBuffers, pOffsets); +} + +void +vn_CmdDraw(VkCommandBuffer commandBuffer, + uint32_t vertexCount, + uint32_t instanceCount, + uint32_t firstVertex, + uint32_t firstInstance) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdDraw(commandBuffer, vertexCount, instanceCount, + firstVertex, firstInstance); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDraw(&cmd->cs, 0, commandBuffer, vertexCount, instanceCount, + firstVertex, firstInstance); +} + +void +vn_CmdDrawIndexed(VkCommandBuffer commandBuffer, + uint32_t indexCount, + uint32_t instanceCount, + uint32_t firstIndex, + int32_t vertexOffset, + uint32_t firstInstance) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = + vn_sizeof_vkCmdDrawIndexed(commandBuffer, indexCount, instanceCount, + firstIndex, vertexOffset, firstInstance); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDrawIndexed(&cmd->cs, 0, commandBuffer, indexCount, + instanceCount, firstIndex, vertexOffset, + firstInstance); +} + +void +vn_CmdDrawIndirect(VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdDrawIndirect(commandBuffer, buffer, offset, + drawCount, stride); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDrawIndirect(&cmd->cs, 0, commandBuffer, buffer, offset, + drawCount, stride); +} + +void +vn_CmdDrawIndexedIndirect(VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + uint32_t drawCount, + uint32_t stride) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdDrawIndexedIndirect(commandBuffer, buffer, + offset, drawCount, stride); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDrawIndexedIndirect(&cmd->cs, 0, commandBuffer, buffer, + offset, drawCount, stride); +} + +void +vn_CmdDrawIndirectCount(VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdDrawIndirectCount(commandBuffer, buffer, offset, + countBuffer, countBufferOffset, + maxDrawCount, stride); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDrawIndirectCount(&cmd->cs, 0, commandBuffer, buffer, + offset, countBuffer, countBufferOffset, + maxDrawCount, stride); +} + +void +vn_CmdDrawIndexedIndirectCount(VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset, + VkBuffer countBuffer, + VkDeviceSize countBufferOffset, + uint32_t maxDrawCount, + uint32_t stride) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdDrawIndexedIndirectCount( + commandBuffer, buffer, offset, countBuffer, countBufferOffset, + maxDrawCount, stride); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDrawIndexedIndirectCount( + &cmd->cs, 0, commandBuffer, buffer, offset, countBuffer, + countBufferOffset, maxDrawCount, stride); +} + +void +vn_CmdDispatch(VkCommandBuffer commandBuffer, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdDispatch(commandBuffer, groupCountX, groupCountY, + groupCountZ); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDispatch(&cmd->cs, 0, commandBuffer, groupCountX, + groupCountY, groupCountZ); +} + +void +vn_CmdDispatchIndirect(VkCommandBuffer commandBuffer, + VkBuffer buffer, + VkDeviceSize offset) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdDispatchIndirect(commandBuffer, buffer, offset); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDispatchIndirect(&cmd->cs, 0, commandBuffer, buffer, + offset); +} + +void +vn_CmdCopyBuffer(VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferCopy *pRegions) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, + regionCount, pRegions); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdCopyBuffer(&cmd->cs, 0, commandBuffer, srcBuffer, dstBuffer, + regionCount, pRegions); +} + +void +vn_CmdCopyImage(VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageCopy *pRegions) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdCopyImage(commandBuffer, srcImage, + srcImageLayout, dstImage, + dstImageLayout, regionCount, pRegions); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdCopyImage(&cmd->cs, 0, commandBuffer, srcImage, + srcImageLayout, dstImage, dstImageLayout, + regionCount, pRegions); +} + +void +vn_CmdBlitImage(VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageBlit *pRegions, + VkFilter filter) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdBlitImage( + commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, + regionCount, pRegions, filter); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdBlitImage(&cmd->cs, 0, commandBuffer, srcImage, + srcImageLayout, dstImage, dstImageLayout, + regionCount, pRegions, filter); +} + +void +vn_CmdCopyBufferToImage(VkCommandBuffer commandBuffer, + VkBuffer srcBuffer, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkBufferImageCopy *pRegions) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = + vn_sizeof_vkCmdCopyBufferToImage(commandBuffer, srcBuffer, dstImage, + dstImageLayout, regionCount, pRegions); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdCopyBufferToImage(&cmd->cs, 0, commandBuffer, srcBuffer, + dstImage, dstImageLayout, regionCount, + pRegions); +} + +void +vn_CmdCopyImageToBuffer(VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkBuffer dstBuffer, + uint32_t regionCount, + const VkBufferImageCopy *pRegions) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdCopyImageToBuffer(commandBuffer, srcImage, + srcImageLayout, dstBuffer, + regionCount, pRegions); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdCopyImageToBuffer(&cmd->cs, 0, commandBuffer, srcImage, + srcImageLayout, dstBuffer, regionCount, + pRegions); +} + +void +vn_CmdUpdateBuffer(VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize dataSize, + const void *pData) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdUpdateBuffer(commandBuffer, dstBuffer, dstOffset, + dataSize, pData); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdUpdateBuffer(&cmd->cs, 0, commandBuffer, dstBuffer, + dstOffset, dataSize, pData); +} + +void +vn_CmdFillBuffer(VkCommandBuffer commandBuffer, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize size, + uint32_t data) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdFillBuffer(commandBuffer, dstBuffer, dstOffset, + size, data); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdFillBuffer(&cmd->cs, 0, commandBuffer, dstBuffer, dstOffset, + size, data); +} + +void +vn_CmdClearColorImage(VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearColorValue *pColor, + uint32_t rangeCount, + const VkImageSubresourceRange *pRanges) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdClearColorImage( + commandBuffer, image, imageLayout, pColor, rangeCount, pRanges); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdClearColorImage(&cmd->cs, 0, commandBuffer, image, + imageLayout, pColor, rangeCount, pRanges); +} + +void +vn_CmdClearDepthStencilImage(VkCommandBuffer commandBuffer, + VkImage image, + VkImageLayout imageLayout, + const VkClearDepthStencilValue *pDepthStencil, + uint32_t rangeCount, + const VkImageSubresourceRange *pRanges) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdClearDepthStencilImage( + commandBuffer, image, imageLayout, pDepthStencil, rangeCount, pRanges); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdClearDepthStencilImage(&cmd->cs, 0, commandBuffer, image, + imageLayout, pDepthStencil, + rangeCount, pRanges); +} + +void +vn_CmdClearAttachments(VkCommandBuffer commandBuffer, + uint32_t attachmentCount, + const VkClearAttachment *pAttachments, + uint32_t rectCount, + const VkClearRect *pRects) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdClearAttachments( + commandBuffer, attachmentCount, pAttachments, rectCount, pRects); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdClearAttachments(&cmd->cs, 0, commandBuffer, + attachmentCount, pAttachments, rectCount, + pRects); +} + +void +vn_CmdResolveImage(VkCommandBuffer commandBuffer, + VkImage srcImage, + VkImageLayout srcImageLayout, + VkImage dstImage, + VkImageLayout dstImageLayout, + uint32_t regionCount, + const VkImageResolve *pRegions) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdResolveImage( + commandBuffer, srcImage, srcImageLayout, dstImage, dstImageLayout, + regionCount, pRegions); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdResolveImage(&cmd->cs, 0, commandBuffer, srcImage, + srcImageLayout, dstImage, dstImageLayout, + regionCount, pRegions); +} + +void +vn_CmdSetEvent(VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdSetEvent(commandBuffer, event, stageMask); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetEvent(&cmd->cs, 0, commandBuffer, event, stageMask); +} + +void +vn_CmdResetEvent(VkCommandBuffer commandBuffer, + VkEvent event, + VkPipelineStageFlags stageMask) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdResetEvent(commandBuffer, event, stageMask); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdResetEvent(&cmd->cs, 0, commandBuffer, event, stageMask); +} + +void +vn_CmdWaitEvents(VkCommandBuffer commandBuffer, + uint32_t eventCount, + const VkEvent *pEvents, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + uint32_t memoryBarrierCount, + const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier *pImageMemoryBarriers) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdWaitEvents( + commandBuffer, eventCount, pEvents, srcStageMask, dstStageMask, + memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, + pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdWaitEvents(&cmd->cs, 0, commandBuffer, eventCount, pEvents, + srcStageMask, dstStageMask, memoryBarrierCount, + pMemoryBarriers, bufferMemoryBarrierCount, + pBufferMemoryBarriers, imageMemoryBarrierCount, + pImageMemoryBarriers); +} + +void +vn_CmdPipelineBarrier(VkCommandBuffer commandBuffer, + VkPipelineStageFlags srcStageMask, + VkPipelineStageFlags dstStageMask, + VkDependencyFlags dependencyFlags, + uint32_t memoryBarrierCount, + const VkMemoryBarrier *pMemoryBarriers, + uint32_t bufferMemoryBarrierCount, + const VkBufferMemoryBarrier *pBufferMemoryBarriers, + uint32_t imageMemoryBarrierCount, + const VkImageMemoryBarrier *pImageMemoryBarriers) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdPipelineBarrier( + commandBuffer, srcStageMask, dstStageMask, dependencyFlags, + memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, + pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdPipelineBarrier( + &cmd->cs, 0, commandBuffer, srcStageMask, dstStageMask, dependencyFlags, + memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, + pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers); +} + +void +vn_CmdBeginQuery(VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query, + VkQueryControlFlags flags) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = + vn_sizeof_vkCmdBeginQuery(commandBuffer, queryPool, query, flags); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdBeginQuery(&cmd->cs, 0, commandBuffer, queryPool, query, + flags); +} + +void +vn_CmdEndQuery(VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t query) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdEndQuery(commandBuffer, queryPool, query); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdEndQuery(&cmd->cs, 0, commandBuffer, queryPool, query); +} + +void +vn_CmdResetQueryPool(VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdResetQueryPool(commandBuffer, queryPool, + firstQuery, queryCount); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdResetQueryPool(&cmd->cs, 0, commandBuffer, queryPool, + firstQuery, queryCount); +} + +void +vn_CmdWriteTimestamp(VkCommandBuffer commandBuffer, + VkPipelineStageFlagBits pipelineStage, + VkQueryPool queryPool, + uint32_t query) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdWriteTimestamp(commandBuffer, pipelineStage, + queryPool, query); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdWriteTimestamp(&cmd->cs, 0, commandBuffer, pipelineStage, + queryPool, query); +} + +void +vn_CmdCopyQueryPoolResults(VkCommandBuffer commandBuffer, + VkQueryPool queryPool, + uint32_t firstQuery, + uint32_t queryCount, + VkBuffer dstBuffer, + VkDeviceSize dstOffset, + VkDeviceSize stride, + VkQueryResultFlags flags) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdCopyQueryPoolResults( + commandBuffer, queryPool, firstQuery, queryCount, dstBuffer, dstOffset, + stride, flags); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdCopyQueryPoolResults(&cmd->cs, 0, commandBuffer, queryPool, + firstQuery, queryCount, dstBuffer, + dstOffset, stride, flags); +} + +void +vn_CmdPushConstants(VkCommandBuffer commandBuffer, + VkPipelineLayout layout, + VkShaderStageFlags stageFlags, + uint32_t offset, + uint32_t size, + const void *pValues) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdPushConstants(commandBuffer, layout, stageFlags, + offset, size, pValues); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdPushConstants(&cmd->cs, 0, commandBuffer, layout, + stageFlags, offset, size, pValues); +} + +void +vn_CmdBeginRenderPass(VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo *pRenderPassBegin, + VkSubpassContents contents) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdBeginRenderPass(commandBuffer, pRenderPassBegin, + contents); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdBeginRenderPass(&cmd->cs, 0, commandBuffer, + pRenderPassBegin, contents); +} + +void +vn_CmdNextSubpass(VkCommandBuffer commandBuffer, VkSubpassContents contents) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdNextSubpass(commandBuffer, contents); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdNextSubpass(&cmd->cs, 0, commandBuffer, contents); +} + +void +vn_CmdEndRenderPass(VkCommandBuffer commandBuffer) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdEndRenderPass(commandBuffer); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdEndRenderPass(&cmd->cs, 0, commandBuffer); +} + +void +vn_CmdBeginRenderPass2(VkCommandBuffer commandBuffer, + const VkRenderPassBeginInfo *pRenderPassBegin, + const VkSubpassBeginInfo *pSubpassBeginInfo) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdBeginRenderPass2(commandBuffer, pRenderPassBegin, + pSubpassBeginInfo); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdBeginRenderPass2(&cmd->cs, 0, commandBuffer, + pRenderPassBegin, pSubpassBeginInfo); +} + +void +vn_CmdNextSubpass2(VkCommandBuffer commandBuffer, + const VkSubpassBeginInfo *pSubpassBeginInfo, + const VkSubpassEndInfo *pSubpassEndInfo) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdNextSubpass2(commandBuffer, pSubpassBeginInfo, + pSubpassEndInfo); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdNextSubpass2(&cmd->cs, 0, commandBuffer, pSubpassBeginInfo, + pSubpassEndInfo); +} + +void +vn_CmdEndRenderPass2(VkCommandBuffer commandBuffer, + const VkSubpassEndInfo *pSubpassEndInfo) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdEndRenderPass2(commandBuffer, pSubpassEndInfo); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdEndRenderPass2(&cmd->cs, 0, commandBuffer, pSubpassEndInfo); +} + +void +vn_CmdExecuteCommands(VkCommandBuffer commandBuffer, + uint32_t commandBufferCount, + const VkCommandBuffer *pCommandBuffers) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdExecuteCommands( + commandBuffer, commandBufferCount, pCommandBuffers); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdExecuteCommands(&cmd->cs, 0, commandBuffer, + commandBufferCount, pCommandBuffers); +} + +void +vn_CmdSetDeviceMask(VkCommandBuffer commandBuffer, uint32_t deviceMask) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdSetDeviceMask(commandBuffer, deviceMask); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdSetDeviceMask(&cmd->cs, 0, commandBuffer, deviceMask); +} + +void +vn_CmdDispatchBase(VkCommandBuffer commandBuffer, + uint32_t baseGroupX, + uint32_t baseGroupY, + uint32_t baseGroupZ, + uint32_t groupCountX, + uint32_t groupCountY, + uint32_t groupCountZ) +{ + struct vn_command_buffer *cmd = + vn_command_buffer_from_handle(commandBuffer); + size_t cmd_size; + + cmd_size = vn_sizeof_vkCmdDispatchBase(commandBuffer, baseGroupX, + baseGroupY, baseGroupZ, groupCountX, + groupCountY, groupCountZ); + if (!vn_cs_encoder_reserve(&cmd->cs, cmd_size)) + return; + + vn_encode_vkCmdDispatchBase(&cmd->cs, 0, commandBuffer, baseGroupX, + baseGroupY, baseGroupZ, groupCountX, + groupCountY, groupCountZ); +} diff --git a/src/virtio/vulkan/vn_device.h b/src/virtio/vulkan/vn_device.h index d7a24441b54..a0037d95da9 100644 --- a/src/virtio/vulkan/vn_device.h +++ b/src/virtio/vulkan/vn_device.h @@ -381,10 +381,33 @@ VK_DEFINE_NONDISP_HANDLE_CASTS(vn_pipeline, VkPipeline, VK_OBJECT_TYPE_PIPELINE) +struct vn_command_pool { + struct vn_object_base base; + + VkAllocationCallbacks allocator; + struct list_head command_buffers; +}; +VK_DEFINE_NONDISP_HANDLE_CASTS(vn_command_pool, + base.base, + VkCommandPool, + VK_OBJECT_TYPE_COMMAND_POOL) + +enum vn_command_buffer_state { + VN_COMMAND_BUFFER_STATE_INITIAL, + VN_COMMAND_BUFFER_STATE_RECORDING, + VN_COMMAND_BUFFER_STATE_EXECUTABLE, + VN_COMMAND_BUFFER_STATE_INVALID, +}; + struct vn_command_buffer { struct vn_object_base base; struct vn_device *device; + + struct list_head head; + + enum vn_command_buffer_state state; + struct vn_cs_encoder cs; }; VK_DEFINE_HANDLE_CASTS(vn_command_buffer, base.base,