diff --git a/include/Refresh.h b/include/Refresh.h index 48e1e36..8882010 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -993,7 +993,7 @@ REFRESHAPI void Refresh_SetBufferData( * data: The client data to write into the buffer. * paramBlockCount: The number of param-sized blocks from the client buffer to write. */ -REFRESHAPI uint32_t Refresh_PushVertexShaderParams( +REFRESHAPI uint32_t Refresh_PushVertexShaderUniforms( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, void *data, @@ -1010,7 +1010,7 @@ REFRESHAPI uint32_t Refresh_PushVertexShaderParams( * data: The client data to write into the buffer. * paramBlockCount: The number of param-sized blocks from the client buffer to write. */ -REFRESHAPI uint32_t Refresh_PushFragmentShaderParams( +REFRESHAPI uint32_t Refresh_PushFragmentShaderUniforms( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, void *data, @@ -1027,7 +1027,7 @@ REFRESHAPI uint32_t Refresh_PushFragmentShaderParams( * data: The client data to write into the buffer. * paramBlockData: The number of param-sized blocks from the client buffer to write. */ -REFRESHAPI uint32_t Refresh_PushComputeShaderParams( +REFRESHAPI uint32_t Refresh_PushComputeShaderUniforms( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, void *data, diff --git a/src/Refresh.c b/src/Refresh.c index 52ccd02..1aee24c 100644 --- a/src/Refresh.c +++ b/src/Refresh.c @@ -494,14 +494,14 @@ uint32_t Refresh_PushFragmentShaderUniforms( ); } -uint32_t Refresh_PushComputeShaderParams( +uint32_t Refresh_PushComputeShaderUniforms( Refresh_Device *device, Refresh_CommandBuffer *commandBuffer, void *data, uint32_t elementCount ) { if (device == NULL) { return 0; } - return device->PushComputeShaderParams( + return device->PushComputeShaderUniforms( device->driverData, commandBuffer, data, diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index 458d1ef..417ed5e 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -324,7 +324,7 @@ struct Refresh_Device uint32_t elementCount ); - uint32_t (*PushComputeShaderParams)( + uint32_t (*PushComputeShaderUniforms)( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, void *data, @@ -518,7 +518,7 @@ struct Refresh_Device ASSIGN_DRIVER_FUNC(SetBufferData, name) \ ASSIGN_DRIVER_FUNC(PushVertexShaderUniforms, name) \ ASSIGN_DRIVER_FUNC(PushFragmentShaderUniforms, name) \ - ASSIGN_DRIVER_FUNC(PushComputeShaderParams, name) \ + ASSIGN_DRIVER_FUNC(PushComputeShaderUniforms, name) \ ASSIGN_DRIVER_FUNC(BindVertexSamplers, name) \ ASSIGN_DRIVER_FUNC(BindFragmentSamplers, name) \ ASSIGN_DRIVER_FUNC(GetBufferData, name) \ diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 1bc5330..07db707 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -1325,7 +1325,7 @@ typedef struct VulkanRenderer VulkanBuffer *dummyComputeUniformBuffer; VulkanBuffer *textureStagingBuffer; - uint32_t textureStagingBufferOffset; + VkDeviceSize textureStagingBufferOffset; VulkanBuffer** buffersInUse; uint32_t buffersInUseCount; @@ -1535,6 +1535,71 @@ static inline uint8_t IsStencilFormat(VkFormat format) } } +static inline uint32_t VULKAN_INTERNAL_BytesPerPixel(VkFormat format) +{ + switch (format) + { + case VK_FORMAT_R32G32B32A32_SFLOAT: + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + return 16; + + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SNORM: + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + case VK_FORMAT_R16G16_UNORM: + case VK_FORMAT_R16G16_SFLOAT: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_D32_SFLOAT: + return 4; + + case VK_FORMAT_R5G6B5_UNORM_PACK16: + case VK_FORMAT_A1R5G5B5_UNORM_PACK16: + case VK_FORMAT_B4G4R4A4_UNORM_PACK16: + case VK_FORMAT_R8G8_SNORM: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_D16_UNORM: + return 2; + + case VK_FORMAT_R16G16B16A16_UNORM: + case VK_FORMAT_R32G32_SFLOAT: + case VK_FORMAT_R16G16B16A16_SFLOAT: + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + return 8; + + case VK_FORMAT_R8_UNORM: + return 1; + + case VK_FORMAT_D16_UNORM_S8_UINT: + return 3; + + case VK_FORMAT_D32_SFLOAT_S8_UINT: + return 5; + + default: + Refresh_LogError("Invalid texture format!"); + return 0; + } +} + +static inline VkDeviceSize VULKAN_INTERNAL_BytesPerImage( + uint32_t width, + uint32_t height, + VkFormat format +) { + uint32_t blocksPerRow = width; + uint32_t blocksPerColumn = height; + + if (format == VK_FORMAT_BC1_RGBA_UNORM_BLOCK || + format == VK_FORMAT_BC3_UNORM_BLOCK || + format == VK_FORMAT_BC5_UNORM_BLOCK) + { + blocksPerRow = (width + 3) / 4; + } + + return blocksPerRow * blocksPerColumn * VULKAN_INTERNAL_BytesPerPixel(format); +} + /* Memory Management */ static inline VkDeviceSize VULKAN_INTERNAL_NextHighestAlignment( @@ -5874,7 +5939,7 @@ static Refresh_Buffer* VULKAN_CreateBuffer( static void VULKAN_INTERNAL_MaybeExpandStagingBuffer( VulkanRenderer *renderer, - uint32_t textureSize + VkDeviceSize textureSize ) { VkDeviceSize nextStagingSize = renderer->textureStagingBuffer->size; @@ -6033,7 +6098,14 @@ static void VULKAN_SetTextureData( SDL_LockMutex(renderer->stagingLock); - VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLengthInBytes); + VULKAN_INTERNAL_MaybeExpandStagingBuffer( + renderer, + VULKAN_INTERNAL_BytesPerImage( + textureSlice->rectangle.w, + textureSlice->rectangle.h, + vulkanTexture->format + ) + ); VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer); stagingBufferPointer = @@ -6130,7 +6202,10 @@ static void VULKAN_SetTextureDataYUV( SDL_LockMutex(renderer->stagingLock); - VULKAN_INTERNAL_MaybeExpandStagingBuffer(renderer, dataLength); + VULKAN_INTERNAL_MaybeExpandStagingBuffer( + renderer, + yDataLength + uvDataLength + ); VULKAN_INTERNAL_MaybeBeginTransferCommandBuffer(renderer); stagingBufferPointer = @@ -6548,7 +6623,7 @@ static uint32_t VULKAN_PushFragmentShaderUniforms( return renderer->fragmentUBOOffset; } -static uint32_t VULKAN_PushComputeShaderParams( +static uint32_t VULKAN_PushComputeShaderUniforms( Refresh_Renderer *driverData, Refresh_CommandBuffer *commandBuffer, void *data,