diff options
| author | Tim Foley <tfoley@nvidia.com> | 2017-06-15 13:12:51 -0700 |
|---|---|---|
| committer | Tim Foley <tfoley@nvidia.com> | 2017-06-15 13:12:51 -0700 |
| commit | 517513645afb8eaf4841e7b7035f1ba3a9c7cd57 (patch) | |
| tree | eb0fdf58f5f42c427ade3aac136a9053fbf21d54 /source/slang/slang-stdlib.cpp | |
| parent | c34a433d7aa3fdbfefee22f20d5aac2d960f392a (diff) | |
Rename `Slang::Compiler` -> `Slang`
This gets rid of one unecessary namespace.
Diffstat (limited to 'source/slang/slang-stdlib.cpp')
| -rw-r--r-- | source/slang/slang-stdlib.cpp | 1368 |
1 files changed, 682 insertions, 686 deletions
diff --git a/source/slang/slang-stdlib.cpp b/source/slang/slang-stdlib.cpp index 40c391bf4..85c876105 100644 --- a/source/slang/slang-stdlib.cpp +++ b/source/slang/slang-stdlib.cpp @@ -951,903 +951,899 @@ using namespace CoreLib::Basic; namespace Slang { - namespace Compiler + static String stdlibPath; + + String getStdlibPath() { - static String stdlibPath; + if(stdlibPath.Length() != 0) + return stdlibPath; - String getStdlibPath() + StringBuilder pathBuilder; + for( auto cc = __FILE__; *cc; ++cc ) { - if(stdlibPath.Length() != 0) - return stdlibPath; - - StringBuilder pathBuilder; - for( auto cc = __FILE__; *cc; ++cc ) + switch( *cc ) { - switch( *cc ) - { - case '\n': - case '\t': - case '\\': - pathBuilder << "\\"; - default: - pathBuilder << *cc; - break; - } + case '\n': + case '\t': + case '\\': + pathBuilder << "\\"; + default: + pathBuilder << *cc; + break; } - stdlibPath = pathBuilder.ProduceString(); - - return stdlibPath; } + stdlibPath = pathBuilder.ProduceString(); - String SlangStdLib::code; + return stdlibPath; + } - enum - { - SINT_MASK = 1 << 0, - FLOAT_MASK = 1 << 1, - COMPARISON = 1 << 2, - BOOL_MASK = 1 << 3, - UINT_MASK = 1 << 4, - ASSIGNMENT = 1 << 5, - POSTFIX = 1 << 6, - - INT_MASK = SINT_MASK | UINT_MASK, - ARITHMETIC_MASK = INT_MASK | FLOAT_MASK, - LOGICAL_MASK = INT_MASK | BOOL_MASK, - ANY_MASK = INT_MASK | FLOAT_MASK | BOOL_MASK, - }; + String SlangStdLib::code; - String SlangStdLib::GetCode() - { - if (code.Length() > 0) - return code; - StringBuilder sb; + enum + { + SINT_MASK = 1 << 0, + FLOAT_MASK = 1 << 1, + COMPARISON = 1 << 2, + BOOL_MASK = 1 << 3, + UINT_MASK = 1 << 4, + ASSIGNMENT = 1 << 5, + POSTFIX = 1 << 6, + + INT_MASK = SINT_MASK | UINT_MASK, + ARITHMETIC_MASK = INT_MASK | FLOAT_MASK, + LOGICAL_MASK = INT_MASK | BOOL_MASK, + ANY_MASK = INT_MASK | FLOAT_MASK | BOOL_MASK, + }; + + String SlangStdLib::GetCode() + { + if (code.Length() > 0) + return code; + StringBuilder sb; - // generate operator overloads + // generate operator overloads - struct OpInfo { IntrinsicOp opCode; char const* opName; unsigned flags; }; + struct OpInfo { IntrinsicOp opCode; char const* opName; unsigned flags; }; - OpInfo unaryOps[] = { - { IntrinsicOp::Neg, "-", ARITHMETIC_MASK }, - { IntrinsicOp::Not, "!", ANY_MASK }, - { IntrinsicOp::Not, "~", INT_MASK }, - { IntrinsicOp::PreInc, "++", ARITHMETIC_MASK | ASSIGNMENT }, - { IntrinsicOp::PreDec, "--", ARITHMETIC_MASK | ASSIGNMENT }, - { IntrinsicOp::PostInc, "++", ARITHMETIC_MASK | ASSIGNMENT | POSTFIX }, - { IntrinsicOp::PostDec, "--", ARITHMETIC_MASK | ASSIGNMENT | POSTFIX }, - }; + OpInfo unaryOps[] = { + { IntrinsicOp::Neg, "-", ARITHMETIC_MASK }, + { IntrinsicOp::Not, "!", ANY_MASK }, + { IntrinsicOp::Not, "~", INT_MASK }, + { IntrinsicOp::PreInc, "++", ARITHMETIC_MASK | ASSIGNMENT }, + { IntrinsicOp::PreDec, "--", ARITHMETIC_MASK | ASSIGNMENT }, + { IntrinsicOp::PostInc, "++", ARITHMETIC_MASK | ASSIGNMENT | POSTFIX }, + { IntrinsicOp::PostDec, "--", ARITHMETIC_MASK | ASSIGNMENT | POSTFIX }, + }; - OpInfo binaryOps[] = { - { IntrinsicOp::Add, "+", ARITHMETIC_MASK }, - { IntrinsicOp::Sub, "-", ARITHMETIC_MASK }, - { IntrinsicOp::Mul, "*", ARITHMETIC_MASK }, - { IntrinsicOp::Div, "/", ARITHMETIC_MASK }, - { IntrinsicOp::Mod, "%", INT_MASK }, + OpInfo binaryOps[] = { + { IntrinsicOp::Add, "+", ARITHMETIC_MASK }, + { IntrinsicOp::Sub, "-", ARITHMETIC_MASK }, + { IntrinsicOp::Mul, "*", ARITHMETIC_MASK }, + { IntrinsicOp::Div, "/", ARITHMETIC_MASK }, + { IntrinsicOp::Mod, "%", INT_MASK }, - { IntrinsicOp::And, "&&", LOGICAL_MASK }, - { IntrinsicOp::Or, "||", LOGICAL_MASK }, + { IntrinsicOp::And, "&&", LOGICAL_MASK }, + { IntrinsicOp::Or, "||", LOGICAL_MASK }, - { IntrinsicOp::BitAnd, "&", LOGICAL_MASK }, - { IntrinsicOp::BitOr, "|", LOGICAL_MASK }, - { IntrinsicOp::BitXor, "^", LOGICAL_MASK }, + { IntrinsicOp::BitAnd, "&", LOGICAL_MASK }, + { IntrinsicOp::BitOr, "|", LOGICAL_MASK }, + { IntrinsicOp::BitXor, "^", LOGICAL_MASK }, - { IntrinsicOp::Lsh, "<<", INT_MASK }, - { IntrinsicOp::Rsh, ">>", INT_MASK }, + { IntrinsicOp::Lsh, "<<", INT_MASK }, + { IntrinsicOp::Rsh, ">>", INT_MASK }, - { IntrinsicOp::Eql, "==", ANY_MASK | COMPARISON }, - { IntrinsicOp::Neq, "!=", ANY_MASK | COMPARISON }, + { IntrinsicOp::Eql, "==", ANY_MASK | COMPARISON }, + { IntrinsicOp::Neq, "!=", ANY_MASK | COMPARISON }, - { IntrinsicOp::Greater, ">", ARITHMETIC_MASK | COMPARISON }, - { IntrinsicOp::Less, "<", ARITHMETIC_MASK | COMPARISON }, - { IntrinsicOp::Geq, ">=", ARITHMETIC_MASK | COMPARISON }, - { IntrinsicOp::Leq, "<=", ARITHMETIC_MASK | COMPARISON }, + { IntrinsicOp::Greater, ">", ARITHMETIC_MASK | COMPARISON }, + { IntrinsicOp::Less, "<", ARITHMETIC_MASK | COMPARISON }, + { IntrinsicOp::Geq, ">=", ARITHMETIC_MASK | COMPARISON }, + { IntrinsicOp::Leq, "<=", ARITHMETIC_MASK | COMPARISON }, - { IntrinsicOp::AddAssign, "+=", ASSIGNMENT | ARITHMETIC_MASK }, - { IntrinsicOp::SubAssign, "-=", ASSIGNMENT | ARITHMETIC_MASK }, - { IntrinsicOp::MulAssign, "*=", ASSIGNMENT | ARITHMETIC_MASK }, - { IntrinsicOp::DivAssign, "/=", ASSIGNMENT | ARITHMETIC_MASK }, - { IntrinsicOp::ModAssign, "%=", ASSIGNMENT | ARITHMETIC_MASK }, - { IntrinsicOp::AndAssign, "&=", ASSIGNMENT | LOGICAL_MASK }, - { IntrinsicOp::OrAssign, "|=", ASSIGNMENT | LOGICAL_MASK }, - { IntrinsicOp::XorAssign, "^=", ASSIGNMENT | LOGICAL_MASK }, - { IntrinsicOp::LshAssign, "<<=", ASSIGNMENT | INT_MASK }, - { IntrinsicOp::RshAssign, ">>=", ASSIGNMENT | INT_MASK }, + { IntrinsicOp::AddAssign, "+=", ASSIGNMENT | ARITHMETIC_MASK }, + { IntrinsicOp::SubAssign, "-=", ASSIGNMENT | ARITHMETIC_MASK }, + { IntrinsicOp::MulAssign, "*=", ASSIGNMENT | ARITHMETIC_MASK }, + { IntrinsicOp::DivAssign, "/=", ASSIGNMENT | ARITHMETIC_MASK }, + { IntrinsicOp::ModAssign, "%=", ASSIGNMENT | ARITHMETIC_MASK }, + { IntrinsicOp::AndAssign, "&=", ASSIGNMENT | LOGICAL_MASK }, + { IntrinsicOp::OrAssign, "|=", ASSIGNMENT | LOGICAL_MASK }, + { IntrinsicOp::XorAssign, "^=", ASSIGNMENT | LOGICAL_MASK }, + { IntrinsicOp::LshAssign, "<<=", ASSIGNMENT | INT_MASK }, + { IntrinsicOp::RshAssign, ">>=", ASSIGNMENT | INT_MASK }, - }; + }; - /* - String floatTypes[] = { "float", "float2", "float3", "float4" }; - String intTypes[] = { "int", "int2", "int3", "int4" }; - String uintTypes[] = { "uint", "uint2", "uint3", "uint4" }; - */ + /* + String floatTypes[] = { "float", "float2", "float3", "float4" }; + String intTypes[] = { "int", "int2", "int3", "int4" }; + String uintTypes[] = { "uint", "uint2", "uint3", "uint4" }; + */ - String path = getStdlibPath(); + String path = getStdlibPath(); #define EMIT_LINE_DIRECTIVE() sb << "#line " << (__LINE__+1) << " \"" << path << "\"\n" - // Generate declarations for all the base types - - static const struct { - char const* name; - BaseType tag; - unsigned flags; - } kBaseTypes[] = { - { "void", BaseType::Void, 0 }, - { "int", BaseType::Int, SINT_MASK }, - { "float", BaseType::Float, FLOAT_MASK }, - { "uint", BaseType::UInt, UINT_MASK }, - { "bool", BaseType::Bool, BOOL_MASK }, - { "uint64_t", BaseType::UInt64, UINT_MASK }, - }; - static const int kBaseTypeCount = sizeof(kBaseTypes) / sizeof(kBaseTypes[0]); - for (int tt = 0; tt < kBaseTypeCount; ++tt) - { - EMIT_LINE_DIRECTIVE(); - sb << "__builtin_type(" << int(kBaseTypes[tt].tag) << ") struct " << kBaseTypes[tt].name; - - // Declare interface conformances for this type + // Generate declarations for all the base types + + static const struct { + char const* name; + BaseType tag; + unsigned flags; + } kBaseTypes[] = { + { "void", BaseType::Void, 0 }, + { "int", BaseType::Int, SINT_MASK }, + { "float", BaseType::Float, FLOAT_MASK }, + { "uint", BaseType::UInt, UINT_MASK }, + { "bool", BaseType::Bool, BOOL_MASK }, + { "uint64_t", BaseType::UInt64, UINT_MASK }, + }; + static const int kBaseTypeCount = sizeof(kBaseTypes) / sizeof(kBaseTypes[0]); + for (int tt = 0; tt < kBaseTypeCount; ++tt) + { + EMIT_LINE_DIRECTIVE(); + sb << "__builtin_type(" << int(kBaseTypes[tt].tag) << ") struct " << kBaseTypes[tt].name; - sb << "\n : __BuiltinType\n"; + // Declare interface conformances for this type - switch( kBaseTypes[tt].tag ) - { - case BaseType::Float: - sb << "\n , __BuiltinFloatingPointType\n"; - sb << "\n , __BuiltinRealType\n"; - // fall through to: - case BaseType::Int: - sb << "\n , __BuiltinSignedArithmeticType\n"; - // fall through to: - case BaseType::UInt: - case BaseType::UInt64: - sb << "\n , __BuiltinArithmeticType\n"; - // fall through to: - case BaseType::Bool: - sb << "\n , __BuiltinType\n"; - break; - - default: - break; - } + sb << "\n : __BuiltinType\n"; - sb << "\n{\n"; + switch( kBaseTypes[tt].tag ) + { + case BaseType::Float: + sb << "\n , __BuiltinFloatingPointType\n"; + sb << "\n , __BuiltinRealType\n"; + // fall through to: + case BaseType::Int: + sb << "\n , __BuiltinSignedArithmeticType\n"; + // fall through to: + case BaseType::UInt: + case BaseType::UInt64: + sb << "\n , __BuiltinArithmeticType\n"; + // fall through to: + case BaseType::Bool: + sb << "\n , __BuiltinType\n"; + break; + + default: + break; + } + sb << "\n{\n"; - // Declare initializers to convert from various other types - for( int ss = 0; ss < kBaseTypeCount; ++ss ) - { - if( kBaseTypes[ss].tag == BaseType::Void ) - continue; - EMIT_LINE_DIRECTIVE(); - sb << "__init(" << kBaseTypes[ss].name << " value);\n"; - } + // Declare initializers to convert from various other types + for( int ss = 0; ss < kBaseTypeCount; ++ss ) + { + if( kBaseTypes[ss].tag == BaseType::Void ) + continue; - sb << "};\n"; + EMIT_LINE_DIRECTIVE(); + sb << "__init(" << kBaseTypes[ss].name << " value);\n"; } - // Declare ad hoc aliases for some types, just to get things compiling - // - // TODO(tfoley): At the very least, `double` should be treated as a distinct type. - sb << "typedef float double;\n"; - sb << "typedef float half;\n"; + sb << "};\n"; + } - // Declare vector and matrix types + // Declare ad hoc aliases for some types, just to get things compiling + // + // TODO(tfoley): At the very least, `double` should be treated as a distinct type. + sb << "typedef float double;\n"; + sb << "typedef float half;\n"; - sb << "__generic<T = float, let N : int = 4> __magic_type(Vector) struct vector\n{\n"; - sb << " __init(T value);\n"; // initialize from single scalar - sb << "};\n"; - sb << "__generic<T = float, let R : int = 4, let C : int = 4> __magic_type(Matrix) struct matrix {};\n"; + // Declare vector and matrix types - static const struct { - char const* name; - char const* glslPrefix; - } kTypes[] = - { - {"float", ""}, - {"int", "i"}, - {"uint", "u"}, - {"bool", "b"}, - }; - static const int kTypeCount = sizeof(kTypes) / sizeof(kTypes[0]); - - for (int tt = 0; tt < kTypeCount; ++tt) + sb << "__generic<T = float, let N : int = 4> __magic_type(Vector) struct vector\n{\n"; + sb << " __init(T value);\n"; // initialize from single scalar + sb << "};\n"; + sb << "__generic<T = float, let R : int = 4, let C : int = 4> __magic_type(Matrix) struct matrix {};\n"; + + static const struct { + char const* name; + char const* glslPrefix; + } kTypes[] = + { + {"float", ""}, + {"int", "i"}, + {"uint", "u"}, + {"bool", "b"}, + }; + static const int kTypeCount = sizeof(kTypes) / sizeof(kTypes[0]); + + for (int tt = 0; tt < kTypeCount; ++tt) + { + // Declare HLSL vector types + for (int ii = 1; ii <= 4; ++ii) { - // Declare HLSL vector types - for (int ii = 1; ii <= 4; ++ii) - { - sb << "typedef vector<" << kTypes[tt].name << "," << ii << "> " << kTypes[tt].name << ii << ";\n"; - } + sb << "typedef vector<" << kTypes[tt].name << "," << ii << "> " << kTypes[tt].name << ii << ";\n"; + } - // Declare HLSL matrix types - for (int rr = 2; rr <= 4; ++rr) - for (int cc = 2; cc <= 4; ++cc) - { - sb << "typedef matrix<" << kTypes[tt].name << "," << rr << "," << cc << "> " << kTypes[tt].name << rr << "x" << cc << ";\n"; - } + // Declare HLSL matrix types + for (int rr = 2; rr <= 4; ++rr) + for (int cc = 2; cc <= 4; ++cc) + { + sb << "typedef matrix<" << kTypes[tt].name << "," << rr << "," << cc << "> " << kTypes[tt].name << rr << "x" << cc << ";\n"; } + } - static const char* kComponentNames[]{ "x", "y", "z", "w" }; - static const char* kVectorNames[]{ "", "x", "xy", "xyz", "xyzw" }; + static const char* kComponentNames[]{ "x", "y", "z", "w" }; + static const char* kVectorNames[]{ "", "x", "xy", "xyz", "xyzw" }; - // Need to add constructors to the types above - for (int N = 2; N <= 4; ++N) + // Need to add constructors to the types above + for (int N = 2; N <= 4; ++N) + { + sb << "__generic<T> __extension vector<T, " << N << ">\n{\n"; + + // initialize from N scalars + sb << "__init("; + for (int ii = 0; ii < N; ++ii) { - sb << "__generic<T> __extension vector<T, " << N << ">\n{\n"; + if (ii != 0) sb << ", "; + sb << "T " << kComponentNames[ii]; + } + sb << ");\n"; - // initialize from N scalars - sb << "__init("; - for (int ii = 0; ii < N; ++ii) + // Initialize from an M-vector and then scalars + for (int M = 2; M < N; ++M) + { + sb << "__init(vector<T," << M << "> " << kVectorNames[M]; + for (int ii = M; ii < N; ++ii) { - if (ii != 0) sb << ", "; - sb << "T " << kComponentNames[ii]; + sb << ", T " << kComponentNames[ii]; } sb << ");\n"; + } - // Initialize from an M-vector and then scalars - for (int M = 2; M < N; ++M) - { - sb << "__init(vector<T," << M << "> " << kVectorNames[M]; - for (int ii = M; ii < N; ++ii) - { - sb << ", T " << kComponentNames[ii]; - } - sb << ");\n"; - } + // initialize from another vector of the same size + // + // TODO(tfoley): this overlaps with implicit conversions. + // We should look for a way that we can define implicit + // conversions directly in the stdlib instead... + sb << "__generic<U> __init(vector<U," << N << ">);\n"; - // initialize from another vector of the same size - // - // TODO(tfoley): this overlaps with implicit conversions. - // We should look for a way that we can define implicit - // conversions directly in the stdlib instead... - sb << "__generic<U> __init(vector<U," << N << ">);\n"; + sb << "}\n"; + } + + for( int R = 2; R <= 4; ++R ) + for( int C = 2; C <= 4; ++C ) + { + sb << "__generic<T> __extension matrix<T, " << R << "," << C << ">\n{\n"; - sb << "}\n"; + // initialize from R*C scalars + sb << "__init("; + for( int ii = 0; ii < R; ++ii ) + for( int jj = 0; jj < C; ++jj ) + { + if ((ii+jj) != 0) sb << ", "; + sb << "T m" << ii << jj; } + sb << ");\n"; - for( int R = 2; R <= 4; ++R ) - for( int C = 2; C <= 4; ++C ) + // Initialize from R C-vectors + sb << "__init("; + for (int ii = 0; ii < R; ++ii) { - sb << "__generic<T> __extension matrix<T, " << R << "," << C << ">\n{\n"; + if(ii != 0) sb << ", "; + sb << "vector<T," << C << "> row" << ii; + } + sb << ");\n"; - // initialize from R*C scalars - sb << "__init("; - for( int ii = 0; ii < R; ++ii ) - for( int jj = 0; jj < C; ++jj ) - { - if ((ii+jj) != 0) sb << ", "; - sb << "T m" << ii << jj; - } - sb << ");\n"; - // Initialize from R C-vectors - sb << "__init("; - for (int ii = 0; ii < R; ++ii) - { - if(ii != 0) sb << ", "; - sb << "vector<T," << C << "> row" << ii; - } - sb << ");\n"; + // initialize from another matrix of the same size + // + // TODO(tfoley): See comment about how this overlaps + // with implicit conversion, in the `vector` case above + sb << "__generic<U> __init(matrix<U," << R << ", " << C << ">);\n"; + sb << "}\n"; + } - // initialize from another matrix of the same size - // - // TODO(tfoley): See comment about how this overlaps - // with implicit conversion, in the `vector` case above - sb << "__generic<U> __init(matrix<U," << R << ", " << C << ">);\n"; - sb << "}\n"; - } + // Declare built-in texture and sampler types + + sb << "__magic_type(SamplerState," << int(SamplerStateType::Flavor::SamplerState) << ") struct SamplerState {};"; + sb << "__magic_type(SamplerState," << int(SamplerStateType::Flavor::SamplerComparisonState) << ") struct SamplerComparisonState {};"; + + // TODO(tfoley): Need to handle `RW*` variants of texture types as well... + static const struct { + char const* name; + TextureType::Shape baseShape; + int coordCount; + } kBaseTextureTypes[] = { + { "Texture1D", TextureType::Shape1D, 1 }, + { "Texture2D", TextureType::Shape2D, 2 }, + { "Texture3D", TextureType::Shape3D, 3 }, + { "TextureCube", TextureType::ShapeCube, 3 }, + }; + static const int kBaseTextureTypeCount = sizeof(kBaseTextureTypes) / sizeof(kBaseTextureTypes[0]); - // Declare built-in texture and sampler types - - sb << "__magic_type(SamplerState," << int(SamplerStateType::Flavor::SamplerState) << ") struct SamplerState {};"; - sb << "__magic_type(SamplerState," << int(SamplerStateType::Flavor::SamplerComparisonState) << ") struct SamplerComparisonState {};"; - - // TODO(tfoley): Need to handle `RW*` variants of texture types as well... - static const struct { - char const* name; - TextureType::Shape baseShape; - int coordCount; - } kBaseTextureTypes[] = { - { "Texture1D", TextureType::Shape1D, 1 }, - { "Texture2D", TextureType::Shape2D, 2 }, - { "Texture3D", TextureType::Shape3D, 3 }, - { "TextureCube", TextureType::ShapeCube, 3 }, - }; - static const int kBaseTextureTypeCount = sizeof(kBaseTextureTypes) / sizeof(kBaseTextureTypes[0]); - - - static const struct { - char const* name; - SlangResourceAccess access; - } kBaseTextureAccessLevels[] = { - { "", SLANG_RESOURCE_ACCESS_READ }, - { "RW", SLANG_RESOURCE_ACCESS_READ_WRITE }, - { "RasterizerOrdered", SLANG_RESOURCE_ACCESS_RASTER_ORDERED }, - }; - static const int kBaseTextureAccessLevelCount = sizeof(kBaseTextureAccessLevels) / sizeof(kBaseTextureAccessLevels[0]); - - for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) + static const struct { + char const* name; + SlangResourceAccess access; + } kBaseTextureAccessLevels[] = { + { "", SLANG_RESOURCE_ACCESS_READ }, + { "RW", SLANG_RESOURCE_ACCESS_READ_WRITE }, + { "RasterizerOrdered", SLANG_RESOURCE_ACCESS_RASTER_ORDERED }, + }; + static const int kBaseTextureAccessLevelCount = sizeof(kBaseTextureAccessLevels) / sizeof(kBaseTextureAccessLevels[0]); + + for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) + { + char const* name = kBaseTextureTypes[tt].name; + TextureType::Shape baseShape = kBaseTextureTypes[tt].baseShape; + + for (int isArray = 0; isArray < 2; ++isArray) { - char const* name = kBaseTextureTypes[tt].name; - TextureType::Shape baseShape = kBaseTextureTypes[tt].baseShape; + // Arrays of 3D textures aren't allowed + if (isArray && baseShape == TextureType::Shape3D) continue; - for (int isArray = 0; isArray < 2; ++isArray) + for (int isMultisample = 0; isMultisample < 2; ++isMultisample) + for (int accessLevel = 0; accessLevel < kBaseTextureAccessLevelCount; ++accessLevel) { - // Arrays of 3D textures aren't allowed - if (isArray && baseShape == TextureType::Shape3D) continue; + auto access = kBaseTextureAccessLevels[accessLevel].access; - for (int isMultisample = 0; isMultisample < 2; ++isMultisample) - for (int accessLevel = 0; accessLevel < kBaseTextureAccessLevelCount; ++accessLevel) - { - auto access = kBaseTextureAccessLevels[accessLevel].access; - - // TODO: any constraints to enforce on what gets to be multisampled? + // TODO: any constraints to enforce on what gets to be multisampled? - unsigned flavor = baseShape; - if (isArray) flavor |= TextureType::ArrayFlag; - if (isMultisample) flavor |= TextureType::MultisampleFlag; + unsigned flavor = baseShape; + if (isArray) flavor |= TextureType::ArrayFlag; + if (isMultisample) flavor |= TextureType::MultisampleFlag; // if (isShadow) flavor |= TextureType::ShadowFlag; - flavor |= (access << 8); + flavor |= (access << 8); - // emit a generic signature - // TODO: allow for multisample count to come in as well... - sb << "__generic<T = float4> "; + // emit a generic signature + // TODO: allow for multisample count to come in as well... + sb << "__generic<T = float4> "; - sb << "__magic_type(Texture," << int(flavor) << ") struct "; - sb << kBaseTextureAccessLevels[accessLevel].name; - sb << name; - if (isMultisample) sb << "MS"; - if (isArray) sb << "Array"; + sb << "__magic_type(Texture," << int(flavor) << ") struct "; + sb << kBaseTextureAccessLevels[accessLevel].name; + sb << name; + if (isMultisample) sb << "MS"; + if (isArray) sb << "Array"; // if (isShadow) sb << "Shadow"; - sb << "\n{"; + sb << "\n{"; - if( !isMultisample ) - { - sb << "float CalculateLevelOfDetail(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount << " location);\n"; + if( !isMultisample ) + { + sb << "float CalculateLevelOfDetail(SamplerState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount << " location);\n"; - sb << "float CalculateLevelOfDetailUnclamped(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount << " location);\n"; + sb << "float CalculateLevelOfDetailUnclamped(SamplerState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount << " location);\n"; - // TODO: `Gather` operation - // (tricky because it returns a 4-vector of the element type - // of the texture components...) - } + // TODO: `Gather` operation + // (tricky because it returns a 4-vector of the element type + // of the texture components...) + } + + // TODO: `GetDimensions` operations + + for(int isFloat = 0; isFloat < 2; ++isFloat) + for(int includeMipInfo = 0; includeMipInfo < 2; ++includeMipInfo) + { + char const* t = isFloat ? "out float " : "out UINT "; - // TODO: `GetDimensions` operations + sb << "void GetDimensions("; + if(includeMipInfo) + sb << "UINT mipLevel, "; - for(int isFloat = 0; isFloat < 2; ++isFloat) - for(int includeMipInfo = 0; includeMipInfo < 2; ++includeMipInfo) + switch(baseShape) { - char const* t = isFloat ? "out float " : "out UINT "; - - sb << "void GetDimensions("; - if(includeMipInfo) - sb << "UINT mipLevel, "; - - switch(baseShape) - { - case TextureType::Shape1D: - sb << t << "width"; - break; - - case TextureType::Shape2D: - case TextureType::ShapeCube: - sb << t << "width,"; - sb << t << "height"; - break; - - case TextureType::Shape3D: - sb << t << "width,"; - sb << t << "height,"; - sb << t << "depth"; - break; - - default: - assert(!"unexpected"); - break; - } - - if(isArray) - { - sb << ", " << t << "elements"; - } - - if(includeMipInfo) - sb << ", " << t << "numberOfLevels"; - - sb << ");\n"; + case TextureType::Shape1D: + sb << t << "width"; + break; + + case TextureType::Shape2D: + case TextureType::ShapeCube: + sb << t << "width,"; + sb << t << "height"; + break; + + case TextureType::Shape3D: + sb << t << "width,"; + sb << t << "height,"; + sb << t << "depth"; + break; + + default: + assert(!"unexpected"); + break; } - // `GetSamplePosition()` - if( isMultisample ) + if(isArray) { - sb << "float2 GetSamplePosition(int s);\n"; + sb << ", " << t << "elements"; } - // `Load()` + if(includeMipInfo) + sb << ", " << t << "numberOfLevels"; + + sb << ");\n"; + } + + // `GetSamplePosition()` + if( isMultisample ) + { + sb << "float2 GetSamplePosition(int s);\n"; + } + + // `Load()` + + if( kBaseTextureTypes[tt].coordCount + isArray < 4 ) + { + sb << "T Load("; + sb << "int" << kBaseTextureTypes[tt].coordCount + isArray + 1 << " location);\n"; - if( kBaseTextureTypes[tt].coordCount + isArray < 4 ) + if( !isMultisample ) { sb << "T Load("; - sb << "int" << kBaseTextureTypes[tt].coordCount + isArray + 1 << " location);\n"; - - if( !isMultisample ) - { - sb << "T Load("; - sb << "int" << kBaseTextureTypes[tt].coordCount + isArray + 1 << " location, "; - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - } - else - { - sb << "T Load("; - sb << "int" << kBaseTextureTypes[tt].coordCount + isArray + 1 << " location, "; - sb << "int sampleIndex, "; - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - } + sb << "int" << kBaseTextureTypes[tt].coordCount + isArray + 1 << " location, "; + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; } - - if(baseShape != TextureType::ShapeCube) + else { - // subscript operator - sb << "__intrinsic __subscript(uint" << kBaseTextureTypes[tt].coordCount + isArray << " location) -> T;\n"; + sb << "T Load("; + sb << "int" << kBaseTextureTypes[tt].coordCount + isArray + 1 << " location, "; + sb << "int sampleIndex, "; + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; } + } - if( !isMultisample ) - { - // `Sample()` + if(baseShape != TextureType::ShapeCube) + { + // subscript operator + sb << "__intrinsic __subscript(uint" << kBaseTextureTypes[tt].coordCount + isArray << " location) -> T;\n"; + } - sb << "T Sample(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location);\n"; + if( !isMultisample ) + { + // `Sample()` - if( baseShape != TextureType::ShapeCube ) - { - sb << "T Sample(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - } + sb << "T Sample(SamplerState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location);\n"; + if( baseShape != TextureType::ShapeCube ) + { sb << "T Sample(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - if( baseShape != TextureType::ShapeCube ) - { - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset, "; - } - sb << "float clamp);\n"; + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; + } - sb << "T Sample(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - if( baseShape != TextureType::ShapeCube ) - { - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset, "; - } - sb << "float clamp, out uint status);\n"; + sb << "T Sample(SamplerState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; + if( baseShape != TextureType::ShapeCube ) + { + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset, "; + } + sb << "float clamp);\n"; + + sb << "T Sample(SamplerState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; + if( baseShape != TextureType::ShapeCube ) + { + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset, "; + } + sb << "float clamp, out uint status);\n"; - // `SampleBias()` + // `SampleBias()` + sb << "T SampleBias(SamplerState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, float bias);\n"; + + if( baseShape != TextureType::ShapeCube ) + { sb << "T SampleBias(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, float bias);\n"; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, float bias, "; + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; + } - if( baseShape != TextureType::ShapeCube ) - { - sb << "T SampleBias(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, float bias, "; - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - } + // `SampleCmp()` and `SampleCmpLevelZero` + sb << "T SampleCmp(SamplerComparisonState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; + sb << "float compareValue"; + sb << ");\n"; - // `SampleCmp()` and `SampleCmpLevelZero` - sb << "T SampleCmp(SamplerComparisonState s, "; + sb << "T SampleCmpLevelZero(SamplerComparisonState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; + sb << "float compareValue"; + sb << ");\n"; + + if( baseShape != TextureType::ShapeCube ) + { + // Note(tfoley): MSDN seems confused, and claims that the `offset` + // parameter for `SampleCmp` is available for everything but 3D + // textures, while `Sample` and `SampleBias` are consistent in + // saying they only exclude `offset` for cube maps (which makes + // sense). I'm going to assume the documentation for `SampleCmp` + // is just wrong. + + sb << "T SampleCmp(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - sb << "float compareValue"; - sb << ");\n"; + sb << "float compareValue, "; + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - sb << "T SampleCmpLevelZero(SamplerComparisonState s, "; + sb << "T SampleCmpLevelZero(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - sb << "float compareValue"; - sb << ");\n"; - - if( baseShape != TextureType::ShapeCube ) - { - // Note(tfoley): MSDN seems confused, and claims that the `offset` - // parameter for `SampleCmp` is available for everything but 3D - // textures, while `Sample` and `SampleBias` are consistent in - // saying they only exclude `offset` for cube maps (which makes - // sense). I'm going to assume the documentation for `SampleCmp` - // is just wrong. - - sb << "T SampleCmp(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - sb << "float compareValue, "; - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - - sb << "T SampleCmpLevelZero(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - sb << "float compareValue, "; - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - } + sb << "float compareValue, "; + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; + } + sb << "T SampleGrad(SamplerState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; + sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; + sb << "float" << kBaseTextureTypes[tt].coordCount << " gradY"; + sb << ");\n"; + + if( baseShape != TextureType::ShapeCube ) + { sb << "T SampleGrad(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; - sb << "float" << kBaseTextureTypes[tt].coordCount << " gradY"; - sb << ");\n"; + sb << "float" << kBaseTextureTypes[tt].coordCount << " gradY, "; + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; + } - if( baseShape != TextureType::ShapeCube ) - { - sb << "T SampleGrad(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - sb << "float" << kBaseTextureTypes[tt].coordCount << " gradX, "; - sb << "float" << kBaseTextureTypes[tt].coordCount << " gradY, "; - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - } + // `SampleLevel` - // `SampleLevel` + sb << "T SampleLevel(SamplerState s, "; + sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; + sb << "float level);\n"; + if( baseShape != TextureType::ShapeCube ) + { sb << "T SampleLevel(SamplerState s, "; sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - sb << "float level);\n"; - - if( baseShape != TextureType::ShapeCube ) - { - sb << "T SampleLevel(SamplerState s, "; - sb << "float" << kBaseTextureTypes[tt].coordCount + isArray << " location, "; - sb << "float level, "; - sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; - } + sb << "float level, "; + sb << "int" << kBaseTextureTypes[tt].coordCount << " offset);\n"; } - - sb << "\n};\n"; } + + sb << "\n};\n"; } } + } - // Declare additional built-in generic types + // Declare additional built-in generic types - sb << "__generic<T> __magic_type(ConstantBuffer) struct ConstantBuffer {};\n"; - sb << "__generic<T> __magic_type(TextureBuffer) struct TextureBuffer {};\n"; + sb << "__generic<T> __magic_type(ConstantBuffer) struct ConstantBuffer {};\n"; + sb << "__generic<T> __magic_type(TextureBuffer) struct TextureBuffer {};\n"; - sb << "__generic<T> __magic_type(PackedBuffer) struct PackedBuffer {};\n"; - sb << "__generic<T> __magic_type(Uniform) struct Uniform {};\n"; - sb << "__generic<T> __magic_type(Patch) struct Patch {};\n"; + sb << "__generic<T> __magic_type(PackedBuffer) struct PackedBuffer {};\n"; + sb << "__generic<T> __magic_type(Uniform) struct Uniform {};\n"; + sb << "__generic<T> __magic_type(Patch) struct Patch {};\n"; - // Stale declarations for GLSL inner-product builtins + // Stale declarations for GLSL inner-product builtins #if 0 - sb << "__intrinsic vec3 operator * (vec3, mat3);\n"; - sb << "__intrinsic vec3 operator * (mat3, vec3);\n"; + sb << "__intrinsic vec3 operator * (vec3, mat3);\n"; + sb << "__intrinsic vec3 operator * (mat3, vec3);\n"; - sb << "__intrinsic vec4 operator * (vec4, mat4);\n"; - sb << "__intrinsic vec4 operator * (mat4, vec4);\n"; + sb << "__intrinsic vec4 operator * (vec4, mat4);\n"; + sb << "__intrinsic vec4 operator * (mat4, vec4);\n"; - sb << "__intrinsic mat3 operator * (mat3, mat3);\n"; - sb << "__intrinsic mat4 operator * (mat4, mat4);\n"; + sb << "__intrinsic mat3 operator * (mat3, mat3);\n"; + sb << "__intrinsic mat4 operator * (mat4, mat4);\n"; #endif - for (auto op : unaryOps) + for (auto op : unaryOps) + { + for (auto type : kBaseTypes) { - for (auto type : kBaseTypes) - { - if ((type.flags & op.flags) == 0) - continue; + if ((type.flags & op.flags) == 0) + continue; - char const* fixity = (op.flags & POSTFIX) != 0 ? "__postfix " : "__prefix "; - char const* qual = (op.flags & ASSIGNMENT) != 0 ? "in out " : ""; + char const* fixity = (op.flags & POSTFIX) != 0 ? "__postfix " : "__prefix "; + char const* qual = (op.flags & ASSIGNMENT) != 0 ? "in out " : ""; - // scalar version - sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") " << type.name << " operator" << op.opName << "(" << qual << type.name << " value);\n"; + // scalar version + sb << fixity; + sb << "__intrinsic_op(" << int(op.opCode) << ") " << type.name << " operator" << op.opName << "(" << qual << type.name << " value);\n"; - // vector version - sb << "__generic<let N : int> "; - sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << type.name << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n"; + // vector version + sb << "__generic<let N : int> "; + sb << fixity; + sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << type.name << ",N> operator" << op.opName << "(" << qual << "vector<" << type.name << ",N> value);\n"; - // matrix version - sb << "__generic<let N : int, let M : int> "; - sb << fixity; - sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << type.name << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n"; - } + // matrix version + sb << "__generic<let N : int, let M : int> "; + sb << fixity; + sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << type.name << ",N,M> operator" << op.opName << "(" << qual << "matrix<" << type.name << ",N,M> value);\n"; } + } - for (auto op : binaryOps) + for (auto op : binaryOps) + { + for (auto type : kBaseTypes) { - for (auto type : kBaseTypes) - { - if ((type.flags & op.flags) == 0) - continue; + if ((type.flags & op.flags) == 0) + continue; - char const* leftType = type.name; - char const* rightType = leftType; - char const* resultType = leftType; + char const* leftType = type.name; + char const* rightType = leftType; + char const* resultType = leftType; - if (op.flags & COMPARISON) resultType = "bool"; + if (op.flags & COMPARISON) resultType = "bool"; - char const* leftQual = ""; - if(op.flags & ASSIGNMENT) leftQual = "in out "; + char const* leftQual = ""; + if(op.flags & ASSIGNMENT) leftQual = "in out "; - // TODO: handle `SHIFT` + // TODO: handle `SHIFT` - // scalar version - sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << leftQual << leftType << " left, " << rightType << " right);\n"; + // scalar version + sb << "__intrinsic_op(" << int(op.opCode) << ") " << resultType << " operator" << op.opName << "(" << leftQual << leftType << " left, " << rightType << " right);\n"; - // vector version - sb << "__generic<let N : int> "; - sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << leftQual << "vector<" << leftType << ",N> left, vector<" << rightType << ",N> right);\n"; + // vector version + sb << "__generic<let N : int> "; + sb << "__intrinsic_op(" << int(op.opCode) << ") vector<" << resultType << ",N> operator" << op.opName << "(" << leftQual << "vector<" << leftType << ",N> left, vector<" << rightType << ",N> right);\n"; - // matrix version - sb << "__generic<let N : int, let M : int> "; - sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftQual << "matrix<" << leftType << ",N,M> left, matrix<" << rightType << ",N,M> right);\n"; - } + // matrix version + sb << "__generic<let N : int, let M : int> "; + sb << "__intrinsic_op(" << int(op.opCode) << ") matrix<" << resultType << ",N,M> operator" << op.opName << "(" << leftQual << "matrix<" << leftType << ",N,M> left, matrix<" << rightType << ",N,M> right);\n"; } + } #if 0 - for (auto op : intUnaryOps) + for (auto op : intUnaryOps) + { + String opName = GetOperatorFunctionName(op); + for (int i = 0; i < 4; i++) { - String opName = GetOperatorFunctionName(op); - for (int i = 0; i < 4; i++) + auto itype = intTypes[i]; + auto utype = uintTypes[i]; + for (int j = 0; j < 2; j++) { - auto itype = intTypes[i]; - auto utype = uintTypes[i]; - for (int j = 0; j < 2; j++) - { - auto retType = (op == Operator::Not) ? "bool" : j == 0 ? itype : utype; - sb << "__intrinsic " << retType << " operator " << opName << "(" << (j == 0 ? itype : utype) << ");\n"; - } + auto retType = (op == Operator::Not) ? "bool" : j == 0 ? itype : utype; + sb << "__intrinsic " << retType << " operator " << opName << "(" << (j == 0 ? itype : utype) << ");\n"; } } + } - for (auto op : floatUnaryOps) + for (auto op : floatUnaryOps) + { + String opName = GetOperatorFunctionName(op); + for (int i = 0; i < 4; i++) { - String opName = GetOperatorFunctionName(op); - for (int i = 0; i < 4; i++) - { - auto type = floatTypes[i]; - auto retType = (op == Operator::Not) ? "bool" : type; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ");\n"; - } + auto type = floatTypes[i]; + auto retType = (op == Operator::Not) ? "bool" : type; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ");\n"; } + } - for (auto op : floatOps) + for (auto op : floatOps) + { + String opName = GetOperatorFunctionName(op); + for (int i = 0; i < 4; i++) { - String opName = GetOperatorFunctionName(op); - for (int i = 0; i < 4; i++) + auto type = floatTypes[i]; + auto itype = intTypes[i]; + auto utype = uintTypes[i]; + auto retType = ((op >= Operator::Eql && op <= Operator::Leq) || op == Operator::And || op == Operator::Or) ? "bool" : type; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << type << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << itype << ", " << type << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << utype << ", " << type << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << itype << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << utype << ");\n"; + if (i > 0) { - auto type = floatTypes[i]; - auto itype = intTypes[i]; - auto utype = uintTypes[i]; - auto retType = ((op >= Operator::Eql && op <= Operator::Leq) || op == Operator::And || op == Operator::Or) ? "bool" : type; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << type << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << itype << ", " << type << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << utype << ", " << type << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << itype << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << utype << ");\n"; - if (i > 0) - { - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << floatTypes[0] << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << floatTypes[0] << ", " << type << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << floatTypes[0] << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << floatTypes[0] << ", " << type << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << intTypes[0] << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << intTypes[0] << ", " << type << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << intTypes[0] << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << intTypes[0] << ", " << type << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << uintTypes[0] << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << uintTypes[0] << ", " << type << ");\n"; - } + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << uintTypes[0] << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << uintTypes[0] << ", " << type << ");\n"; } } + } - for (auto op : intOps) + for (auto op : intOps) + { + String opName = GetOperatorFunctionName(op); + for (int i = 0; i < 4; i++) { - String opName = GetOperatorFunctionName(op); - for (int i = 0; i < 4; i++) + auto type = intTypes[i]; + auto utype = uintTypes[i]; + auto retType = ((op >= Operator::Eql && op <= Operator::Leq) || op == Operator::And || op == Operator::Or) ? "bool" : type; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << type << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << utype << ", " << type << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << utype << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << utype << ", " << utype << ");\n"; + if (i > 0) { - auto type = intTypes[i]; - auto utype = uintTypes[i]; - auto retType = ((op >= Operator::Eql && op <= Operator::Leq) || op == Operator::And || op == Operator::Or) ? "bool" : type; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << type << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << utype << ", " << type << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << utype << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << utype << ", " << utype << ");\n"; - if (i > 0) - { - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << intTypes[0] << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << intTypes[0] << ", " << type << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << intTypes[0] << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << intTypes[0] << ", " << type << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << uintTypes[0] << ");\n"; - sb << "__intrinsic " << retType << " operator " << opName << "(" << uintTypes[0] << ", " << type << ");\n"; - } + sb << "__intrinsic " << retType << " operator " << opName << "(" << type << ", " << uintTypes[0] << ");\n"; + sb << "__intrinsic " << retType << " operator " << opName << "(" << uintTypes[0] << ", " << type << ");\n"; } } + } #endif - // Output a suitable `#line` directive to point at our raw stdlib code above - sb << "\n#line " << kLibIncludeStringLine << " \"" << path << "\"\n"; - - int chunkCount = sizeof(LibIncludeStringChunks) / sizeof(LibIncludeStringChunks[0]); - for (int cc = 0; cc < chunkCount; ++cc) - { - sb << LibIncludeStringChunks[cc]; - } + // Output a suitable `#line` directive to point at our raw stdlib code above + sb << "\n#line " << kLibIncludeStringLine << " \"" << path << "\"\n"; - code = sb.ProduceString(); - return code; + int chunkCount = sizeof(LibIncludeStringChunks) / sizeof(LibIncludeStringChunks[0]); + for (int cc = 0; cc < chunkCount; ++cc) + { + sb << LibIncludeStringChunks[cc]; } + code = sb.ProduceString(); + return code; + } - // GLSL-specific library code - String glslLibraryCode; + // GLSL-specific library code - String getGLSLLibraryCode() - { - if(glslLibraryCode.Length() != 0) - return glslLibraryCode; + String glslLibraryCode; - String path = getStdlibPath(); + String getGLSLLibraryCode() + { + if(glslLibraryCode.Length() != 0) + return glslLibraryCode; - StringBuilder sb; + String path = getStdlibPath(); + + StringBuilder sb; #define RAW(TEXT) \ - EMIT_LINE_DIRECTIVE(); \ - sb << TEXT; +EMIT_LINE_DIRECTIVE(); \ +sb << TEXT; + + static const struct { + char const* name; + char const* glslPrefix; + } kTypes[] = + { + {"float", ""}, + {"int", "i"}, + {"uint", "u"}, + {"bool", "b"}, + }; + static const int kTypeCount = sizeof(kTypes) / sizeof(kTypes[0]); - static const struct { - char const* name; - char const* glslPrefix; - } kTypes[] = + for( int tt = 0; tt < kTypeCount; ++tt ) + { + // Declare GLSL aliases for HLSL types + for (int vv = 2; vv <= 4; ++vv) { - {"float", ""}, - {"int", "i"}, - {"uint", "u"}, - {"bool", "b"}, - }; - static const int kTypeCount = sizeof(kTypes) / sizeof(kTypes[0]); - - for( int tt = 0; tt < kTypeCount; ++tt ) + sb << "typedef " << kTypes[tt].name << vv << " " << kTypes[tt].glslPrefix << "vec" << vv << ";\n"; + sb << "typedef " << kTypes[tt].name << vv << "x" << vv << " " << kTypes[tt].glslPrefix << "mat" << vv << ";\n"; + } + for (int rr = 2; rr <= 4; ++rr) + for (int cc = 2; cc <= 4; ++cc) { - // Declare GLSL aliases for HLSL types - for (int vv = 2; vv <= 4; ++vv) - { - sb << "typedef " << kTypes[tt].name << vv << " " << kTypes[tt].glslPrefix << "vec" << vv << ";\n"; - sb << "typedef " << kTypes[tt].name << vv << "x" << vv << " " << kTypes[tt].glslPrefix << "mat" << vv << ";\n"; - } - for (int rr = 2; rr <= 4; ++rr) - for (int cc = 2; cc <= 4; ++cc) - { - sb << "typedef " << kTypes[tt].name << rr << "x" << cc << " " << kTypes[tt].glslPrefix << "mat" << rr << "x" << cc << ";\n"; - } + sb << "typedef " << kTypes[tt].name << rr << "x" << cc << " " << kTypes[tt].glslPrefix << "mat" << rr << "x" << cc << ";\n"; } + } - // TODO(tfoley): Need to handle `RW*` variants of texture types as well... - static const struct { - char const* name; - TextureType::Shape baseShape; - int coordCount; - } kBaseTextureTypes[] = { - { "1D", TextureType::Shape1D, 1 }, - { "2D", TextureType::Shape2D, 2 }, - { "3D", TextureType::Shape3D, 3 }, - { "Cube", TextureType::ShapeCube, 3 }, - }; - static const int kBaseTextureTypeCount = sizeof(kBaseTextureTypes) / sizeof(kBaseTextureTypes[0]); - - - static const struct { - char const* name; - SlangResourceAccess access; - } kBaseTextureAccessLevels[] = { - { "", SLANG_RESOURCE_ACCESS_READ }, - { "RW", SLANG_RESOURCE_ACCESS_READ_WRITE }, - { "RasterizerOrdered", SLANG_RESOURCE_ACCESS_RASTER_ORDERED }, - }; - static const int kBaseTextureAccessLevelCount = sizeof(kBaseTextureAccessLevels) / sizeof(kBaseTextureAccessLevels[0]); - - for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) + // TODO(tfoley): Need to handle `RW*` variants of texture types as well... + static const struct { + char const* name; + TextureType::Shape baseShape; + int coordCount; + } kBaseTextureTypes[] = { + { "1D", TextureType::Shape1D, 1 }, + { "2D", TextureType::Shape2D, 2 }, + { "3D", TextureType::Shape3D, 3 }, + { "Cube", TextureType::ShapeCube, 3 }, + }; + static const int kBaseTextureTypeCount = sizeof(kBaseTextureTypes) / sizeof(kBaseTextureTypes[0]); + + + static const struct { + char const* name; + SlangResourceAccess access; + } kBaseTextureAccessLevels[] = { + { "", SLANG_RESOURCE_ACCESS_READ }, + { "RW", SLANG_RESOURCE_ACCESS_READ_WRITE }, + { "RasterizerOrdered", SLANG_RESOURCE_ACCESS_RASTER_ORDERED }, + }; + static const int kBaseTextureAccessLevelCount = sizeof(kBaseTextureAccessLevels) / sizeof(kBaseTextureAccessLevels[0]); + + for (int tt = 0; tt < kBaseTextureTypeCount; ++tt) + { + char const* shapeName = kBaseTextureTypes[tt].name; + TextureType::Shape baseShape = kBaseTextureTypes[tt].baseShape; + + for (int isArray = 0; isArray < 2; ++isArray) { - char const* shapeName = kBaseTextureTypes[tt].name; - TextureType::Shape baseShape = kBaseTextureTypes[tt].baseShape; + // Arrays of 3D textures aren't allowed + if (isArray && baseShape == TextureType::Shape3D) continue; - for (int isArray = 0; isArray < 2; ++isArray) + for (int isMultisample = 0; isMultisample < 2; ++isMultisample) { - // Arrays of 3D textures aren't allowed - if (isArray && baseShape == TextureType::Shape3D) continue; + auto access = SLANG_RESOURCE_ACCESS_READ; - for (int isMultisample = 0; isMultisample < 2; ++isMultisample) - { - auto access = SLANG_RESOURCE_ACCESS_READ; - - // TODO: any constraints to enforce on what gets to be multisampled? + // TODO: any constraints to enforce on what gets to be multisampled? - unsigned flavor = baseShape; - if (isArray) flavor |= TextureType::ArrayFlag; - if (isMultisample) flavor |= TextureType::MultisampleFlag; + unsigned flavor = baseShape; + if (isArray) flavor |= TextureType::ArrayFlag; + if (isMultisample) flavor |= TextureType::MultisampleFlag; // if (isShadow) flavor |= TextureType::ShadowFlag; - flavor |= (access << 8); + flavor |= (access << 8); - StringBuilder nameBuilder; - nameBuilder << shapeName; - if (isMultisample) nameBuilder << "MS"; - if (isArray) nameBuilder << "Array"; - auto name = nameBuilder.ProduceString(); + StringBuilder nameBuilder; + nameBuilder << shapeName; + if (isMultisample) nameBuilder << "MS"; + if (isArray) nameBuilder << "Array"; + auto name = nameBuilder.ProduceString(); - sb << "__generic<T> "; - sb << "__magic_type(TextureSampler," << int(flavor) << ") struct "; - sb << "__sampler" << name; - sb << " {};\n"; + sb << "__generic<T> "; + sb << "__magic_type(TextureSampler," << int(flavor) << ") struct "; + sb << "__sampler" << name; + sb << " {};\n"; - sb << "__generic<T> "; - sb << "__magic_type(Texture," << int(flavor) << ") struct "; - sb << "__texture" << name; - sb << " {};\n"; + sb << "__generic<T> "; + sb << "__magic_type(Texture," << int(flavor) << ") struct "; + sb << "__texture" << name; + sb << " {};\n"; - sb << "__generic<T> "; - sb << "__magic_type(GLSLImageType," << int(flavor) << ") struct "; - sb << "__image" << name; - sb << " {};\n"; + sb << "__generic<T> "; + sb << "__magic_type(GLSLImageType," << int(flavor) << ") struct "; + sb << "__image" << name; + sb << " {};\n"; - // TODO(tfoley): flesh this out for all the available prefixes - static const struct - { - char const* prefix; - char const* elementType; - } kTextureElementTypes[] = { - { "", "vec4" }, - { "i", "ivec4" }, - { "u", "uvec4" }, - { nullptr, nullptr }, - }; - for( auto ee = kTextureElementTypes; ee->prefix; ++ee ) - { - sb << "typedef __sampler" << name << "<" << ee->elementType << "> " << ee->prefix << "sampler" << name << ";\n"; - sb << "typedef __texture" << name << "<" << ee->elementType << "> " << ee->prefix << "texture" << name << ";\n"; - sb << "typedef __image" << name << "<" << ee->elementType << "> " << ee->prefix << "image" << name << ";\n"; - } + // TODO(tfoley): flesh this out for all the available prefixes + static const struct + { + char const* prefix; + char const* elementType; + } kTextureElementTypes[] = { + { "", "vec4" }, + { "i", "ivec4" }, + { "u", "uvec4" }, + { nullptr, nullptr }, + }; + for( auto ee = kTextureElementTypes; ee->prefix; ++ee ) + { + sb << "typedef __sampler" << name << "<" << ee->elementType << "> " << ee->prefix << "sampler" << name << ";\n"; + sb << "typedef __texture" << name << "<" << ee->elementType << "> " << ee->prefix << "texture" << name << ";\n"; + sb << "typedef __image" << name << "<" << ee->elementType << "> " << ee->prefix << "image" << name << ";\n"; } } } + } - sb << "__generic<T> __magic_type(GLSLInputParameterBlockType) struct __GLSLInputParameterBlock {};\n"; - sb << "__generic<T> __magic_type(GLSLOutputParameterBlockType) struct __GLSLOutputParameterBlock {};\n"; - sb << "__generic<T> __magic_type(GLSLShaderStorageBufferType) struct __GLSLShaderStorageBuffer {};\n"; - - sb << "__magic_type(SamplerState," << int(SamplerStateType::Flavor::SamplerState) << ") struct sampler {};"; + sb << "__generic<T> __magic_type(GLSLInputParameterBlockType) struct __GLSLInputParameterBlock {};\n"; + sb << "__generic<T> __magic_type(GLSLOutputParameterBlockType) struct __GLSLOutputParameterBlock {};\n"; + sb << "__generic<T> __magic_type(GLSLShaderStorageBufferType) struct __GLSLShaderStorageBuffer {};\n"; - sb << "__magic_type(GLSLInputAttachmentType) struct subpassInput {};"; + sb << "__magic_type(SamplerState," << int(SamplerStateType::Flavor::SamplerState) << ") struct sampler {};"; - // Define additional keywords - sb << "__modifier(GLSLBufferModifier) buffer;\n"; - sb << "__modifier(GLSLWriteOnlyModifier) writeonly;\n"; - sb << "__modifier(GLSLReadOnlyModifier) readonly;\n"; - sb << "__modifier(GLSLPatchModifier) patch;\n"; + sb << "__magic_type(GLSLInputAttachmentType) struct subpassInput {};"; - sb << "__modifier(SimpleModifier) flat;\n"; + // Define additional keywords + sb << "__modifier(GLSLBufferModifier) buffer;\n"; + sb << "__modifier(GLSLWriteOnlyModifier) writeonly;\n"; + sb << "__modifier(GLSLReadOnlyModifier) readonly;\n"; + sb << "__modifier(GLSLPatchModifier) patch;\n"; - glslLibraryCode = sb.ProduceString(); - return glslLibraryCode; - } + sb << "__modifier(SimpleModifier) flat;\n"; + glslLibraryCode = sb.ProduceString(); + return glslLibraryCode; + } - // - void SlangStdLib::Finalize() - { - code = nullptr; - stdlibPath = String(); - glslLibraryCode = String(); - } + // + void SlangStdLib::Finalize() + { + code = nullptr; + stdlibPath = String(); + glslLibraryCode = String(); } -} +} |
