diff options
Diffstat (limited to 'source/slang')
| -rw-r--r-- | source/slang/check.cpp | 121 | ||||
| -rw-r--r-- | source/slang/compiler.h | 3 | ||||
| -rw-r--r-- | source/slang/core.meta.slang | 40 | ||||
| -rw-r--r-- | source/slang/core.meta.slang.h | 40 | ||||
| -rw-r--r-- | source/slang/dxc-support.cpp | 15 | ||||
| -rw-r--r-- | source/slang/emit.cpp | 29 | ||||
| -rw-r--r-- | source/slang/lexer.cpp | 59 | ||||
| -rw-r--r-- | source/slang/mangle.cpp | 59 | ||||
| -rw-r--r-- | source/slang/parser.cpp | 25 | ||||
| -rw-r--r-- | source/slang/reflection.cpp | 19 | ||||
| -rw-r--r-- | source/slang/slang-stdlib.cpp | 12 | ||||
| -rw-r--r-- | source/slang/syntax.cpp | 51 | ||||
| -rw-r--r-- | source/slang/syntax.h | 2 | ||||
| -rw-r--r-- | source/slang/type-defs.h | 1 | ||||
| -rw-r--r-- | source/slang/type-layout.cpp | 68 | ||||
| -rw-r--r-- | source/slang/type-layout.h | 6 | ||||
| -rw-r--r-- | source/slang/type-system-shared.h | 5 |
17 files changed, 272 insertions, 283 deletions
diff --git a/source/slang/check.cpp b/source/slang/check.cpp index 7f91ac0c3..bddf813f2 100644 --- a/source/slang/check.cpp +++ b/source/slang/check.cpp @@ -205,41 +205,6 @@ namespace Slang typeCheckingCache = nullptr; } - bool IsNumeric(BaseType t) - { - return t == BaseType::Int || t == BaseType::Float || t == BaseType::UInt; - } - - String TranslateHLSLTypeNames(String name) - { - if (name == "float2" || name == "half2") - return "vec2"; - else if (name == "float3" || name == "half3") - return "vec3"; - else if (name == "float4" || name == "half4") - return "vec4"; - else if (name == "half") - return "float"; - else if (name == "int2") - return "ivec2"; - else if (name == "int3") - return "ivec3"; - else if (name == "int4") - return "ivec4"; - else if (name == "uint2") - return "uvec2"; - else if (name == "uint3") - return "uvec3"; - else if (name == "uint4") - return "uvec4"; - else if (name == "float3x3" || name == "half3x3") - return "mat3"; - else if (name == "float4x4" || name == "half4x4") - return "mat4"; - else - return name; - } - enum class CheckingPhase { Header, Body @@ -2916,25 +2881,37 @@ namespace Slang decl->SetCheckState(getCheckedState()); } + bool isIntegerBaseType(BaseType baseType) + { + switch(baseType) + { + default: + return false; + + case BaseType::Int8: + case BaseType::Int16: + case BaseType::Int: + case BaseType::Int64: + case BaseType::UInt8: + case BaseType::UInt16: + case BaseType::UInt: + case BaseType::UInt64: + return true; + } + } + // Validate that `type` is a suitable type to use // as the tag type for an `enum` void validateEnumTagType(Type* type, SourceLoc const& loc) { if(auto basicType = type->As<BasicExpressionType>()) { - switch(basicType->baseType) - { - default: - // By default, don't allow a type to be used - // as an `enum` tag type. - break; - - case BaseType::Int: - case BaseType::UInt: - case BaseType::UInt64: - // These are all allowed. + // Allow the built-in intteger types. + if(isIntegerBaseType(basicType->baseType)) return; - } + + // By default, don't allow other types to be used + // as an `enum` tag type. } getSink()->diagnose(loc, Diagnostics::invalidEnumTagType, type); @@ -4420,16 +4397,8 @@ namespace Slang // Check if type is acceptable for an integer constant expression if(auto basicType = exp->type.type->As<BasicExpressionType>()) { - switch(basicType->baseType) - { - default: + if(!isIntegerBaseType(basicType->baseType)) return nullptr; - - case BaseType::Int: - case BaseType::UInt: - case BaseType::UInt64: - break; - } } else { @@ -7724,46 +7693,6 @@ namespace Slang // Now process this like any other explicit call (so casts // and constructor calls are semantically equivalent). return CheckInvokeExprWithCheckedOperands(expr); - -#if 0 - expr->Expression = CheckTerm(expr->Expression); - auto targetType = CheckProperType(expr->TargetType); - expr->TargetType = targetType; - - // The way to perform casting depends on the types involved - if (expr->Expression->type->Equals(getSession()->getErrorType())) - { - // If the expression being casted has an error type, then just silently succeed - expr->type = targetType.Ptr(); - return expr; - } - else if (auto targetArithType = targetType->AsArithmeticType()) - { - if (auto exprArithType = expr->Expression->type->AsArithmeticType()) - { - // Both source and destination types are arithmetic, so we might - // have a valid cast - auto targetScalarType = targetArithType->GetScalarType(); - auto exprScalarType = exprArithType->GetScalarType(); - - if (!IsNumeric(exprScalarType->baseType)) goto fail; - if (!IsNumeric(targetScalarType->baseType)) goto fail; - - // TODO(tfoley): this checking is incomplete here, and could - // lead to downstream compilation failures - expr->type = targetType.Ptr(); - return expr; - } - } - // TODO: other cases? Should we allow a cast to succeeed whenever - // a single-argument constructor for the target type would work? - - fail: - // Default: in no other case succeds, then the cast failed and we emit a diagnostic. - getSink()->diagnose(expr, Diagnostics::invalidTypeCast, expr->Expression->type, targetType->ToString()); - expr->type = QualType(getSession()->getErrorType()); - return expr; -#endif } // Get the type to use when referencing a declaration diff --git a/source/slang/compiler.h b/source/slang/compiler.h index c6a114d7d..bf71dd217 100644 --- a/source/slang/compiler.h +++ b/source/slang/compiler.h @@ -550,10 +550,13 @@ namespace Slang void initializeTypes(); Type* getBoolType(); + Type* getHalfType(); Type* getFloatType(); Type* getDoubleType(); Type* getIntType(); + Type* getInt64Type(); Type* getUIntType(); + Type* getUInt64Type(); Type* getVoidType(); Type* getBuiltinType(BaseType flavor); diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 31da44f3c..b5b78c2e5 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -1,5 +1,14 @@ // Slang `core` library +// Aliases for base types +typedef half float16_t; +typedef float float32_t; +typedef double float64_t; + +typedef int int32_t; +typedef uint uint32_t; + + // Modifier for variables that must resolve to compile-time constants // as part of translation. syntax constexpr : ConstExprModifier; @@ -72,9 +81,14 @@ for (int tt = 0; tt < kBaseTypeCount; ++tt) sb << "\n , __BuiltinFloatingPointType\n"; sb << "\n , __BuiltinRealType\n"; // fall through to: + case BaseType::Int8: + case BaseType::Int16: case BaseType::Int: + case BaseType::Int64: sb << "\n , __BuiltinSignedArithmeticType\n"; // fall through to: + case BaseType::UInt8: + case BaseType::UInt16: case BaseType::UInt: case BaseType::UInt64: sb << "\n , __BuiltinArithmeticType\n"; @@ -121,6 +135,7 @@ for (int tt = 0; tt < kBaseTypeCount; ++tt) // switch (kBaseTypes[tt].tag) { + // TODO: should this cover the full gamut of integer types? case BaseType::Int: case BaseType::UInt: }}}} @@ -196,10 +211,27 @@ static const struct { char const* glslPrefix; } kTypes[] = { - {"float", ""}, - {"int", "i"}, - {"uint", "u"}, - {"bool", "b"}, + {"half", "f16"}, + {"float", ""}, + {"double", "d"}, + + {"float16_t", "f16"}, + {"float32_t", "f32"}, + {"float64_t", "f64"}, + + {"int8_t", "i8"}, + {"int16_t", "i16"}, + {"int32_t", "i32"}, + {"int", "i"}, + {"int64_t", "i64"}, + + {"uint8_t", "u8"}, + {"uint16_t", "u16"}, + {"uint32_t", "u32"}, + {"uint", "u"}, + {"uint64_t", "u64"}, + + {"bool", "b"}, }; static const int kTypeCount = sizeof(kTypes) / sizeof(kTypes[0]); diff --git a/source/slang/core.meta.slang.h b/source/slang/core.meta.slang.h index 12c76d213..c69878112 100644 --- a/source/slang/core.meta.slang.h +++ b/source/slang/core.meta.slang.h @@ -1,5 +1,14 @@ SLANG_RAW("// Slang `core` library\n") SLANG_RAW("\n") +SLANG_RAW("// Aliases for base types\n") +SLANG_RAW("typedef half float16_t;\n") +SLANG_RAW("typedef float float32_t;\n") +SLANG_RAW("typedef double float64_t;\n") +SLANG_RAW("\n") +SLANG_RAW("typedef int int32_t;\n") +SLANG_RAW("typedef uint uint32_t;\n") +SLANG_RAW("\n") +SLANG_RAW("\n") SLANG_RAW("// Modifier for variables that must resolve to compile-time constants\n") SLANG_RAW("// as part of translation.\n") SLANG_RAW("syntax constexpr : ConstExprModifier;\n") @@ -72,9 +81,14 @@ for (int tt = 0; tt < kBaseTypeCount; ++tt) sb << "\n , __BuiltinFloatingPointType\n"; sb << "\n , __BuiltinRealType\n"; // fall through to: + case BaseType::Int8: + case BaseType::Int16: case BaseType::Int: + case BaseType::Int64: sb << "\n , __BuiltinSignedArithmeticType\n"; // fall through to: + case BaseType::UInt8: + case BaseType::UInt16: case BaseType::UInt: case BaseType::UInt64: sb << "\n , __BuiltinArithmeticType\n"; @@ -121,6 +135,7 @@ for (int tt = 0; tt < kBaseTypeCount; ++tt) // switch (kBaseTypes[tt].tag) { + // TODO: should this cover the full gamut of integer types? case BaseType::Int: case BaseType::UInt: SLANG_RAW("\n") @@ -211,10 +226,27 @@ static const struct { char const* glslPrefix; } kTypes[] = { - {"float", ""}, - {"int", "i"}, - {"uint", "u"}, - {"bool", "b"}, + {"half", "f16"}, + {"float", ""}, + {"double", "d"}, + + {"float16_t", "f16"}, + {"float32_t", "f32"}, + {"float64_t", "f64"}, + + {"int8_t", "i8"}, + {"int16_t", "i16"}, + {"int32_t", "i32"}, + {"int", "i"}, + {"int64_t", "i64"}, + + {"uint8_t", "u8"}, + {"uint16_t", "u16"}, + {"uint32_t", "u32"}, + {"uint", "u"}, + {"uint64_t", "u64"}, + + {"bool", "b"}, }; static const int kTypeCount = sizeof(kTypes) / sizeof(kTypes[0]); diff --git a/source/slang/dxc-support.cpp b/source/slang/dxc-support.cpp index 68b46f1b9..30817d31c 100644 --- a/source/slang/dxc-support.cpp +++ b/source/slang/dxc-support.cpp @@ -129,6 +129,21 @@ namespace Slang String profileName = GetHLSLProfileName(profile); OSString wideProfileName = profileName.ToWString(); + // We will enable the flag to generate proper code for 16-bit types + // by default, as long as the user is requesting a sufficiently + // high shader model. + // + // TODO: Need to check that this is safe to enable in all cases, + // or if it will make a shader demand hardware features that + // aren't always present. + // + // TODO: Ideally the dxc back-end should be passed some information + // on the "capabilities" that were used and/or requested in the code. + // + if( profile.GetVersion() >= ProfileVersion::DX_6_2 ) + { + args[argCount++] = L"-enable-16bit-types"; + } IDxcOperationResult* dxcResult = nullptr; if (FAILED(dxcCompiler->Compile(dxcSourceBlob, diff --git a/source/slang/emit.cpp b/source/slang/emit.cpp index 74678ef94..1e833838c 100644 --- a/source/slang/emit.cpp +++ b/source/slang/emit.cpp @@ -786,10 +786,20 @@ struct EmitVisitor // no prefix break; - case kIROp_IntType: Emit("i"); break; - case kIROp_UIntType: Emit("u"); break; - case kIROp_BoolType: Emit("b"); break; - case kIROp_DoubleType: Emit("d"); break; + case kIROp_Int8Type: Emit("i8"); break; + case kIROp_Int16Type: Emit("i16"); break; + case kIROp_IntType: Emit("i"); break; + case kIROp_Int64Type: Emit("i64"); break; + + case kIROp_UInt8Type: Emit("u8"); break; + case kIROp_UInt16Type: Emit("u16"); break; + case kIROp_UIntType: Emit("u"); break; + case kIROp_UInt64Type: Emit("u64"); break; + + case kIROp_BoolType: Emit("b"); break; + + case kIROp_HalfType: Emit("f16"); break; + case kIROp_DoubleType: Emit("d"); break; case kIROp_VectorType: emitGLSLTypePrefix(cast<IRVectorType>(type)->getElementType()); @@ -1179,9 +1189,18 @@ struct EmitVisitor break; case kIROp_VoidType: Emit("void"); return; + case kIROp_BoolType: Emit("bool"); return; + + case kIROp_Int8Type: Emit("int8_t"); return; + case kIROp_Int16Type: Emit("int16_t"); return; case kIROp_IntType: Emit("int"); return; + case kIROp_Int64Type: Emit("int64_t"); return; + + case kIROp_UInt8Type: Emit("uint8_t"); return; + case kIROp_UInt16Type: Emit("uint16_t"); return; case kIROp_UIntType: Emit("uint"); return; - case kIROp_BoolType: Emit("bool"); return; + case kIROp_UInt64Type: Emit("uint64_t"); return; + case kIROp_HalfType: Emit("half"); return; case kIROp_FloatType: Emit("float"); return; case kIROp_DoubleType: Emit("double"); return; diff --git a/source/slang/lexer.cpp b/source/slang/lexer.cpp index 5e6d15384..9ea86cc82 100644 --- a/source/slang/lexer.cpp +++ b/source/slang/lexer.cpp @@ -393,55 +393,28 @@ namespace Slang static TokenType maybeLexNumberSuffix(Lexer* lexer, TokenType tokenType) { - // First check for suffixes that - // indicate a floating-point number - switch(peek(lexer)) - { - case 'f': case 'F': - advance(lexer); - return TokenType::FloatingPointLiteral; - - default: - break; - } - - // Once we've ruled out floating-point - // suffixes, we can check for the inter cases - - // TODO: allow integer suffixes in any order... - - // Leading `u` or `U` for unsigned - switch(peek(lexer)) - { - default: - break; - - case 'u': case 'U': - advance(lexer); - break; - } - - // Optional `l`, `L`, `ll`, or `LL` - switch(peek(lexer)) + // Be liberal in what we accept here, so that figuring out + // the semantics of a numeric suffix is left up to the parser + // and semantic checking logic. + // + for( ;;) { - default: - break; + int c = peek(lexer); - case 'l': case 'L': - advance(lexer); - switch(peek(lexer)) + // Accept any alphanumeric character, plus underscores. + if(('a' <= c ) && (c <= 'z') + || ('A' <= c) && (c <= 'Z') + || ('0' <= c) && (c <= '9') + || (c == '_')) { - default: - break; - - case 'l': case 'L': advance(lexer); - break; + continue; } - break; - } - return tokenType; + // Stop at the first character that isn't + // alphanumeric. + return tokenType; + } } static bool isNumberExponent(int c, int base) diff --git a/source/slang/mangle.cpp b/source/slang/mangle.cpp index dc2738d8f..c35ad1e14 100644 --- a/source/slang/mangle.cpp +++ b/source/slang/mangle.cpp @@ -78,6 +78,33 @@ namespace Slang emitVal(context, val); } + void emitBaseType( + ManglingContext* context, + BaseType baseType) + { + switch( baseType ) + { + case BaseType::Void: emitRaw(context, "V"); break; + case BaseType::Bool: emitRaw(context, "b"); break; + case BaseType::Int8: emitRaw(context, "c"); break; + case BaseType::Int16: emitRaw(context, "s"); break; + case BaseType::Int: emitRaw(context, "i"); break; + case BaseType::Int64: emitRaw(context, "I"); break; + case BaseType::UInt8: emitRaw(context, "C"); break; + case BaseType::UInt16: emitRaw(context, "S"); break; + case BaseType::UInt: emitRaw(context, "u"); break; + case BaseType::UInt64: emitRaw(context, "U"); break; + case BaseType::Half: emitRaw(context, "h"); break; + case BaseType::Float: emitRaw(context, "f"); break; + case BaseType::Double: emitRaw(context, "d"); break; + break; + + default: + SLANG_UNEXPECTED("unimplemented case in mangling"); + break; + } + } + void emitType( ManglingContext* context, Type* type) @@ -86,22 +113,7 @@ namespace Slang if( auto basicType = dynamic_cast<BasicExpressionType*>(type) ) { - switch( basicType->baseType ) - { - case BaseType::Void: emitRaw(context, "V"); break; - case BaseType::Bool: emitRaw(context, "b"); break; - case BaseType::Int: emitRaw(context, "i"); break; - case BaseType::UInt: emitRaw(context, "u"); break; - case BaseType::UInt64: emitRaw(context, "U"); break; - case BaseType::Half: emitRaw(context, "h"); break; - case BaseType::Float: emitRaw(context, "f"); break; - case BaseType::Double: emitRaw(context, "d"); break; - break; - - default: - SLANG_UNEXPECTED("unimplemented case in mangling"); - break; - } + emitBaseType(context, basicType->baseType); } else if( auto vecType = dynamic_cast<VectorExpressionType*>(type) ) { @@ -212,19 +224,10 @@ namespace Slang ManglingContext* context, IRInst* inst) { - switch (inst->op) + if(auto basicType = as<IRBasicType>(inst) ) { - case kIROp_VoidType: emitRaw(context, "V"); return; - case kIROp_BoolType: emitRaw(context, "b"); return; - case kIROp_IntType: emitRaw(context, "i"); return; - case kIROp_UIntType: emitRaw(context, "u"); return; - case kIROp_UInt64Type: emitRaw(context, "U"); return; - case kIROp_HalfType: emitRaw(context, "h"); return; - case kIROp_FloatType: emitRaw(context, "f"); return; - case kIROp_DoubleType: emitRaw(context, "d"); return; - - default: - break; + emitBaseType(context, basicType->getBaseType()); + return; } if (auto globalVal = as<IRGlobalValue>(inst)) diff --git a/source/slang/parser.cpp b/source/slang/parser.cpp index e3982aee4..37cc24459 100644 --- a/source/slang/parser.cpp +++ b/source/slang/parser.cpp @@ -4035,8 +4035,17 @@ namespace Slang { suffixType = parser->getSession()->getIntType(); } - // TODO: probably need `ll` and `ull` - // TODO: are there other suffixes we need to handle? + // `ull` suffix -> `uint64_t` + else if(uCount == 1 && lCount == 2) + { + suffixType = parser->getSession()->getUInt64Type(); + } + // `ll` suffix -> `int64_t` + else if(uCount == 0 && lCount == 2) + { + suffixType = parser->getSession()->getInt64Type(); + } + // TODO: do we need suffixes for smaller integer types? else { parser->sink->diagnose(token, Diagnostics::invalidIntegerLiteralSuffix, suffix); @@ -4070,6 +4079,7 @@ namespace Slang { int fCount = 0; int lCount = 0; + int hCount = 0; int unknownCount = 0; while(*suffixCursor) { @@ -4083,6 +4093,10 @@ namespace Slang lCount++; break; + case 'h': case 'H': + hCount++; + break; + default: unknownCount++; break; @@ -4099,11 +4113,16 @@ namespace Slang { suffixType = parser->getSession()->getFloatType(); } - // `l` or `lf` suffix on float -> `double` + // `l` or `lf` suffix on floating-point literal -> `double` else if(lCount == 1 && (fCount <= 1)) { suffixType = parser->getSession()->getDoubleType(); } + // `h` or `hf` suffix on floating-point literal -> `half` + else if(lCount == 1 && (fCount <= 1)) + { + suffixType = parser->getSession()->getHalfType(); + } // TODO: are there other suffixes we need to handle? else { diff --git a/source/slang/reflection.cpp b/source/slang/reflection.cpp index 9a593d18b..6e635a8ce 100644 --- a/source/slang/reflection.cpp +++ b/source/slang/reflection.cpp @@ -326,12 +326,19 @@ SLANG_API SlangScalarType spReflectionType_GetScalarType(SlangReflectionType* in #define CASE(BASE, TAG) \ case BaseType::BASE: return SLANG_SCALAR_TYPE_##TAG - CASE(Void, VOID); - CASE(Int, INT32); - CASE(Float, FLOAT32); - CASE(UInt, UINT32); - CASE(Bool, BOOL); - CASE(UInt64, UINT64); + CASE(Void, VOID); + CASE(Bool, BOOL); + CASE(Int8, INT8); + CASE(Int16, INT16); + CASE(Int, INT32); + CASE(Int64, INT64); + CASE(UInt8, UINT8); + CASE(UInt16, UINT16); + CASE(UInt, UINT32); + CASE(UInt64, UINT64); + CASE(Half, FLOAT16); + CASE(Float, FLOAT32); + CASE(Double, FLOAT64); #undef CASE diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index bd2ce2561..5a4718af4 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -102,15 +102,19 @@ namespace Slang { "bool", BaseType::Bool, BOOL_MASK, kBaseTypeConversionKind_Unsigned, kBaseTypeConversionRank_Bool }, - // TODO: should declare explicit types for 8-, 16-, 32- and 64-bit integers - { "int", BaseType::Int, SINT_MASK, kBaseTypeConversionKind_Signed, kBaseTypeConversionRank_Int32}, + { "int8_t", BaseType::Int8, SINT_MASK, kBaseTypeConversionKind_Signed, kBaseTypeConversionRank_Int8}, + { "int16_t", BaseType::Int16, SINT_MASK, kBaseTypeConversionKind_Signed, kBaseTypeConversionRank_Int16}, + { "int", BaseType::Int, SINT_MASK, kBaseTypeConversionKind_Signed, kBaseTypeConversionRank_Int32}, + { "int64_t", BaseType::Int64, SINT_MASK, kBaseTypeConversionKind_Signed, kBaseTypeConversionRank_Int64}, { "half", BaseType::Half, FLOAT_MASK, kBaseTypeConversionKind_Float, kBaseTypeConversionRank_Int16}, { "float", BaseType::Float, FLOAT_MASK, kBaseTypeConversionKind_Float, kBaseTypeConversionRank_Int32}, { "double", BaseType::Double, FLOAT_MASK, kBaseTypeConversionKind_Float, kBaseTypeConversionRank_Int64}, - { "uint", BaseType::UInt, UINT_MASK, kBaseTypeConversionKind_Unsigned, kBaseTypeConversionRank_Int32}, - { "uint64_t", BaseType::UInt64, UINT_MASK, kBaseTypeConversionKind_Unsigned, kBaseTypeConversionRank_Int64}, + { "uint8_t", BaseType::UInt8, UINT_MASK, kBaseTypeConversionKind_Unsigned, kBaseTypeConversionRank_Int8}, + { "uint16_t", BaseType::UInt16, UINT_MASK, kBaseTypeConversionKind_Unsigned, kBaseTypeConversionRank_Int16}, + { "uint", BaseType::UInt, UINT_MASK, kBaseTypeConversionKind_Unsigned, kBaseTypeConversionRank_Int32}, + { "uint64_t", BaseType::UInt64, UINT_MASK, kBaseTypeConversionKind_Unsigned, kBaseTypeConversionRank_Int64}, }; // Given two base types, we need to be able to compute the cost of converting between them. diff --git a/source/slang/syntax.cpp b/source/slang/syntax.cpp index bb6d6a575..c1585a51a 100644 --- a/source/slang/syntax.cpp +++ b/source/slang/syntax.cpp @@ -24,42 +24,6 @@ namespace Slang return this; } - Slang::String BasicExpressionType::ToString() - { - Slang::StringBuilder res; - - switch (this->baseType) - { - case Slang::BaseType::Int: - res.Append("int"); - break; - case Slang::BaseType::UInt: - res.Append("uint"); - break; - case Slang::BaseType::UInt64: - res.Append("uint64_t"); - break; - case Slang::BaseType::Bool: - res.Append("bool"); - break; - case Slang::BaseType::Float: - res.Append("float"); - break; - case Slang::BaseType::Double: - res.Append("double"); - break; - case Slang::BaseType::Half: - res.Append("half"); - break; - case Slang::BaseType::Void: - res.Append("void"); - break; - default: - break; - } - return res.ProduceString(); - } - // Generate dispatch logic and other definitions for all syntax classes #define SYNTAX_CLASS(NAME, BASE) /* empty */ #include "object-meta-begin.h" @@ -235,6 +199,11 @@ void Type::accept(IValVisitor* visitor, void* extra) return getBuiltinType(BaseType::Bool); } + Type* Session::getHalfType() + { + return getBuiltinType(BaseType::Half); + } + Type* Session::getFloatType() { return getBuiltinType(BaseType::Float); @@ -250,11 +219,21 @@ void Type::accept(IValVisitor* visitor, void* extra) return getBuiltinType(BaseType::Int); } + Type* Session::getInt64Type() + { + return getBuiltinType(BaseType::Int64); + } + Type* Session::getUIntType() { return getBuiltinType(BaseType::UInt); } + Type* Session::getUInt64Type() + { + return getBuiltinType(BaseType::UInt64); + } + Type* Session::getVoidType() { return getBuiltinType(BaseType::Void); diff --git a/source/slang/syntax.h b/source/slang/syntax.h index 00f7eb95b..24660b7fd 100644 --- a/source/slang/syntax.h +++ b/source/slang/syntax.h @@ -49,7 +49,7 @@ namespace Slang kConversionCost_CastToInterface = 50, // Conversion that is lossless and keeps the "kind" of the value the same - kConversionCost_RankPromotion = 100, + kConversionCost_RankPromotion = 150, // Conversions that are lossless, but change "kind" kConversionCost_UnsignedToSignedPromotion = 200, diff --git a/source/slang/type-defs.h b/source/slang/type-defs.h index cfb928e13..bce8edcd3 100644 --- a/source/slang/type-defs.h +++ b/source/slang/type-defs.h @@ -85,7 +85,6 @@ RAW( Slang::BaseType baseType) : baseType(baseType) {} - virtual Slang::String ToString() override; protected: virtual BasicExpressionType* GetScalarType() override; virtual bool EqualsImpl(Type * type) override; diff --git a/source/slang/type-layout.cpp b/source/slang/type-layout.cpp index d7a4e68bc..3fbb9b31b 100644 --- a/source/slang/type-layout.cpp +++ b/source/slang/type-layout.cpp @@ -34,43 +34,35 @@ struct DefaultLayoutRulesImpl : SimpleLayoutRulesImpl { switch (baseType) { - case BaseType::Int: - case BaseType::UInt: - case BaseType::Float: - case BaseType::Bool: - return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4, 4 ); + case BaseType::Void: return SimpleLayoutInfo(); - case BaseType::Double: - return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8, 8 ); + // Note: By convention, a `bool` in a constant buffer is stored as an `int. + // This default may eventually change, at which point this logic will need + // to be updated. + // + // TODO: We should probably warn in this case, since storing a `bool` in + // a constant buffer seems like a Bad Idea anyway. + // + case BaseType::Bool: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4, 4 ); - default: - SLANG_UNEXPECTED("uhandled scalar type"); - UNREACHABLE_RETURN(SimpleLayoutInfo( LayoutResourceKind::Uniform, 0, 1 )); - } - } - virtual SimpleLayoutInfo GetScalarLayout(slang::TypeReflection::ScalarType scalarType) - { - switch( scalarType ) - { - case slang::TypeReflection::ScalarType::Void: return SimpleLayoutInfo(); - case slang::TypeReflection::ScalarType::None: return SimpleLayoutInfo(); + case BaseType::Int8: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 1,1); + case BaseType::Int16: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 2,2); + case BaseType::Int: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4,4); + case BaseType::Int64: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8,8); - // TODO(tfoley): At some point we don't want to lay out `bool` as 4 bytes by default... - case slang::TypeReflection::ScalarType::Bool: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4,4); - case slang::TypeReflection::ScalarType::Int32: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4,4); - case slang::TypeReflection::ScalarType::UInt32: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4,4); - case slang::TypeReflection::ScalarType::Int64: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8,8); - case slang::TypeReflection::ScalarType::UInt64: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8,8); + case BaseType::UInt8: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 1,1); + case BaseType::UInt16: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 2,2); + case BaseType::UInt: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4,4); + case BaseType::UInt64: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8,8); - // TODO(tfoley): What actually happens if you use `half` in a constant buffer? - case slang::TypeReflection::ScalarType::Float16: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 2,2); - case slang::TypeReflection::ScalarType::Float32: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4,4); - case slang::TypeReflection::ScalarType::Float64: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8,8); + case BaseType::Half: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 2,2); + case BaseType::Float: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 4,4); + case BaseType::Double: return SimpleLayoutInfo( LayoutResourceKind::Uniform, 8,8); default: - SLANG_UNEXPECTED("unhandled scalar type"); - UNREACHABLE_RETURN(SimpleLayoutInfo()); + SLANG_UNEXPECTED("uhandled scalar type"); + UNREACHABLE_RETURN(SimpleLayoutInfo( LayoutResourceKind::Uniform, 0, 1 )); } } @@ -267,14 +259,6 @@ struct DefaultVaryingLayoutRulesImpl : DefaultLayoutRulesImpl 1); } - virtual SimpleLayoutInfo GetScalarLayout(slang::TypeReflection::ScalarType) - { - // Assume that all scalars take up one "slot" - return SimpleLayoutInfo( - getKind(), - 1); - } - SimpleLayoutInfo GetVectorLayout(SimpleLayoutInfo, size_t) override { // Vectors take up one slot by default @@ -318,14 +302,6 @@ struct GLSLSpecializationConstantLayoutRulesImpl : DefaultLayoutRulesImpl 1); } - virtual SimpleLayoutInfo GetScalarLayout(slang::TypeReflection::ScalarType) - { - // Assume that all scalars take up one "slot" - return SimpleLayoutInfo( - getKind(), - 1); - } - SimpleLayoutInfo GetVectorLayout(SimpleLayoutInfo, size_t elementCount) override { // GLSL doesn't support vectors of specialization constants, diff --git a/source/slang/type-layout.h b/source/slang/type-layout.h index c3f6f2679..f151a498a 100644 --- a/source/slang/type-layout.h +++ b/source/slang/type-layout.h @@ -510,7 +510,6 @@ struct SimpleLayoutRulesImpl { // Get size and alignment for a single value of base type. virtual SimpleLayoutInfo GetScalarLayout(BaseType baseType) = 0; - virtual SimpleLayoutInfo GetScalarLayout(slang::TypeReflection::ScalarType scalarType) = 0; // Get size and alignment for an array of elements virtual SimpleArrayLayoutInfo GetArrayLayout(SimpleLayoutInfo elementInfo, size_t elementCount) = 0; @@ -548,11 +547,6 @@ struct LayoutRulesImpl return simpleRules->GetScalarLayout(baseType); } - SimpleLayoutInfo GetScalarLayout(slang::TypeReflection::ScalarType scalarType) - { - return simpleRules->GetScalarLayout(scalarType); - } - SimpleArrayLayoutInfo GetArrayLayout(SimpleLayoutInfo elementInfo, size_t elementCount) { return simpleRules->GetArrayLayout(elementInfo, elementCount); diff --git a/source/slang/type-system-shared.h b/source/slang/type-system-shared.h index dd06026c5..183cacb4b 100644 --- a/source/slang/type-system-shared.h +++ b/source/slang/type-system-shared.h @@ -8,7 +8,12 @@ namespace Slang #define FOREACH_BASE_TYPE(X) \ X(Void) \ X(Bool) \ + X(Int8) \ + X(Int16) \ X(Int) \ + X(Int64) \ + X(UInt8) \ + X(UInt16) \ X(UInt) \ X(UInt64) \ X(Half) \ |
