diff --git a/renderdoc/driver/vulkan/vk_resources.cpp b/renderdoc/driver/vulkan/vk_resources.cpp index 66a8aa86a..bb2fa8972 100644 --- a/renderdoc/driver/vulkan/vk_resources.cpp +++ b/renderdoc/driver/vulkan/vk_resources.cpp @@ -1188,520 +1188,6 @@ VkFormat GetViewCastedFormat(VkFormat f, CompType typeHint) return f; } -uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, uint32_t mip) -{ - uint32_t w = RDCMAX(Width >> mip, 1U); - uint32_t h = RDCMAX(Height >> mip, 1U); - uint32_t d = RDCMAX(Depth >> mip, 1U); - - uint32_t ret = w * h * d; - - uint32_t astc[2] = {0, 0}; - - switch(Format) - { - case VK_FORMAT_R64G64B64A64_UINT: - case VK_FORMAT_R64G64B64A64_SINT: - case VK_FORMAT_R64G64B64A64_SFLOAT: ret *= 32; break; - case VK_FORMAT_R64G64B64_UINT: - case VK_FORMAT_R64G64B64_SINT: - case VK_FORMAT_R64G64B64_SFLOAT: ret *= 24; break; - case VK_FORMAT_R32G32B32A32_UINT: - case VK_FORMAT_R32G32B32A32_SINT: - case VK_FORMAT_R32G32B32A32_SFLOAT: - case VK_FORMAT_R64G64_UINT: - case VK_FORMAT_R64G64_SINT: - case VK_FORMAT_R64G64_SFLOAT: ret *= 16; break; - case VK_FORMAT_R32G32B32_UINT: - case VK_FORMAT_R32G32B32_SINT: - case VK_FORMAT_R32G32B32_SFLOAT: ret *= 12; break; - case VK_FORMAT_R16G16B16A16_UNORM: - case VK_FORMAT_R16G16B16A16_SNORM: - case VK_FORMAT_R16G16B16A16_USCALED: - case VK_FORMAT_R16G16B16A16_SSCALED: - case VK_FORMAT_R16G16B16A16_UINT: - case VK_FORMAT_R16G16B16A16_SINT: - case VK_FORMAT_R16G16B16A16_SFLOAT: - case VK_FORMAT_R32G32_UINT: - case VK_FORMAT_R32G32_SINT: - case VK_FORMAT_R32G32_SFLOAT: - case VK_FORMAT_R64_UINT: - case VK_FORMAT_R64_SINT: - case VK_FORMAT_R64_SFLOAT: ret *= 8; break; - case VK_FORMAT_R16G16B16_UNORM: - case VK_FORMAT_R16G16B16_SNORM: - case VK_FORMAT_R16G16B16_USCALED: - case VK_FORMAT_R16G16B16_SSCALED: - case VK_FORMAT_R16G16B16_UINT: - case VK_FORMAT_R16G16B16_SINT: - case VK_FORMAT_R16G16B16_SFLOAT: ret *= 6; break; - case VK_FORMAT_D32_SFLOAT_S8_UINT: ret *= 8; break; - case VK_FORMAT_R8G8B8_UNORM: - case VK_FORMAT_R8G8B8_SNORM: - case VK_FORMAT_R8G8B8_USCALED: - case VK_FORMAT_R8G8B8_SSCALED: - case VK_FORMAT_R8G8B8_UINT: - case VK_FORMAT_R8G8B8_SINT: - case VK_FORMAT_R8G8B8_SRGB: - case VK_FORMAT_B8G8R8_UNORM: - case VK_FORMAT_B8G8R8_SNORM: - case VK_FORMAT_B8G8R8_USCALED: - case VK_FORMAT_B8G8R8_SSCALED: - case VK_FORMAT_B8G8R8_UINT: - case VK_FORMAT_B8G8R8_SINT: - case VK_FORMAT_B8G8R8_SRGB: ret *= 3; break; - case VK_FORMAT_A2B10G10R10_UNORM_PACK32: - case VK_FORMAT_A2B10G10R10_SNORM_PACK32: - case VK_FORMAT_A2B10G10R10_USCALED_PACK32: - case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: - case VK_FORMAT_A2B10G10R10_UINT_PACK32: - case VK_FORMAT_A2B10G10R10_SINT_PACK32: - case VK_FORMAT_A2R10G10B10_UNORM_PACK32: - case VK_FORMAT_A2R10G10B10_SNORM_PACK32: - case VK_FORMAT_A2R10G10B10_USCALED_PACK32: - case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: - case VK_FORMAT_A2R10G10B10_UINT_PACK32: - case VK_FORMAT_A2R10G10B10_SINT_PACK32: - case VK_FORMAT_B10G11R11_UFLOAT_PACK32: - case VK_FORMAT_R8G8B8A8_UNORM: - case VK_FORMAT_R8G8B8A8_SNORM: - case VK_FORMAT_R8G8B8A8_USCALED: - case VK_FORMAT_R8G8B8A8_SSCALED: - case VK_FORMAT_R8G8B8A8_UINT: - case VK_FORMAT_R8G8B8A8_SINT: - case VK_FORMAT_R8G8B8A8_SRGB: - case VK_FORMAT_B8G8R8A8_UNORM: - case VK_FORMAT_B8G8R8A8_SNORM: - case VK_FORMAT_B8G8R8A8_USCALED: - case VK_FORMAT_B8G8R8A8_SSCALED: - case VK_FORMAT_B8G8R8A8_UINT: - case VK_FORMAT_B8G8R8A8_SINT: - case VK_FORMAT_B8G8R8A8_SRGB: - case VK_FORMAT_A8B8G8R8_UNORM_PACK32: - case VK_FORMAT_A8B8G8R8_SNORM_PACK32: - case VK_FORMAT_A8B8G8R8_USCALED_PACK32: - case VK_FORMAT_A8B8G8R8_SSCALED_PACK32: - case VK_FORMAT_A8B8G8R8_UINT_PACK32: - case VK_FORMAT_A8B8G8R8_SINT_PACK32: - case VK_FORMAT_A8B8G8R8_SRGB_PACK32: - case VK_FORMAT_R16G16_UNORM: - case VK_FORMAT_R16G16_SNORM: - case VK_FORMAT_R16G16_USCALED: - case VK_FORMAT_R16G16_SSCALED: - case VK_FORMAT_R16G16_UINT: - case VK_FORMAT_R16G16_SINT: - case VK_FORMAT_R16G16_SFLOAT: - case VK_FORMAT_R32_UINT: - case VK_FORMAT_R32_SINT: - case VK_FORMAT_R32_SFLOAT: - case VK_FORMAT_X8_D24_UNORM_PACK32: - case VK_FORMAT_D24_UNORM_S8_UINT: - case VK_FORMAT_D32_SFLOAT: - case VK_FORMAT_E5B9G9R9_UFLOAT_PACK32: ret *= 4; break; - case VK_FORMAT_D16_UNORM_S8_UINT: ret *= 4; break; - case VK_FORMAT_R8G8_UNORM: - case VK_FORMAT_R8G8_SNORM: - case VK_FORMAT_R8G8_USCALED: - case VK_FORMAT_R8G8_SSCALED: - case VK_FORMAT_R8G8_UINT: - case VK_FORMAT_R8G8_SINT: - case VK_FORMAT_R8G8_SRGB: - case VK_FORMAT_R16_UNORM: - case VK_FORMAT_R16_SNORM: - case VK_FORMAT_R16_USCALED: - case VK_FORMAT_R16_SSCALED: - case VK_FORMAT_R16_UINT: - case VK_FORMAT_R16_SINT: - case VK_FORMAT_R16_SFLOAT: - case VK_FORMAT_D16_UNORM: - case VK_FORMAT_R5G6B5_UNORM_PACK16: - case VK_FORMAT_R5G5B5A1_UNORM_PACK16: - case VK_FORMAT_B5G5R5A1_UNORM_PACK16: - case VK_FORMAT_A1R5G5B5_UNORM_PACK16: - case VK_FORMAT_B5G6R5_UNORM_PACK16: - case VK_FORMAT_R4G4B4A4_UNORM_PACK16: - case VK_FORMAT_B4G4R4A4_UNORM_PACK16: ret *= 2; break; - case VK_FORMAT_R4G4_UNORM_PACK8: - case VK_FORMAT_R8_UNORM: - case VK_FORMAT_R8_SNORM: - case VK_FORMAT_R8_USCALED: - case VK_FORMAT_R8_SSCALED: - case VK_FORMAT_R8_UINT: - case VK_FORMAT_R8_SINT: - case VK_FORMAT_R8_SRGB: - case VK_FORMAT_S8_UINT: ret *= 1; break; - case VK_FORMAT_BC1_RGB_UNORM_BLOCK: - case VK_FORMAT_BC1_RGB_SRGB_BLOCK: - case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: - case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: - case VK_FORMAT_BC4_UNORM_BLOCK: - case VK_FORMAT_BC4_SNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: - case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: - case VK_FORMAT_EAC_R11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11_SNORM_BLOCK: - ret = AlignUp4(w) * AlignUp4(h) * d; - ret /= 2; - break; - case VK_FORMAT_BC2_UNORM_BLOCK: - case VK_FORMAT_BC2_SRGB_BLOCK: - case VK_FORMAT_BC3_UNORM_BLOCK: - case VK_FORMAT_BC3_SRGB_BLOCK: - case VK_FORMAT_BC5_UNORM_BLOCK: - case VK_FORMAT_BC5_SNORM_BLOCK: - case VK_FORMAT_BC6H_UFLOAT_BLOCK: - case VK_FORMAT_BC6H_SFLOAT_BLOCK: - case VK_FORMAT_BC7_UNORM_BLOCK: - case VK_FORMAT_BC7_SRGB_BLOCK: - case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: - case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: - ret = AlignUp4(w) * AlignUp4(h) * d; - ret *= 1; - break; - case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_4x4_SRGB_BLOCK: - astc[0] = 4; - astc[1] = 4; - break; - case VK_FORMAT_ASTC_5x4_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x4_SRGB_BLOCK: - astc[0] = 5; - astc[1] = 4; - break; - case VK_FORMAT_ASTC_5x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_5x5_SRGB_BLOCK: - astc[0] = 5; - astc[1] = 5; - break; - case VK_FORMAT_ASTC_6x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x5_SRGB_BLOCK: - astc[0] = 6; - astc[1] = 5; - break; - case VK_FORMAT_ASTC_6x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_6x6_SRGB_BLOCK: - astc[0] = 6; - astc[1] = 6; - break; - case VK_FORMAT_ASTC_8x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x5_SRGB_BLOCK: - astc[0] = 8; - astc[1] = 5; - break; - case VK_FORMAT_ASTC_8x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x6_SRGB_BLOCK: - astc[0] = 8; - astc[1] = 6; - break; - case VK_FORMAT_ASTC_8x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_8x8_SRGB_BLOCK: - astc[0] = 8; - astc[1] = 8; - break; - case VK_FORMAT_ASTC_10x5_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x5_SRGB_BLOCK: - astc[0] = 10; - astc[1] = 5; - break; - case VK_FORMAT_ASTC_10x6_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x6_SRGB_BLOCK: - astc[0] = 10; - astc[1] = 6; - break; - case VK_FORMAT_ASTC_10x8_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x8_SRGB_BLOCK: - astc[0] = 10; - astc[1] = 8; - break; - case VK_FORMAT_ASTC_10x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_10x10_SRGB_BLOCK: - astc[0] = 10; - astc[1] = 10; - break; - case VK_FORMAT_ASTC_12x10_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: - astc[0] = 12; - astc[1] = 10; - break; - case VK_FORMAT_ASTC_12x12_UNORM_BLOCK: - case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: - astc[0] = 12; - astc[1] = 12; - break; - case VK_FORMAT_PVRTC1_2BPP_UNORM_BLOCK_IMG: - case VK_FORMAT_PVRTC1_2BPP_SRGB_BLOCK_IMG: - case VK_FORMAT_PVRTC2_2BPP_UNORM_BLOCK_IMG: - case VK_FORMAT_PVRTC2_2BPP_SRGB_BLOCK_IMG: - ret = (uint32_t)(ceil(w / 8.0) * ceil(h / 4.0) * 8.0); - break; - case VK_FORMAT_PVRTC1_4BPP_UNORM_BLOCK_IMG: - case VK_FORMAT_PVRTC1_4BPP_SRGB_BLOCK_IMG: - case VK_FORMAT_PVRTC2_4BPP_UNORM_BLOCK_IMG: - case VK_FORMAT_PVRTC2_4BPP_SRGB_BLOCK_IMG: - ret = (uint32_t)(ceil(w / 4.0) * ceil(h / 4.0) * 8.0); - break; - - /* - * YUV planar/packed subsampled textures. - * - * In each diagram we indicate (maybe part) of the data for a 4x4 texture: - * - * +---+---+---+---+ - * | 0 | 1 | 2 | 3 | - * +---+---+---+---+ - * | 4 | 5 | 6 | 7 | - * +---+---+---+---+ - * | 8 | 9 | A | B | - * +---+---+---+---+ - * | C | D | E | F | - * +---+---+---+---+ - * - * - * FOURCC decoding: - * - char 0: 'Y' = packed, 'P' = planar - * - char 1: '4' = 4:4:4, '2' = 4:2:2, '1' = 4:2:1, '0' = 4:2:0 - * - char 2+3: '16' = 16-bit, '10' = 10-bit, '08' = 8-bit - * - * planar = Y is first, all together, then UV comes second. - * packed = YUV is interleaved - * - * ======================= 4:4:4 lossless packed ========================= - * - * Equivalent to uncompressed formats, just YUV instead of RGB. For 8-bit: - * - * pixel: 0 1 2 3 - * byte: 0 1 2 3 4 5 6 7 8 9 A B C D E F - * Y0 U0 V0 A0 Y1 U1 V1 A1 Y2 U2 V2 A2 Y3 U3 V3 A3 - * - * 16-bit is similar with two bytes per sample, 10-bit for uncompressed is - * equivalent to R10G10B10A2 but with RGB=>YUV - * - * ============================ 4:2:2 packed ============================= - * - * 50% horizontal subsampling packed, two Y samples for each U/V sample pair. For 8-bit: - * - * pixel: 0 | 1 2 | 3 4 | 5 6 | 7 - * byte: 0 1 2 3 4 5 6 7 8 9 A B C D E F - * Y0 U0 Y1 V0 Y2 U1 Y3 V1 Y4 U2 Y5 V2 Y6 U3 Y7 V3 - * - * 16-bit is similar with two bytes per sample, 10-bit is stored identically to 16-bit but in - * the most significant bits: - * - * bit: FEDCBA9876543210 - * 16-bit: XXXXXXXXXXXXXXXX - * 10-bit: XXXXXXXXXX000000 - * - * Since the data is unorm this just spaces out valid values. - * - * ============================ 4:2:0 planar ============================= - * - * 50% horizontal and vertical subsampled planar, four Y samples for each U/V sample pair. - * For 8-bit: - * - * - * pixel: 0 1 2 3 4 5 6 7 - * byte: 0 1 2 3 4 5 6 7 - * Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 - * - * pixel: 8 9 A B C D E F - * byte: 8 9 A B C D E F - * Y8 Y9 Ya Yb Yc Yd Ye Yf - * - * ... all of the rest of Y luma ... - * - * pixel: T&4 | 1&5 2&6 | 3&7 - * byte: 0 1 2 3 4 5 6 7 - * U0 V0 U1 V1 U2 V2 U3 V3 - * - * pixel: 8&C | 9&D A&E | B&F - * byte: 8 9 A B C D E F - * U4 V4 U5 V5 U6 V6 U7 V7 - */ - case VK_FORMAT_G8B8G8R8_422_UNORM: - case VK_FORMAT_B8G8R8G8_422_UNORM: - // 4:2:2 packed 8-bit, so 1 byte per pixel for luma and 1 byte per pixel for chroma (2 chroma - // samples, with 50% subsampling = 1 byte per pixel) - ret *= 2; - break; - case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: - case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: - // 4:2:0 planar. Since we can assume even width and height, resulting size is 1 byte per pixel - // for luma, plus 1 byte per 2 pixels for chroma. - // 2 or 3 planes makes no difference to size - ret = ret + ret / 2; - break; - case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: - case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: - // 4:2:2 planar 8-bit, same as VK_FORMAT_G8B8G8R8_422_UNORM - // 2 or 3 planes makes no difference to size - ret *= 2; - break; - case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: - // uncompressed with 3 planes, so 3 bytes per pixel - ret *= 3; - break; - // basically just 16-bit format with only top 10-bits used - // 10-bit and 12-bit formats are stored identically to 16-bit formats - case VK_FORMAT_R10X6_UNORM_PACK16: - case VK_FORMAT_R12X4_UNORM_PACK16: ret *= 2; break; - case VK_FORMAT_R10X6G10X6_UNORM_2PACK16: - case VK_FORMAT_R12X4G12X4_UNORM_2PACK16: - // just a 16-bit format with only top N-bits used - // 10-bit and 12-bit formats are stored identically to 16-bit formats - ret *= 4; - break; - case VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16: - case VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16: - // just a 16-bit format with only top N-bits used - // 10-bit and 12-bit formats are stored identically to 16-bit formats - ret *= 8; - break; - case VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16: - case VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16: - case VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16: - case VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16: - case VK_FORMAT_G16B16G16R16_422_UNORM: - case VK_FORMAT_B16G16R16G16_422_UNORM: - // 10-bit and 12-bit formats are stored identically to 16-bit formats - // 4:2:2 packed 16-bit - ret *= 4; - break; - case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: - case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: - case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: - case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: - // 10-bit and 12-bit formats are stored identically to 16-bit formats - // 4:2:0 planar but 16-bit, so pixelCount*2 + (pixelCount*2) / 2 - ret *= 2; - ret = ret + ret / 2; - break; - case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: - case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: - case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: - case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: - // 10-bit and 12-bit formats are stored identically to 16-bit formats - // 4:2:2 16-bit in means 4 bytes per pixel - 2 bytes for luma, then 2 bytes each for chroma - // samples but half the number of samples = 2 bytes for chroma. Packed vs. planar doesn't - // change overall size - ret *= 4; - break; - case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: - case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: - // 10-bit and 12-bit formats are stored identically to 16-bit formats - // 4:4:4 16-bit in 3 planes means 6 bytes per pixel - ret *= 6; - break; - - default: - ret = 1; - RDCERR("Unrecognised Vulkan Format: %d", Format); - break; - } - - if(astc[0] > 0 && astc[1] > 0) - { - uint32_t blocks[2] = {(w / astc[0]), (h / astc[1])}; - - // how many blocks are needed - including any extra partial blocks - blocks[0] += (w % astc[0]) ? 1 : 0; - blocks[1] += (h % astc[1]) ? 1 : 0; - - // ASTC blocks are all 128 bits each - return blocks[0] * blocks[1] * 16 * d; - } - - return ret; -} - -uint32_t GetPlaneByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, - uint32_t mip, uint32_t plane) -{ - switch(Format) - { - case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: - if(plane == 0) - return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip); - else - return GetByteSize(RDCMAX(1U, Width >> 1), RDCMAX(1U, Height >> 1), Depth, - VK_FORMAT_R8G8_UNORM, mip); - - case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: - case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: - if(plane == 0) - return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip); - else - return GetByteSize(RDCMAX(1U, Width >> 1), RDCMAX(1U, Height >> 1), Depth, - VK_FORMAT_R16G16_UNORM, mip); - - case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: - if(plane == 0) - return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip); - else - return GetByteSize(RDCMAX(1U, Width >> 1), Height, Depth, VK_FORMAT_R8G8_UNORM, mip); - - case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: - case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: - if(plane == 0) - return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip); - else - return GetByteSize(RDCMAX(1U, Width >> 1), Height, Depth, VK_FORMAT_R16G16_UNORM, mip); - - case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: - if(plane == 0) - return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip); - else - return GetByteSize(RDCMAX(1U, Width >> 1), RDCMAX(1U, Height >> 1), Depth, - VK_FORMAT_R8_UNORM, mip); - - case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: - case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: - - if(plane == 0) - return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip); - else - return GetByteSize(RDCMAX(1U, Width >> 1), RDCMAX(1U, Height >> 1), Depth, - VK_FORMAT_R16_UNORM, mip); - - case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: - if(plane == 0) - return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip); - else - return GetByteSize(RDCMAX(1U, Width >> 1), Height, Depth, VK_FORMAT_R8_UNORM, mip); - - case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: - case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: - if(plane == 0) - return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip); - else - return GetByteSize(RDCMAX(1U, Width >> 1), Height, Depth, VK_FORMAT_R16_UNORM, mip); - - case VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM: - return GetByteSize(Width, Height, Depth, VK_FORMAT_R8_UNORM, mip); - - case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16: - case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16: - case VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM: - return GetByteSize(Width, Height, Depth, VK_FORMAT_R16_UNORM, mip); - - default: break; - } - - return GetByteSize(Width, Height, Depth, Format, mip); -} - // The shape of blocks in (a plane of) an image format. // Non-block formats are considered to have 1x1 blocks. // For some planar formats, the block shape depends on the plane-- @@ -2060,6 +1546,66 @@ BlockShape GetBlockShape(VkFormat Format, uint32_t plane) return BlockShape(); } +VkExtent2D GetPlaneShape(uint32_t Width, uint32_t Height, VkFormat Format, uint32_t plane) +{ + switch(Format) + { + case VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM: + case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16: + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16: + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16: + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16: + case VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM: + case VK_FORMAT_G16_B16R16_2PLANE_420_UNORM: + if(plane == 0) + return {Width, Height}; + else + return {RDCMAX(1U, (Width + 1) / 2), RDCMAX(1U, (Height + 1) / 2)}; + + case VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM: + case VK_FORMAT_G8_B8R8_2PLANE_422_UNORM: + case VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16: + case VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16: + case VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16: + case VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16: + case VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM: + case VK_FORMAT_G16_B16R16_2PLANE_422_UNORM: + if(plane == 0) + return {Width, Height}; + else + return {RDCMAX(1U, (Width + 1) / 2), Height}; + + default: return {Width, Height}; + } +} + +uint32_t GetPlaneByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, + uint32_t mip, uint32_t plane) +{ + uint32_t mipWidth = RDCMAX(Width >> mip, 1U); + uint32_t mipHeight = RDCMAX(Height >> mip, 1U); + uint32_t mipDepth = RDCMAX(Depth >> mip, 1U); + + VkExtent2D planeShape = GetPlaneShape(mipWidth, mipHeight, Format, plane); + + BlockShape blockShape = GetBlockShape(Format, plane); + + uint32_t widthInBlocks = (planeShape.width + blockShape.width - 1) / blockShape.width; + uint32_t heightInBlocks = (planeShape.height + blockShape.height - 1) / blockShape.height; + + return blockShape.bytes * widthInBlocks * heightInBlocks * mipDepth; +} + +uint32_t GetByteSize(uint32_t Width, uint32_t Height, uint32_t Depth, VkFormat Format, uint32_t mip) +{ + uint32_t planeCount = GetYUVPlaneCount(Format); + uint32_t size = 0; + for(uint32_t p = 0; p < planeCount; p++) + size += GetPlaneByteSize(Width, Height, Depth, Format, mip, p); + return size; +} + ResourceFormat MakeResourceFormat(VkFormat fmt) { ResourceFormat ret; @@ -4259,42 +3805,57 @@ TEST_CASE("Vulkan formats", "[format][vulkan]") { const uint32_t width = 24, height = 24; - for(VkFormat f : { - VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, - VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, - VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, - VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, - VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, - VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, - VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, - VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, - VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, - VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, - VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, - VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, - VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, - }) + std::vector > > tests = { + {VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, {576, 144, 144}}, + {VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, {576, 288}}, + {VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, {576, 288, 288}}, + {VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, {576, 576}}, + {VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, {576, 576, 576}}, + {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16, {1152, 288, 288}}, + {VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16, {1152, 576}}, + {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16, {1152, 576, 576}}, + {VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16, {1152, 1152}}, + {VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16, {1152, 1152, 1152}}, + {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16, {1152, 288, 288}}, + {VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16, {1152, 576}}, + {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16, {1152, 576, 576}}, + {VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16, {1152, 1152}}, + {VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16, {1152, 1152, 1152}}, + {VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, {1152, 288, 288}}, + {VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, {1152, 576}}, + {VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, {1152, 576, 576}}, + {VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, {1152, 1152}}, + {VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, {1152, 1152, 1152}}, + }; + + for(std::pair > e : tests) { + INFO("Format is " << ToStr(e.first)); + for(uint32_t p = 0; p < e.second.size(); p++) + CHECK(e.second[p] == GetPlaneByteSize(width, height, 1, e.first, 0, p)); + } + }; + + SECTION("GetPlaneByteSize is consistent with GetByteSize") + { + const uint32_t width = 24, height = 24; + + for(VkFormat f : formats) + { + if(f == VK_FORMAT_UNDEFINED) + continue; + INFO("Format is " << ToStr(f)); uint32_t planeCount = GetYUVPlaneCount(f); - CHECK(planeCount > 1); - uint32_t planeSum = 0; for(uint32_t p = 0; p < planeCount; p++) planeSum += GetPlaneByteSize(width, height, 1, f, 0, p); CHECK(planeSum == GetByteSize(width, height, 1, f, 0)); } - } + }; }; #endif // ENABLED(ENABLE_UNIT_TESTS)