diff --git a/include/sksl/DSLType.h b/include/sksl/DSLType.h index 115711c6f0..9d1d5f5ca5 100644 --- a/include/sksl/DSLType.h +++ b/include/sksl/DSLType.h @@ -88,7 +88,8 @@ public: DSLType(skstd::string_view name); - DSLType(skstd::string_view name, const DSLModifiers& modifiers, + DSLType(skstd::string_view name, + DSLModifiers* modifiers, PositionInfo pos = PositionInfo::Capture()); /** diff --git a/resources/sksl/runtime/PrecisionQualifiers.rts b/resources/sksl/runtime/PrecisionQualifiers.rts index 18b77f0157..bc7baa3cd0 100644 --- a/resources/sksl/runtime/PrecisionQualifiers.rts +++ b/resources/sksl/runtime/PrecisionQualifiers.rts @@ -48,6 +48,10 @@ bool test_array() { return mf[0] == hf[0] && hv[0] == mv[0] && mv[1] == hv[1]; } +bool highp_param (highp float value) { return value == 1; } +bool mediump_param(mediump float value) { return value == 2; } +bool lowp_param (lowp float value) { return value == 3; } + vec4 main(vec2 coords) { highp vec4 zero = vec4(0); mediump vec4 one = vec4(1); @@ -57,5 +61,6 @@ vec4 main(vec2 coords) { highp vec4 red = colorRed; red = (red + zero) * one; - return (test_scalar() && test_vector() && test_matrix() && test_array()) ? green : red; + return (test_scalar() && test_vector() && test_matrix() && test_array() && + highp_param(1) && mediump_param(2) && lowp_param(3)) ? green : red; } diff --git a/src/sksl/SkSLDSLParser.cpp b/src/sksl/SkSLDSLParser.cpp index 95de449259..830bac6e00 100644 --- a/src/sksl/SkSLDSLParser.cpp +++ b/src/sksl/SkSLDSLParser.cpp @@ -321,7 +321,7 @@ bool DSLParser::declaration() { this->structVarDeclaration(modifiers); return true; } - skstd::optional type = this->type(modifiers); + skstd::optional type = this->type(&modifiers); if (!type) { return false; } @@ -551,7 +551,7 @@ DSLStatement DSLParser::varDeclarationsOrExpressionStatement() { bool DSLParser::varDeclarationsPrefix(VarDeclarationsPrefix* prefixData) { prefixData->fPosition = this->position(this->peek()); prefixData->fModifiers = this->modifiers(); - skstd::optional type = this->type(prefixData->fModifiers); + skstd::optional type = this->type(&prefixData->fModifiers); if (!type) { return false; } @@ -588,8 +588,7 @@ skstd::optional DSLParser::structDeclaration() { SkTArray fields; while (!this->checkNext(Token::Kind::TK_RBRACE)) { DSLModifiers modifiers = this->modifiers(); - - skstd::optional type = this->type(modifiers); + skstd::optional type = this->type(&modifiers); if (!type) { return skstd::nullopt; } @@ -639,7 +638,7 @@ SkTArray DSLParser::structVarDeclaration(const DSLModifiers& /* modifiers type IDENTIFIER (LBRACKET INT_LITERAL RBRACKET)? */ skstd::optional> DSLParser::parameter() { DSLModifiers modifiers = this->modifiersWithDefaults(0); - skstd::optional type = this->type(modifiers); + skstd::optional type = this->type(&modifiers); if (!type) { return skstd::nullopt; } @@ -833,7 +832,7 @@ DSLStatement DSLParser::statement() { } /* IDENTIFIER(type) (LBRACKET intLiteral? RBRACKET)* QUESTION? */ -skstd::optional DSLParser::type(const DSLModifiers& modifiers) { +skstd::optional DSLParser::type(DSLModifiers* modifiers) { Token type; if (!this->expect(Token::Kind::TK_IDENTIFIER, "a type", &type)) { return skstd::nullopt; @@ -873,7 +872,7 @@ bool DSLParser::interfaceBlock(const dsl::DSLModifiers& modifiers) { SkTArray fields; while (!this->checkNext(Token::Kind::TK_RBRACE)) { DSLModifiers fieldModifiers = this->modifiers(); - skstd::optional type = this->type(fieldModifiers); + skstd::optional type = this->type(&fieldModifiers); if (!type) { return false; } diff --git a/src/sksl/SkSLDSLParser.h b/src/sksl/SkSLDSLParser.h index 6dc12bba0b..e01f5584a0 100644 --- a/src/sksl/SkSLDSLParser.h +++ b/src/sksl/SkSLDSLParser.h @@ -188,7 +188,7 @@ private: dsl::DSLStatement statement(); - skstd::optional type(const dsl::DSLModifiers& modifiers); + skstd::optional type(dsl::DSLModifiers* modifiers); bool interfaceBlock(const dsl::DSLModifiers& mods); diff --git a/src/sksl/dsl/DSLType.cpp b/src/sksl/dsl/DSLType.cpp index 4b529bf9b4..7e010f2a1a 100644 --- a/src/sksl/dsl/DSLType.cpp +++ b/src/sksl/dsl/DSLType.cpp @@ -41,7 +41,7 @@ static const Type* find_type(skstd::string_view name, PositionInfo pos) { return &result; } -static const Type* find_type(skstd::string_view name, const Modifiers& modifiers, +static const Type* find_type(skstd::string_view name, Modifiers* modifiers, PositionInfo pos) { const Type* type = find_type(name, pos); if (!type) { @@ -56,8 +56,8 @@ static const Type* find_type(skstd::string_view name, const Modifiers& modifiers DSLType::DSLType(skstd::string_view name) : fSkSLType(find_type(name, PositionInfo())) {} -DSLType::DSLType(skstd::string_view name, const DSLModifiers& modifiers, PositionInfo position) - : fSkSLType(find_type(name, modifiers.fModifiers, position)) {} +DSLType::DSLType(skstd::string_view name, DSLModifiers* modifiers, PositionInfo position) + : fSkSLType(find_type(name, &modifiers->fModifiers, position)) {} bool DSLType::isBoolean() const { return this->skslType().isBoolean(); diff --git a/src/sksl/ir/SkSLType.cpp b/src/sksl/ir/SkSLType.cpp index 05eb14378c..63376a3b42 100644 --- a/src/sksl/ir/SkSLType.cpp +++ b/src/sksl/ir/SkSLType.cpp @@ -472,13 +472,13 @@ CoercionCost Type::coercionCost(const Type& other) const { } const Type* Type::applyPrecisionQualifiers(const Context& context, - const Modifiers& modifiers, + Modifiers* modifiers, SymbolTable* symbols, int line) const { // SkSL doesn't support low precision, so `lowp` is interpreted as medium precision. - bool highp = modifiers.fFlags & Modifiers::kHighp_Flag; - bool mediump = modifiers.fFlags & Modifiers::kMediump_Flag; - bool lowp = modifiers.fFlags & Modifiers::kLowp_Flag; + bool highp = modifiers->fFlags & Modifiers::kHighp_Flag; + bool mediump = modifiers->fFlags & Modifiers::kMediump_Flag; + bool lowp = modifiers->fFlags & Modifiers::kLowp_Flag; if (!lowp && !mediump && !highp) { // No precision qualifiers here. Return the type as-is. @@ -497,6 +497,11 @@ const Type* Type::applyPrecisionQualifiers(const Context& context, return nullptr; } + // We're going to return a whole new type, so the modifier bits can be cleared out. + modifiers->fFlags &= ~(Modifiers::kHighp_Flag | + Modifiers::kMediump_Flag | + Modifiers::kLowp_Flag); + const Type& component = this->componentType(); if (component.highPrecision()) { if (highp) { diff --git a/src/sksl/ir/SkSLType.h b/src/sksl/ir/SkSLType.h index e1617708a2..5b8343cbed 100644 --- a/src/sksl/ir/SkSLType.h +++ b/src/sksl/ir/SkSLType.h @@ -532,7 +532,7 @@ public: * don't make sense, e.g. `highp bool` or `mediump MyStruct`. */ const Type* applyPrecisionQualifiers(const Context& context, - const Modifiers& modifiers, + Modifiers* modifiers, SymbolTable* symbols, int line) const; diff --git a/tests/SkSLTest.cpp b/tests/SkSLTest.cpp index cfc0fccb68..941658394e 100644 --- a/tests/SkSLTest.cpp +++ b/tests/SkSLTest.cpp @@ -266,6 +266,7 @@ SKSL_TEST_ES3(SkSLIntrinsicUintBitsToFloat, "intrinsics/UintBitsToFloat.sksl" SKSL_TEST_ES3(SkSLArrayNarrowingConversions, "runtime/ArrayNarrowingConversions.rts") SKSL_TEST_ES3(SkSLLoopFloat, "runtime/LoopFloat.rts") SKSL_TEST_ES3(SkSLLoopInt, "runtime/LoopInt.rts") +SKSL_TEST(SkSLPrecisionQualifiers, "runtime/PrecisionQualifiers.rts") SKSL_TEST_ES3(SkSLArrayComparison, "shared/ArrayComparison.sksl") SKSL_TEST_ES3(SkSLArrayConstructors, "shared/ArrayConstructors.sksl") diff --git a/tests/sksl/runtime/PrecisionQualifiers.stage b/tests/sksl/runtime/PrecisionQualifiers.stage index 0d93a6250a..95016b2848 100644 --- a/tests/sksl/runtime/PrecisionQualifiers.stage +++ b/tests/sksl/runtime/PrecisionQualifiers.stage @@ -3,6 +3,9 @@ uniform half4 colorRed; bool test_vector_0(); bool test_matrix_0(); bool test_array_0(); +bool highp_param_0(float value); +bool mediump_param_0(half value); +bool lowp_param_0(half value); bool test_vector_0() { half2 mp2 = half2(2.0); @@ -43,6 +46,18 @@ bool test_array_0() hv[1] = float2(2.0, 3.0); return (float(mf[0]) == hf[0] && hv[0] == float2(mv[0])) && float2(mv[1]) == hv[1]; } +bool highp_param_0(float value) +{ + return value == 1.0; +} +bool mediump_param_0(half value) +{ + return value == 2.0; +} +bool lowp_param_0(half value) +{ + return value == 3.0; +} float4 main(float2 coords) { float4 zero = float4(0.0); @@ -55,5 +70,5 @@ float4 main(float2 coords) float _1_hp = float(_0_mp); int _2_ihp = 2; short _3_imp = short(_2_ihp); - return half4((((float(_0_mp) == _1_hp && _2_ihp == int(_3_imp)) && test_vector_0()) && test_matrix_0()) && test_array_0() ? float4(green) : red); + return half4(((((((float(_0_mp) == _1_hp && _2_ihp == int(_3_imp)) && test_vector_0()) && test_matrix_0()) && test_array_0()) && highp_param_0(1.0)) && mediump_param_0(2.0)) && lowp_param_0(3.0) ? float4(green) : red); }