diff --git a/include/Refresh.h b/include/Refresh.h index 308ccfe..e8d4ea5 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -148,7 +148,8 @@ typedef enum Refresh_TextureUsageFlagBits { REFRESH_TEXTUREUSAGE_SAMPLER_BIT = 0x00000001, REFRESH_TEXTUREUSAGE_COLOR_TARGET_BIT = 0x00000002, - REFRESH_TEXTUREUSAGE_DEPTH_STENCIL_TARGET_BIT = 0x00000004 + REFRESH_TEXTUREUSAGE_DEPTH_STENCIL_TARGET_BIT = 0x00000004, + REFRESH_TEXTUREUSAGE_COMPUTE_BIT = 0X00000008 } Refresh_TextureUsageFlagBits; typedef uint32_t Refresh_TextureUsageFlags; @@ -176,9 +177,10 @@ typedef enum Refresh_CubeMapFace typedef enum Refresh_BufferUsageFlagBits { - REFRESH_BUFFERUSAGE_VERTEX_BIT = 0x00000001, - REFRESH_BUFFERUSAGE_INDEX_BIT = 0x00000002, - REFRESH_BUFFERUSAGE_COMPUTE_BIT = 0x00000004 + REFRESH_BUFFERUSAGE_VERTEX_BIT = 0x00000001, + REFRESH_BUFFERUSAGE_INDEX_BIT = 0x00000002, + REFRESH_BUFFERUSAGE_COMPUTE_BIT = 0x00000004, + REFRESH_BUFFERUSAGE_INDIRECT_BIT = 0x00000008 } Refresh_BufferUsageFlagBits; typedef uint32_t Refresh_BufferUsageFlags; @@ -601,12 +603,12 @@ REFRESHAPI void Refresh_DestroyDevice(Refresh_Device *device); /* Draws data from vertex/index buffers with instancing enabled. * - * baseVertex: The starting offset to read from the vertex buffer. - * startIndex: The starting offset to read from the index buffer. - * primitiveCount: The number of primitives to draw. - * instanceCount: The number of instances that will be drawn. - * vertexParamOffset: The offset of the vertex shader param data. - * fragmentParamOffset: The offset of the fragment shader param data. + * baseVertex: The starting offset to read from the vertex buffer. + * startIndex: The starting offset to read from the index buffer. + * primitiveCount: The number of primitives to draw. + * instanceCount: The number of instances that will be drawn. + * vertexParamOffset: The offset of the vertex shader param data. + * fragmentParamOffset: The offset of the fragment shader param data. */ REFRESHAPI void Refresh_DrawInstancedPrimitives( Refresh_Device *device, @@ -621,11 +623,11 @@ REFRESHAPI void Refresh_DrawInstancedPrimitives( /* Draws data from vertex/index buffers. * - * baseVertex: The starting offset to read from the vertex buffer. - * startIndex: The starting offset to read from the index buffer. - * primitiveCount: The number of primitives to draw. - * vertexParamOffset: The offset of the vertex shader param data. - * fragmentParamOffset: The offset of the fragment shader param data. + * baseVertex: The starting offset to read from the vertex buffer. + * startIndex: The starting offset to read from the index buffer. + * primitiveCount: The number of primitives to draw. + * vertexParamOffset: The offset of the vertex shader param data. + * fragmentParamOffset: The offset of the fragment shader param data. */ REFRESHAPI void Refresh_DrawIndexedPrimitives( Refresh_Device *device, @@ -639,10 +641,10 @@ REFRESHAPI void Refresh_DrawIndexedPrimitives( /* Draws data from vertex buffers. * - * vertexStart: The starting offset to read from the vertex buffer. - * primitiveCount: The number of primitives to draw. - * vertexParamOffset: The offset of the vertex shader param data. - * fragmentParamOffset: The offset of the fragment shader param data. + * vertexStart: The starting offset to read from the vertex buffer. + * primitiveCount: The number of primitives to draw. + * vertexParamOffset: The offset of the vertex shader param data. + * fragmentParamOffset: The offset of the fragment shader param data. */ REFRESHAPI void Refresh_DrawPrimitives( Refresh_Device *device, @@ -653,6 +655,26 @@ REFRESHAPI void Refresh_DrawPrimitives( uint32_t fragmentParamOffset ); +/* Similar to Refresh_DrawPrimitives, but draw parameters are set from a buffer. + * + * buffer: A buffer containing draw parameters. + * offsetInBytes: The offset to start reading from the draw buffer. + * drawCount: The number of draw parameter sets that should be read from the draw buffer. + * stride: The byte stride between sets of draw parameters. + * vertexParamOffset: The offset of the vertex shader param data. + * fragmentParamOffset: The offset of the fragment shader param data. + */ +REFRESHAPI void Refresh_DrawPrimitivesIndirect( + Refresh_Device *device, + Refresh_CommandBuffer *commandBuffer, + Refresh_Buffer *buffer, + uint32_t offsetInBytes, + uint32_t drawCount, + uint32_t stride, + uint32_t vertexParamOffset, + uint32_t fragmentParamOffset +); + /* Dispatches work compute items. * * groupCountX: Number of local workgroups to dispatch in the X dimension. diff --git a/src/Refresh.c b/src/Refresh.c index 3261f4a..ee24022 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -215,6 +215,29 @@ void Refresh_DrawPrimitives( ); } +void Refresh_DrawPrimitivesIndirect( + Refresh_Device *device, + Refresh_CommandBuffer *commandBuffer, + Refresh_Buffer *buffer, + uint32_t offsetInBytes, + uint32_t drawCount, + uint32_t stride, + uint32_t vertexParamOffset, + uint32_t fragmentParamOffset +) { + NULL_RETURN(device); + device->DrawPrimitivesIndirect( + device->driverData, + commandBuffer, + buffer, + offsetInBytes, + drawCount, + stride, + vertexParamOffset, + fragmentParamOffset + ); +} + void Refresh_DispatchCompute( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index a98e60a..aca69a8 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -207,6 +207,17 @@ struct Refresh_Device uint32_t fragmentParamOffset ); + void (*DrawPrimitivesIndirect)( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_Buffer *buffer, + uint32_t offsetInBytes, + uint32_t drawCount, + uint32_t stride, + uint32_t vertexParamOffset, + uint32_t fragmentParamOffset + ); + void (*DispatchCompute)( Refresh_Renderer *device, Refresh_CommandBuffer *commandBuffer, @@ -481,6 +492,7 @@ struct Refresh_Device ASSIGN_DRIVER_FUNC(DrawIndexedPrimitives, name) \ ASSIGN_DRIVER_FUNC(DrawInstancedPrimitives, name) \ ASSIGN_DRIVER_FUNC(DrawPrimitives, name) \ + ASSIGN_DRIVER_FUNC(DrawPrimitivesIndirect, name) \ ASSIGN_DRIVER_FUNC(DispatchCompute, name) \ ASSIGN_DRIVER_FUNC(CreateComputePipeline, name) \ ASSIGN_DRIVER_FUNC(CreateGraphicsPipeline, name) \ diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 2a0d075..393160b 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -134,6 +134,7 @@ typedef enum VulkanResourceAccessType RESOURCE_ACCESS_NONE, /* For initialization */ RESOURCE_ACCESS_INDEX_BUFFER, RESOURCE_ACCESS_VERTEX_BUFFER, + RESOURCE_ACCESS_INDIRECT_BUFFER, RESOURCE_ACCESS_VERTEX_SHADER_READ_UNIFORM_BUFFER, RESOURCE_ACCESS_VERTEX_SHADER_READ_SAMPLED_IMAGE, RESOURCE_ACCESS_FRAGMENT_SHADER_READ_UNIFORM_BUFFER, @@ -162,7 +163,9 @@ typedef enum VulkanResourceAccessType /* Read-Writes */ RESOURCE_ACCESS_COLOR_ATTACHMENT_READ_WRITE, RESOURCE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_WRITE, - RESOURCE_ACCESS_MEMORY_TRANSFER_READ_WRITE, + RESOURCE_ACCESS_COMPUTE_SHADER_STORAGE_IMAGE_READ_WRITE, + RESOURCE_ACCESS_COMPUTE_SHADER_BUFFER_READ_WRITE, + RESOURCE_ACCESS_TRANSFER_READ_WRITE, RESOURCE_ACCESS_GENERAL, /* Count */ @@ -450,7 +453,14 @@ static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] = /* RESOURCE_ACCESS_VERTEX_BUFFER */ { VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, - VK_ACCESS_INDEX_READ_BIT, + VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT, + VK_IMAGE_LAYOUT_UNDEFINED + }, + + /* RESOURCE_ACCESS_INDIRECT_BUFFER */ + { + VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT, + VK_ACCESS_INDIRECT_COMMAND_READ_BIT, VK_IMAGE_LAYOUT_UNDEFINED }, @@ -621,7 +631,21 @@ static const VulkanResourceAccessInfo AccessMap[RESOURCE_ACCESS_TYPES_COUNT] = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL }, - /* RESOURCE_ACCESS_MEMORY_TRANSFER_READ_WRITE */ + /* RESOURCE_ACCESS_COMPUTE_SHADER_STORAGE_IMAGE_READ_WRITE */ + { + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + VK_IMAGE_LAYOUT_GENERAL + }, + + /* RESOURCE_ACCESS_COMPUTE_SHADER_BUFFER_READ_WRITE */ + { + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + VK_IMAGE_LAYOUT_UNDEFINED + }, + + /* RESOURCE_ACCESS_TRANSFER_READ_WRITE */ { VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT | VK_ACCESS_TRANSFER_WRITE_BIT, @@ -736,6 +760,8 @@ typedef struct VulkanTexture VulkanResourceAccessType resourceAccessType; VkImageUsageFlags usageFlags; + VkImageAspectFlags aspectFlags; + SDL_atomic_t referenceCount; } VulkanTexture; @@ -1505,6 +1531,18 @@ typedef struct VulkanCommandBuffer uint32_t boundDescriptorSetDataCount; uint32_t boundDescriptorSetDataCapacity; + /* Keep track of compute resources for memory barriers */ + + VulkanBuffer **boundComputeBuffers; + uint32_t boundComputeBufferCount; + uint32_t boundComputeBufferCapacity; + + VulkanTexture **boundComputeTextures; + uint32_t boundComputeTextureCount; + uint32_t boundComputeTextureCapacity; + + /* Viewport/scissor state */ + VkViewport currentViewport; VkRect2D currentScissor; @@ -4524,6 +4562,7 @@ static uint8_t VULKAN_INTERNAL_CreateSwapchain( swapchainData->textures[i].usageFlags = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; + swapchainData->textures[i].aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT; swapchainData->textures[i].resourceAccessType = RESOURCE_ACCESS_NONE; } @@ -4999,6 +5038,52 @@ static void VULKAN_DrawPrimitives( ); } +static void VULKAN_DrawPrimitivesIndirect( + Refresh_Renderer *driverData, + Refresh_CommandBuffer *commandBuffer, + Refresh_Buffer *buffer, + uint32_t offsetInBytes, + uint32_t drawCount, + uint32_t stride, + uint32_t vertexParamOffset, + uint32_t fragmentParamOffset +) { + VulkanRenderer* renderer = (VulkanRenderer*) driverData; + VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; + VulkanBuffer *vulkanBuffer = (VulkanBuffer*) buffer; + VkDescriptorSet descriptorSets[4]; + uint32_t dynamicOffsets[2]; + + descriptorSets[0] = vulkanCommandBuffer->vertexSamplerDescriptorSet; + descriptorSets[1] = vulkanCommandBuffer->fragmentSamplerDescriptorSet; + descriptorSets[2] = vulkanCommandBuffer->vertexUniformBuffer->descriptorSet; + descriptorSets[3] = vulkanCommandBuffer->fragmentUniformBuffer->descriptorSet; + + dynamicOffsets[0] = vertexParamOffset; + dynamicOffsets[1] = fragmentParamOffset; + + renderer->vkCmdBindDescriptorSets( + vulkanCommandBuffer->commandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + vulkanCommandBuffer->currentGraphicsPipeline->pipelineLayout->pipelineLayout, + 0, + 4, + descriptorSets, + 2, + dynamicOffsets + ); + + renderer->vkCmdDrawIndirect( + vulkanCommandBuffer->commandBuffer, + vulkanBuffer->buffer, + offsetInBytes, + drawCount, + stride + ); + + VULKAN_INTERNAL_TrackBuffer(renderer, vulkanCommandBuffer, vulkanBuffer); +} + static void VULKAN_DispatchCompute( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, @@ -5010,8 +5095,11 @@ static void VULKAN_DispatchCompute( VulkanRenderer* renderer = (VulkanRenderer*) driverData; VulkanCommandBuffer *vulkanCommandBuffer = (VulkanCommandBuffer*) commandBuffer; VulkanComputePipeline *computePipeline = vulkanCommandBuffer->currentComputePipeline; - VkDescriptorSet descriptorSets[3]; + VulkanResourceAccessType resourceAccessType = RESOURCE_ACCESS_NONE; + VulkanBuffer *currentComputeBuffer; + VulkanTexture *currentComputeTexture; + uint32_t i; descriptorSets[0] = vulkanCommandBuffer->bufferDescriptorSet; descriptorSets[1] = vulkanCommandBuffer->imageDescriptorSet; @@ -5034,6 +5122,64 @@ static void VULKAN_DispatchCompute( groupCountY, groupCountZ ); + + /* Re-transition buffers after dispatch */ + for (i = 0; i < vulkanCommandBuffer->boundComputeBufferCount; i += 1) + { + currentComputeBuffer = vulkanCommandBuffer->boundComputeBuffers[i]; + + if (currentComputeBuffer->usage & VK_BUFFER_USAGE_VERTEX_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_VERTEX_BUFFER; + } + else if (currentComputeBuffer->usage & VK_BUFFER_USAGE_INDEX_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_INDEX_BUFFER; + } + else if (currentComputeBuffer->usage & VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT) + { + resourceAccessType = RESOURCE_ACCESS_INDIRECT_BUFFER; + } + + if (resourceAccessType != RESOURCE_ACCESS_NONE) + { + VULKAN_INTERNAL_BufferMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + resourceAccessType, + currentComputeBuffer + ); + } + } + + vulkanCommandBuffer->boundComputeBufferCount = 0; + + /* Re-transition sampler images after dispatch */ + for (i = 0; i < vulkanCommandBuffer->boundComputeTextureCount; i += 1) + { + currentComputeTexture = vulkanCommandBuffer->boundComputeTextures[i]; + + if (currentComputeTexture->usageFlags & VK_IMAGE_USAGE_SAMPLED_BIT) + { + resourceAccessType = RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE; + + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + resourceAccessType, + currentComputeTexture->aspectFlags, + 0, + currentComputeTexture->layerCount, + 0, + currentComputeTexture->levelCount, + 0, + currentComputeTexture->image, + ¤tComputeTexture->resourceAccessType + ); + } + } + + vulkanCommandBuffer->boundComputeTextureCount = 0; } static VulkanTexture* VULKAN_INTERNAL_CreateTexture( @@ -5220,6 +5366,7 @@ static VulkanTexture* VULKAN_INTERNAL_CreateTexture( texture->layerCount = layerCount; texture->resourceAccessType = RESOURCE_ACCESS_NONE; texture->usageFlags = imageUsageFlags; + texture->aspectFlags = aspectMask; SDL_AtomicSet(&texture->referenceCount, 0); @@ -5258,7 +5405,6 @@ static VulkanRenderTarget* VULKAN_INTERNAL_CreateRenderTarget( aspectFlags |= VK_IMAGE_ASPECT_COLOR_BIT; } - /* create resolve target for multisample */ if (multisampleCount > REFRESH_SAMPLECOUNT_1) { @@ -6426,6 +6572,11 @@ static Refresh_Texture* VULKAN_CreateTexture( imageUsageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; } + if (textureCreateInfo->usageFlags & REFRESH_TEXTUREUSAGE_COMPUTE_BIT) + { + imageUsageFlags |= VK_IMAGE_USAGE_STORAGE_BIT; + } + if (IsDepthFormat(format)) { imageAspectFlags = VK_IMAGE_ASPECT_DEPTH_BIT; @@ -6461,29 +6612,43 @@ static Refresh_Buffer* VULKAN_CreateBuffer( uint32_t sizeInBytes ) { VulkanBuffer* buffer; - + VulkanResourceAccessType resourceAccessType; VkBufferUsageFlags vulkanUsageFlags = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT; + if (usageFlags == 0) + { + resourceAccessType = RESOURCE_ACCESS_TRANSFER_READ_WRITE; + } + if (usageFlags & REFRESH_BUFFERUSAGE_VERTEX_BIT) { vulkanUsageFlags |= VK_BUFFER_USAGE_VERTEX_BUFFER_BIT; + resourceAccessType = RESOURCE_ACCESS_VERTEX_BUFFER; } if (usageFlags & REFRESH_BUFFERUSAGE_INDEX_BIT) { vulkanUsageFlags |= VK_BUFFER_USAGE_INDEX_BUFFER_BIT; + resourceAccessType = RESOURCE_ACCESS_INDEX_BUFFER; } if (usageFlags & REFRESH_BUFFERUSAGE_COMPUTE_BIT) { vulkanUsageFlags |= VK_BUFFER_USAGE_STORAGE_BUFFER_BIT; + resourceAccessType = RESOURCE_ACCESS_COMPUTE_SHADER_BUFFER_READ_WRITE; + } + + if (usageFlags & REFRESH_BUFFERUSAGE_INDIRECT_BIT) + { + vulkanUsageFlags |= VK_BUFFER_USAGE_INDIRECT_BUFFER_BIT; + resourceAccessType = RESOURCE_ACCESS_INDIRECT_BUFFER; } buffer = VULKAN_INTERNAL_CreateBuffer( (VulkanRenderer*)driverData, sizeInBytes, - RESOURCE_ACCESS_MEMORY_TRANSFER_READ_WRITE, + resourceAccessType, vulkanUsageFlags ); @@ -6565,7 +6730,7 @@ static VulkanTransferBuffer* VULKAN_INTERNAL_AcquireTransferBuffer( transferBuffer->buffer = VULKAN_INTERNAL_CreateBuffer( renderer, size, - RESOURCE_ACCESS_MEMORY_TRANSFER_READ_WRITE, + RESOURCE_ACCESS_TRANSFER_READ_WRITE, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT ); @@ -8355,7 +8520,23 @@ static void VULKAN_EndRenderPass( renderer, vulkanCommandBuffer->commandBuffer, RESOURCE_ACCESS_ANY_SHADER_READ_SAMPLED_IMAGE, - VK_IMAGE_ASPECT_COLOR_BIT, + currentTexture->aspectFlags, + 0, + currentTexture->layerCount, + 0, + currentTexture->levelCount, + 0, + currentTexture->image, + ¤tTexture->resourceAccessType + ); + } + else if (currentTexture->usageFlags & VK_IMAGE_USAGE_STORAGE_BIT) + { + VULKAN_INTERNAL_ImageMemoryBarrier( + renderer, + vulkanCommandBuffer->commandBuffer, + RESOURCE_ACCESS_COMPUTE_SHADER_STORAGE_IMAGE_READ_WRITE, + currentTexture->aspectFlags, 0, currentTexture->layerCount, 0, @@ -8548,8 +8729,6 @@ static void VULKAN_BindComputePipeline( vulkanCommandBuffer->computeUniformBuffer ); } - vulkanCommandBuffer->computeUniformBuffer = NULL; - renderer->vkCmdBindPipeline( vulkanCommandBuffer->commandBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, @@ -8558,7 +8737,11 @@ static void VULKAN_BindComputePipeline( vulkanCommandBuffer->currentComputePipeline = vulkanComputePipeline; - if (vulkanComputePipeline->uniformBlockSize != 0) + if (vulkanComputePipeline->uniformBlockSize == 0) + { + vulkanCommandBuffer->computeUniformBuffer = renderer->dummyComputeUniformBuffer; + } + else { vulkanCommandBuffer->computeUniformBuffer = VULKAN_INTERNAL_AcquireUniformBufferFromPool( renderer, @@ -8599,7 +8782,7 @@ static void VULKAN_BindComputeBuffers( VULKAN_INTERNAL_BufferMemoryBarrier( renderer, vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_COMPUTE_SHADER_READ_OTHER, + RESOURCE_ACCESS_COMPUTE_SHADER_BUFFER_READ_WRITE, currentVulkanBuffer ); @@ -8614,6 +8797,18 @@ static void VULKAN_BindComputeBuffers( NULL, descriptorBufferInfos ); + + if (vulkanCommandBuffer->boundComputeBufferCount == vulkanCommandBuffer->boundComputeBufferCapacity) + { + vulkanCommandBuffer->boundComputeBufferCapacity *= 2; + vulkanCommandBuffer->boundComputeBuffers = SDL_realloc( + vulkanCommandBuffer->boundComputeBuffers, + vulkanCommandBuffer->boundComputeBufferCapacity * sizeof(VulkanBuffer*) + ); + } + + vulkanCommandBuffer->boundComputeBuffers[vulkanCommandBuffer->boundComputeBufferCount] = currentVulkanBuffer; + vulkanCommandBuffer->boundComputeBufferCount += 1; } static void VULKAN_BindComputeTextures( @@ -8639,12 +8834,12 @@ static void VULKAN_BindComputeTextures( currentTexture = (VulkanTexture*) pTextures[i]; descriptorImageInfos[i].imageView = currentTexture->view; descriptorImageInfos[i].sampler = VK_NULL_HANDLE; - descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + descriptorImageInfos[i].imageLayout = VK_IMAGE_LAYOUT_GENERAL; VULKAN_INTERNAL_ImageMemoryBarrier( renderer, vulkanCommandBuffer->commandBuffer, - RESOURCE_ACCESS_COMPUTE_SHADER_READ_SAMPLED_IMAGE_OR_UNIFORM_TEXEL_BUFFER, + RESOURCE_ACCESS_COMPUTE_SHADER_STORAGE_IMAGE_READ_WRITE, VK_IMAGE_ASPECT_COLOR_BIT, 0, currentTexture->layerCount, @@ -8656,6 +8851,18 @@ static void VULKAN_BindComputeTextures( ); VULKAN_INTERNAL_TrackTexture(renderer, vulkanCommandBuffer, currentTexture); + + if (vulkanCommandBuffer->boundComputeTextureCount == vulkanCommandBuffer->boundComputeTextureCapacity) + { + vulkanCommandBuffer->boundComputeTextureCapacity *= 2; + vulkanCommandBuffer->boundComputeTextures = SDL_realloc( + vulkanCommandBuffer->boundComputeTextures, + vulkanCommandBuffer->boundComputeTextureCapacity * sizeof(VulkanTexture *) + ); + } + + vulkanCommandBuffer->boundComputeTextures[i] = currentTexture; + vulkanCommandBuffer->boundComputeTextureCount += 1; } vulkanCommandBuffer->imageDescriptorSet = @@ -8774,6 +8981,20 @@ static void VULKAN_INTERNAL_AllocateCommandBuffers( commandBuffer->boundDescriptorSetDataCapacity * sizeof(DescriptorSetData) ); + /* Bound compute resource tracking */ + + commandBuffer->boundComputeBufferCapacity = 16; + commandBuffer->boundComputeBufferCount = 0; + commandBuffer->boundComputeBuffers = SDL_malloc( + commandBuffer->boundComputeBufferCapacity * sizeof(VulkanBuffer*) + ); + + commandBuffer->boundComputeTextureCapacity = 16; + commandBuffer->boundComputeTextureCount = 0; + commandBuffer->boundComputeTextures = SDL_malloc( + commandBuffer->boundComputeTextureCapacity * sizeof(VulkanTexture*) + ); + /* Resource tracking */ commandBuffer->usedBufferCapacity = 4; diff --git a/src/Refresh_Driver_Vulkan_vkfuncs.h b/src/Refresh_Driver_Vulkan_vkfuncs.h index 14b0ace..69f06ea 100644 --- a/src/Refresh_Driver_Vulkan_vkfuncs.h +++ b/src/Refresh_Driver_Vulkan_vkfuncs.h @@ -92,6 +92,7 @@ VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdCopyImageToBuffer, (VkCommandBuffer co VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDispatch, (VkCommandBuffer commandBuffer, uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDraw, (VkCommandBuffer commandBuffer, uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex, uint32_t firstInstance)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDrawIndexed, (VkCommandBuffer commandBuffer, uint32_t indexCount, uint32_t instanceCount, uint32_t firstIndex, int32_t vertexOffset, uint32_t firstInstance)) +VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdDrawIndirect, (VkCommandBuffer commandBuffer, VkBuffer buffer, VkDeviceSize offset, uint32_t drawCount, uint32_t stride)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdEndRenderPass, (VkCommandBuffer commandBuffer)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdPipelineBarrier, (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)) VULKAN_DEVICE_FUNCTION(BaseVK, void, vkCmdResolveImage, (VkCommandBuffer commandBuffer, VkImage srcImage, VkImageLayout srcImageLayout, VkImage dstImage, VkImageLayout dstImageLayout, uint32_t regionCount, const VkImageResolve *pRegions))