From 4233c7767e4805dfa368ad67fd6a09577730932e Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Sun, 20 Dec 2020 01:29:15 -0800 Subject: [PATCH] draw functions --- include/Refresh.h | 75 ++++++++------- src/Refresh.c | 6 ++ src/Refresh_Driver.h | 27 +++--- src/Refresh_Driver_Vulkan.c | 179 ++++++++++++++++++++++++++++++++---- 4 files changed, 224 insertions(+), 63 deletions(-) diff --git a/include/Refresh.h b/include/Refresh.h index 3bd407f..2f08df5 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -628,43 +628,22 @@ REFRESHAPI void REFRESH_Clear( int32_t stencil ); -/* Draws data from vertex/index buffers. - * - * primitiveType: The primitive topology of the vertex data. - * baseVertex: The starting offset to read from the vertex buffer. - * minVertexIndex: The lowest index value expected from the index buffer. - * numVertices: The highest offset expected from the index buffer. - * startIndex: The starting offset to read from the index buffer. - * primitiveCount: The number of primitives to draw. - * indices: The index buffer to bind for this draw call. - * indexElementSize: The size of the index type for this index buffer. - */ -REFRESHAPI void REFRESH_DrawIndexedPrimitives( - REFRESH_Device *device, - REFRESH_PrimitiveType primitiveType, - uint32_t baseVertex, - uint32_t minVertexIndex, - uint32_t numVertices, - uint32_t startIndex, - uint32_t primitiveCount, - REFRESH_Buffer *indices, - REFRESH_IndexElementSize indexElementSize -); - /* Draws data from vertex/index buffers with instancing enabled. * - * primitiveType: The primitive topology of the vertex data. - * baseVertex: The starting offset to read from the vertex buffer. - * minVertexIndex: The lowest index value expected from the index buffer. - * numVertices: The highest offset expected from the index 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. - * indices: The index buffer to bind for this draw call. + * graphicsPipeline: The graphics pipeline through which to draw. + * primitiveType: The primitive topology of the vertex data. + * baseVertex: The starting offset to read from the vertex buffer. + * minVertexIndex: The lowest index value expected from the index buffer. + * numVertices: The highest offset expected from the index 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. + * indices: The index buffer to bind for this draw call. * indexElementSize: The size of the index type for this index buffer. */ REFRESHAPI void REFRESH_DrawInstancedPrimitives( REFRESH_Device *device, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t baseVertex, uint32_t minVertexIndex, @@ -676,13 +655,41 @@ REFRESHAPI void REFRESH_DrawInstancedPrimitives( REFRESH_IndexElementSize indexElementSize ); +/* Draws data from vertex/index buffers. + * + * graphicsPipeline: The graphics pipeline through which to draw. + * primitiveType: The primitive topology of the vertex data. + * baseVertex: The starting offset to read from the vertex buffer. + * minVertexIndex: The lowest index value expected from the index buffer. + * numVertices: The highest offset expected from the index buffer. + * startIndex: The starting offset to read from the index buffer. + * primitiveCount: The number of primitives to draw. + * indices: The index buffer to bind for this draw call. + * indexElementSize: The size of the index type for this index buffer. + */ +REFRESHAPI void REFRESH_DrawIndexedPrimitives( + REFRESH_Device *device, + REFRESH_GraphicsPipeline *graphicsPipeline, + REFRESH_PrimitiveType primitiveType, + uint32_t baseVertex, + uint32_t minVertexIndex, + uint32_t numVertices, + uint32_t startIndex, + uint32_t primitiveCount, + REFRESH_Buffer *indices, + REFRESH_IndexElementSize indexElementSize +); + /* Draws data from vertex buffers. - * primitiveType: The primitive topology of the vertex data. - * vertexStart: The starting offset to read from the vertex buffer. - * primitiveCount: The number of primitives to draw. + * + * graphicsPipeline: The graphics pipeline through which to draw. + * primitiveType: The primitive topology of the vertex data. + * vertexStart: The starting offset to read from the vertex buffer. + * primitiveCount: The number of primitives to draw. */ REFRESHAPI void REFRESH_DrawPrimitives( REFRESH_Device *device, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t vertexStart, uint32_t primitiveCount diff --git a/src/Refresh.c b/src/Refresh.c index 4bc53c9..77736b8 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -161,6 +161,7 @@ void REFRESH_Clear( void REFRESH_DrawIndexedPrimitives( REFRESH_Device *device, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t baseVertex, uint32_t minVertexIndex, @@ -173,6 +174,7 @@ void REFRESH_DrawIndexedPrimitives( NULL_RETURN(device); device->DrawIndexedPrimitives( device->driverData, + graphicsPipeline, primitiveType, baseVertex, minVertexIndex, @@ -186,6 +188,7 @@ void REFRESH_DrawIndexedPrimitives( void REFRESH_DrawInstancedPrimitives( REFRESH_Device *device, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t baseVertex, uint32_t minVertexIndex, @@ -199,6 +202,7 @@ void REFRESH_DrawInstancedPrimitives( NULL_RETURN(device); device->DrawInstancedPrimitives( device->driverData, + graphicsPipeline, primitiveType, baseVertex, minVertexIndex, @@ -213,6 +217,7 @@ void REFRESH_DrawInstancedPrimitives( void REFRESH_DrawPrimitives( REFRESH_Device *device, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t vertexStart, uint32_t primitiveCount @@ -220,6 +225,7 @@ void REFRESH_DrawPrimitives( NULL_RETURN(device); device->DrawPrimitives( device->driverData, + graphicsPipeline, primitiveType, vertexStart, primitiveCount diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index a9f3e5d..8cd310b 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -177,19 +177,9 @@ struct REFRESH_Device int32_t stencil ); - void (*DrawIndexedPrimitives)( - REFRESH_Renderer *driverData, - REFRESH_PrimitiveType primitiveType, - uint32_t baseVertex, - uint32_t minVertexIndex, - uint32_t numVertices, - uint32_t startIndex, - uint32_t primitiveCount, - REFRESH_Buffer *indices, - REFRESH_IndexElementSize indexElementSize - ); void (*DrawInstancedPrimitives)( REFRESH_Renderer *driverData, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t baseVertex, uint32_t minVertexIndex, @@ -200,8 +190,23 @@ struct REFRESH_Device REFRESH_Buffer *indices, REFRESH_IndexElementSize indexElementSize ); + + void (*DrawIndexedPrimitives)( + REFRESH_Renderer *driverData, + REFRESH_GraphicsPipeline *graphicsPipeline, + REFRESH_PrimitiveType primitiveType, + uint32_t baseVertex, + uint32_t minVertexIndex, + uint32_t numVertices, + uint32_t startIndex, + uint32_t primitiveCount, + REFRESH_Buffer *indices, + REFRESH_IndexElementSize indexElementSize + ); + void (*DrawPrimitives)( REFRESH_Renderer *driverData, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t vertexStart, uint32_t primitiveCount diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index ba51d36..be4183d 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -683,8 +683,11 @@ typedef struct VulkanRenderer VkDescriptorPool *descriptorPools; uint32_t descriptorPoolCount; + VkDescriptorPool UBODescriptorPool; VkDescriptorSetLayout vertexParamLayout; VkDescriptorSetLayout fragmentParamLayout; + VkDescriptorSet vertexUBODescriptorSet; + VkDescriptorSet fragmentUBODescriptorSet; VulkanBuffer *textureStagingBuffer; VulkanBuffer *vertexUBO; @@ -750,11 +753,16 @@ typedef struct VulkanDepthStencilTarget typedef struct VulkanGraphicsPipeline { VkPipeline pipeline; + VkPipelineLayout layout; VkDescriptorPool descriptorPool; VkDescriptorSetLayout vertexSamplerLayout; uint32_t vertexSamplerBindingCount; VkDescriptorSetLayout fragmentSamplerLayout; uint32_t fragmentSamplerBindingCount; + VkDescriptorSet vertexSamplerDescriptorSet; /* updated by SetVertexSamplers */ + VkDescriptorSet fragmentSamplerDescriptorSet; /* updated by SetFragmentSamplers */ + uint32_t vertexUBOOffset; /* updated by PushVertexShaderParams */ + uint32_t fragmentUBOOffset; /* updated by PushFragmentShaderParams */ } VulkanGraphicsPipeline; /* Forward declarations */ @@ -1707,22 +1715,9 @@ static void VULKAN_Clear( SDL_assert(0); } -static void VULKAN_DrawIndexedPrimitives( - REFRESH_Renderer *driverData, - REFRESH_PrimitiveType primitiveType, - uint32_t baseVertex, - uint32_t minVertexIndex, - uint32_t numVertices, - uint32_t startIndex, - uint32_t primitiveCount, - REFRESH_Buffer *indices, - REFRESH_IndexElementSize indexElementSize -) { - SDL_assert(0); -} - static void VULKAN_DrawInstancedPrimitives( REFRESH_Renderer *driverData, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t baseVertex, uint32_t minVertexIndex, @@ -1733,16 +1728,108 @@ static void VULKAN_DrawInstancedPrimitives( REFRESH_Buffer *indices, REFRESH_IndexElementSize indexElementSize ) { - SDL_assert(0); + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanGraphicsPipeline *pipeline = (VulkanGraphicsPipeline*) graphicsPipeline; + VkDescriptorSet descriptorSets[4]; + uint32_t dynamicOffsets[2]; + + descriptorSets[0] = pipeline->vertexSamplerDescriptorSet; + descriptorSets[1] = pipeline->fragmentSamplerDescriptorSet; + descriptorSets[2] = renderer->vertexUBODescriptorSet; + descriptorSets[3] = renderer->fragmentUBODescriptorSet; + + dynamicOffsets[0] = pipeline->vertexUBOOffset; + dynamicOffsets[1] = pipeline->fragmentUBOOffset; + + RECORD_CMD(renderer->vkCmdBindDescriptorSets( + renderer->currentCommandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline->layout, + 0, + 4, + descriptorSets, + 2, + dynamicOffsets + )); + + RECORD_CMD(renderer->vkCmdDrawIndexed( + renderer->currentCommandBuffer, + PrimitiveVerts(primitiveType, primitiveCount), + instanceCount, + startIndex, + baseVertex, + 0 + )); +} + +static void VULKAN_DrawIndexedPrimitives( + REFRESH_Renderer *driverData, + REFRESH_GraphicsPipeline *graphicsPipeline, + REFRESH_PrimitiveType primitiveType, + uint32_t baseVertex, + uint32_t minVertexIndex, + uint32_t numVertices, + uint32_t startIndex, + uint32_t primitiveCount, + REFRESH_Buffer *indices, + REFRESH_IndexElementSize indexElementSize +) { + VULKAN_DrawInstancedPrimitives( + driverData, + graphicsPipeline, + primitiveType, + baseVertex, + minVertexIndex, + numVertices, + startIndex, + primitiveCount, + 1, + indices, + indexElementSize + ); } static void VULKAN_DrawPrimitives( REFRESH_Renderer *driverData, + REFRESH_GraphicsPipeline *graphicsPipeline, REFRESH_PrimitiveType primitiveType, uint32_t vertexStart, uint32_t primitiveCount ) { - SDL_assert(0); + VulkanRenderer *renderer = (VulkanRenderer*) driverData; + VulkanGraphicsPipeline *pipeline = (VulkanGraphicsPipeline*) graphicsPipeline; + VkDescriptorSet descriptorSets[4]; + uint32_t dynamicOffsets[2]; + + descriptorSets[0] = pipeline->vertexSamplerDescriptorSet; + descriptorSets[1] = pipeline->fragmentSamplerDescriptorSet; + descriptorSets[2] = renderer->vertexUBODescriptorSet; + descriptorSets[3] = renderer->fragmentUBODescriptorSet; + + dynamicOffsets[0] = pipeline->vertexUBOOffset; + dynamicOffsets[1] = pipeline->fragmentUBOOffset; + + RECORD_CMD(renderer->vkCmdBindDescriptorSets( + renderer->currentCommandBuffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + pipeline->layout, + 0, + 4, + descriptorSets, + 2, + dynamicOffsets + )); + + RECORD_CMD(renderer->vkCmdDraw( + renderer->currentCommandBuffer, + PrimitiveVerts( + primitiveType, + primitiveCount + ), + 1, + vertexStart, + 0 + )); } static REFRESH_RenderPass* VULKAN_CreateRenderPass( @@ -1938,7 +2025,7 @@ static REFRESH_RenderPass* VULKAN_CreateRenderPass( return (REFRESH_RenderPass*) renderPass; } -static uint8_t VULKAN_INTERNAL_CreateDescriptorPool( +static uint8_t VULKAN_INTERNAL_CreateSamplerDescriptorPool( VulkanRenderer *renderer, REFRESH_PipelineLayoutCreateInfo *pipelineLayoutCreateInfo, VkDescriptorPool *pDescriptorPool @@ -2367,6 +2454,7 @@ static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( graphicsPipeline->fragmentSamplerLayout = setLayouts[1]; graphicsPipeline->vertexSamplerBindingCount = pipelineCreateInfo->pipelineLayoutCreateInfo.vertexSamplerBindingCount; graphicsPipeline->fragmentSamplerBindingCount = pipelineCreateInfo->pipelineLayoutCreateInfo.fragmentSamplerBindingCount; + graphicsPipeline->layout = pipelineLayout; /* Pipeline */ @@ -2422,7 +2510,7 @@ static REFRESH_GraphicsPipeline* VULKAN_CreateGraphicsPipeline( SDL_stack_free(vertexSamplerLayoutBindings); SDL_stack_free(fragmentSamplerLayoutBindings); - if (!VULKAN_INTERNAL_CreateDescriptorPool( + if (!VULKAN_INTERNAL_CreateSamplerDescriptorPool( renderer, &pipelineCreateInfo->pipelineLayoutCreateInfo, &graphicsPipeline->descriptorPool @@ -3686,6 +3774,8 @@ static void VULKAN_SetVertexSamplers( NULL ); + graphicsPipeline->vertexSamplerDescriptorSet = descriptorSet; + SDL_stack_free(writeDescriptorSets); SDL_stack_free(descriptorImageInfos); } @@ -3751,6 +3841,8 @@ static void VULKAN_SetFragmentSamplers( NULL ); + graphicsPipeline->fragmentSamplerDescriptorSet = descriptorSet; + SDL_stack_free(writeDescriptorSets); SDL_stack_free(descriptorImageInfos); } @@ -5003,6 +5095,12 @@ static REFRESH_Device* VULKAN_CreateDevice( VkDescriptorSetLayoutBinding vertexParamLayoutBinding; VkDescriptorSetLayoutBinding fragmentParamLayoutBinding; + /* Variables: UBO Creation */ + VkDescriptorPoolCreateInfo uboDescriptorPoolInfo; + VkDescriptorPoolSize uboPoolSize; + VkDescriptorSetAllocateInfo vertexUBODescriptorAllocateInfo; + VkDescriptorSetAllocateInfo fragmentUBODescriptorAllocateInfo; + result = (REFRESH_Device*) SDL_malloc(sizeof(REFRESH_Device)); ASSIGN_DRIVER(VULKAN) @@ -5253,6 +5351,51 @@ static REFRESH_Device* VULKAN_CreateDevice( return NULL; } + /* UBO Descriptors */ + + uboPoolSize.descriptorCount = 2; + uboPoolSize.type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC; + + uboDescriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + uboDescriptorPoolInfo.pNext = NULL; + uboDescriptorPoolInfo.flags = 0; + uboDescriptorPoolInfo.maxSets = 2; + uboDescriptorPoolInfo.poolSizeCount = 1; + uboDescriptorPoolInfo.pPoolSizes = &uboPoolSize; + + renderer->vkCreateDescriptorPool( + renderer->logicalDevice, + &uboDescriptorPoolInfo, + NULL, + &renderer->UBODescriptorPool + ); + + vertexUBODescriptorAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + vertexUBODescriptorAllocateInfo.pNext = NULL; + vertexUBODescriptorAllocateInfo.descriptorPool = renderer->UBODescriptorPool; + vertexUBODescriptorAllocateInfo.descriptorSetCount = 1; + vertexUBODescriptorAllocateInfo.pSetLayouts = &renderer->vertexParamLayout; + + renderer->vkAllocateDescriptorSets( + renderer->logicalDevice, + &vertexUBODescriptorAllocateInfo, + &renderer->vertexUBODescriptorSet + ); + + fragmentUBODescriptorAllocateInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; + fragmentUBODescriptorAllocateInfo.pNext = NULL; + fragmentUBODescriptorAllocateInfo.descriptorPool = renderer->UBODescriptorPool; + fragmentUBODescriptorAllocateInfo.descriptorSetCount = 1; + fragmentUBODescriptorAllocateInfo.pSetLayouts = &renderer->fragmentParamLayout; + + renderer->vkAllocateDescriptorSets( + renderer->logicalDevice, + &fragmentUBODescriptorAllocateInfo, + &renderer->fragmentUBODescriptorSet + ); + + /* UBO Data */ + renderer->vertexUBO = (VulkanBuffer*) SDL_malloc(sizeof(VulkanBuffer)); if (!VULKAN_INTERNAL_CreateBuffer(