Commit d4c75347 by Hyunchang Kim Committed by Commit Bot

Vulkan: Enable GPU conversion from RGB16F to RGBA16F

- Add proper GPU conversion routine when the source and destination format of vertex attribute is half float data type. - Add an end2end test which utilizes half float GPU conversion path. Bug: angleproject:3802 Test: angle_end2end_tests --gtest_filter=*VertexAttributeTest.HalfFloatBuffer* Change-Id: Ia88a4984156f8967796bea3852c3cde714f2acab Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1824799Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Commit-Queue: Mohan Maiya <m.maiya@samsung.com>
parent 096b08fa
......@@ -169,6 +169,10 @@
"d6cfcf49825f3da242d0f8935b0e30f6",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000029.inc":
"59e6c4a829283dc6db1664bb397ed6a2",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.0000002A.inc":
"4090206500b8e40b293de75230b1b532",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.0000002B.inc":
"35ac7eddef7947f070b4f8419674f048",
"src/libANGLE/renderer/vulkan/shaders/gen/FullScreenQuad.vert.00000000.inc":
"235ca7c3979ce29a49c320d000ee7409",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000000.inc":
......@@ -280,7 +284,7 @@
"src/libANGLE/renderer/vulkan/shaders/src/ConvertIndex.comp":
"ca35df77d258baa0636529d1f0f446a9",
"src/libANGLE/renderer/vulkan/shaders/src/ConvertVertex.comp":
"debe6949313d7c23395e603a5f01162c",
"88d434e43a01906e6a6b1dd5d5e45cdc",
"src/libANGLE/renderer/vulkan/shaders/src/FullScreenQuad.vert":
"805ec8b2f87d4bd4242dc5b1c58ba3b4",
"src/libANGLE/renderer/vulkan/shaders/src/ImageClear.frag":
......@@ -292,9 +296,9 @@
"src/libANGLE/renderer/vulkan/shaders/src/OverlayDraw.comp":
"dcc246b398b2e07a869a264666499362",
"src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.cpp":
"0e9742f5a784d2b43f5ca758cb23719a",
"c38ca374f8af3ce9a394b7170747cb27",
"src/libANGLE/renderer/vulkan/vk_internal_shaders_autogen.h":
"996dc7cf95d03551b55a903b2c8ac755",
"c1fdbaf6ed5605cd453eb94276e9c990",
"tools/glslang/glslang_validator.exe.sha1":
"289f30598865a987a21b79ae525fc66f",
"tools/glslang/glslang_validator.sha1":
......
......@@ -57,6 +57,7 @@ struct Format final : private angle::NonCopyable
constexpr bool isSnorm() const;
constexpr bool isUnorm() const;
constexpr bool isFloat() const;
constexpr bool isVertexTypeHalfFloat() const;
constexpr bool isInt() const { return isSint() || isUint(); }
constexpr bool isNorm() const { return isSnorm() || isUnorm(); }
......@@ -209,6 +210,11 @@ constexpr bool Format::isFloat() const
return componentType == GL_FLOAT;
}
constexpr bool Format::isVertexTypeHalfFloat() const
{
return vertexAttribType == gl::VertexAttribType::HalfFloat;
}
} // namespace angle
#endif // LIBANGLE_RENDERER_FORMAT_H_
......@@ -90,15 +90,20 @@ uint32_t GetConvertVertexFlags(const UtilsVk::ConvertVertexParameters &params)
((params.srcFormat->vertexAttribType == gl::VertexAttribType::UnsignedInt1010102) ||
params.srcFormat->vertexAttribType == gl::VertexAttribType::Int1010102) &&
!params.srcFormat->alphaBits;
bool destIsSint = params.destFormat->isSint();
bool destIsUint = params.destFormat->isUint();
bool destIsFloat = params.destFormat->isFloat();
bool srcIsHalfFloat = params.srcFormat->isVertexTypeHalfFloat();
bool destIsSint = params.destFormat->isSint();
bool destIsUint = params.destFormat->isUint();
bool destIsFloat = params.destFormat->isFloat();
bool destIsHalfFloat = params.destFormat->isVertexTypeHalfFloat();
// Assert on the types to make sure the shader supports its. These are based on
// ConvertVertex_comp::Conversion values.
ASSERT(!destIsSint || srcIsSint); // If destination is sint, src must be sint too
ASSERT(!destIsUint || srcIsUint); // If destination is uint, src must be uint too
ASSERT(!srcIsFixed || destIsFloat); // If source is fixed, dest must be float
ASSERT(srcIsHalfFloat == destIsHalfFloat); // Both src and dest are half float or neither
// One of each bool set must be true
ASSERT(srcIsSint || srcIsUint || srcIsSnorm || srcIsUnorm || srcIsFixed || srcIsFloat);
ASSERT(destIsSint || destIsUint || destIsFloat);
......@@ -187,6 +192,10 @@ uint32_t GetConvertVertexFlags(const UtilsVk::ConvertVertexParameters &params)
UNREACHABLE();
}
}
else if (srcIsHalfFloat && destIsHalfFloat)
{
flags |= ConvertVertex_comp::kHalfFloatToHalfFloat;
}
else if (srcIsSint && destIsSint)
{
flags |= ConvertVertex_comp::kSintToSint;
......
......@@ -66,7 +66,7 @@
// * RGB10X2UintToFloat: Same types as RGB10X2UintToUint for source (including uscaled).
// Converts to float.
// * RGB10X2SnormToFloat: Similar to IntToFloat, but normalized and only for RGB10X2.
// * RGB10X2UnormToFloat: Similar to UintToFloat, but normalized and only for RGB10X2.
// * HalfFloatToHalfFloat: covers half float type only.
//
// SintToSint, UintToUint and FloatToFloat correspond to CopyNativeVertexData() and
// Copy8SintTo16SintVertexData() in renderer/copyvertex.inc, FixedToFloat corresponds to
......@@ -77,7 +77,7 @@
// RGB10A2SintToFloat, RGB10A2UintToFloat, RGB10A2SnormToFloat, and RGB10X2UnormToFloat correspond
// to CopyW2XYZ10ToXYZW32FVertexData, and RGB10X2SintToFloat, RGB10UintToFloat,
// RGB10X2SnormToFloat, and RGB10X2UnormToFloat correspond to CopyXYZ10ToXYZW32FVertexData with
// the proper options.
// the proper options. HalfFloatToHalfFloat correspond to CopyNativeVertexData().
#version 450 core
......@@ -86,7 +86,7 @@
RGB10X2SintToFloat
#define SrcType int
#elif UintToUint || UintToFloat || A2BGR10UintToUint || A2BGR10UintToFloat || \
RGB10A2UintToFloat || RGB10X2UintToFloat
RGB10A2UintToFloat || RGB10X2UintToFloat || HalfFloatToHalfFloat
#define SrcType uint
#elif SnormToFloat || UnormToFloat || FixedToFloat || FloatToFloat || A2BGR10SnormToFloat || \
RGB10A2SnormToFloat || RGB10A2UnormToFloat || RGB10X2SnormToFloat || RGB10X2UnormToFloat
......@@ -99,7 +99,7 @@
#if SintToSint || A2BGR10SintToSint
#define DestType int
#define IsDestFloat 0
#elif UintToUint || A2BGR10UintToUint
#elif UintToUint || A2BGR10UintToUint || HalfFloatToHalfFloat
#define DestType uint
#define IsDestFloat 0
#elif SintToFloat || UintToFloat || SnormToFloat || UnormToFloat || FixedToFloat || FloatToFloat || \
......@@ -275,7 +275,7 @@ SrcType loadSourceComponent(uint cd)
}
SrcType value = SrcType(valueAsUint);
#elif UintToUint || UintToFloat || A2BGR10UintToUint || A2BGR10UintToFloat || RGB10A2UintToFloat \
|| RGB10X2UintToFloat
|| RGB10X2UintToFloat || HalfFloatToHalfFloat
SrcType value = valueAsUint;
#elif SnormToFloat || A2BGR10SnormToFloat || RGB10A2SnormToFloat || RGB10X2SnormToFloat
if (valueBits < 32)
......@@ -314,7 +314,7 @@ uint makeDestinationComponent(uint cd, DestType value)
// Return valueAsUint, shifted to the right spot. Multiple calls to this function should be |ed
// and eventually written to the destination.
#if SintToSint || UintToUint || A2BGR10SintToSint || A2BGR10UintToUint
#if SintToSint || UintToUint || A2BGR10SintToSint || A2BGR10UintToUint || HalfFloatToHalfFloat
uint vertex = cd / Nd;
uint component = cd % Nd;
......
......@@ -30,7 +30,8 @@
"RGB10X2SintToFloat",
"RGB10X2UintToFloat",
"RGB10X2SnormToFloat",
"RGB10X2UnormToFloat"
"RGB10X2UnormToFloat",
"HalfFloatToHalfFloat"
]
}
......@@ -100,6 +100,8 @@ namespace
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000027.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000028.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000029.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.0000002A.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.0000002B.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/FullScreenQuad.vert.00000000.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000000.inc"
#include "libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000001.inc"
......@@ -252,6 +254,8 @@ constexpr ShaderBlob kConvertVertex_comp_shaders[] = {
{kConvertVertex_comp_00000027, sizeof(kConvertVertex_comp_00000027)},
{kConvertVertex_comp_00000028, sizeof(kConvertVertex_comp_00000028)},
{kConvertVertex_comp_00000029, sizeof(kConvertVertex_comp_00000029)},
{kConvertVertex_comp_0000002A, sizeof(kConvertVertex_comp_0000002A)},
{kConvertVertex_comp_0000002B, sizeof(kConvertVertex_comp_0000002B)},
};
constexpr ShaderBlob kFullScreenQuad_vert_shaders[] = {
{kFullScreenQuad_vert_00000000, sizeof(kFullScreenQuad_vert_00000000)},
......
......@@ -93,6 +93,8 @@ angle_vulkan_internal_shaders = [
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000027.inc",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000028.inc",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.00000029.inc",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.0000002A.inc",
"src/libANGLE/renderer/vulkan/shaders/gen/ConvertVertex.comp.0000002B.inc",
"src/libANGLE/renderer/vulkan/shaders/gen/FullScreenQuad.vert.00000000.inc",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000000.inc",
"src/libANGLE/renderer/vulkan/shaders/gen/ImageClear.frag.00000001.inc",
......
......@@ -85,29 +85,30 @@ enum flags
};
enum Conversion
{
kSintToSint = 0x00000000,
kUintToUint = 0x00000002,
kSintToFloat = 0x00000004,
kUintToFloat = 0x00000006,
kSnormToFloat = 0x00000008,
kUnormToFloat = 0x0000000A,
kFixedToFloat = 0x0000000C,
kFloatToFloat = 0x0000000E,
kA2BGR10SintToSint = 0x00000010,
kA2BGR10UintToUint = 0x00000012,
kA2BGR10SintToFloat = 0x00000014,
kA2BGR10UintToFloat = 0x00000016,
kA2BGR10SnormToFloat = 0x00000018,
kRGB10A2SintToFloat = 0x0000001A,
kRGB10A2UintToFloat = 0x0000001C,
kRGB10A2SnormToFloat = 0x0000001E,
kRGB10A2UnormToFloat = 0x00000020,
kRGB10X2SintToFloat = 0x00000022,
kRGB10X2UintToFloat = 0x00000024,
kRGB10X2SnormToFloat = 0x00000026,
kRGB10X2UnormToFloat = 0x00000028,
};
constexpr size_t kArrayLen = 0x0000002A;
kSintToSint = 0x00000000,
kUintToUint = 0x00000002,
kSintToFloat = 0x00000004,
kUintToFloat = 0x00000006,
kSnormToFloat = 0x00000008,
kUnormToFloat = 0x0000000A,
kFixedToFloat = 0x0000000C,
kFloatToFloat = 0x0000000E,
kA2BGR10SintToSint = 0x00000010,
kA2BGR10UintToUint = 0x00000012,
kA2BGR10SintToFloat = 0x00000014,
kA2BGR10UintToFloat = 0x00000016,
kA2BGR10SnormToFloat = 0x00000018,
kRGB10A2SintToFloat = 0x0000001A,
kRGB10A2UintToFloat = 0x0000001C,
kRGB10A2SnormToFloat = 0x0000001E,
kRGB10A2UnormToFloat = 0x00000020,
kRGB10X2SintToFloat = 0x00000022,
kRGB10X2UintToFloat = 0x00000024,
kRGB10X2SnormToFloat = 0x00000026,
kRGB10X2UnormToFloat = 0x00000028,
kHalfFloatToHalfFloat = 0x0000002A,
};
constexpr size_t kArrayLen = 0x0000002C;
} // namespace ConvertVertex_comp
namespace FullScreenQuad_vert
......
......@@ -550,6 +550,34 @@ TEST_P(VertexAttributeTest, HalfFloatClientMemoryPointer)
}
}
// Verify that vertex data is updated correctly when using a float/half-float buffer.
TEST_P(VertexAttributeTest, HalfFloatBuffer)
{
std::array<GLhalf, kVertexCount> inputData;
std::array<GLfloat, kVertexCount> expectedData = {
{0.f, 1.5f, 2.3f, 3.2f, -1.8f, -2.2f, -3.9f, -4.f, 34.5f, 32.2f, -78.8f, -77.4f, -76.1f}};
for (size_t i = 0; i < kVertexCount; i++)
{
inputData[i] = gl::float32ToFloat16(expectedData[i]);
}
// If the extension is enabled run the test on all contexts
if (IsGLExtensionEnabled("GL_OES_vertex_half_float"))
{
TestData bufferData(GL_HALF_FLOAT_OES, GL_FALSE, Source::BUFFER, inputData.data(),
expectedData.data());
runTest(bufferData);
}
// Otherwise run the test only if it is an ES3 context
else if (getClientMajorVersion() >= 3)
{
TestData bufferData(GL_HALF_FLOAT, GL_FALSE, Source::BUFFER, inputData.data(),
expectedData.data());
runTest(bufferData);
}
}
// Verify that using the same client memory pointer in different format won't mess up the draw.
TEST_P(VertexAttributeTest, UsingDifferentFormatAndSameClientMemoryPointer)
{
......
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