From feb4b5e16bcbc14083e6953a2fca47b4a5151839 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Mon, 21 Dec 2020 12:37:54 -0800 Subject: [PATCH] vertex and index buffers --- include/Refresh.h | 4 +- src/Refresh.c | 4 +- src/Refresh_Driver.h | 2 +- src/Refresh_Driver_Vulkan.c | 78 +++++++++++++++++++++++++++++++++---- 4 files changed, 76 insertions(+), 12 deletions(-) diff --git a/include/Refresh.h b/include/Refresh.h index 791b818..727b786 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -939,7 +939,7 @@ REFRESHAPI void REFRESH_SetTextureDataYUV( * offsetInBytes: The starting offset of the buffer to write into. * data: The client data to write into the buffer. * elementCount: The number of elements from the client buffer to write. - * elementSizeInBytes: The size of each element in the client buffer. + * vertexStride: The size of each element in the client buffer (including padding). */ REFRESHAPI void REFRESH_SetVertexBufferData( REFRESH_Device *device, @@ -947,7 +947,7 @@ REFRESHAPI void REFRESH_SetVertexBufferData( uint32_t offsetInBytes, void* data, uint32_t elementCount, - uint32_t elementSizeInBytes + uint32_t vertexStride ); /* Sets a region of the index buffer with client data. diff --git a/src/Refresh.c b/src/Refresh.c index 3ac253b..96db87d 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -508,7 +508,7 @@ void REFRESH_SetVertexBufferData( uint32_t offsetInBytes, void* data, uint32_t elementCount, - uint32_t elementSizeInBytes + uint32_t vertexStride ) { NULL_RETURN(device); device->SetVertexBufferData( @@ -517,7 +517,7 @@ void REFRESH_SetVertexBufferData( offsetInBytes, data, elementCount, - elementSizeInBytes + vertexStride ); } diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index 83530e2..12c44ff 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -349,7 +349,7 @@ struct REFRESH_Device uint32_t offsetInBytes, void* data, uint32_t elementCount, - uint32_t elementSizeInBytes + uint32_t vertexStride ); void(*SetIndexBufferData)( diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 504f44c..99c5c57 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -604,8 +604,8 @@ struct VulkanBuffer /* cast from FNA3D_Buffer */ { VkDeviceSize size; VulkanSubBuffer **subBuffers; - int32_t subBufferCount; - int32_t currentSubBufferIndex; + uint32_t subBufferCount; + uint32_t currentSubBufferIndex; VulkanResourceAccessType resourceAccessType; VkBufferUsageFlags usage; uint8_t bound; @@ -1150,7 +1150,7 @@ static uint8_t VULKAN_INTERNAL_FindAvailableMemory( VkDeviceSize requiredSize, allocationSize; VkDeviceSize alignedOffset; - uint32_t newRegionSize, newRegionOffset; + VkDeviceSize newRegionSize, newRegionOffset; uint8_t allocationResult; if (buffer != VK_NULL_HANDLE && image != VK_NULL_HANDLE) @@ -3682,15 +3682,72 @@ static void VULKAN_SetTextureDataYUV( )); } +static void VULKAN_INTERNAL_SetBufferData( + REFRESH_Renderer* driverData, + REFRESH_Buffer* buffer, + uint32_t offsetInBytes, + void* data, + uint32_t dataLength +) { + VulkanRenderer* renderer = (VulkanRenderer*)driverData; + VulkanBuffer* vulkanBuffer = (VulkanBuffer*)buffer; + uint8_t* mapPointer; + VkResult vulkanResult; + + #define SUBBUF vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex] + + /* Buffer already bound, time to die */ + if (vulkanBuffer->subBuffers[vulkanBuffer->currentSubBufferIndex]->bound) + { + REFRESH_LogError("Buffer already bound. It is an error to write data to a buffer after binding before calling Present."); + return; + } + + /* Map the memory and perform the copy */ + vulkanResult = renderer->vkMapMemory( + renderer->logicalDevice, + SUBBUF->allocation->memory, + SUBBUF->offset, + SUBBUF->size, + 0, + (void**)&mapPointer + ); + + if (vulkanResult != VK_SUCCESS) + { + REFRESH_LogError("Failed to map buffer memory!"); + return; + } + + SDL_memcpy( + mapPointer + offsetInBytes, + data, + dataLength + ); + + renderer->vkUnmapMemory( + renderer->logicalDevice, + SUBBUF->allocation->memory + ); + + #undef SUBBUF +} + static void VULKAN_SetVertexBufferData( REFRESH_Renderer *driverData, REFRESH_Buffer *buffer, uint32_t offsetInBytes, void* data, uint32_t elementCount, - uint32_t elementSizeInBytes + uint32_t vertexStride ) { - SDL_assert(0); + VULKAN_INTERNAL_SetBufferData( + driverData, + buffer, + offsetInBytes, + data, + elementCount * vertexStride + ); } static void VULKAN_SetIndexBufferData( @@ -3700,7 +3757,13 @@ static void VULKAN_SetIndexBufferData( void* data, uint32_t dataLength ) { - SDL_assert(0); + VULKAN_INTERNAL_SetBufferData( + driverData, + buffer, + offsetInBytes, + data, + dataLength + ); } static void VULKAN_PushVertexShaderParams( @@ -4049,8 +4112,9 @@ static void VULKAN_BindVertexBuffers( VkBuffer *buffers = SDL_stack_alloc(VkBuffer, bindingCount); VulkanBuffer* currentBuffer; VulkanRenderer* renderer = (VulkanRenderer*) driverData; + uint32_t i; - for (int i = 0; i < bindingCount; i += 1) + for (i = 0; i < bindingCount; i += 1) { currentBuffer = (VulkanBuffer*) pBuffers[i]; buffers[i] = currentBuffer->subBuffers[currentBuffer->currentSubBufferIndex]->buffer;