46 , fTargetType(targetType) {}
68 int rows()
const override {
69 return fTargetType.
rows();
145 using INHERITED =
Type;
147 const Type& fTargetType;
190 return fComponentType;
212 return fCount * fComponentType.
slotCount();
221 using INHERITED =
Type;
223 const Type& fComponentType;
236 SkASSERT(fNumTypes <= std::size(fCoercibleTypes));
241 return SkSpan(fCoercibleTypes, fNumTypes);
249 using INHERITED =
Type;
251 const Type* fCoercibleTypes[9];
252 const Type* fSlotType;
262 , fScalarType(scalarType)
315 using INHERITED =
Type;
317 const Type& fScalarType;
385 : short_limits::lowest();
392 return float_limits::lowest();
401 : short_limits::max();
405 : ushort_limits::max();
409 return float_limits::max();
414 using INHERITED =
Type;
439 using INHERITED =
Type;
457 return fComponentType;
477 return fColumns == fRows;
481 return fColumns * fRows;
486 return fComponentType;
490 using INHERITED =
Type;
506 , fIsArrayed(isArrayed)
523 return fIsMultisampled;
527 return fTextureAccess;
536 using INHERITED =
Type;
541 bool fIsMultisampled;
588 using INHERITED =
Type;
601 , fNestingDepth(nestingDepth)
602 , fInterfaceBlock(interfaceBlock)
604 for (
const Field& f : fFields) {
605 fContainsArray = fContainsArray || f.fType->isOrContainsArray();
606 fContainsUnsizedArray = fContainsUnsizedArray || f.fType->isOrContainsUnsizedArray();
607 fContainsAtomic = fContainsAtomic || f.fType->isOrContainsAtomic();
608 fIsAllowedInES2 = fIsAllowedInES2 && f.fType->isAllowedInES2();
610 for (
const Field& f : fFields) {
611 Position errorPosition = f.fPosition;
612 if (!f.fType->isAllowedInUniform(&errorPosition)) {
613 fUniformErrorPosition = errorPosition;
617 if (!fContainsUnsizedArray) {
618 for (
const Field& f : fFields) {
619 fSlotCount += f.fType->slotCount();
633 return fInterfaceBlock;
641 return fIsAllowedInES2;
645 if (errorPosition !=
nullptr) {
646 *errorPosition = fUniformErrorPosition;
648 return !fUniformErrorPosition.
valid();
652 return fContainsArray;
656 return fContainsUnsizedArray;
660 return fContainsAtomic;
669 return fNestingDepth;
673 for (
const Field& field : fFields) {
674 size_t fieldSlots = field.fType->
slotCount();
675 if (n < fieldSlots) {
676 return field.fType->slotType(n);
686 using INHERITED =
Type;
689 size_t fSlotCount = 0;
690 int fNestingDepth = 0;
691 Position fUniformErrorPosition = {};
692 bool fInterfaceBlock =
false;
693 bool fContainsArray =
false;
694 bool fContainsUnsizedArray =
false;
695 bool fContainsAtomic =
false;
696 bool fIsBuiltin =
false;
697 bool fIsAllowedInES2 =
true;
713 return fComponentType;
746 return fComponentType;
750 using INHERITED =
Type;
757 std::string_view
name = this->
name();
765 return std::make_unique<AliasType>(std::move(
name), targetType);
769 std::string_view
name,
770 const Type& componentType,
778 const Type* slotType) {
779 return std::make_unique<GenericType>(
name, types,
slotType);
784 return std::make_unique<LiteralType>(
name, scalarType,
priority);
788 const Type& componentType,
int columns, int8_t rows) {
808 return std::make_unique<AtomicType>(
name, abbrev);
813 std::string_view
name,
815 bool interfaceBlock) {
816 const char*
const structOrIB = interfaceBlock ?
"interface block" :
"struct";
817 const char*
const aStructOrIB = interfaceBlock ?
"an interface block" :
"a struct";
821 "' must contain at least one field");
828 int numFieldNames = fieldNames.
count();
829 fieldNames.
add(field.fName);
830 if (fieldNames.
count() == numFieldNames) {
831 context.
fErrors->
error(field.fPosition,
"field '" + std::string(field.fName) +
832 "' was already defined in the same " +
833 std::string(structOrIB) +
" ('" +
834 std::string(
name) +
"')");
837 std::string desc = field.fModifierFlags.description();
838 context.
fErrors->
error(field.fPosition,
"modifier '" + desc +
"' is not permitted on " +
839 std::string(aStructOrIB) +
" field");
842 context.
fErrors->
error(field.fPosition,
"layout qualifier 'binding' is not permitted "
843 "on " + std::string(aStructOrIB) +
" field");
846 context.
fErrors->
error(field.fPosition,
"layout qualifier 'set' is not permitted on " +
847 std::string(aStructOrIB) +
" field");
850 if (field.fType->isVoid()) {
851 context.
fErrors->
error(field.fPosition,
"type 'void' is not permitted in " +
852 std::string(aStructOrIB));
854 if (field.fType->isOpaque() && !field.fType->isAtomic()) {
855 context.
fErrors->
error(field.fPosition,
"opaque type '" + field.fType->displayName() +
856 "' is not permitted in " +
857 std::string(aStructOrIB));
859 if (field.fType->isOrContainsUnsizedArray()) {
860 if (!interfaceBlock) {
862 context.
fErrors->
error(field.fPosition,
"unsized arrays are not permitted here");
870 context.
fErrors->
error(
pos, std::string(structOrIB) +
" is too large");
875 int nestingDepth = 0;
877 nestingDepth = std::max(nestingDepth, field.fType->structNestingDepth());
881 "' is too deeply nested");
883 return std::make_unique<StructType>(
pos,
name, std::move(
fields), nestingDepth + 1,
888 bool isArrayedTexture,
bool isMultisampled,
895 const Type& componentType,
int columns) {
904 (this->isVector() || this->isMatrix() || this->isArray())) {
919 }
else if (other.
priority() >= this->priority()) {
927 for (
size_t i = 0; i < types.
size(); i++) {
928 if (types[i]->
matches(other)) {
964 context.
fErrors->
error(
pos,
"only one precision qualifier can be used");
982 const Type* mediumpType;
1010 "' does not support precision qualifiers");
1036 ?
"'readonly' and 'writeonly' qualifiers cannot be combined"
1037 :
"'texture2D' requires a 'readonly' or 'writeonly' access qualifier");
1041 if (accessQualifiers) {
1043 "qualifier '" + accessQualifiers.
description() +
"'");
1051 if (columns == 1 &&
rows == 1) {
1198 if (existingSymbol !=
nullptr) {
1199 const Type* existingType = &existingSymbol->
as<
Type>();
1201 return existingType;
1213 return symbolTable->
add(
1215 std::make_unique<StructType>(this->
fPosition,
1218 this->structNestingDepth(),
1219 this->isInterfaceBlock(),
1229 const Context& context)
const {
1230 if (!expr || expr->isIncomplete(context)) {
1233 if (expr->type().matches(*
this)) {
1239 if (!expr->coercionCost(*this).isPossible(settings.fAllowNarrowingConversions)) {
1241 expr->type().displayName() +
"'");
1263 bool foundError =
false;
1271 for (
int slot = 0; slot < numSlots; ++slot) {
1274 if (slotVal.has_value() &&
1303 context.
fErrors->
error(arrayPos,
"multi-dimensional arrays are not supported");
1307 context.
fErrors->
error(arrayPos,
"type 'void' may not be used in an array");
1311 context.
fErrors->
error(arrayPos,
"opaque type '" + std::string(this->
name()) +
1312 "' may not be used in an array");
1320 std::unique_ptr<Expression> size)
const {
1321 size = context.
fTypes.
fInt->coerceExpression(std::move(size), context);
1327 context.
fErrors->
error(size->fPosition,
"array size must be an integer");
1342 context.
fErrors->
error(sizePos,
"array size must be positive");
1350 context.
fErrors->
error(sizePos,
"array size is too large");
1359 ' ' + std::string(
fName) +
';';
#define SkDEBUGFAIL(message)
#define SK_ABORT(message,...)
#define SkDEBUGFAILF(fmt,...)
static int SkPopCount(uint32_t n)
constexpr size_t SkToSizeT(S x)
SK_ALWAYS_INLINE constexpr int value() const
size_t slotCount() const override
SpvDim_ dimensions() const override
bool isStruct() const override
int bitWidth() const override
bool isArrayedTexture() const override
bool isDepth() const override
bool isVector() const override
bool isMultisampled() const override
int columns() const override
const Type & slotType(size_t n) const override
int rows() const override
bool isScalar() const override
bool isUnsizedArray() const override
int priority() const override
TextureAccess textureAccess() const override
bool isMatrix() const override
const Type & componentType() const override
bool isInterfaceBlock() const override
SkSpan< const Type *const > coercibleTypes() const override
bool isAllowedInES2() const override
bool isLiteral() const override
NumberKind numberKind() const override
bool isArray() const override
AliasType(std::string_view name, const Type &targetType)
const Type & resolve() const override
int columns() const override
bool isArray() const override
const Type & componentType() const override
bool isOrContainsAtomic() const override
bool isOrContainsArray() const override
bool isBuiltin() const override
bool isUnsizedArray() const override
bool isAllowedInES2() const override
const Type & slotType(size_t n) const override
bool isOrContainsUnsizedArray() const override
int bitWidth() const override
size_t slotCount() const override
static constexpr TypeKind kTypeKind
ArrayType(std::string_view name, const char *abbrev, const Type &componentType, int count, bool isBuiltin)
bool isAllowedInUniform(Position *errorPosition) const override
bool isAllowedInUniform(Position *) const override
const Type & slotType(size_t n) const override
AtomicType(std::string_view name, const char *abbrev)
bool isOrContainsAtomic() const override
static constexpr TypeKind kTypeKind
bool isAllowedInES2() const override
const std::unique_ptr< Type > fFloat2
const std::unique_ptr< Type > fFloatLiteral
const std::unique_ptr< Type > fHalf4
const std::unique_ptr< Type > fFloat4x3
const std::unique_ptr< Type > fInt4
const std::unique_ptr< Type > fHalf2x3
const std::unique_ptr< Type > fHalf2x2
const std::unique_ptr< Type > fUInt2
const std::unique_ptr< Type > fShort3
const std::unique_ptr< Type > fInt2
const std::unique_ptr< Type > fUShort
const std::unique_ptr< Type > fInt
const std::unique_ptr< Type > fHalf4x3
const std::unique_ptr< Type > fFloat3x2
const std::unique_ptr< Type > fTexture2D
const std::unique_ptr< Type > fFloat2x2
const std::unique_ptr< Type > fFloat3x4
const std::unique_ptr< Type > fHalf3x4
const std::unique_ptr< Type > fIntLiteral
const std::unique_ptr< Type > fFloat4x4
const std::unique_ptr< Type > fShort2
const std::unique_ptr< Type > fShort
const std::unique_ptr< Type > fInt3
const std::unique_ptr< Type > fHalf2x4
const std::unique_ptr< Type > fUInt3
const std::unique_ptr< Type > fUShort4
const std::unique_ptr< Type > fFloat4
const std::unique_ptr< Type > fHalf2
const std::unique_ptr< Type > fUInt4
const std::unique_ptr< Type > fHalf3x3
const std::unique_ptr< Type > fShort4
const std::unique_ptr< Type > fBool2
const std::unique_ptr< Type > fFloat3x3
const std::unique_ptr< Type > fUShort2
const std::unique_ptr< Type > fBool3
const std::unique_ptr< Type > fWriteOnlyTexture2D
const std::unique_ptr< Type > fHalf4x2
const std::unique_ptr< Type > fUInt
const std::unique_ptr< Type > fFloat2x3
const std::unique_ptr< Type > fUShort3
const std::unique_ptr< Type > fBool
const std::unique_ptr< Type > fVoid
const std::unique_ptr< Type > fHalf3
const std::unique_ptr< Type > fFloat2x4
const std::unique_ptr< Type > fFloat
const std::unique_ptr< Type > fFloat3
const std::unique_ptr< Type > fHalf
const std::unique_ptr< Type > fPoison
const std::unique_ptr< Type > fHalf3x2
const std::unique_ptr< Type > fHalf4x4
const std::unique_ptr< Type > fFloat4x2
const std::unique_ptr< Type > fReadOnlyTexture2D
const std::unique_ptr< Type > fBool4
static bool GetConstantInt(const Expression &value, SKSL_INT *out)
static const Expression * GetConstantValueForVariable(const Expression &value)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
static std::unique_ptr< Expression > Make(const Context &context, Position pos, const Type &type, std::unique_ptr< Expression > arg)
const BuiltinTypes & fTypes
SymbolTable * fSymbolTable
void error(Position position, std::string_view msg)
virtual const Type & type() const
virtual bool supportsConstantValues() const
virtual std::optional< double > getConstantValue(int n) const
SkSpan< const Type *const > coercibleTypes() const override
static constexpr TypeKind kTypeKind
const Type & slotType(size_t) const override
GenericType(const char *name, SkSpan< const Type *const > coercibleTypes, const Type *slotType)
bool isScalar() const override
const Type & slotType(size_t n) const override
int priority() const override
LiteralType(const char *name, const Type &scalarType, int8_t priority)
double minimumValue() const override
double maximumValue() const override
const Type & scalarTypeForLiteral() const override
NumberKind numberKind() const override
int bitWidth() const override
bool isLiteral() const override
size_t slotCount() const override
int rows() const override
static constexpr TypeKind kTypeKind
int columns() const override
int rows() const override
int bitWidth() const override
MatrixType(std::string_view name, const char *abbrev, const Type &componentType, int8_t columns, int8_t rows)
int columns() const override
bool isAllowedInES2() const override
static constexpr TypeKind kTypeKind
bool isMatrix() const override
const Type & slotType(size_t n) const override
const ScalarType & componentType() const override
size_t slotCount() const override
std::string paddedDescription() const
std::string description() const
const TextureType & textureType() const override
TextureAccess textureAccess() const override
bool isDepth() const override
static constexpr TypeKind kTypeKind
SamplerType(const char *name, const Type &textureType)
const Type & slotType(size_t n) const override
SpvDim_ dimensions() const override
bool isMultisampled() const override
bool isArrayedTexture() const override
bool isAllowedInUniform(Position *) const override
ScalarType(std::string_view name, const char *abbrev, NumberKind numberKind, int8_t priority, int8_t bitWidth)
int bitWidth() const override
std::numeric_limits< float > float_limits
bool isScalar() const override
size_t slotCount() const override
std::numeric_limits< uint16_t > ushort_limits
int priority() const override
double minimumValue() const override
static constexpr TypeKind kTypeKind
NumberKind numberKind() const override
int columns() const override
std::numeric_limits< int32_t > int_limits
const Type & slotType(size_t n) const override
std::numeric_limits< uint32_t > uint_limits
std::numeric_limits< int16_t > short_limits
bool isAllowedInES2() const override
double maximumValue() const override
int rows() const override
bool isInterfaceBlock() const override
const Type & slotType(size_t n) const override
int structNestingDepth() const override
size_t slotCount() const override
bool isOrContainsAtomic() const override
SkSpan< const Field > fields() const override
StructType(Position pos, std::string_view name, TArray< Field > fields, int nestingDepth, bool interfaceBlock, bool isBuiltin)
bool isOrContainsArray() const override
bool isOrContainsUnsizedArray() const override
bool isAllowedInUniform(Position *errorPosition) const override
bool isStruct() const override
bool isAllowedInES2() const override
static constexpr TypeKind kTypeKind
bool isBuiltin() const override
const Type * addArrayDimension(const Context &context, const Type *type, int arraySize)
const Symbol * find(std::string_view name) const
const std::string * takeOwnershipOfString(std::string n)
T * add(const Context &context, std::unique_ptr< T > symbol)
std::string_view name() const
const Type & type() const
static constexpr TypeKind kTypeKind
SpvDim_ dimensions() const override
const Type & slotType(size_t n) const override
bool isDepth() const override
bool isArrayedTexture() const override
TextureAccess textureAccess() const override
TextureType(const char *name, SpvDim_ dimensions, bool isDepth, bool isArrayed, bool isMultisampled, TextureAccess textureAccess)
bool isMultisampled() const override
virtual const Type & slotType(size_t) const
static std::unique_ptr< Type > MakeAliasType(std::string_view name, const Type &targetType)
static std::unique_ptr< Type > MakeTextureType(const char *name, SpvDim_ dimensions, bool isDepth, bool isArrayedTexture, bool isMultisampled, TextureAccess textureAccess)
virtual bool isArray() const
const Type * applyPrecisionQualifiers(const Context &context, ModifierFlags *modifierFlags, Position pos) const
bool isInRootSymbolTable() const
virtual int bitWidth() const
bool highPrecision() const
static std::unique_ptr< Type > MakeScalarType(std::string_view name, const char *abbrev, Type::NumberKind numberKind, int8_t priority, int8_t bitWidth)
virtual bool isVector() const
CoercionCost coercionCost(const Type &other) const
static std::unique_ptr< Type > MakeArrayType(const Context &context, std::string_view name, const Type &componentType, int columns)
virtual int priority() const
bool isAllowedInES2(const Context &context) const
std::unique_ptr< Expression > coerceExpression(std::unique_ptr< Expression > expr, const Context &context) const
virtual const Type & componentType() const
virtual bool isInterfaceBlock() const
SKSL_INT convertArraySize(const Context &context, Position arrayPos, std::unique_ptr< Expression > size) const
const char * abbreviatedName() const
virtual SkSpan< const Field > fields() const
bool matches(const Type &other) const
virtual bool isMatrix() const
virtual bool isDepth() const
static std::unique_ptr< Type > MakeSamplerType(const char *name, const Type &textureType)
virtual bool isLiteral() const
virtual TextureAccess textureAccess() const
bool checkIfUsableInArray(const Context &context, Position arrayPos) const
static std::unique_ptr< Type > MakeGenericType(const char *name, SkSpan< const Type *const > types, const Type *slotType)
virtual const Type & textureType() const
virtual int columns() const
virtual size_t slotCount() const
static constexpr int kUnsizedArray
virtual bool isScalar() const
virtual NumberKind numberKind() const
virtual bool isAllowedInES2() const
virtual bool isUnsizedArray() const
virtual bool isAllowedInUniform(Position *errorPosition=nullptr) const
std::string description() const override
static std::unique_ptr< Type > MakeLiteralType(const char *name, const Type &scalarType, int8_t priority)
const Type * applyAccessQualifiers(const Context &context, ModifierFlags *modifierFlags, Position pos) const
static std::unique_ptr< Type > MakeStructType(const Context &context, Position pos, std::string_view name, skia_private::TArray< Field > fields, bool interfaceBlock=false)
static std::unique_ptr< Type > MakeMatrixType(std::string_view name, const char *abbrev, const Type &componentType, int columns, int8_t rows)
virtual double maximumValue() const
std::string getArrayName(int arraySize) const
static std::unique_ptr< Type > MakeAtomicType(std::string_view name, const char *abbrev)
virtual bool isOrContainsAtomic() const
virtual bool isMultisampled() const
virtual SkSpan< const Type *const > coercibleTypes() const
virtual bool isArrayedTexture() const
static std::unique_ptr< Type > MakeSpecialType(const char *name, const char *abbrev, Type::TypeKind typeKind)
bool checkForOutOfRangeLiteral(const Context &context, const Expression &expr) const
static std::unique_ptr< Type > MakeVectorType(std::string_view name, const char *abbrev, const Type &componentType, int columns)
std::string displayName() const
const Type & toCompound(const Context &context, int columns, int rows) const
TypeKind typeKind() const
virtual bool isStruct() const
const Type * clone(const Context &context, SymbolTable *symbolTable) const
virtual SpvDim_ dimensions() const
virtual double minimumValue() const
virtual bool isOrContainsUnsizedArray() const
const Type * applyQualifiers(const Context &context, ModifierFlags *modifierFlags, Position pos) const
bool isAllowedInUniform(Position *errorPosition) const override
VectorType(std::string_view name, const char *abbrev, const Type &componentType, int8_t columns)
const ScalarType & componentType() const override
const Type & slotType(size_t n) const override
bool isVector() const override
size_t slotCount() const override
bool isAllowedInES2() const override
int bitWidth() const override
int columns() const override
int rows() const override
static constexpr TypeKind kTypeKind
static size_t Add(size_t x, size_t y)
static size_t Mul(size_t x, size_t y)
constexpr T * data() const
constexpr size_t size() const
std::string printf(const char *fmt,...) SK_PRINTF_LIKE(1
static constexpr int kMaxStructDepth
static constexpr int kVariableSlotLimit
static CoercionCost Impossible()
static CoercionCost Narrowing(int cost)
static CoercionCost Free()
static CoercionCost Normal(int cost)
std::string description() const
ModifierFlags fModifierFlags
std::string paddedDescription() const
static bool IsRuntimeEffect(ProgramKind kind)
bool strictES2Mode() const
ProgramSettings fSettings