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:
/// BCn_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output
/// @param src Pointer to BCn encoded image
/// @param dst Pointer to decoded output image
/// @param w src image width
/// @param h src image height
/// @param dstW dst image width
/// @param dstH dst image height
/// @param w image width
/// @param h image height
/// @param dstPitch dst image pitch (bytes per row)
/// @param dstBpp dst image bytes per pixel
/// @param n n in BCn format
/// @param isNoAlphaU BC1: true if RGB, BC2/BC3: unused, BC4/BC5: true if unsigned
/// @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:
} // namespace
// 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];
sources[0] = (const ETC2 *)src;
......@@ -683,7 +683,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in
unsigned char *dstRow = dst + (y * dstPitch);
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;
......@@ -695,7 +695,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in
unsigned char *dstRow = dst + (y * dstPitch);
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;
......@@ -706,7 +706,7 @@ bool ETC_Decoder::Decode(const unsigned char *src, unsigned char *dst, int w, in
unsigned char *dstRow = dst + (y * dstPitch);
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;
......@@ -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)
{
// 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
// 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]++;
}
}
......
......@@ -29,13 +29,11 @@ public:
/// ETC_Decoder::Decode - Decodes 1 to 4 channel images to 8 bit output
/// @param src Pointer to ETC2 encoded image
/// @param dst Pointer to BGRA, 8 bit output
/// @param w src image width
/// @param h src image height
/// @param dstW dst image width
/// @param dstH dst image height
/// @param w image width
/// @param h image height
/// @param dstPitch dst image pitch (bytes per row)
/// @param dstBpp dst image bytes per pixel
/// @param inputType src's format
/// @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
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 VK_FORMAT_B8G8R8A8_UNORM;
case VK_FORMAT_BC1_RGB_SRGB_BLOCK:
case VK_FORMAT_BC1_RGBA_SRGB_BLOCK:
case VK_FORMAT_BC2_SRGB_BLOCK:
case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC7_SRGB_BLOCK:
return VK_FORMAT_B8G8R8A8_SRGB;
case VK_FORMAT_BC4_UNORM_BLOCK:
return VK_FORMAT_R8_UNORM;
......@@ -636,6 +638,8 @@ VkFormat Format::getDecompressedFormat() const
case VK_FORMAT_ASTC_12x10_SRGB_BLOCK:
case VK_FORMAT_ASTC_12x12_SRGB_BLOCK:
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_5x4_SFLOAT_BLOCK_EXT:
case VK_FORMAT_ASTC_5x5_SFLOAT_BLOCK_EXT:
......@@ -1316,6 +1320,8 @@ int Format::componentCount() const
case VK_FORMAT_G8_B8R8_2PLANE_420_UNORM:
case VK_FORMAT_BC1_RGB_UNORM_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_SRGB_BLOCK:
return 3;
......@@ -1376,6 +1382,8 @@ int Format::componentCount() const
case VK_FORMAT_BC2_SRGB_BLOCK:
case VK_FORMAT_BC3_UNORM_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_SRGB_BLOCK:
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
......@@ -1515,6 +1523,9 @@ bool Format::isUnsignedComponent(int component) const
case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC4_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_R11G11_UNORM_BLOCK:
case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
......@@ -1577,6 +1588,7 @@ bool Format::isUnsignedComponent(int component) const
case VK_FORMAT_R64G64B64A64_SFLOAT:
case VK_FORMAT_BC4_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_R11G11_SNORM_BLOCK:
case VK_FORMAT_ASTC_4x4_SFLOAT_BLOCK_EXT:
......@@ -1916,6 +1928,10 @@ int Format::pitchB(int width, int border, bool target) const
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:
case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
......
......@@ -78,6 +78,12 @@ int GetBCn(const vk::Format &format)
case VK_FORMAT_BC5_UNORM_BLOCK:
case VK_FORMAT_BC5_SNORM_BLOCK:
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:
UNSUPPORTED("format: %d", int(format));
return 0;
......@@ -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 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)
{
switch(format)
......@@ -104,6 +110,10 @@ bool GetNoAlphaOrUnsigned(const vk::Format &format)
case VK_FORMAT_BC3_SRGB_BLOCK:
case VK_FORMAT_BC4_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;
default:
UNSUPPORTED("format: %d", int(format));
......@@ -986,6 +996,10 @@ void Image::prepareForSampling(const VkImageSubresourceRange &subresourceRange)
case VK_FORMAT_BC4_SNORM_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:
decodeBC(subresourceRange);
break;
case VK_FORMAT_ASTC_4x4_UNORM_BLOCK:
......@@ -1103,7 +1117,7 @@ void Image::decodeETC2(const VkImageSubresourceRange &subresourceRange) const
}
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
uint8_t *dest = static_cast<uint8_t *>(decompressedImage->getTexelPointer({ 0, 0, depth }, subresourceLayers));
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
case VK_FORMAT_BC4_SNORM_BLOCK:
case VK_FORMAT_BC5_UNORM_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_SRGB_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