Rearrange SkSL pre-include modules to hide things
This makes numerous internal and GLSL types or intrinsics hidden from public (runtime effect) SkSL. In particular: - Only core numeric types are visible to all program types. GLSL types involving images, textures, and sampling are restricted to internal use. - sk_Caps is no longer visible to runtime effects. - The set of intrinsics available to runtime effects is now a separate, curated list in sksl_public.sksl. It exactly matches the GLSL ES 1.00 spec order. - The blend intrinsics are no longer visible, which also fixes a bug. These are nice, but we're not going to offer them yet - they involve enums, which creates complications. Bug: skia:10680 Bug: skia:10709 Bug: skia:10913 Change-Id: I8fa1c94f6e4899f38530bb9cff33d147f6983ab3 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/332597 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: John Stiles <johnstiles@google.com>
This commit is contained in:
parent
f8f23b2030
commit
bea0dc67f4
1
BUILD.gn
1
BUILD.gn
@ -604,6 +604,7 @@ if (skia_compile_processors || skia_compile_sksl_tests) {
|
||||
"src/sksl/sksl_gpu.sksl",
|
||||
"src/sksl/sksl_interp.sksl",
|
||||
"src/sksl/sksl_pipeline.sksl",
|
||||
"src/sksl/sksl_public.sksl",
|
||||
"src/sksl/sksl_vert.sksl",
|
||||
]
|
||||
outputs = [ "$root_out_dir/{{source_file_part}}" ]
|
||||
|
@ -9,6 +9,9 @@ Milestone 88
|
||||
|
||||
* <insert new release notes here>
|
||||
|
||||
* Limit the types and intrinsics supported in SkRuntimeEffect to GLSL ES 1.00
|
||||
https://review.skia.org/332597
|
||||
|
||||
* Image filters with perspective, for saveLayer and draws, are now drawn correctly. Performance
|
||||
and quality is highest if user bounds are provided to saveLayer.
|
||||
https://review.skia.org/328376
|
||||
|
@ -43,9 +43,9 @@ ByteCodeGenerator::ByteCodeGenerator(const Context* context, const Program* prog
|
||||
: INHERITED(program, errors, nullptr)
|
||||
, fContext(*context)
|
||||
, fOutput(output)
|
||||
// If you're adding new intrinsics here, ensure that they're declared in sksl_interp.inc, so
|
||||
// they're available to "generic" interpreter programs (eg particles).
|
||||
// You can probably copy the declarations from sksl_gpu.inc.
|
||||
// If you're adding new intrinsics here, ensure that they're declared in sksl_interp.sksl or
|
||||
// sksl_public.sksl, so they're available to "generic" interpreter programs (eg particles).
|
||||
// You can probably copy the declarations from sksl_gpu.sksl.
|
||||
, fIntrinsics {
|
||||
{ "abs", ByteCodeInstruction::kAbs },
|
||||
{ "atan", ByteCodeInstruction::kATan },
|
||||
|
@ -61,6 +61,7 @@
|
||||
#include "src/sksl/generated/sksl_gpu.dehydrated.sksl"
|
||||
#include "src/sksl/generated/sksl_interp.dehydrated.sksl"
|
||||
#include "src/sksl/generated/sksl_pipeline.dehydrated.sksl"
|
||||
#include "src/sksl/generated/sksl_public.dehydrated.sksl"
|
||||
#include "src/sksl/generated/sksl_vert.dehydrated.sksl"
|
||||
|
||||
#define MODULE_DATA(name) MakeModuleData(SKSL_INCLUDE_sksl_##name,\
|
||||
@ -89,142 +90,93 @@ Compiler::Compiler(const ShaderCapsClass* caps, Flags flags)
|
||||
, fContext(std::make_shared<Context>())
|
||||
, fErrorCount(0) {
|
||||
fRootSymbolTable = std::make_shared<SymbolTable>(this, /*builtin=*/true);
|
||||
fPrivateSymbolTable = std::make_shared<SymbolTable>(fRootSymbolTable, /*builtin=*/true);
|
||||
fIRGenerator = std::make_unique<IRGenerator>(fContext.get(), &fInliner, *this);
|
||||
#define ADD_TYPE(t) fRootSymbolTable->addWithoutOwnership(fContext->f##t##_Type.get())
|
||||
ADD_TYPE(Void);
|
||||
ADD_TYPE(Float);
|
||||
ADD_TYPE(Float2);
|
||||
ADD_TYPE(Float3);
|
||||
ADD_TYPE(Float4);
|
||||
ADD_TYPE(Half);
|
||||
ADD_TYPE(Half2);
|
||||
ADD_TYPE(Half3);
|
||||
ADD_TYPE(Half4);
|
||||
ADD_TYPE(Int);
|
||||
ADD_TYPE(Int2);
|
||||
ADD_TYPE(Int3);
|
||||
ADD_TYPE(Int4);
|
||||
ADD_TYPE(UInt);
|
||||
ADD_TYPE(UInt2);
|
||||
ADD_TYPE(UInt3);
|
||||
ADD_TYPE(UInt4);
|
||||
ADD_TYPE(Short);
|
||||
ADD_TYPE(Short2);
|
||||
ADD_TYPE(Short3);
|
||||
ADD_TYPE(Short4);
|
||||
ADD_TYPE(UShort);
|
||||
ADD_TYPE(UShort2);
|
||||
ADD_TYPE(UShort3);
|
||||
ADD_TYPE(UShort4);
|
||||
ADD_TYPE(Byte);
|
||||
ADD_TYPE(Byte2);
|
||||
ADD_TYPE(Byte3);
|
||||
ADD_TYPE(Byte4);
|
||||
ADD_TYPE(UByte);
|
||||
ADD_TYPE(UByte2);
|
||||
ADD_TYPE(UByte3);
|
||||
ADD_TYPE(UByte4);
|
||||
ADD_TYPE(Bool);
|
||||
ADD_TYPE(Bool2);
|
||||
ADD_TYPE(Bool3);
|
||||
ADD_TYPE(Bool4);
|
||||
ADD_TYPE(Float2x2);
|
||||
ADD_TYPE(Float2x3);
|
||||
ADD_TYPE(Float2x4);
|
||||
ADD_TYPE(Float3x2);
|
||||
ADD_TYPE(Float3x3);
|
||||
ADD_TYPE(Float3x4);
|
||||
ADD_TYPE(Float4x2);
|
||||
ADD_TYPE(Float4x3);
|
||||
ADD_TYPE(Float4x4);
|
||||
ADD_TYPE(Half2x2);
|
||||
ADD_TYPE(Half2x3);
|
||||
ADD_TYPE(Half2x4);
|
||||
ADD_TYPE(Half3x2);
|
||||
ADD_TYPE(Half3x3);
|
||||
ADD_TYPE(Half3x4);
|
||||
ADD_TYPE(Half4x2);
|
||||
ADD_TYPE(Half4x3);
|
||||
ADD_TYPE(Half4x4);
|
||||
ADD_TYPE(GenType);
|
||||
ADD_TYPE(GenHType);
|
||||
ADD_TYPE(GenIType);
|
||||
ADD_TYPE(GenUType);
|
||||
ADD_TYPE(GenBType);
|
||||
ADD_TYPE(Mat);
|
||||
ADD_TYPE(Vec);
|
||||
ADD_TYPE(GVec);
|
||||
ADD_TYPE(GVec2);
|
||||
ADD_TYPE(GVec3);
|
||||
ADD_TYPE(GVec4);
|
||||
ADD_TYPE(HVec);
|
||||
ADD_TYPE(IVec);
|
||||
ADD_TYPE(UVec);
|
||||
ADD_TYPE(SVec);
|
||||
ADD_TYPE(USVec);
|
||||
ADD_TYPE(ByteVec);
|
||||
ADD_TYPE(UByteVec);
|
||||
ADD_TYPE(BVec);
|
||||
|
||||
ADD_TYPE(Sampler1D);
|
||||
ADD_TYPE(Sampler2D);
|
||||
ADD_TYPE(Sampler3D);
|
||||
ADD_TYPE(SamplerExternalOES);
|
||||
ADD_TYPE(SamplerCube);
|
||||
ADD_TYPE(Sampler2DRect);
|
||||
ADD_TYPE(Sampler1DArray);
|
||||
ADD_TYPE(Sampler2DArray);
|
||||
ADD_TYPE(SamplerCubeArray);
|
||||
ADD_TYPE(SamplerBuffer);
|
||||
ADD_TYPE(Sampler2DMS);
|
||||
ADD_TYPE(Sampler2DMSArray);
|
||||
#define TYPE(t) fContext->f##t##_Type.get()
|
||||
|
||||
ADD_TYPE(ISampler2D);
|
||||
const SkSL::Symbol* rootTypes[] = {
|
||||
TYPE(Void),
|
||||
|
||||
ADD_TYPE(Image2D);
|
||||
ADD_TYPE(IImage2D);
|
||||
TYPE( Float), TYPE( Float2), TYPE( Float3), TYPE( Float4),
|
||||
TYPE( Half), TYPE( Half2), TYPE( Half3), TYPE( Half4),
|
||||
TYPE( Int), TYPE( Int2), TYPE( Int3), TYPE( Int4),
|
||||
TYPE( UInt), TYPE( UInt2), TYPE( UInt3), TYPE( UInt4),
|
||||
TYPE( Short), TYPE( Short2), TYPE( Short3), TYPE( Short4),
|
||||
TYPE(UShort), TYPE(UShort2), TYPE(UShort3), TYPE(UShort4),
|
||||
TYPE( Byte), TYPE( Byte2), TYPE( Byte3), TYPE( Byte4),
|
||||
TYPE( UByte), TYPE( UByte2), TYPE( UByte3), TYPE( UByte4),
|
||||
TYPE( Bool), TYPE( Bool2), TYPE( Bool3), TYPE( Bool4),
|
||||
|
||||
ADD_TYPE(SubpassInput);
|
||||
ADD_TYPE(SubpassInputMS);
|
||||
TYPE(Float2x2), TYPE(Float2x3), TYPE(Float2x4),
|
||||
TYPE(Float3x2), TYPE(Float3x3), TYPE(Float3x4),
|
||||
TYPE(Float4x2), TYPE(Float4x3), TYPE(Float4x4),
|
||||
|
||||
ADD_TYPE(GSampler1D);
|
||||
ADD_TYPE(GSampler2D);
|
||||
ADD_TYPE(GSampler3D);
|
||||
ADD_TYPE(GSamplerCube);
|
||||
ADD_TYPE(GSampler2DRect);
|
||||
ADD_TYPE(GSampler1DArray);
|
||||
ADD_TYPE(GSampler2DArray);
|
||||
ADD_TYPE(GSamplerCubeArray);
|
||||
ADD_TYPE(GSamplerBuffer);
|
||||
ADD_TYPE(GSampler2DMS);
|
||||
ADD_TYPE(GSampler2DMSArray);
|
||||
TYPE(Half2x2), TYPE(Half2x3), TYPE(Half2x4),
|
||||
TYPE(Half3x2), TYPE(Half3x3), TYPE(Half3x4),
|
||||
TYPE(Half4x2), TYPE(Half4x3), TYPE(Half4x4),
|
||||
|
||||
ADD_TYPE(Sampler1DShadow);
|
||||
ADD_TYPE(Sampler2DShadow);
|
||||
ADD_TYPE(SamplerCubeShadow);
|
||||
ADD_TYPE(Sampler2DRectShadow);
|
||||
ADD_TYPE(Sampler1DArrayShadow);
|
||||
ADD_TYPE(Sampler2DArrayShadow);
|
||||
ADD_TYPE(SamplerCubeArrayShadow);
|
||||
ADD_TYPE(GSampler2DArrayShadow);
|
||||
ADD_TYPE(GSamplerCubeArrayShadow);
|
||||
ADD_TYPE(FragmentProcessor);
|
||||
ADD_TYPE(Sampler);
|
||||
ADD_TYPE(Texture2D);
|
||||
TYPE(GenType), TYPE(GenHType), TYPE(GenIType), TYPE(GenUType), TYPE(GenBType),
|
||||
TYPE(Mat), TYPE(Vec),
|
||||
TYPE(GVec), TYPE(GVec2), TYPE(GVec3), TYPE(GVec4),
|
||||
TYPE(HVec), TYPE(IVec), TYPE(UVec), TYPE(SVec), TYPE(USVec),
|
||||
TYPE(ByteVec), TYPE(UByteVec), TYPE(BVec),
|
||||
|
||||
TYPE(FragmentProcessor),
|
||||
};
|
||||
|
||||
const SkSL::Symbol* privateTypes[] = {
|
||||
TYPE(Sampler1D), TYPE(Sampler2D), TYPE(Sampler3D),
|
||||
TYPE(SamplerExternalOES),
|
||||
TYPE(SamplerCube),
|
||||
TYPE(Sampler2DRect),
|
||||
TYPE(Sampler1DArray), TYPE(Sampler2DArray), TYPE(SamplerCubeArray),
|
||||
TYPE(SamplerBuffer),
|
||||
TYPE(Sampler2DMS), TYPE(Sampler2DMSArray),
|
||||
|
||||
TYPE(ISampler2D),
|
||||
TYPE(Image2D), TYPE(IImage2D),
|
||||
TYPE(SubpassInput), TYPE(SubpassInputMS),
|
||||
|
||||
TYPE(GSampler1D), TYPE(GSampler2D), TYPE(GSampler3D),
|
||||
TYPE(GSamplerCube),
|
||||
TYPE(GSampler2DRect),
|
||||
TYPE(GSampler1DArray), TYPE(GSampler2DArray), TYPE(GSamplerCubeArray),
|
||||
TYPE(GSamplerBuffer),
|
||||
TYPE(GSampler2DMS), TYPE(GSampler2DMSArray),
|
||||
|
||||
TYPE(Sampler1DShadow), TYPE(Sampler2DShadow), TYPE(SamplerCubeShadow),
|
||||
TYPE(Sampler2DRectShadow),
|
||||
TYPE(Sampler1DArrayShadow), TYPE(Sampler2DArrayShadow), TYPE(SamplerCubeArrayShadow),
|
||||
|
||||
TYPE(GSampler2DArrayShadow), TYPE(GSamplerCubeArrayShadow),
|
||||
TYPE(Sampler),
|
||||
TYPE(Texture2D),
|
||||
};
|
||||
|
||||
for (const SkSL::Symbol* type : rootTypes) {
|
||||
fRootSymbolTable->addWithoutOwnership(type);
|
||||
}
|
||||
for (const SkSL::Symbol* type : privateTypes) {
|
||||
fPrivateSymbolTable->addWithoutOwnership(type);
|
||||
}
|
||||
|
||||
#undef TYPE
|
||||
|
||||
// sk_Caps is "builtin", but all references to it are resolved to Settings, so we don't need to
|
||||
// treat it as builtin (ie, no need to clone it into the Program).
|
||||
StringFragment skCapsName("sk_Caps");
|
||||
fRootSymbolTable->add(std::make_unique<Variable>(/*offset=*/-1,
|
||||
fIRGenerator->fModifiers->handle(Modifiers()),
|
||||
skCapsName,
|
||||
fContext->fSkCaps_Type.get(),
|
||||
/*builtin=*/false,
|
||||
Variable::Storage::kGlobal));
|
||||
fPrivateSymbolTable->add(
|
||||
std::make_unique<Variable>(/*offset=*/-1,
|
||||
fIRGenerator->fModifiers->handle(Modifiers()),
|
||||
"sk_Caps",
|
||||
fContext->fSkCaps_Type.get(),
|
||||
/*builtin=*/false,
|
||||
Variable::Storage::kGlobal));
|
||||
|
||||
fRootModule = {fRootSymbolTable, /*fIntrinsics=*/nullptr};
|
||||
fPrivateModule = {fPrivateSymbolTable, /*fIntrinsics=*/nullptr};
|
||||
|
||||
fGPUModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(gpu), fRootModule);
|
||||
fGPUModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(gpu), fPrivateModule);
|
||||
fVertexModule = this->parseModule(Program::kVertex_Kind, MODULE_DATA(vert), fGPUModule);
|
||||
fFragmentModule = this->parseModule(Program::kFragment_Kind, MODULE_DATA(frag), fGPUModule);
|
||||
}
|
||||
@ -246,10 +198,17 @@ const ParsedModule& Compiler::loadFPModule() {
|
||||
return fFPModule;
|
||||
}
|
||||
|
||||
const ParsedModule& Compiler::loadPublicModule() {
|
||||
if (!fPublicModule.fSymbols) {
|
||||
fPublicModule = this->parseModule(Program::kGeneric_Kind, MODULE_DATA(public), fRootModule);
|
||||
}
|
||||
return fPublicModule;
|
||||
}
|
||||
|
||||
const ParsedModule& Compiler::loadPipelineModule() {
|
||||
if (!fPipelineModule.fSymbols) {
|
||||
fPipelineModule =
|
||||
this->parseModule(Program::kPipelineStage_Kind, MODULE_DATA(pipeline), fGPUModule);
|
||||
fPipelineModule = this->parseModule(Program::kPipelineStage_Kind, MODULE_DATA(pipeline),
|
||||
this->loadPublicModule());
|
||||
|
||||
// Add some aliases to the pipeline module so that it's friendlier, and more like GLSL
|
||||
fPipelineModule.fSymbols->addAlias("shader", fContext->fFragmentProcessor_Type.get());
|
||||
@ -283,8 +242,8 @@ const ParsedModule& Compiler::loadPipelineModule() {
|
||||
|
||||
const ParsedModule& Compiler::loadInterpreterModule() {
|
||||
if (!fInterpreterModule.fSymbols) {
|
||||
fInterpreterModule =
|
||||
this->parseModule(Program::kGeneric_Kind, MODULE_DATA(interp), fRootModule);
|
||||
fInterpreterModule = this->parseModule(Program::kGeneric_Kind, MODULE_DATA(interp),
|
||||
this->loadPublicModule());
|
||||
}
|
||||
return fInterpreterModule;
|
||||
}
|
||||
@ -305,7 +264,13 @@ LoadedModule Compiler::loadModule(Program::Kind kind,
|
||||
ModuleData data,
|
||||
std::shared_ptr<SymbolTable> base) {
|
||||
if (!base) {
|
||||
base = fRootSymbolTable;
|
||||
// NOTE: This is a workaround. The only time 'base' is null is when dehydrating includes.
|
||||
// In that case, skslc doesn't know which module it's preparing, nor what the correct base
|
||||
// module is. We can't use 'Root', because many GPU intrinsics reference private types,
|
||||
// like samplers or textures. Today, 'Private' does contain the union of all known types,
|
||||
// so this is safe. If we ever have types that only exist in 'Public' (for example), this
|
||||
// logic needs to be smarter (by choosing the correct base for the module we're compiling).
|
||||
base = fPrivateSymbolTable;
|
||||
}
|
||||
|
||||
#if defined(SKSL_STANDALONE)
|
||||
|
@ -221,6 +221,7 @@ public:
|
||||
private:
|
||||
const ParsedModule& loadFPModule();
|
||||
const ParsedModule& loadGeometryModule();
|
||||
const ParsedModule& loadPublicModule();
|
||||
const ParsedModule& loadInterpreterModule();
|
||||
const ParsedModule& loadPipelineModule();
|
||||
|
||||
@ -266,15 +267,20 @@ private:
|
||||
const ShaderCapsClass* fCaps = nullptr;
|
||||
|
||||
std::shared_ptr<SymbolTable> fRootSymbolTable;
|
||||
std::shared_ptr<SymbolTable> fPrivateSymbolTable;
|
||||
|
||||
ParsedModule fRootModule;
|
||||
ParsedModule fGPUModule;
|
||||
ParsedModule fInterpreterModule;
|
||||
ParsedModule fVertexModule;
|
||||
ParsedModule fFragmentModule;
|
||||
ParsedModule fGeometryModule;
|
||||
ParsedModule fPipelineModule;
|
||||
ParsedModule fFPModule;
|
||||
ParsedModule fRootModule; // Core types
|
||||
|
||||
ParsedModule fPrivateModule; // [Root] + Internal types
|
||||
ParsedModule fGPUModule; // [Private] + GPU intrinsics, helper functions
|
||||
ParsedModule fVertexModule; // [GPU] + Vertex stage decls
|
||||
ParsedModule fFragmentModule; // [GPU] + Fragment stage decls
|
||||
ParsedModule fGeometryModule; // [GPU] + Geometry stage decls
|
||||
ParsedModule fFPModule; // [GPU] + FP features
|
||||
|
||||
ParsedModule fPublicModule; // [Root] + Public features
|
||||
ParsedModule fInterpreterModule; // [Public] + Interpreter-only decls
|
||||
ParsedModule fPipelineModule; // [Public] + Runtime effect decls
|
||||
|
||||
// holds ModifiersPools belonging to the core includes for lifetime purposes
|
||||
std::vector<std::unique_ptr<ModifiersPool>> fModifiers;
|
||||
|
File diff suppressed because it is too large
Load Diff
1076
src/sksl/generated/sksl_public.dehydrated.sksl
Normal file
1076
src/sksl/generated/sksl_public.dehydrated.sksl
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,108 +1,27 @@
|
||||
$genType atan($genType y_over_x);
|
||||
$genHType atan($genHType y_over_x);
|
||||
$genType cos($genType y);
|
||||
$genHType cos($genHType y);
|
||||
float dot($genType x, $genType y);
|
||||
half dot($genHType x, $genHType y);
|
||||
$genType fract($genType x);
|
||||
$genHType fract($genHType x);
|
||||
float2x2 inverse(float2x2 m);
|
||||
float3x3 inverse(float3x3 m);
|
||||
float4x4 inverse(float4x4 m);
|
||||
half2x2 inverse(half2x2 m);
|
||||
half3x3 inverse(half3x3 m);
|
||||
half4x4 inverse(half4x4 m);
|
||||
float length($genType x);
|
||||
half length($genHType x);
|
||||
$genType normalize($genType x);
|
||||
$genHType normalize($genHType x);
|
||||
$genType pow($genType x, $genType y);
|
||||
$genHType pow($genHType x, $genHType y);
|
||||
$genType sin($genType x);
|
||||
$genHType sin($genHType x);
|
||||
$genType sqrt($genType x);
|
||||
$genHType sqrt($genHType x);
|
||||
$genType tan($genType x);
|
||||
$genHType tan($genHType x);
|
||||
// Certain useful GLSL intrinsics (or integer versions of those) that aren't in GLSL ES 1.00,
|
||||
// but are supported by the ByteCode interpreter.
|
||||
|
||||
$genType min($genType x, $genType y);
|
||||
$genType min($genType x, float y);
|
||||
$genHType min($genHType x, $genHType y);
|
||||
$genHType min($genHType x, half y);
|
||||
$genIType min($genIType x, $genIType y);
|
||||
$genIType min($genIType x, int y);
|
||||
$genType max($genType x, $genType y);
|
||||
$genType max($genType x, float y);
|
||||
$genHType max($genHType x, $genHType y);
|
||||
$genHType max($genHType x, half y);
|
||||
$genIType min($genIType x, int y);
|
||||
$genIType max($genIType x, $genIType y);
|
||||
$genIType max($genIType x, int y);
|
||||
$genType clamp($genType x, $genType minVal, $genType maxVal);
|
||||
$genType clamp($genType x, float minVal, float maxVal);
|
||||
$genHType clamp($genHType x, $genHType minVal, $genHType maxVal);
|
||||
$genHType clamp($genHType x, half minVal, half maxVal);
|
||||
$genIType max($genIType x, int y);
|
||||
$genIType clamp($genIType x, $genIType minVal, $genIType maxVal);
|
||||
$genIType clamp($genIType x, int minVal, int maxVal);
|
||||
$genType saturate($genType x);
|
||||
$genHType saturate($genHType x);
|
||||
$genIType clamp($genIType x, int minVal, int maxVal);
|
||||
|
||||
$genType mix($genType x, $genType y, $genBType a);
|
||||
$genHType mix($genHType x, $genHType y, $genBType a);
|
||||
$genIType mix($genIType x, $genIType y, $genBType a);
|
||||
$genBType mix($genBType x, $genBType y, $genBType a);
|
||||
|
||||
$genType mix($genType x, $genType y, $genType a);
|
||||
$genType mix($genType x, $genType y, float a);
|
||||
$genHType mix($genHType x, $genHType y, $genHType a);
|
||||
$genHType mix($genHType x, $genHType y, half a);
|
||||
|
||||
$bvec lessThan($vec x, $vec y);
|
||||
$bvec lessThan($hvec x, $hvec y);
|
||||
$bvec lessThan($ivec x, $ivec y);
|
||||
$bvec lessThan($uvec x, $uvec y);
|
||||
$bvec lessThanEqual($vec x, $vec y);
|
||||
$bvec lessThanEqual($hvec x, $hvec y);
|
||||
$bvec lessThanEqual($ivec x, $ivec y);
|
||||
$bvec lessThanEqual($uvec x, $uvec y);
|
||||
$bvec greaterThan($vec x, $vec y);
|
||||
$bvec greaterThan($hvec x, $hvec y);
|
||||
$bvec greaterThan($ivec x, $ivec y);
|
||||
$bvec greaterThan($uvec x, $uvec y);
|
||||
$bvec greaterThanEqual($vec x, $vec y);
|
||||
$bvec greaterThanEqual($hvec x, $hvec y);
|
||||
$bvec greaterThanEqual($ivec x, $ivec y);
|
||||
$bvec greaterThanEqual($uvec x, $uvec y);
|
||||
$bvec equal($vec x, $vec y);
|
||||
$bvec equal($hvec x, $hvec y);
|
||||
$bvec equal($ivec x, $ivec y);
|
||||
$bvec equal($uvec x, $uvec y);
|
||||
$bvec equal($bvec x, $bvec y);
|
||||
$bvec notEqual($vec x, $vec y);
|
||||
$bvec notEqual($hvec x, $hvec y);
|
||||
$bvec notEqual($ivec x, $ivec y);
|
||||
$bvec notEqual($uvec x, $uvec y);
|
||||
$bvec notEqual($bvec x, $bvec y);
|
||||
|
||||
bool any($bvec x);
|
||||
bool all($bvec x);
|
||||
$bvec not($bvec x);
|
||||
|
||||
float degrees(float rad) { return rad * 57.2957795; }
|
||||
float2 degrees(float2 rad) { return rad * 57.2957795; }
|
||||
float3 degrees(float3 rad) { return rad * 57.2957795; }
|
||||
float4 degrees(float4 rad) { return rad * 57.2957795; }
|
||||
|
||||
float radians(float deg) { return deg * 0.0174532925; }
|
||||
float2 radians(float2 deg) { return deg * 0.0174532925; }
|
||||
float3 radians(float3 deg) { return deg * 0.0174532925; }
|
||||
float4 radians(float4 deg) { return deg * 0.0174532925; }
|
||||
|
||||
float distance(float2 a, float2 b) { return length(a - b); }
|
||||
float distance(float3 a, float3 b) { return length(a - b); }
|
||||
float distance(float4 a, float4 b) { return length(a - b); }
|
||||
|
||||
float3 cross(float3 a, float3 b) {
|
||||
return float3(a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x);
|
||||
}
|
||||
|
133
src/sksl/sksl_public.sksl
Normal file
133
src/sksl/sksl_public.sksl
Normal file
@ -0,0 +1,133 @@
|
||||
// Reduced set of intrinsics that are available to public SkSL (RuntimeEffect and Interpreter)
|
||||
|
||||
// See "The OpenGL ES Shading Language, Version 1.00, Section 8"
|
||||
// For all of the TODO comments, refer to skbug.com/10913
|
||||
|
||||
// 8.1 : Angle and Trigonometry Functions
|
||||
float radians(float deg) { return deg * 0.0174532925; }
|
||||
float2 radians(float2 deg) { return deg * 0.0174532925; }
|
||||
float3 radians(float3 deg) { return deg * 0.0174532925; }
|
||||
float4 radians(float4 deg) { return deg * 0.0174532925; }
|
||||
|
||||
float degrees(float rad) { return rad * 57.2957795; }
|
||||
float2 degrees(float2 rad) { return rad * 57.2957795; }
|
||||
float3 degrees(float3 rad) { return rad * 57.2957795; }
|
||||
float4 degrees(float4 rad) { return rad * 57.2957795; }
|
||||
|
||||
$genType sin($genType angle);
|
||||
$genHType sin($genHType angle);
|
||||
$genType cos($genType angle);
|
||||
$genHType cos($genHType angle);
|
||||
$genType tan($genType angle);
|
||||
$genHType tan($genHType angle);
|
||||
// TODO: asin(x)
|
||||
// TODO: acos(y)
|
||||
// TODO: atan(y, x)
|
||||
$genType atan($genType y_over_x);
|
||||
$genHType atan($genHType y_over_x);
|
||||
|
||||
// 8.2 : Exponential Functions
|
||||
$genType pow($genType x, $genType y);
|
||||
$genHType pow($genHType x, $genHType y);
|
||||
// TODO: exp
|
||||
// TODO: log
|
||||
// TODO: exp2
|
||||
// TODO: log2
|
||||
$genType sqrt($genType x);
|
||||
$genHType sqrt($genHType x);
|
||||
// TODO: inversesqrt
|
||||
|
||||
// 8.3 : Common Functions
|
||||
$genType abs($genType x);
|
||||
$genHType abs($genHType x);
|
||||
// TODO: sign(x)
|
||||
$genType floor($genType x);
|
||||
$genHType floor($genHType x);
|
||||
$genType ceil($genType x);
|
||||
$genHType ceil($genHType x);
|
||||
$genType fract($genType x);
|
||||
$genHType fract($genHType x);
|
||||
// TODO: mod(x, y)
|
||||
|
||||
$genType min($genType x, $genType y);
|
||||
$genType min($genType x, float y);
|
||||
$genHType min($genHType x, $genHType y);
|
||||
$genHType min($genHType x, half y);
|
||||
$genType max($genType x, $genType y);
|
||||
$genType max($genType x, float y);
|
||||
$genHType max($genHType x, $genHType y);
|
||||
$genHType max($genHType x, half y);
|
||||
$genType clamp($genType x, $genType minVal, $genType maxVal);
|
||||
$genType clamp($genType x, float minVal, float maxVal);
|
||||
$genHType clamp($genHType x, $genHType minVal, $genHType maxVal);
|
||||
$genHType clamp($genHType x, half minVal, half maxVal);
|
||||
$genType mix($genType x, $genType y, $genType a);
|
||||
$genType mix($genType x, $genType y, float a);
|
||||
$genHType mix($genHType x, $genHType y, $genHType a);
|
||||
$genHType mix($genHType x, $genHType y, half a);
|
||||
// TODO: step(edge, x)
|
||||
// TODO: smoothstep(edge0, edge1, x)
|
||||
|
||||
// SkSL Extension to GLSL:
|
||||
$genType saturate($genType x);
|
||||
$genHType saturate($genHType x);
|
||||
|
||||
// 8.4 : Geometric Functions
|
||||
float length($genType x);
|
||||
half length($genHType x);
|
||||
|
||||
float distance(float2 a, float2 b) { return length(a - b); }
|
||||
float distance(float3 a, float3 b) { return length(a - b); }
|
||||
float distance(float4 a, float4 b) { return length(a - b); }
|
||||
|
||||
float dot($genType x, $genType y);
|
||||
half dot($genHType x, $genHType y);
|
||||
|
||||
float3 cross(float3 a, float3 b) {
|
||||
return float3(a.y * b.z - a.z * b.y,
|
||||
a.z * b.x - a.x * b.z,
|
||||
a.x * b.y - a.y * b.x);
|
||||
}
|
||||
|
||||
$genType normalize($genType x);
|
||||
$genHType normalize($genHType x);
|
||||
// TODO: faceforward(N, I, Nref)
|
||||
// TODO: reflect(I, N)
|
||||
// TODO: refract(I, N, eta)
|
||||
|
||||
// 8.5 : Matrix Functions
|
||||
// TODO: matrixCompMult(x, y)
|
||||
|
||||
// Not supported until GLSL 1.40. Poly-filled by SkSL:
|
||||
float2x2 inverse(float2x2 m);
|
||||
float3x3 inverse(float3x3 m);
|
||||
float4x4 inverse(float4x4 m);
|
||||
half2x2 inverse(half2x2 m);
|
||||
half3x3 inverse(half3x3 m);
|
||||
half4x4 inverse(half4x4 m);
|
||||
|
||||
// 8.6 : Vector Relational Functions
|
||||
$bvec lessThan($vec x, $vec y);
|
||||
$bvec lessThan($hvec x, $hvec y);
|
||||
$bvec lessThanEqual($vec x, $vec y);
|
||||
$bvec lessThanEqual($hvec x, $hvec y);
|
||||
$bvec greaterThan($vec x, $vec y);
|
||||
$bvec greaterThan($hvec x, $hvec y);
|
||||
$bvec greaterThanEqual($vec x, $vec y);
|
||||
$bvec greaterThanEqual($hvec x, $hvec y);
|
||||
$bvec equal($vec x, $vec y);
|
||||
$bvec equal($hvec x, $hvec y);
|
||||
$bvec equal($bvec x, $bvec y);
|
||||
$bvec notEqual($vec x, $vec y);
|
||||
$bvec notEqual($hvec x, $hvec y);
|
||||
$bvec notEqual($bvec x, $bvec y);
|
||||
|
||||
bool any($bvec x);
|
||||
bool all($bvec x);
|
||||
$bvec not($bvec x);
|
||||
|
||||
// Miscellaneous SkSL intrinsics that are not part of GLSL:
|
||||
|
||||
// The max() guards against division by zero when the incoming color is transparent black
|
||||
half4 unpremul (half4 color) { return half4 (color.rgb / max(color.a, 0.0001), color.a); }
|
||||
float4 unpremul_float(float4 color) { return float4(color.rgb / max(color.a, 0.0001), color.a); }
|
@ -39,8 +39,11 @@ DEF_TEST(SkRuntimeEffectInvalid, r) {
|
||||
test("in bool Flag; layout(when=Flag) uniform float Input;", "", "when");
|
||||
test("layout(tracked) uniform float Input;", "", "tracked");
|
||||
|
||||
// Runtime SkSL supports a limited set of uniform types. No samplers, bool, or int, for example:
|
||||
test("uniform sampler2D s;", "", "uniform");
|
||||
// GLSL types like sampler2D and texture2D are not allowed anywhere:
|
||||
test("uniform sampler2D s;", "", "no type named 'sampler2D'");
|
||||
test("uniform texture2D s;", "", "no type named 'texture2D'");
|
||||
|
||||
// Runtime SkSL supports a limited set of uniform types. No bool, or int, for example:
|
||||
test("uniform bool b;", "", "uniform");
|
||||
test("uniform int i;", "", "uniform");
|
||||
|
||||
@ -75,6 +78,9 @@ DEF_TEST(SkRuntimeEffectInvalid, r) {
|
||||
"half4 color = sample(p.x > 10 ? child1 : child2);",
|
||||
"expression");
|
||||
|
||||
// sk_Caps is an internal system. It should not be visible to runtime effects
|
||||
test("", "if (sk_Caps.integerSupport) { p = p.yx; }", "unknown identifier 'sk_Caps'");
|
||||
|
||||
// Errors that aren't caught until later in the compilation process (during optimize())
|
||||
test("", "return half4(1);", "unreachable");
|
||||
test("half badFunc() { }", "", "without returning");
|
||||
|
Loading…
Reference in New Issue
Block a user