Add SkRuntimeEffect flag indicating half-precision uniforms.

Graphite's uniforms (SkUniform) distinguish between "Float" and "Half"
as separate types, so we now preserve this information in a Uniform
flag. We didn't have any tests verifying the behavior of Uniform flags
in SkRuntimeEffect at all, so I added a test here.

Change-Id: If6323ce26eeca2ef7da6c7424ad7350c6a0b7362
Bug: skia:13405
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/553594
Reviewed-by: Brian Salomon <bsalomon@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
This commit is contained in:
John Stiles 2022-06-28 12:12:50 -04:00 committed by SkCQ
parent 6ef5116f78
commit 27e5eb1281
4 changed files with 45 additions and 12 deletions

View File

@ -83,6 +83,10 @@ public:
// When used with SkMeshSpecification, indicates that the uniform is present in the
// fragment shader. Not used with SkRuntimeEffect.
kFragment_Flag = 0x8,
// This flag indicates that the SkSL uniform uses a medium-precision type
// (i.e., `half` instead of `float`).
kHalfPrecision_Flag = 0x10,
};
SkString name;

View File

@ -105,6 +105,10 @@ SkRuntimeEffect::Uniform SkRuntimeEffectPriv::VarAsUniform(const SkSL::Variable&
type = &type->componentType();
}
if (type->hasPrecision() && !type->highPrecision()) {
uni.flags |= Uniform::kHalfPrecision_Flag;
}
SkAssertResult(init_uniform_type(context, type, &uni));
if (var.modifiers().fLayout.fFlags & SkSL::Layout::Flag::kColor_Flag) {
uni.flags |= Uniform::kColor_Flag;

View File

@ -277,6 +277,7 @@ static void test_good_uniforms(skiatest::Reporter* r) {
constexpr Flags kVS = Uniform::kVertex_Flag;
constexpr Flags kFS = Uniform::kFragment_Flag;
constexpr Flags kColor = Uniform::kColor_Flag;
constexpr Flags kHalfP = Uniform::kHalfPrecision_Flag;
auto make_uni = [](Type type, const char* name, size_t offset, uint32_t flags, int count = 0) {
if (count) {
@ -354,8 +355,8 @@ static void test_good_uniforms(skiatest::Reporter* r) {
"uniform half x[2];",
},
{
make_uni(Type::kFloat, "x", 0, kVS|kFS, 2),
make_uni(Type::kInt, "y", 8, kVS , 0)
make_uni(Type::kFloat, "x", 0, kVS|kFS|kHalfP, 2),
make_uni(Type::kInt, "y", 8, kVS , 0)
}
},
@ -384,8 +385,8 @@ static void test_good_uniforms(skiatest::Reporter* r) {
"uniform int3 i3[1];",
},
{
make_uni(Type::kFloat4x4, "m", 0, kVS|kFS, 4),
make_uni(Type::kInt3, "i3", 256, kFS , 1)
make_uni(Type::kFloat4x4, "m", 0, kVS|kFS|kHalfP, 4),
make_uni(Type::kInt3, "i3", 256, kFS , 1)
}
},
@ -406,14 +407,14 @@ static void test_good_uniforms(skiatest::Reporter* r) {
"uniform int i;"
},
{
make_uni(Type::kFloat, "x" , 0, kVS , 0),
make_uni(Type::kFloat4x4, "m" , 4, kVS|kFS, 4),
make_uni(Type::kInt2, "i2", 260, kVS , 2),
make_uni(Type::kFloat3, "v" , 276, kVS|kFS, 8),
make_uni(Type::kInt3, "i3", 372, kVS , 0),
make_uni(Type::kFloat, "y" , 384, kFS , 0),
make_uni(Type::kInt4, "i4", 388, kFS , 2),
make_uni(Type::kInt, "i" , 420, kFS , 0),
make_uni(Type::kFloat, "x" , 0, kVS , 0),
make_uni(Type::kFloat4x4, "m" , 4, kVS|kFS|kHalfP, 4),
make_uni(Type::kInt2, "i2", 260, kVS , 2),
make_uni(Type::kFloat3, "v" , 276, kVS|kFS , 8),
make_uni(Type::kInt3, "i3", 372, kVS , 0),
make_uni(Type::kFloat, "y" , 384, kFS , 0),
make_uni(Type::kInt4, "i4", 388, kFS , 2),
make_uni(Type::kInt, "i" , 420, kFS , 0),
}
},
};

View File

@ -111,6 +111,30 @@ DEF_TEST(SkRuntimeEffectCanEnableVersion300, r) {
test_valid (r, "#version 300\nfloat f[2] = float[2](0, 1);" EMPTY_MAIN);
}
DEF_TEST(SkRuntimeEffectUniformFlags, r) {
auto [effect, errorText] = SkRuntimeEffect::MakeForShader(SkString(R"(
uniform int simple; // should have no flags
uniform float arrayOfOne[1]; // should have kArray_Flag
uniform float arrayOfMultiple[2]; // should have kArray_Flag
layout(color) uniform float4 color; // should have kColor_Flag
uniform half3 halfPrecisionFloat; // should have kHalfPrecision_Flag
layout(color) uniform half4 allFlags[2]; // should have Array | Color | HalfPrecision
)" EMPTY_MAIN));
REPORTER_ASSERT(r, effect, "%s", errorText.c_str());
SkSpan<const SkRuntimeEffect::Uniform> uniforms = effect->uniforms();
REPORTER_ASSERT(r, uniforms.size() == 6);
REPORTER_ASSERT(r, uniforms[0].flags == 0);
REPORTER_ASSERT(r, uniforms[1].flags == SkRuntimeEffect::Uniform::kArray_Flag);
REPORTER_ASSERT(r, uniforms[2].flags == SkRuntimeEffect::Uniform::kArray_Flag);
REPORTER_ASSERT(r, uniforms[3].flags == SkRuntimeEffect::Uniform::kColor_Flag);
REPORTER_ASSERT(r, uniforms[4].flags == SkRuntimeEffect::Uniform::kHalfPrecision_Flag);
REPORTER_ASSERT(r, uniforms[5].flags == (SkRuntimeEffect::Uniform::kArray_Flag |
SkRuntimeEffect::Uniform::kColor_Flag |
SkRuntimeEffect::Uniform::kHalfPrecision_Flag));
}
DEF_TEST(SkRuntimeEffectForColorFilter, r) {
// Tests that the color filter factory rejects or accepts certain SkSL constructs
auto test_valid = [r](const char* sksl) {