Commit cbabea73 by Tim Van Patten Committed by Commit Bot

Vulkan: Desktop ETC/EAC formats support

Initial attempt to give desktop ETC/EAC formats support. Bug: angleproject:3676 Change-Id: Id147b0c1808e30df77097d0c7ff6a06534554b93 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1699307 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org>
parent 3a36f306
......@@ -2,7 +2,7 @@
"src/libANGLE/renderer/gen_load_functions_table.py":
"e65c50e84fc38ad34d0eb0bebb84aab6",
"src/libANGLE/renderer/load_functions_data.json":
"f32172c72959103dd38d044c8865ac2d",
"c32a5f4b267223629d941ae9fa569a41",
"src/libANGLE/renderer/load_functions_table_autogen.cpp":
"6ae60fe18896d4898d569cf791cf81db"
"03b0e7283d98cca5faf9218b40c49979"
}
\ No newline at end of file
......@@ -6,7 +6,7 @@
"src/libANGLE/renderer/vulkan/gen_vk_format_table.py":
"63e0efcbe3802518058186cdbfba730e",
"src/libANGLE/renderer/vulkan/vk_format_map.json":
"b15efb8e2ff455767eb5be0590cc340c",
"bfc6328eb428c3e6dc280429113d7f81",
"src/libANGLE/renderer/vulkan/vk_format_table_autogen.cpp":
"3d9440ef4e00925920f2c3b92e744851"
"14b88d4ab20bcb737741ebd2fef64593"
}
\ No newline at end of file
......@@ -181,6 +181,14 @@ destType bitCast(const sourceType &source)
return output;
}
// https://stackoverflow.com/a/37581284
template <typename T>
static constexpr double normalize(T value)
{
return value < 0 ? -static_cast<double>(value) / std::numeric_limits<T>::min()
: static_cast<double>(value) / std::numeric_limits<T>::max();
}
inline unsigned short float32ToFloat16(float fp32)
{
unsigned int fp32i = bitCast<unsigned int>(fp32);
......
......@@ -631,6 +631,46 @@ void LoadEACRG11SToRG16(size_t width,
size_t outputRowPitch,
size_t outputDepthPitch);
void LoadEACR11ToR16F(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch);
void LoadEACR11SToR16F(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch);
void LoadEACRG11ToRG16F(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch);
void LoadEACRG11SToRG16F(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch);
void LoadETC2RGB8ToRGBA8(size_t width,
size_t height,
size_t depth,
......
......@@ -8,6 +8,7 @@
#include "image_util/loadimage.h"
#include <type_traits>
#include "common/mathutil.h"
#include "image_util/imageformats.h"
......@@ -89,7 +90,8 @@ struct ETC2Block
size_t h,
size_t destPixelStride,
size_t destRowPitch,
bool isSigned) const
bool isSigned,
bool isFloat) const
{
for (size_t j = 0; j < 4 && (y + j) < h; j++)
{
......@@ -100,11 +102,17 @@ struct ETC2Block
uint16_t *pixel = row + (i * destPixelStride);
if (isSigned)
{
*pixel = renormalizeSignedEAC(getSingleEACChannel(i, j, isSigned));
int16_t tempPixel =
renormalizeEAC<int16_t>(getSingleEACChannel(i, j, isSigned));
*pixel =
isFloat ? gl::float32ToFloat16(float(gl::normalize(tempPixel))) : tempPixel;
}
else
{
*pixel = renormalizeUnsignedEAC(getSingleEACChannel(i, j, isSigned));
uint16_t tempPixel =
renormalizeEAC<uint16_t>(getSingleEACChannel(i, j, isSigned));
*pixel =
isFloat ? gl::float32ToFloat16(float(gl::normalize(tempPixel))) : tempPixel;
}
}
}
......@@ -361,17 +369,33 @@ struct ETC2Block
return static_cast<signed char>(gl::clamp(value, -128, 127));
}
static uint16_t renormalizeUnsignedEAC(int value)
template <typename T>
static T renormalizeEAC(int value)
{
// Data is in the range 0 to 2047, clamp it and then scale it to 16-bit
return static_cast<uint16_t>(gl::clamp(value, 0, 2047)) << 5;
}
int upper = 0;
int lower = 0;
int shift = 0;
static int16_t renormalizeSignedEAC(int value)
{
// Data is in the range -1023 to 1023, clamp it and then scale it to 16-bit
// The spec states that -1024 invalid and should be clamped to -1023
return static_cast<int16_t>(gl::clamp(value, -1023, 1023)) * 32;
if (std::is_same<T, int16_t>::value)
{
// The spec states that -1024 invalid and should be clamped to -1023
upper = 1023;
lower = -1023;
shift = 5;
}
else if (std::is_same<T, uint16_t>::value)
{
upper = 2047;
lower = 0;
shift = 5;
}
else
{
// We currently only support renormalizing int16_t or uint16_t
UNREACHABLE();
}
return static_cast<T>(gl::clamp(value, lower, upper)) << shift;
}
static R8G8B8A8 createRGBA(int red, int green, int blue, int alpha)
......@@ -1466,7 +1490,8 @@ void LoadR11EACToR16(size_t width,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch,
bool isSigned)
bool isSigned,
bool isFloat)
{
for (size_t z = 0; z < depth; z++)
{
......@@ -1483,7 +1508,7 @@ void LoadR11EACToR16(size_t width,
uint16_t *destPixels = destRow + x;
sourceBlock->decodeAsSingleEACChannel(destPixels, x, y, width, height, 1,
outputRowPitch, isSigned);
outputRowPitch, isSigned, isFloat);
}
}
}
......@@ -1498,7 +1523,8 @@ void LoadRG11EACToRG16(size_t width,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch,
bool isSigned)
bool isSigned,
bool isFloat)
{
for (size_t z = 0; z < depth; z++)
{
......@@ -1514,12 +1540,12 @@ void LoadRG11EACToRG16(size_t width,
uint16_t *destPixelsRed = destRow + (x * 2);
const ETC2Block *sourceBlockRed = sourceRow + (x / 2);
sourceBlockRed->decodeAsSingleEACChannel(destPixelsRed, x, y, width, height, 2,
outputRowPitch, isSigned);
outputRowPitch, isSigned, isFloat);
uint16_t *destPixelsGreen = destPixelsRed + 1;
const ETC2Block *sourceBlockGreen = sourceBlockRed + 1;
sourceBlockGreen->decodeAsSingleEACChannel(destPixelsGreen, x, y, width, height, 2,
outputRowPitch, isSigned);
outputRowPitch, isSigned, isFloat);
}
}
}
......@@ -1724,7 +1750,7 @@ void LoadEACR11ToR16(size_t width,
size_t outputDepthPitch)
{
LoadR11EACToR16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
outputRowPitch, outputDepthPitch, false);
outputRowPitch, outputDepthPitch, false, false);
}
void LoadEACR11SToR16(size_t width,
......@@ -1738,7 +1764,7 @@ void LoadEACR11SToR16(size_t width,
size_t outputDepthPitch)
{
LoadR11EACToR16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
outputRowPitch, outputDepthPitch, true);
outputRowPitch, outputDepthPitch, true, false);
}
void LoadEACRG11ToRG16(size_t width,
......@@ -1752,7 +1778,7 @@ void LoadEACRG11ToRG16(size_t width,
size_t outputDepthPitch)
{
LoadRG11EACToRG16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
outputRowPitch, outputDepthPitch, false);
outputRowPitch, outputDepthPitch, false, false);
}
void LoadEACRG11SToRG16(size_t width,
......@@ -1766,7 +1792,63 @@ void LoadEACRG11SToRG16(size_t width,
size_t outputDepthPitch)
{
LoadRG11EACToRG16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
outputRowPitch, outputDepthPitch, true);
outputRowPitch, outputDepthPitch, true, false);
}
void LoadEACR11ToR16F(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch)
{
LoadR11EACToR16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
outputRowPitch, outputDepthPitch, false, true);
}
void LoadEACR11SToR16F(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch)
{
LoadR11EACToR16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
outputRowPitch, outputDepthPitch, true, true);
}
void LoadEACRG11ToRG16F(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch)
{
LoadRG11EACToRG16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
outputRowPitch, outputDepthPitch, false, true);
}
void LoadEACRG11SToRG16F(size_t width,
size_t height,
size_t depth,
const uint8_t *input,
size_t inputRowPitch,
size_t inputDepthPitch,
uint8_t *output,
size_t outputRowPitch,
size_t outputDepthPitch)
{
LoadRG11EACToRG16(width, height, depth, input, inputRowPitch, inputDepthPitch, output,
outputRowPitch, outputDepthPitch, true, true);
}
void LoadETC2RGB8ToRGBA8(size_t width,
......
......@@ -75,6 +75,9 @@
"R16_UNORM": {
"GL_UNSIGNED_BYTE": "LoadEACR11ToR16"
},
"R16_FLOAT": {
"GL_UNSIGNED_BYTE": "LoadEACR11ToR16F"
},
"EAC_R11_UNORM_BLOCK": {
"GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 8>"
}
......@@ -210,6 +213,9 @@
"R16G16_SNORM": {
"GL_UNSIGNED_BYTE": "LoadEACRG11SToRG16"
},
"R16G16_FLOAT": {
"GL_UNSIGNED_BYTE": "LoadEACRG11SToRG16F"
},
"EAC_R11G11_SNORM_BLOCK": {
"GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 16>"
}
......@@ -505,6 +511,9 @@
"R16G16_UNORM": {
"GL_UNSIGNED_BYTE": "LoadEACRG11ToRG16"
},
"R16G16_FLOAT": {
"GL_UNSIGNED_BYTE": "LoadEACRG11ToRG16F"
},
"EAC_R11G11_UNORM_BLOCK": {
"GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 16>"
}
......@@ -576,6 +585,9 @@
"R16_SNORM": {
"GL_UNSIGNED_BYTE": "LoadEACR11SToR16"
},
"R16_FLOAT": {
"GL_UNSIGNED_BYTE": "LoadEACR11SToR16F"
},
"EAC_R11_SNORM_BLOCK": {
"GL_UNSIGNED_BYTE": "LoadCompressedToNative<4, 4, 1, 8>"
}
......
......@@ -288,6 +288,18 @@ LoadImageFunctionInfo COMPRESSED_R11_EAC_to_EAC_R11_UNORM_BLOCK(GLenum type)
}
}
LoadImageFunctionInfo COMPRESSED_R11_EAC_to_R16_FLOAT(GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
return LoadImageFunctionInfo(LoadEACR11ToR16F, true);
default:
UNREACHABLE();
return LoadImageFunctionInfo(UnreachableLoadFunction, true);
}
}
LoadImageFunctionInfo COMPRESSED_R11_EAC_to_R16_UNORM(GLenum type)
{
switch (type)
......@@ -312,6 +324,18 @@ LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_EAC_R11G11_UNORM_BLOCK(GLenum type)
}
}
LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_R16G16_FLOAT(GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
return LoadImageFunctionInfo(LoadEACRG11ToRG16F, true);
default:
UNREACHABLE();
return LoadImageFunctionInfo(UnreachableLoadFunction, true);
}
}
LoadImageFunctionInfo COMPRESSED_RG11_EAC_to_R16G16_UNORM(GLenum type)
{
switch (type)
......@@ -806,6 +830,18 @@ LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_EAC_R11_SNORM_BLOCK(GLenum ty
}
}
LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_R16_FLOAT(GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
return LoadImageFunctionInfo(LoadEACR11SToR16F, true);
default:
UNREACHABLE();
return LoadImageFunctionInfo(UnreachableLoadFunction, true);
}
}
LoadImageFunctionInfo COMPRESSED_SIGNED_R11_EAC_to_R16_SNORM(GLenum type)
{
switch (type)
......@@ -830,6 +866,18 @@ LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_EAC_R11G11_SNORM_BLOCK(GLenu
}
}
LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_R16G16_FLOAT(GLenum type)
{
switch (type)
{
case GL_UNSIGNED_BYTE:
return LoadImageFunctionInfo(LoadEACRG11SToRG16F, true);
default:
UNREACHABLE();
return LoadImageFunctionInfo(UnreachableLoadFunction, true);
}
}
LoadImageFunctionInfo COMPRESSED_SIGNED_RG11_EAC_to_R16G16_SNORM(GLenum type)
{
switch (type)
......@@ -2946,6 +2994,8 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat)
{
case FormatID::EAC_R11_UNORM_BLOCK:
return COMPRESSED_R11_EAC_to_EAC_R11_UNORM_BLOCK;
case FormatID::R16_FLOAT:
return COMPRESSED_R11_EAC_to_R16_FLOAT;
case FormatID::R16_UNORM:
return COMPRESSED_R11_EAC_to_R16_UNORM;
default:
......@@ -2959,6 +3009,8 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat)
{
case FormatID::EAC_R11G11_UNORM_BLOCK:
return COMPRESSED_RG11_EAC_to_EAC_R11G11_UNORM_BLOCK;
case FormatID::R16G16_FLOAT:
return COMPRESSED_RG11_EAC_to_R16G16_FLOAT;
case FormatID::R16G16_UNORM:
return COMPRESSED_RG11_EAC_to_R16G16_UNORM;
default:
......@@ -3095,6 +3147,8 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat)
{
case FormatID::EAC_R11_SNORM_BLOCK:
return COMPRESSED_SIGNED_R11_EAC_to_EAC_R11_SNORM_BLOCK;
case FormatID::R16_FLOAT:
return COMPRESSED_SIGNED_R11_EAC_to_R16_FLOAT;
case FormatID::R16_SNORM:
return COMPRESSED_SIGNED_R11_EAC_to_R16_SNORM;
default:
......@@ -3108,6 +3162,8 @@ LoadFunctionMap GetLoadFunctionsMap(GLenum internalFormat, FormatID angleFormat)
{
case FormatID::EAC_R11G11_SNORM_BLOCK:
return COMPRESSED_SIGNED_RG11_EAC_to_EAC_R11G11_SNORM_BLOCK;
case FormatID::R16G16_FLOAT:
return COMPRESSED_SIGNED_RG11_EAC_to_R16G16_FLOAT;
case FormatID::R16G16_SNORM:
return COMPRESSED_SIGNED_RG11_EAC_to_R16G16_SNORM;
default:
......
......@@ -410,6 +410,36 @@
},
"R32G32B32_FLOAT": {
"image": "R32G32B32A32_FLOAT"
},
"ETC2_R8G8B8_UNORM_BLOCK": {
"image": "R8G8B8A8_UNORM"
},
"ETC2_R8G8B8_SRGB_BLOCK": {
"image": "R8G8B8A8_UNORM_SRGB"
},
"ETC2_R8G8B8A1_UNORM_BLOCK": {
"image": "R8G8B8A8_UNORM"
},
"ETC2_R8G8B8A1_SRGB_BLOCK": {
"image": "R8G8B8A8_UNORM_SRGB"
},
"ETC2_R8G8B8A8_UNORM_BLOCK": {
"image": "R8G8B8A8_UNORM"
},
"ETC2_R8G8B8A8_SRGB_BLOCK": {
"image": "R8G8B8A8_UNORM_SRGB"
},
"EAC_R11_UNORM_BLOCK": {
"image": ["R16_UNORM", "R16_FLOAT"]
},
"EAC_R11_SNORM_BLOCK": {
"image": ["R16_SNORM", "R16_FLOAT"]
},
"EAC_R11G11_UNORM_BLOCK": {
"image": ["R16G16_UNORM", "R16G16_FLOAT"]
},
"EAC_R11G11_SNORM_BLOCK": {
"image": ["R16G16_SNORM", "R16G16_FLOAT"]
}
}
}
......@@ -116,10 +116,11 @@ void Format::initImageFallback(RendererVk *renderer, const ImageFormatInitInfo *
// enabled automatically by examining format capabilities.
testFunction = HasNonFilterableTextureFormatSupport;
}
if (format.isSnorm())
if (format.isSnorm() || format.isBlock)
{
// Rendering to SNORM textures is not supported on Android, and it's
// enabled by the extension EXT_render_snorm.
// Compressed textures also need to perform this check.
testFunction = HasNonRenderableTextureFormatSupport;
}
int i = FindSupportedFormat(renderer, info + skip, numInfo - skip, testFunction);
......
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