From 163adfb5cd7176a5eb714cc80a6511b3041630f8 Mon Sep 17 00:00:00 2001 From: cosmonaut Date: Wed, 11 May 2022 21:16:24 -0700 Subject: [PATCH] add BC7 support --- include/Refresh.h | 1 + src/Refresh_Driver.h | 7 +++-- src/Refresh_Driver_Vulkan.c | 54 ++++++++++++++++++++++++++++++++----- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/include/Refresh.h b/include/Refresh.h index c282651..5bbc980 100644 --- a/include/Refresh.h +++ b/include/Refresh.h @@ -124,6 +124,7 @@ typedef enum Refresh_TextureFormat REFRESH_TEXTUREFORMAT_BC1, REFRESH_TEXTUREFORMAT_BC2, REFRESH_TEXTUREFORMAT_BC3, + REFRESH_TEXTUREFORMAT_BC7, REFRESH_TEXTUREFORMAT_R8G8_SNORM, REFRESH_TEXTUREFORMAT_R8G8B8A8_SNORM, REFRESH_TEXTUREFORMAT_A2R10G10B10, diff --git a/src/Refresh_Driver.h b/src/Refresh_Driver.h index a46270d..56d8ec6 100644 --- a/src/Refresh_Driver.h +++ b/src/Refresh_Driver.h @@ -51,6 +51,7 @@ static inline uint32_t Texture_GetFormatSize( return 8; case REFRESH_TEXTUREFORMAT_BC2: case REFRESH_TEXTUREFORMAT_BC3: + case REFRESH_TEXTUREFORMAT_BC7: return 16; case REFRESH_TEXTUREFORMAT_R8: return 1; @@ -117,7 +118,8 @@ static inline uint32_t BytesPerRow( if ( format == REFRESH_TEXTUREFORMAT_BC1 || format == REFRESH_TEXTUREFORMAT_BC2 || - format == REFRESH_TEXTUREFORMAT_BC3 ) + format == REFRESH_TEXTUREFORMAT_BC3 || + format == REFRESH_TEXTUREFORMAT_BC7 ) { blocksPerRow = (width + 3) / 4; } @@ -135,7 +137,8 @@ static inline int32_t BytesPerImage( if ( format == REFRESH_TEXTUREFORMAT_BC1 || format == REFRESH_TEXTUREFORMAT_BC2 || - format == REFRESH_TEXTUREFORMAT_BC3 ) + format == REFRESH_TEXTUREFORMAT_BC3 || + format == REFRESH_TEXTUREFORMAT_BC7 ) { blocksPerRow = (width + 3) / 4; blocksPerColumn = (height + 3) / 4; diff --git a/src/Refresh_Driver_Vulkan.c b/src/Refresh_Driver_Vulkan.c index 72c2a5c..b9bc451 100644 --- a/src/Refresh_Driver_Vulkan.c +++ b/src/Refresh_Driver_Vulkan.c @@ -190,6 +190,7 @@ static VkFormat RefreshToVK_SurfaceFormat[] = VK_FORMAT_BC1_RGBA_UNORM_BLOCK, /* BC1 */ VK_FORMAT_BC2_UNORM_BLOCK, /* BC3 */ VK_FORMAT_BC3_UNORM_BLOCK, /* BC5 */ + VK_FORMAT_BC7_UNORM_BLOCK, /* BC7 */ VK_FORMAT_R8G8_SNORM, /* R8G8_SNORM */ VK_FORMAT_R8G8B8A8_SNORM, /* R8G8B8A8_SNORM */ VK_FORMAT_A2R10G10B10_UNORM_PACK32, /* A2R10G10B10 */ @@ -1817,6 +1818,7 @@ static inline uint32_t VULKAN_INTERNAL_BytesPerPixel(VkFormat format) case VK_FORMAT_R32G32B32A32_SFLOAT: case VK_FORMAT_BC2_UNORM_BLOCK: case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC7_UNORM_BLOCK: return 16; case VK_FORMAT_R8G8B8A8_UNORM: @@ -1857,6 +1859,40 @@ static inline uint32_t VULKAN_INTERNAL_BytesPerPixel(VkFormat format) } } +static inline uint32_t VULKAN_INTERNAL_GetTextureBlockSize( + VkFormat format +) { + switch (format) + { + case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: + case VK_FORMAT_BC2_UNORM_BLOCK: + case VK_FORMAT_BC3_UNORM_BLOCK: + case VK_FORMAT_BC7_UNORM_BLOCK: + return 4; + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_B8G8R8A8_UNORM: + 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_R8G8B8A8_SNORM: + case VK_FORMAT_A2R10G10B10_UNORM_PACK32: + case VK_FORMAT_R16G16_UNORM: + case VK_FORMAT_R16G16B16A16_UNORM: + case VK_FORMAT_R8_UNORM: + case VK_FORMAT_R32_SFLOAT: + case VK_FORMAT_R32G32_SFLOAT: + case VK_FORMAT_R32G32B32A32_SFLOAT: + case VK_FORMAT_R16_SFLOAT: + case VK_FORMAT_R16G16_SFLOAT: + case VK_FORMAT_R16G16B16A16_SFLOAT: + return 1; + default: + Refresh_LogError("Unrecognized texture format!"); + return 0; + } +} + static inline VkDeviceSize VULKAN_INTERNAL_BytesPerImage( uint32_t width, uint32_t height, @@ -1864,12 +1900,12 @@ static inline VkDeviceSize VULKAN_INTERNAL_BytesPerImage( ) { uint32_t blocksPerRow = width; uint32_t blocksPerColumn = height; + uint32_t blockSize = VULKAN_INTERNAL_GetTextureBlockSize(format); - if (format == VK_FORMAT_BC1_RGBA_UNORM_BLOCK || - format == VK_FORMAT_BC3_UNORM_BLOCK || - format == VK_FORMAT_BC5_UNORM_BLOCK) + if (blockSize > 1) { - blocksPerRow = (width + 3) / 4; + blocksPerRow = (width + blockSize - 1) / blockSize; + blocksPerColumn = (height + blockSize - 1) / blockSize; } return blocksPerRow * blocksPerColumn * VULKAN_INTERNAL_BytesPerPixel(format); @@ -6507,6 +6543,9 @@ static void VULKAN_SetTextureData( VulkanTransferBuffer *transferBuffer; VkBufferImageCopy imageCopy; uint8_t *stagingBufferPointer; + uint32_t blockSize = VULKAN_INTERNAL_GetTextureBlockSize(vulkanTexture->format); + uint32_t bufferRowLength; + uint32_t bufferImageHeight; if (vulkanCommandBuffer->renderPassInProgress) { @@ -6555,6 +6594,9 @@ static void VULKAN_SetTextureData( &vulkanTexture->resourceAccessType ); + bufferRowLength = SDL_max(blockSize, textureSlice->rectangle.w); + bufferImageHeight = SDL_max(blockSize, textureSlice->rectangle.h); + imageCopy.imageExtent.width = textureSlice->rectangle.w; imageCopy.imageExtent.height = textureSlice->rectangle.h; imageCopy.imageExtent.depth = 1; @@ -6566,8 +6608,8 @@ static void VULKAN_SetTextureData( imageCopy.imageSubresource.layerCount = 1; imageCopy.imageSubresource.mipLevel = textureSlice->level; imageCopy.bufferOffset = transferBuffer->offset; - imageCopy.bufferRowLength = 0; - imageCopy.bufferImageHeight = 0; + imageCopy.bufferRowLength = bufferRowLength; + imageCopy.bufferImageHeight = bufferImageHeight; renderer->vkCmdCopyBufferToImage( vulkanCommandBuffer->commandBuffer,