Commit 5751f9e3 by Ben Clayton

VkImage: Implement BC7 texture format

Also contains the following changes: * Replace the use of `unsigned char` with `uint8_t`. `char` is not guaranteed to be 8-bit. * Remove the `dstW` and `dstH` parameters from `BC_Decoder::Decode` and `ETC_Decoder::Decode`. They're always the same as the `w` and `h` parameters. * Add BC6 types to various switch cases. The actual decode logic is not implemented for these formats. Tests: *bc7* Bug: b/151203718 Change-Id: I7b232b9dc3a9b02d172f87a62c88ce56b2cca956 Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/41508Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com> Tested-by: 's avatarBen Clayton <bclayton@google.com> Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
parent 569a9a43
...@@ -18,15 +18,13 @@ public: ...@@ -18,15 +18,13 @@ public:
/// BCn_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output /// BCn_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output
/// @param src Pointer to BCn encoded image /// @param src Pointer to BCn encoded image
/// @param dst Pointer to decoded output image /// @param dst Pointer to decoded output image
/// @param w src image width /// @param w image width
/// @param h src image height /// @param h image height
/// @param dstW dst image width
/// @param dstH dst image height
/// @param dstPitch dst image pitch (bytes per row) /// @param dstPitch dst image pitch (bytes per row)
/// @param dstBpp dst image bytes per pixel /// @param dstBpp dst image bytes per pixel
/// @param n n in BCn format /// @param n n in BCn format
/// @param isNoAlphaU BC1: true if RGB, BC2/BC3: unused, BC4/BC5: true if unsigned /// @param isNoAlphaU BC1: true if RGB, BC2/BC3: unused, BC4/BC5: true if unsigned
/// @return true if the decoding was performed /// @return true if the decoding was performed
static bool Decode(const unsigned char *src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, int n, bool isNoAlphaU); static bool Decode(const unsigned char *src, unsigned char *dst, int w, int h, int dstPitch, int dstBpp, int n, bool isNoAlphaU);
}; };
...@@ -667,7 +667,7 @@ private: ...@@ -667,7 +667,7 @@ private:
} // namespace } // namespace
// Decodes 1 to 4 channel images to 8 bit output // Decodes 1 to 4 channel images to 8 bit output
bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, InputType inputType) bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, int h, int dstPitch, int dstBpp, InputType inputType)
{ {
const ETC2 *sources[2]; const ETC2 *sources[2];
sources[0] = (const ETC2 *)src; sources[0] = (const ETC2 *)src;
...@@ -683,7 +683,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in ...@@ -683,7 +683,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in
unsigned char *dstRow = dst + (y * dstPitch); unsigned char *dstRow = dst + (y * dstPitch);
for(int x = 0; x < w; x += 4, sources[0]++) for(int x = 0; x < w; x += 4, sources[0]++)
{ {
ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 1, x, y, dstW, dstH, dstPitch, inputType == ETC_R_SIGNED, true); ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 1, x, y, w, h, dstPitch, inputType == ETC_R_SIGNED, true);
} }
} }
break; break;
...@@ -695,7 +695,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in ...@@ -695,7 +695,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in
unsigned char *dstRow = dst + (y * dstPitch); unsigned char *dstRow = dst + (y * dstPitch);
for(int x = 0; x < w; x += 4, sources[0] += 2, sources[1] += 2) for(int x = 0; x < w; x += 4, sources[0] += 2, sources[1] += 2)
{ {
ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 2, x, y, dstW, dstH, dstPitch, inputType == ETC_RG_SIGNED, true); ETC2::DecodeBlock(sources, dstRow + (x * dstBpp), 2, x, y, w, h, dstPitch, inputType == ETC_RG_SIGNED, true);
} }
} }
break; break;
...@@ -706,7 +706,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in ...@@ -706,7 +706,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in
unsigned char *dstRow = dst + (y * dstPitch); unsigned char *dstRow = dst + (y * dstPitch);
for(int x = 0; x < w; x += 4, sources[0]++) for(int x = 0; x < w; x += 4, sources[0]++)
{ {
sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, dstW, dstH, dstPitch, alphaValues, inputType == ETC_RGB_PUNCHTHROUGH_ALPHA); sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, w, h, dstPitch, alphaValues, inputType == ETC_RGB_PUNCHTHROUGH_ALPHA);
} }
} }
break; break;
...@@ -717,11 +717,11 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in ...@@ -717,11 +717,11 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in
for(int x = 0; x < w; x += 4) for(int x = 0; x < w; x += 4)
{ {
// Decode Alpha // Decode Alpha
ETC2::DecodeBlock(&sources[0], &(alphaValues[0][0]), 1, x, y, dstW, dstH, 4, false, false); ETC2::DecodeBlock(&sources[0], &(alphaValues[0][0]), 1, x, y, w, h, 4, false, false);
sources[0]++; // RGBA packets are 128 bits, so move on to the next 64 bit packet to decode the RGB color sources[0]++; // RGBA packets are 128 bits, so move on to the next 64 bit packet to decode the RGB color
// Decode RGB // Decode RGB
sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, dstW, dstH, dstPitch, alphaValues, false); sources[0]->decodeBlock(dstRow + (x * dstBpp), x, y, w, h, dstPitch, alphaValues, false);
sources[0]++; sources[0]++;
} }
} }
......
...@@ -29,13 +29,11 @@ public: ...@@ -29,13 +29,11 @@ public:
/// ETC_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output /// ETC_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output
/// @param src Pointer to ETC2 encoded image /// @param src Pointer to ETC2 encoded image
/// @param dst Pointer to BGRA, 8 bit output /// @param dst Pointer to BGRA, 8 bit output
/// @param w src image width /// @param w image width
/// @param h src image height /// @param h image height
/// @param dstW dst image width
/// @param dstH dst image height
/// @param dstPitch dst image pitch (bytes per row) /// @param dstPitch dst image pitch (bytes per row)
/// @param dstBpp dst image bytes per pixel /// @param dstBpp dst image bytes per pixel
/// @param inputType src's format /// @param inputType src's format
/// @return true if the decoding was performed /// @return true if the decoding was performed
static bool Decode(const unsigned char *src, unsigned char *dst, int w, int h, int dstW, int dstH, int dstPitch, int dstBpp, InputType inputType); static bool Decode(const unsigned char *src, unsigned char *dst, int w, int h, int dstPitch, int dstBpp, InputType inputType);
}; };
...@@ -592,11 +592,13 @@ VkFormat Format::getDecompressedFormat() const ...@@ -592,11 +592,13 @@ VkFormat Format::getDecompressedFormat() const
case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: case VK_FORMAT_BC1_RGBA_UNORM_BLOCK:
case VK_FORMAT_BC2_UNORM_BLOCK: case VK_FORMAT_BC2_UNORM_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK: case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
return VK_FORMAT_B8G8R8A8_UNORM; return VK_FORMAT_B8G8R8A8_UNORM;
case VK_FORMAT_BC1_RGB_SRGB_BLOCK: case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
case VK_FORMAT_BC2_SRGB_BLOCK: case VK_FORMAT_BC2_SRGB_BLOCK:
case VK_FORMAT_BC3_SRGB_BLOCK: case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
return VK_FORMAT_B8G8R8A8_SRGB; return VK_FORMAT_B8G8R8A8_SRGB;
case VK_FORMAT_BC4_UNORM_BLOCK: case VK_FORMAT_BC4_UNORM_BLOCK:
return VK_FORMAT_R8_UNORM; return VK_FORMAT_R8_UNORM;
...@@ -636,6 +638,8 @@ VkFormat Format::getDecompressedFormat() const ...@@ -636,6 +638,8 @@ VkFormat Format::getDecompressedFormat() const
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK: case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK: case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
return VK_FORMAT_R8G8B8A8_SRGB; return VK_FORMAT_R8G8B8A8_SRGB;
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT: case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT:
case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT: case VK_FORMAT_ASTC_5x4_SFLOAT_BLOCK_EXT:
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT: case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT:
...@@ -1316,6 +1320,8 @@ int Format::componentCount() const ...@@ -1316,6 +1320,8 @@ int Format::componentCount() const
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM: case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_BC1_RGB_UNORM_BLOCK: case VK_FORMAT_BC1_RGB_UNORM_BLOCK:
case VK_FORMAT_BC1_RGB_SRGB_BLOCK: case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
return 3; return 3;
...@@ -1376,6 +1382,8 @@ int Format::componentCount() const ...@@ -1376,6 +1382,8 @@ int Format::componentCount() const
case VK_FORMAT_BC2_SRGB_BLOCK: case VK_FORMAT_BC2_SRGB_BLOCK:
case VK_FORMAT_BC3_UNORM_BLOCK: case VK_FORMAT_BC3_UNORM_BLOCK:
case VK_FORMAT_BC3_SRGB_BLOCK: case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
...@@ -1515,6 +1523,9 @@ bool Format::isUnsignedComponent(int component) const ...@@ -1515,6 +1523,9 @@ bool Format::isUnsignedComponent(int component) const
case VK_FORMAT_BC3_SRGB_BLOCK: case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC4_UNORM_BLOCK: case VK_FORMAT_BC4_UNORM_BLOCK:
case VK_FORMAT_BC5_UNORM_BLOCK: case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
case VK_FORMAT_EAC_R11_UNORM_BLOCK: case VK_FORMAT_EAC_R11_UNORM_BLOCK:
case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
...@@ -1577,6 +1588,7 @@ bool Format::isUnsignedComponent(int component) const ...@@ -1577,6 +1588,7 @@ bool Format::isUnsignedComponent(int component) const
case VK_FORMAT_R64G64B64A64_SFLOAT: case VK_FORMAT_R64G64B64A64_SFLOAT:
case VK_FORMAT_BC4_SNORM_BLOCK: case VK_FORMAT_BC4_SNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_BLOCK: case VK_FORMAT_BC5_SNORM_BLOCK:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
case VK_FORMAT_EAC_R11_SNORM_BLOCK: case VK_FORMAT_EAC_R11_SNORM_BLOCK:
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT: case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT:
...@@ -1916,6 +1928,10 @@ int Format::pitchB(int width, int border, bool target) const ...@@ -1916,6 +1928,10 @@ int Format::pitchB(int width, int border, bool target) const
case VK_FORMAT_BC3_SRGB_BLOCK: case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC5_UNORM_BLOCK: case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_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_UNORM_BLOCK:
case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
......
...@@ -78,6 +78,12 @@ int GetBCn(const vk::Format &format) ...@@ -78,6 +78,12 @@ int GetBCn(const vk::Format &format)
case VK_FORMAT_BC5_UNORM_BLOCK: case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_BLOCK: case VK_FORMAT_BC5_SNORM_BLOCK:
return 5; return 5;
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
return 6;
case VK_FORMAT_BC7_UNORM_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
return 7;
default: default:
UNSUPPORTED("format: %d", int(format)); UNSUPPORTED("format: %d", int(format));
return 0; return 0;
...@@ -86,7 +92,7 @@ int GetBCn(const vk::Format &format) ...@@ -86,7 +92,7 @@ int GetBCn(const vk::Format &format)
// Returns true for BC1 if we have an RGB format, false for RGBA // Returns true for BC1 if we have an RGB format, false for RGBA
// Returns true for BC4 and BC5 if we have an unsigned format, false for signed // Returns true for BC4 and BC5 if we have an unsigned format, false for signed
// Ignored by BC2 and BC3 // Ignored by BC2, BC3, BC6 and BC7
bool GetNoAlphaOrUnsigned(const vk::Format &format) bool GetNoAlphaOrUnsigned(const vk::Format &format)
{ {
switch(format) switch(format)
...@@ -104,6 +110,10 @@ bool GetNoAlphaOrUnsigned(const vk::Format &format) ...@@ -104,6 +110,10 @@ bool GetNoAlphaOrUnsigned(const vk::Format &format)
case VK_FORMAT_BC3_SRGB_BLOCK: case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC4_SNORM_BLOCK: case VK_FORMAT_BC4_SNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_BLOCK: case VK_FORMAT_BC5_SNORM_BLOCK:
case VK_FORMAT_BC6H_UFLOAT_BLOCK:
case VK_FORMAT_BC6H_SFLOAT_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
return false; return false;
default: default:
UNSUPPORTED("format: %d", int(format)); UNSUPPORTED("format: %d", int(format));
...@@ -986,6 +996,10 @@ void Image::prepareForSampling(const VkImageSubresourceRange &subresourceRange) ...@@ -986,6 +996,10 @@ void Image::prepareForSampling(const VkImageSubresourceRange &subresourceRange)
case VK_FORMAT_BC4_SNORM_BLOCK: case VK_FORMAT_BC4_SNORM_BLOCK:
case VK_FORMAT_BC5_UNORM_BLOCK: case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_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:
decodeBC(subresourceRange); decodeBC(subresourceRange);
break; break;
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK: case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
...@@ -1103,7 +1117,7 @@ void Image::decodeETC2(const VkImageSubresourceRange &subresourceRange) const ...@@ -1103,7 +1117,7 @@ void Image::decodeETC2(const VkImageSubresourceRange &subresourceRange) const
} }
ETC_Decoder::Decode(source, dest, mipLevelExtent.width, mipLevelExtent.height, ETC_Decoder::Decode(source, dest, mipLevelExtent.width, mipLevelExtent.height,
mipLevelExtent.width, mipLevelExtent.height, pitchB, bytes, inputType); pitchB, bytes, inputType);
} }
} }
} }
...@@ -1136,7 +1150,7 @@ void Image::decodeBC(const VkImageSubresourceRange &subresourceRange) const ...@@ -1136,7 +1150,7 @@ void Image::decodeBC(const VkImageSubresourceRange &subresourceRange) const
uint8_t *dest = static_cast<uint8_t *>(decompressedImage->getTexelPointer({ 0, 0, depth }, subresourceLayers)); uint8_t *dest = static_cast<uint8_t *>(decompressedImage->getTexelPointer({ 0, 0, depth }, subresourceLayers));
BC_Decoder::Decode(source, dest, mipLevelExtent.width, mipLevelExtent.height, BC_Decoder::Decode(source, dest, mipLevelExtent.width, mipLevelExtent.height,
mipLevelExtent.width, mipLevelExtent.height, pitchB, bytes, n, noAlphaU); pitchB, bytes, n, noAlphaU);
} }
} }
} }
......
...@@ -521,6 +521,8 @@ void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties *pFor ...@@ -521,6 +521,8 @@ void PhysicalDevice::getFormatProperties(Format format, VkFormatProperties *pFor
case VK_FORMAT_BC4_SNORM_BLOCK: case VK_FORMAT_BC4_SNORM_BLOCK:
case VK_FORMAT_BC5_UNORM_BLOCK: case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_BLOCK: case VK_FORMAT_BC5_SNORM_BLOCK:
case VK_FORMAT_BC7_UNORM_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment