diff options
Diffstat (limited to 'source')
| -rw-r--r-- | source/core/core.vcxproj | 2 | ||||
| -rw-r--r-- | source/core/core.vcxproj.filters | 6 | ||||
| -rw-r--r-- | source/core/slang-downstream-compiler.cpp | 105 | ||||
| -rw-r--r-- | source/core/slang-downstream-compiler.h | 11 | ||||
| -rw-r--r-- | source/core/slang-type-text-util.cpp | 165 | ||||
| -rw-r--r-- | source/core/slang-type-text-util.h | 38 | ||||
| -rw-r--r-- | source/core/slang-writer.cpp | 5 | ||||
| -rw-r--r-- | source/core/slang-writer.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-check.cpp | 4 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 327 | ||||
| -rw-r--r-- | source/slang/slang-emit-cpp.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-emit-cuda.cpp | 16 | ||||
| -rw-r--r-- | source/slang/slang-hlsl-intrinsic-set.cpp | 34 | ||||
| -rw-r--r-- | source/slang/slang-hlsl-intrinsic-set.h | 26 | ||||
| -rw-r--r-- | source/slang/slang-options.cpp | 10 | ||||
| -rw-r--r-- | source/slang/slang-state-serialize.cpp | 3 |
16 files changed, 501 insertions, 255 deletions
diff --git a/source/core/core.vcxproj b/source/core/core.vcxproj index b10bcc683..fe3d45f1b 100644 --- a/source/core/core.vcxproj +++ b/source/core/core.vcxproj @@ -207,6 +207,7 @@ <ClInclude Include="slang-test-tool-util.h" /> <ClInclude Include="slang-text-io.h" /> <ClInclude Include="slang-token-reader.h" /> + <ClInclude Include="slang-type-text-util.h" /> <ClInclude Include="slang-type-traits.h" /> <ClInclude Include="slang-uint-set.h" /> <ClInclude Include="slang-visual-studio-compiler-util.h" /> @@ -238,6 +239,7 @@ <ClCompile Include="slang-test-tool-util.cpp" /> <ClCompile Include="slang-text-io.cpp" /> <ClCompile Include="slang-token-reader.cpp" /> + <ClCompile Include="slang-type-text-util.cpp" /> <ClCompile Include="slang-uint-set.cpp" /> <ClCompile Include="slang-visual-studio-compiler-util.cpp" /> <ClCompile Include="slang-writer.cpp" /> diff --git a/source/core/core.vcxproj.filters b/source/core/core.vcxproj.filters index b296b23af..aeac70769 100644 --- a/source/core/core.vcxproj.filters +++ b/source/core/core.vcxproj.filters @@ -120,6 +120,9 @@ <ClInclude Include="slang-token-reader.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="slang-type-text-util.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="slang-type-traits.h"> <Filter>Header Files</Filter> </ClInclude> @@ -209,6 +212,9 @@ <ClCompile Include="slang-token-reader.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="slang-type-text-util.cpp"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="slang-uint-set.cpp"> <Filter>Source Files</Filter> </ClCompile> diff --git a/source/core/slang-downstream-compiler.cpp b/source/core/slang-downstream-compiler.cpp index 2f0cff1a9..0a40092ea 100644 --- a/source/core/slang-downstream-compiler.cpp +++ b/source/core/slang-downstream-compiler.cpp @@ -5,6 +5,8 @@ #include "../../slang-com-helper.h" #include "slang-string-util.h" +#include "slang-type-text-util.h" + #include "slang-io.h" #include "slang-shared-library.h" #include "slang-blob.h" @@ -47,7 +49,7 @@ static DownstreamCompiler::Infos _calcInfos() void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const { - out << getCompilerTypeAsText(type); + out << TypeTextUtil::asHumanText(type); // Append the version if there is a version if (majorVersion || minorVersion) @@ -74,21 +76,6 @@ void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! DownstreamCompiler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ -/* static */UnownedStringSlice DownstreamCompiler::getCompilerTypeAsText(SlangPassThrough type) -{ - switch (type) - { - default: - case SLANG_PASS_THROUGH_NONE: return UnownedStringSlice::fromLiteral("Unknown"); - case SLANG_PASS_THROUGH_VISUAL_STUDIO: return UnownedStringSlice::fromLiteral("Visual Studio"); - case SLANG_PASS_THROUGH_GCC: return UnownedStringSlice::fromLiteral("GCC"); - case SLANG_PASS_THROUGH_CLANG: return UnownedStringSlice::fromLiteral("Clang"); - case SLANG_PASS_THROUGH_NVRTC: return UnownedStringSlice::fromLiteral("NVRTC"); - case SLANG_PASS_THROUGH_FXC: return UnownedStringSlice::fromLiteral("fxc"); - case SLANG_PASS_THROUGH_DXC: return UnownedStringSlice::fromLiteral("dxc"); - case SLANG_PASS_THROUGH_GLSLANG: return UnownedStringSlice::fromLiteral("glslang"); - } -} /* static */bool DownstreamCompiler::canCompile(SlangPassThrough compiler, SlangSourceLanguage sourceLanguage) { @@ -96,92 +83,6 @@ void DownstreamCompiler::Desc::appendAsText(StringBuilder& out) const return (info.sourceLanguageFlags & (SourceLanguageFlags(1) << int(sourceLanguage))) != 0; } -/* static */SlangSourceLanguage DownstreamCompiler::getSourceLanguageFromName(const UnownedStringSlice& text) -{ - if (text == "c" || text == "C") - { - return SLANG_SOURCE_LANGUAGE_C; - } - else if (text == "cpp" || text == "c++" || text == "C++" || text == "cxx") - { - return SLANG_SOURCE_LANGUAGE_CPP; - } - else if (text == "slang") - { - return SLANG_SOURCE_LANGUAGE_SLANG; - } - else if (text == "glsl") - { - return SLANG_SOURCE_LANGUAGE_GLSL; - } - else if (text == "hlsl") - { - return SLANG_SOURCE_LANGUAGE_HLSL; - } - else if (text == "cu" || text == "cuda") - { - return SLANG_SOURCE_LANGUAGE_CUDA; - } - return SLANG_SOURCE_LANGUAGE_UNKNOWN; -} - -#define SLANG_PASS_THROUGH_TYPES(x) \ - x(none, NONE) \ - x(fxc, FXC) \ - x(dxc, DXC) \ - x(glslang, GLSLANG) \ - x(visualstudio, VISUAL_STUDIO) \ - x(clang, CLANG) \ - x(gcc, GCC) \ - x(genericcpp, GENERIC_C_CPP) \ - x(nvrtc, NVRTC) - - - -/* static */SlangPassThrough DownstreamCompiler::getPassThroughFromName(const UnownedStringSlice& slice) -{ -#define SLANG_PASS_THROUGH_NAME_TO_TYPE(x, y) \ - if (slice == UnownedStringSlice::fromLiteral(#x)) return SLANG_PASS_THROUGH_##y; - - SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_NAME_TO_TYPE) - - // Other options - if (slice == "c" || slice == "cpp") - { - return SLANG_PASS_THROUGH_GENERIC_C_CPP; - } - else if (slice == "vs") - { - return SLANG_PASS_THROUGH_VISUAL_STUDIO; - } - - return SLANG_PASS_THROUGH_NONE; -} - -/* static */SlangResult DownstreamCompiler::getPassThroughFromName(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough) -{ - outPassThrough = getPassThroughFromName(slice); - // It could be none on error - if it's not equal to "none" then it msut be an error - if (outPassThrough == SLANG_PASS_THROUGH_NONE && slice != UnownedStringSlice::fromLiteral("none")) - { - return SLANG_FAIL; - } - return SLANG_OK; -} - -/* static */UnownedStringSlice DownstreamCompiler::getPassThroughName(SlangPassThrough passThru) -{ -#define SLANG_PASS_THROUGH_TYPE_TO_NAME(x, y) \ - case SLANG_PASS_THROUGH_##y: return UnownedStringSlice::fromLiteral(#x); - - switch (passThru) - { - SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_TYPE_TO_NAME) - default: break; - } - return UnownedStringSlice::fromLiteral("unknown"); -} - /* static */SlangCompileTarget DownstreamCompiler::getCompileTarget(SlangSourceLanguage sourceLanguage) { switch (sourceLanguage) diff --git a/source/core/slang-downstream-compiler.h b/source/core/slang-downstream-compiler.h index a4238ce38..f9e33ed6c 100644 --- a/source/core/slang-downstream-compiler.h +++ b/source/core/slang-downstream-compiler.h @@ -280,22 +280,11 @@ public: /// Some downstream compilers are backed by a shared library. This allows access to the shared library to access internal functions. virtual ISlangSharedLibrary* getSharedLibrary() { return nullptr; } - /// Return the compiler type as name - static UnownedStringSlice getCompilerTypeAsText(SlangPassThrough type); - /// Get info for a compiler type static const Info& getInfo(SlangPassThrough compiler) { return s_infos.infos[int(compiler)]; } /// True if this compiler can compile the specified language static bool canCompile(SlangPassThrough compiler, SlangSourceLanguage sourceLanguage); - /// Given a source language name returns a source language. Name here is distinct from extension - static SlangSourceLanguage getSourceLanguageFromName(const UnownedStringSlice& text); - /// Given a name returns the pass through - static SlangPassThrough getPassThroughFromName(const UnownedStringSlice& slice); - static SlangResult getPassThroughFromName(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough); - /// Get the compilers name - static UnownedStringSlice getPassThroughName(SlangPassThrough passThru); - /// Given a source language return as the equivalent compile target static SlangCompileTarget getCompileTarget(SlangSourceLanguage sourceLanguage); diff --git a/source/core/slang-type-text-util.cpp b/source/core/slang-type-text-util.cpp new file mode 100644 index 000000000..b9ccc4971 --- /dev/null +++ b/source/core/slang-type-text-util.cpp @@ -0,0 +1,165 @@ + +#include "slang-type-text-util.h" + + +namespace Slang +{ + +#define SLANG_SCALAR_TYPES(x) \ + x(None, none) \ + x(Void, void) \ + x(Bool, bool) \ + x(Float16, half) \ + x(UInt32, uint32_t) \ + x(Int32, int32_t) \ + x(Int64, int64_t) \ + x(UInt64, uint64_t) \ + x(Float32, float) \ + x(Float64, double) + +#define SLANG_PASS_THROUGH_TYPES(x) \ + x(none, NONE) \ + x(fxc, FXC) \ + x(dxc, DXC) \ + x(glslang, GLSLANG) \ + x(visualstudio, VISUAL_STUDIO) \ + x(clang, CLANG) \ + x(gcc, GCC) \ + x(genericcpp, GENERIC_C_CPP) \ + x(nvrtc, NVRTC) + +namespace { // anonymous + +struct ScalarTypeInfo +{ + slang::TypeReflection::ScalarType type; + UnownedStringSlice text; +}; + +static const ScalarTypeInfo s_scalarTypeInfo[] = +{ + #define SLANG_SCALAR_TYPE_INFO(value, text) \ + { slang::TypeReflection::ScalarType::value, UnownedStringSlice::fromLiteral(#text) }, + SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_INFO) +}; + +} // anonymous + +/* static */UnownedStringSlice TypeTextUtil::asText(slang::TypeReflection::ScalarType scalarType) +{ + typedef slang::TypeReflection::ScalarType ScalarType; + switch (scalarType) + { +#define SLANG_SCALAR_TYPE_TO_TEXT(value, text) case ScalarType::value: return UnownedStringSlice::fromLiteral(#text); + SLANG_SCALAR_TYPES(SLANG_SCALAR_TYPE_TO_TEXT) + default: break; + } + + return UnownedStringSlice(); +} + +/* static */slang::TypeReflection::ScalarType TypeTextUtil::asScalarType(const UnownedStringSlice& inText) +{ + for (Index i = 0; i < SLANG_COUNT_OF(s_scalarTypeInfo); ++i) + { + const auto& info = s_scalarTypeInfo[i]; + if (info.text == inText) + { + return info.type; + } + } + return slang::TypeReflection::ScalarType::None; +} + +/* static */UnownedStringSlice TypeTextUtil::asHumanText(SlangPassThrough type) +{ + switch (type) + { + default: + case SLANG_PASS_THROUGH_NONE: return UnownedStringSlice::fromLiteral("Unknown"); + case SLANG_PASS_THROUGH_VISUAL_STUDIO: return UnownedStringSlice::fromLiteral("Visual Studio"); + case SLANG_PASS_THROUGH_GCC: return UnownedStringSlice::fromLiteral("GCC"); + case SLANG_PASS_THROUGH_CLANG: return UnownedStringSlice::fromLiteral("Clang"); + case SLANG_PASS_THROUGH_NVRTC: return UnownedStringSlice::fromLiteral("NVRTC"); + case SLANG_PASS_THROUGH_FXC: return UnownedStringSlice::fromLiteral("fxc"); + case SLANG_PASS_THROUGH_DXC: return UnownedStringSlice::fromLiteral("dxc"); + case SLANG_PASS_THROUGH_GLSLANG: return UnownedStringSlice::fromLiteral("glslang"); + } +} + +/* static */SlangSourceLanguage TypeTextUtil::asSourceLanguage(const UnownedStringSlice& text) +{ + if (text == "c" || text == "C") + { + return SLANG_SOURCE_LANGUAGE_C; + } + else if (text == "cpp" || text == "c++" || text == "C++" || text == "cxx") + { + return SLANG_SOURCE_LANGUAGE_CPP; + } + else if (text == "slang") + { + return SLANG_SOURCE_LANGUAGE_SLANG; + } + else if (text == "glsl") + { + return SLANG_SOURCE_LANGUAGE_GLSL; + } + else if (text == "hlsl") + { + return SLANG_SOURCE_LANGUAGE_HLSL; + } + else if (text == "cu" || text == "cuda") + { + return SLANG_SOURCE_LANGUAGE_CUDA; + } + return SLANG_SOURCE_LANGUAGE_UNKNOWN; +} + +/* static */SlangPassThrough TypeTextUtil::asPassThrough(const UnownedStringSlice& slice) +{ +#define SLANG_PASS_THROUGH_NAME_TO_TYPE(x, y) \ + if (slice == UnownedStringSlice::fromLiteral(#x)) return SLANG_PASS_THROUGH_##y; + + SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_NAME_TO_TYPE) + + // Other options + if (slice == "c" || slice == "cpp") + { + return SLANG_PASS_THROUGH_GENERIC_C_CPP; + } + else if (slice == "vs") + { + return SLANG_PASS_THROUGH_VISUAL_STUDIO; + } + + return SLANG_PASS_THROUGH_NONE; +} + +/* static */SlangResult TypeTextUtil::asPassThrough(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough) +{ + outPassThrough = asPassThrough(slice); + // It could be none on error - if it's not equal to "none" then it must be an error + if (outPassThrough == SLANG_PASS_THROUGH_NONE && slice != UnownedStringSlice::fromLiteral("none")) + { + return SLANG_FAIL; + } + return SLANG_OK; +} + +/* static */UnownedStringSlice TypeTextUtil::asText(SlangPassThrough passThru) +{ +#define SLANG_PASS_THROUGH_TYPE_TO_NAME(x, y) \ + case SLANG_PASS_THROUGH_##y: return UnownedStringSlice::fromLiteral(#x); + + switch (passThru) + { + SLANG_PASS_THROUGH_TYPES(SLANG_PASS_THROUGH_TYPE_TO_NAME) + default: break; + } + return UnownedStringSlice::fromLiteral("unknown"); +} + + +} + diff --git a/source/core/slang-type-text-util.h b/source/core/slang-type-text-util.h new file mode 100644 index 000000000..73c1d9ef0 --- /dev/null +++ b/source/core/slang-type-text-util.h @@ -0,0 +1,38 @@ +#ifndef SLANG_CORE_TYPE_TEXT_UTIL_H +#define SLANG_CORE_TYPE_TEXT_UTIL_H + +#include "../../slang.h" + +#include "slang-string.h" + + +namespace Slang +{ + +/// Utility class to allow conversion of types (such as enums) to and from text types +struct TypeTextUtil +{ + + /// Get the scalar type as text. + static Slang::UnownedStringSlice asText(slang::TypeReflection::ScalarType scalarType); + + // Converts text to scalar type. Returns 'none' if not determined + static slang::TypeReflection::ScalarType asScalarType(const Slang::UnownedStringSlice& text); + + /// As human readable text + static UnownedStringSlice asHumanText(SlangPassThrough type); + + /// Given a source language name returns a source language. Name here is distinct from extension + static SlangSourceLanguage asSourceLanguage(const UnownedStringSlice& text); + + /// Given a name returns the pass through + static SlangPassThrough asPassThrough(const UnownedStringSlice& slice); + static SlangResult asPassThrough(const UnownedStringSlice& slice, SlangPassThrough& outPassThrough); + + /// Get the compilers name + static UnownedStringSlice asText(SlangPassThrough passThru); +}; + +} + +#endif // SLANG_CORE_TYPE_TEXT_UTIL_H diff --git a/source/core/slang-writer.cpp b/source/core/slang-writer.cpp index 2f694aeec..0688bea6c 100644 --- a/source/core/slang-writer.cpp +++ b/source/core/slang-writer.cpp @@ -57,6 +57,11 @@ SlangResult WriterHelper::put(const char* text) return m_writer->write(text, ::strlen(text)); } +SlangResult WriterHelper::put(const UnownedStringSlice& text) +{ + return m_writer->write(text.begin(), text.size()); +} + /* !!!!!!!!!!!!!!!!!!!!!!!!! BaseWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ ISlangUnknown* BaseWriter::getInterface(const Guid& guid) diff --git a/source/core/slang-writer.h b/source/core/slang-writer.h index 759644fde..380823b39 100644 --- a/source/core/slang-writer.h +++ b/source/core/slang-writer.h @@ -16,6 +16,7 @@ class WriterHelper public: SlangResult print(const char* format, ...); SlangResult put(const char* text); + SlangResult put(const UnownedStringSlice& text); SLANG_FORCE_INLINE SlangResult write(const char* chars, size_t numChars) { return m_writer->write(chars, numChars); } SLANG_FORCE_INLINE void flush() { m_writer->flush(); } diff --git a/source/slang/slang-check.cpp b/source/slang/slang-check.cpp index bd7e2ea12..77e3ffc9f 100644 --- a/source/slang/slang-check.cpp +++ b/source/slang/slang-check.cpp @@ -7,6 +7,8 @@ #include "slang-check-impl.h" +#include "../core/slang-type-text-util.h" + namespace Slang { namespace { // anonymous @@ -180,7 +182,7 @@ namespace Slang SlangFuncPtr func = sharedLibrary->findFuncByName(info.name); if (!func) { - UnownedStringSlice compilerName = DownstreamCompiler::getCompilerTypeAsText(SlangPassThrough(info.compilerType)); + UnownedStringSlice compilerName = TypeTextUtil::asText(SlangPassThrough(info.compilerType)); sink->diagnose(SourceLoc(), Diagnostics::failedToFindFunctionForCompiler, info.name, compilerName); return nullptr; } diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 93d1cf2dd..30388479e 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -394,6 +394,23 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S { switch (type->op) { + case kIROp_PtrType: + { + auto ptrType = static_cast<IRPtrType*>(type); + SLANG_RETURN_ON_FAIL(calcTypeName(ptrType->getValueType(), target, out)); + // TODO(JS): It seems although it says it is a pointer, it can actually be output as a reference + // not clear where the ptr aspect is there, as in the definition it is just 'out', implying out + // is somewhere converted to a ptr? + out << "&"; + return SLANG_OK; + } + case kIROp_RefType: + { + auto refType = static_cast<IRRefType*>(type); + SLANG_RETURN_ON_FAIL(calcTypeName(refType->getValueType(), target, out)); + out << "&"; + return SLANG_OK; + } case kIROp_HalfType: { // Special case half @@ -571,6 +588,21 @@ static IRBasicType* _getElementType(IRType* type) { switch (type->op) { + case kIROp_PtrType: + { + type = static_cast<IRPtrType*>(type)->getValueType(); + break; + } + case kIROp_RefType: + { + type = static_cast<IRRefType*>(type)->getValueType(); + break; + } + default: break; + } + + switch (type->op) + { case kIROp_VectorType: { auto vecType = static_cast<IRVectorType*>(type); @@ -658,7 +690,6 @@ void CPPSourceEmitter::_emitAryDefinition(const HLSLIntrinsic* specOp) } IRType* retType = specOp->returnType; - TypeDimension retDim = _getTypeDimension(retType, false); UnownedStringSlice scalarFuncName(funcName); if (isOperator) @@ -677,15 +708,31 @@ void CPPSourceEmitter::_emitAryDefinition(const HLSLIntrinsic* specOp) writer->emit("\n{\n"); writer->indent(); - emitType(retType); - writer->emit(" r;\n"); + const bool hasReturnType = retType->op != kIROp_VoidType; - for (int i = 0; i < retDim.rowCount; ++i) + TypeDimension calcDim; + if (hasReturnType) { - for (int j = 0; j < retDim.colCount; ++j) + emitType(retType); + writer->emit(" r;\n"); + + calcDim = _getTypeDimension(retType, false); + } + else + { + calcDim = _getTypeDimension(funcType->getParamType(0), false); + } + + for (int i = 0; i < calcDim.rowCount; ++i) + { + for (int j = 0; j < calcDim.colCount; ++j) { - _emitAccess(UnownedStringSlice::fromLiteral("r"), retDim, i, j, writer); - writer->emit(" = "); + if (hasReturnType) + { + _emitAccess(UnownedStringSlice::fromLiteral("r"), calcDim, i, j, writer); + writer->emit(" = "); + } + if (isOperator) { switch (numParams) @@ -727,7 +774,10 @@ void CPPSourceEmitter::_emitAryDefinition(const HLSLIntrinsic* specOp) } } - writer->emit("return r;\n"); + if (hasReturnType) + { + writer->emit("return r;\n"); + } writer->dedent(); writer->emit("}\n\n"); @@ -1066,6 +1116,7 @@ void CPPSourceEmitter::_emitNormalizeDefinition(const UnownedStringSlice& funcNa writer->emit("}\n\n"); } + void CPPSourceEmitter::_emitConstructConvertDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp) { SourceWriter* writer = getSourceWriter(); @@ -1134,6 +1185,91 @@ void CPPSourceEmitter::_emitConstructConvertDefinition(const UnownedStringSlice& writer->emit("}\n\n"); } +void CPPSourceEmitter::_emitInitDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp) +{ + SourceWriter* writer = getSourceWriter(); + IRFuncType* funcType = specOp->signatureType; + + emitFunctionPreambleImpl(nullptr); + + IRType* retType = specOp->returnType; + + _emitSignature(funcName, specOp); + writer->emit("\n{\n"); + writer->indent(); + + // Use C++ construction + writer->emit("return "); + emitType(retType); + writer->emit("{ "); + + const Index paramCount = Index(funcType->getParamCount()); + + if (IRVectorType* vecType = as<IRVectorType>(retType)) + { + Index elementCount = Index(GetIntVal(vecType->getElementCount())); + + Index paramIndex = 0; + Index paramSubIndex = 0; + + for (Index i = 0; i < elementCount; ++i) + { + if (i > 0) + { + writer->emit(", "); + } + + if (paramIndex >= paramCount) + { + writer->emit("0"); + } + else + { + IRType* paramType = funcType->getParamType(paramIndex); + + if (IRVectorType* paramVecType = as<IRVectorType>(paramType)) + { + Index paramElementCount = Index(GetIntVal(paramVecType->getElementCount())); + + writer->emitChar('a' + char(paramIndex)); + writer->emit("."); + writer->emitChar(s_elemNames[paramSubIndex]); + + paramSubIndex ++; + + if (paramSubIndex >= paramElementCount) + { + paramIndex++; + paramSubIndex = 0; + } + } + else + { + writer->emitChar('a' + char(paramIndex)); + paramIndex++; + } + } + } + } + else + { + for (Index i = 0; i < paramCount; ++i) + { + if (i > 0) + { + writer->emit(", "); + } + writer->emitChar('a' + char(i)); + } + } + + writer->emit("};\n"); + + writer->dedent(); + writer->emit("}\n\n"); +} + + void CPPSourceEmitter::_emitConstructFromScalarDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp) { SourceWriter* writer = getSourceWriter(); @@ -1246,6 +1382,10 @@ void CPPSourceEmitter::emitSpecializedOperationDefinition(const HLSLIntrinsic* s switch (specOp->op) { + case Op::Init: + { + return _emitInitDefinition(_getFuncName(specOp), specOp); + } case Op::VecMatMul: case Op::Dot: { @@ -1284,6 +1424,11 @@ void CPPSourceEmitter::emitSpecializedOperationDefinition(const HLSLIntrinsic* s { return _emitGetAtDefinition(_getFuncName(specOp), specOp); } + case Op::Swizzle: + { + // Don't have to output anything for swizzle for now + return; + } default: { const auto& info = HLSLIntrinsic::getInfo(specOp->op); @@ -1306,80 +1451,23 @@ void CPPSourceEmitter::emitCall(const HLSLIntrinsic* specOp, IRInst* inst, const SLANG_UNUSED(inOuterPrec); SourceWriter* writer = getSourceWriter(); - - // Getting the name means that this op is registered as used switch (specOp->op) { case Op::Init: { - // For C++ we don't need an init function - // For C we'll need the construct function for the return type - //UnownedStringSlice name = _getFuncName(specOp); - IRType* retType = specOp->returnType; - - switch (retType->op) + if (IRBasicType::isaImpl(retType->op)) { - case kIROp_VectorType: - { - // Get the type name - emitType(retType); - writer->emitChar('{'); - - for (int i = 0; i < numOperands; ++i) - { - if (i > 0) - { - writer->emit(", "); - } - emitOperand(operands[i].get(), getInfo(EmitOp::General)); - } - - writer->emitChar('}'); - break; - } - case kIROp_MatrixType: - { - IRMatrixType* matType = static_cast<IRMatrixType*>(retType); - - //int colsCount = int(GetIntVal(matType->getColumnCount())); - int rowsCount = int(GetIntVal(matType->getRowCount())); - - SLANG_ASSERT(rowsCount == numOperands); - - emitType(retType); - writer->emitChar('{'); - - for (int j = 0; j < rowsCount; ++j) - { - if (j > 0) - { - writer->emit(", "); - } - emitOperand(operands[j].get(), getInfo(EmitOp::General)); - } - - writer->emitChar('}'); - break; - } - default: - { - if (IRBasicType::isaImpl(retType->op)) - { - SLANG_ASSERT(numOperands == 1); + SLANG_ASSERT(numOperands == 1); - writer->emit(_getTypeName(retType)); - writer->emitChar('('); - - emitOperand(operands[0].get(), getInfo(EmitOp::General)); + writer->emit(_getTypeName(retType)); + writer->emitChar('('); - writer->emitChar(')'); - break; - } + emitOperand(operands[0].get(), getInfo(EmitOp::General)); - SLANG_ASSERT(!"Not handled"); - } + writer->emitChar(')'); + return; } break; } @@ -1419,56 +1507,55 @@ void CPPSourceEmitter::emitCall(const HLSLIntrinsic* specOp, IRInst* inst, const } writer->emit("}"); - break; + return; } - default: - { - const auto& info = HLSLIntrinsic::getInfo(specOp->op); - // Make sure that the return type is available - bool isOperator = _isOperator(info.funcName); - - UnownedStringSlice funcName = _getFuncName(specOp); + default: break; + } + + { + const auto& info = HLSLIntrinsic::getInfo(specOp->op); + // Make sure that the return type is available + const bool isOperator = _isOperator(info.funcName); + const UnownedStringSlice funcName = _getFuncName(specOp); - switch (specOp->op) + switch (specOp->op) + { + case Op::ConstructFromScalar: { - case Op::ConstructFromScalar: - { - // We need to special case, because this may have come from a swizzle from a built in - // type, in that case the only parameter we want is the first one - numOperands = 1; - break; - } - - default: break; + // We need to special case, because this may have come from a swizzle from a built in + // type, in that case the only parameter we want is the first one + numOperands = 1; + break; } - // add that we want a function - SLANG_ASSERT(info.numOperands < 0 || numOperands == info.numOperands); + default: break; + } - useType(specOp->returnType); + // add that we want a function + SLANG_ASSERT(info.numOperands < 0 || numOperands == info.numOperands); + + useType(specOp->returnType); - if (isOperator) - { - // Just do the default output - defaultEmitInstExpr(inst, inOuterPrec); - } - else - { - writer->emit(funcName); - writer->emitChar('('); + if (isOperator) + { + // Just do the default output + defaultEmitInstExpr(inst, inOuterPrec); + } + else + { + writer->emit(funcName); + writer->emitChar('('); - for (int i = 0; i < numOperands; ++i) + for (int i = 0; i < numOperands; ++i) + { + if (i > 0) { - if (i > 0) - { - writer->emit(", "); - } - emitOperand(operands[i].get(), getInfo(EmitOp::General)); + writer->emit(", "); } - - writer->emitChar(')'); + emitOperand(operands[i].get(), getInfo(EmitOp::General)); } - break; + + writer->emitChar(')'); } } } @@ -1577,6 +1664,12 @@ SlangResult CPPSourceEmitter::calcFuncName(const HLSLIntrinsic* specOp, StringBu outBuilder << "getAt"; return SLANG_OK; } + case Op::Init: + { + outBuilder << "make_"; + SLANG_RETURN_ON_FAIL(calcTypeName(specOp->returnType, CodeGenTarget::CSource, outBuilder)); + return SLANG_OK; + } default: break; } @@ -2061,10 +2154,16 @@ void CPPSourceEmitter::emitPreprocessorDirectivesImpl() } } - // Emit all the intrinsics that were used - for (const auto& keyValue : m_intrinsicNameMap) { - _maybeEmitSpecializedOperationDefinition(keyValue.Key); + List<const HLSLIntrinsic*> intrinsics; + m_intrinsicSet.getIntrinsics(intrinsics); + + // Emit all the intrinsics that were used + for (auto intrinsic: intrinsics) + { + _maybeEmitSpecializedOperationDefinition(intrinsic); + } + } } diff --git a/source/slang/slang-emit-cpp.h b/source/slang/slang-emit-cpp.h index 082497510..da8d026ee 100644 --- a/source/slang/slang-emit-cpp.h +++ b/source/slang/slang-emit-cpp.h @@ -104,7 +104,8 @@ protected: void _emitConstructConvertDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp); void _emitConstructFromScalarDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp); void _emitGetAtDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp); - + void _emitInitDefinition(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp); + void _emitSignature(const UnownedStringSlice& funcName, const HLSLIntrinsic* specOp); void _emitInOutParamType(IRType* type, String const& name, IRType* valueType); diff --git a/source/slang/slang-emit-cuda.cpp b/source/slang/slang-emit-cuda.cpp index 2d49e606c..019bf8b94 100644 --- a/source/slang/slang-emit-cuda.cpp +++ b/source/slang/slang-emit-cuda.cpp @@ -393,9 +393,9 @@ void CUDASourceEmitter::emitCall(const HLSLIntrinsic* specOp, IRInst* inst, cons IRType* retType = specOp->returnType; - switch (retType->op) + if (IRVectorType* vecType = as<IRVectorType>(retType)) { - case kIROp_VectorType: + if (numOperands == GetIntVal(vecType->getElementCount())) { // Get the type name writer->emit("make_"); @@ -414,8 +414,8 @@ void CUDASourceEmitter::emitCall(const HLSLIntrinsic* specOp, IRInst* inst, cons writer->emitChar(')'); return; } - default: break; } + // Just use the default break; } default: break; @@ -542,10 +542,14 @@ void CUDASourceEmitter::emitPreprocessorDirectivesImpl() } } - // Emit all the intrinsics that were used - for (const auto& keyValue : m_intrinsicNameMap) { - _maybeEmitSpecializedOperationDefinition(keyValue.Key); + List<const HLSLIntrinsic*> intrinsics; + m_intrinsicSet.getIntrinsics(intrinsics); + // Emit all the intrinsics that were used + for (auto intrinsic : intrinsics) + { + _maybeEmitSpecializedOperationDefinition(intrinsic); + } } } diff --git a/source/slang/slang-hlsl-intrinsic-set.cpp b/source/slang/slang-hlsl-intrinsic-set.cpp index 1f42836f3..7500e799a 100644 --- a/source/slang/slang-hlsl-intrinsic-set.cpp +++ b/source/slang/slang-hlsl-intrinsic-set.cpp @@ -245,19 +245,37 @@ SlangResult HLSLIntrinsicSet::makeIntrinsic(IRInst* inst, HLSLIntrinsic& out) // If it's constructed from a type conversion calcIntrinsic(Op::ConstructConvert, inst, out); } + return SLANG_OK; } else { - // We only emit as if it has one operand, but we can tell how many it actually has from the return type - calcIntrinsic(Op::Init, inst, 1, out); + // If we are constructing a basic type, we don't need an Op::Init + if (!IRBasicType::isaImpl(dstType->op)) + { + // Emit the 'init' intrinsic + calcIntrinsic(Op::Init, inst, inst->getOperandCount(), out); + return SLANG_OK; + } } - return SLANG_OK; + return SLANG_FAIL; } case kIROp_makeVector: + { + if (inst->getOperandCount() == 1 && as<IRBasicType>(inst->getOperand(0)->getDataType())) + { + // This is make from scalar + calcIntrinsic(Op::ConstructFromScalar, inst, out); + } + else + { + calcIntrinsic(Op::Init, inst, inst->getOperandCount(), out); + } + return SLANG_OK; + } case kIROp_MakeMatrix: { // We only emit as if it has one operand, but we can tell how many it actually has from the return type - calcIntrinsic(Op::Init, inst, 1, out); + calcIntrinsic(Op::Init, inst, inst->getOperandCount(), out); return SLANG_OK; } case kIROp_swizzle: @@ -346,6 +364,14 @@ SlangResult HLSLIntrinsicSet::makeIntrinsic(IRInst* inst, HLSLIntrinsic& out) return SLANG_FAIL; } +void HLSLIntrinsicSet::getIntrinsics(List<const HLSLIntrinsic*>& out) const +{ + for (auto& pair : m_intrinsics) + { + out.add(pair.Value); + } +} + HLSLIntrinsic* HLSLIntrinsicSet::add(const HLSLIntrinsic& intrinsic) { // Make sure it's valid(!) diff --git a/source/slang/slang-hlsl-intrinsic-set.h b/source/slang/slang-hlsl-intrinsic-set.h index 17e88fc9a..90ed9368f 100644 --- a/source/slang/slang-hlsl-intrinsic-set.h +++ b/source/slang/slang-hlsl-intrinsic-set.h @@ -146,26 +146,28 @@ struct HLSLIntrinsic bool operator==(const ThisType& rhs) const { return op == rhs.op && returnType == rhs.returnType && signatureType == rhs.signatureType; } bool operator!=(const ThisType& rhs) const { return !(*this == rhs); } + static bool isTypeScalar(IRType* type) + { + // Strip off ptr if it's an operand type + if (type->op == kIROp_PtrType) + { + type = as<IRType>(type->getOperand(0)); + } + // If any are vec or matrix, then we + return !(type->op == kIROp_MatrixType || type->op == kIROp_VectorType); + } + bool isScalar() const { Index paramCount = Index(signatureType->getParamCount()); for (Index i = 0; i < paramCount; ++i) { - IRType* paramType = signatureType->getParamType(i); - - // Strip off ptr if it's an operand type - if (paramType->op == kIROp_PtrType) - { - paramType = as<IRType>(paramType->getOperand(0)); - } - - // If any are vec or matrix, then we - if (paramType->op == kIROp_MatrixType || paramType->op == kIROp_VectorType) + if (!isTypeScalar(signatureType->getParamType(i))) { return false; } } - return true; + return isTypeScalar(returnType); } int GetHashCode() const { return combineHash(int(op), combineHash(Slang::GetHashCode(returnType), Slang::GetHashCode(signatureType))); } @@ -255,6 +257,8 @@ public: /// Returns the intrinsic constructed if there is one from the inst. If not possible to construct returns nullptr. HLSLIntrinsic* add(IRInst* inst); + void getIntrinsics(List<const HLSLIntrinsic*>& out) const; + HLSLIntrinsicSet(IRTypeSet* typeSet, HLSLIntrinsicOpLookup* lookup); protected: diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index f9f8db0e2..456c43fa6 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -15,6 +15,8 @@ #include "slang-state-serialize.h" #include "slang-ir-serialize.h" +#include "../core/slang-type-text-util.h" + #include <assert.h> namespace Slang { @@ -708,7 +710,7 @@ struct OptionsParser SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, name)); SlangPassThrough passThrough = SLANG_PASS_THROUGH_NONE; - if (SLANG_FAILED(DownstreamCompiler::getPassThroughFromName(name.getUnownedSlice(), passThrough))) + if (SLANG_FAILED(TypeTextUtil::asPassThrough(name.getUnownedSlice(), passThrough))) { sink->diagnose(SourceLoc(), Diagnostics::unknownPassThroughTarget, name); return SLANG_FAIL; @@ -943,7 +945,7 @@ struct OptionsParser String compilerText; SLANG_RETURN_ON_FAIL(tryReadCommandLineArgument(sink, arg, &argCursor, argEnd, compilerText)); - SlangSourceLanguage sourceLanguage = DownstreamCompiler::getSourceLanguageFromName(sourceLanguageText.getUnownedSlice()); + SlangSourceLanguage sourceLanguage = TypeTextUtil::asSourceLanguage(sourceLanguageText.getUnownedSlice()); if (sourceLanguage == SLANG_SOURCE_LANGUAGE_UNKNOWN) { sink->diagnose(SourceLoc(), Diagnostics::unknownSourceLanguage, sourceLanguageText); @@ -951,7 +953,7 @@ struct OptionsParser } SlangPassThrough compiler; - if (SLANG_FAILED(DownstreamCompiler::getPassThroughFromName(compilerText.getUnownedSlice(), compiler))) + if (SLANG_FAILED(TypeTextUtil::asPassThrough(compilerText.getUnownedSlice(), compiler))) { sink->diagnose(SourceLoc(), Diagnostics::unknownPassThroughTarget, compilerText); return SLANG_FAIL; @@ -985,7 +987,7 @@ struct OptionsParser String slice = argStr.subString(1, index - 1); SlangPassThrough passThrough = SLANG_PASS_THROUGH_NONE; - if (SLANG_SUCCEEDED(DownstreamCompiler::getPassThroughFromName(slice.getUnownedSlice(), passThrough))) + if (SLANG_SUCCEEDED(TypeTextUtil::asPassThrough(slice.getUnownedSlice(), passThrough))) { session->setDownstreamCompilerPath(passThrough, name.getBuffer()); continue; diff --git a/source/slang/slang-state-serialize.cpp b/source/slang/slang-state-serialize.cpp index b97756965..7b689e762 100644 --- a/source/slang/slang-state-serialize.cpp +++ b/source/slang/slang-state-serialize.cpp @@ -6,6 +6,7 @@ #include "../core/slang-stream.h" #include "../core/slang-math.h" +#include "../core/slang-type-text-util.h" #include "slang-options.h" @@ -1228,7 +1229,7 @@ static SlangResult _calcCommandLine(OffsetBase& base, StateSerializeUtil::Reques default: { cmd.addArg("-pass-through"); - cmd.addArg(DownstreamCompiler::getPassThroughName(SlangPassThrough(requestState->passThroughMode))); + cmd.addArg(TypeTextUtil::asText(SlangPassThrough(requestState->passThroughMode))); break; } } |
