Add unit test verifying float encoding of uniforms.
This test verifies that float scalars and vectors can be added as uniforms. In Metal, this is a particularly interesting challenge because we represent half values as 16-bit floats. Change-Id: I4ce2280a61afee905ac5980792b6dbe6e4be572f Bug: skia:13478 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/554344 Reviewed-by: Jim Van Verth <jvanverth@google.com> Auto-Submit: John Stiles <johnstiles@google.com> Commit-Queue: Jim Van Verth <jvanverth@google.com>
This commit is contained in:
parent
91c25e9b05
commit
eb35a3783e
@ -162,6 +162,60 @@ static constexpr bool SkSLTypeIsIntegralType(SkSLType type) {
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
|
||||
/** Is the shading language type full precision? */
|
||||
static constexpr bool SkSLTypeIsFullPrecisionNumericType(SkSLType type) {
|
||||
switch (type) {
|
||||
// Half-precision types:
|
||||
case SkSLType::kShort:
|
||||
case SkSLType::kShort2:
|
||||
case SkSLType::kShort3:
|
||||
case SkSLType::kShort4:
|
||||
case SkSLType::kUShort:
|
||||
case SkSLType::kUShort2:
|
||||
case SkSLType::kUShort3:
|
||||
case SkSLType::kUShort4:
|
||||
case SkSLType::kHalf:
|
||||
case SkSLType::kHalf2:
|
||||
case SkSLType::kHalf3:
|
||||
case SkSLType::kHalf4:
|
||||
case SkSLType::kHalf2x2:
|
||||
case SkSLType::kHalf3x3:
|
||||
case SkSLType::kHalf4x4:
|
||||
// Non-numeric types:
|
||||
case SkSLType::kVoid:
|
||||
case SkSLType::kTexture2DSampler:
|
||||
case SkSLType::kTextureExternalSampler:
|
||||
case SkSLType::kTexture2DRectSampler:
|
||||
case SkSLType::kTexture2D:
|
||||
case SkSLType::kSampler:
|
||||
case SkSLType::kInput:
|
||||
case SkSLType::kBool:
|
||||
case SkSLType::kBool2:
|
||||
case SkSLType::kBool3:
|
||||
case SkSLType::kBool4:
|
||||
return false;
|
||||
|
||||
// Full-precision numeric types:
|
||||
case SkSLType::kInt:
|
||||
case SkSLType::kInt2:
|
||||
case SkSLType::kInt3:
|
||||
case SkSLType::kInt4:
|
||||
case SkSLType::kUInt:
|
||||
case SkSLType::kUInt2:
|
||||
case SkSLType::kUInt3:
|
||||
case SkSLType::kUInt4:
|
||||
case SkSLType::kFloat:
|
||||
case SkSLType::kFloat2:
|
||||
case SkSLType::kFloat3:
|
||||
case SkSLType::kFloat4:
|
||||
case SkSLType::kFloat2x2:
|
||||
case SkSLType::kFloat3x3:
|
||||
case SkSLType::kFloat4x4:
|
||||
return true;
|
||||
}
|
||||
SkUNREACHABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the shading language type supported as a uniform (ie, does it have a corresponding set
|
||||
* function on GrGLSLProgramDataManager)?
|
||||
|
@ -5,6 +5,8 @@
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "include/private/SkHalf.h"
|
||||
#include "src/core/SkPipelineData.h"
|
||||
#include "src/core/SkSLTypeShared.h"
|
||||
#include "src/core/SkUniform.h"
|
||||
#include "src/gpu/graphite/UniformManager.h"
|
||||
@ -29,7 +31,15 @@ static constexpr SkSLType kTypes[] = {
|
||||
SkSLType::kHalf2x2, SkSLType::kHalf3x3, SkSLType::kHalf4x4,
|
||||
};
|
||||
|
||||
static constexpr uint8_t kZeroData[64] = {};
|
||||
static constexpr float kFloats[16] = { 1.0f, 2.0f, 3.0f, 4.0f,
|
||||
5.0f, 6.0f, 7.0f, 8.0f,
|
||||
9.0f, 10.0f, 11.0f, 12.0f,
|
||||
13.0f, 14.0f, 15.0f, 16.0f };
|
||||
|
||||
static constexpr SkHalf kHalfs[16] = { 0x3C00, 0x4000, 0x4200, 0x4400,
|
||||
0x4500, 0x4600, 0x4700, 0x4800,
|
||||
0x4880, 0x4900, 0x4980, 0x4A00,
|
||||
0x4A80, 0x4B00, 0x4B80, 0x4C00 };
|
||||
|
||||
DEF_TEST(UniformManagerCheckSingleUniform, r) {
|
||||
// Verify that the uniform manager can hold all the basic uniform types, in every layout.
|
||||
@ -39,9 +49,47 @@ DEF_TEST(UniformManagerCheckSingleUniform, r) {
|
||||
for (SkSLType type : kTypes) {
|
||||
const SkUniform expectations[] = {{"uniform", type}};
|
||||
mgr.setExpectedUniforms(SkSpan(expectations));
|
||||
mgr.write(type, 1, kZeroData);
|
||||
mgr.write(type, 1, kFloats);
|
||||
REPORTER_ASSERT(r, mgr.size() > 0);
|
||||
mgr.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEF_TEST(UniformManagerCheckFloatEncoding, r) {
|
||||
// Verify that the uniform manager encodes float data properly.
|
||||
for (Layout layout : kLayouts) {
|
||||
UniformManager mgr(layout);
|
||||
|
||||
for (SkSLType type : kTypes) {
|
||||
// Only test scalar and vector floats. (Matrices can introduce padding between values.)
|
||||
int vecLength = SkSLTypeVecLength(type);
|
||||
if (!SkSLTypeIsFloatType(type) || vecLength < 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Write our uniform float scalar/vector.
|
||||
const SkUniform expectations[] = {{"uniform", type}};
|
||||
mgr.setExpectedUniforms(SkSpan(expectations));
|
||||
mgr.write(type, 1, kFloats);
|
||||
|
||||
// Read back the uniform data.
|
||||
SkUniformDataBlock uniformData = mgr.peekData();
|
||||
if (layout == Layout::kMetal && !SkSLTypeIsFullPrecisionNumericType(type)) {
|
||||
// Metal should encode half-precision float uniforms in 16-bit floats.
|
||||
REPORTER_ASSERT(r, uniformData.size() >= vecLength * sizeof(SkHalf));
|
||||
REPORTER_ASSERT(r, 0 == memcmp(kHalfs, uniformData.data(),
|
||||
vecLength * sizeof(SkHalf)),
|
||||
"Layout:%d Type:%d encoding failed", (int)layout, (int)type);
|
||||
} else {
|
||||
// Other layouts should always encode float uniforms in full precision.
|
||||
REPORTER_ASSERT(r, uniformData.size() >= vecLength * sizeof(float));
|
||||
REPORTER_ASSERT(r, 0 == memcmp(kFloats, uniformData.data(),
|
||||
vecLength * sizeof(float)),
|
||||
"Layout:%d Type:%d encoding failed", (int)layout, (int)type);
|
||||
}
|
||||
|
||||
mgr.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user