summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/core/core.vcxproj2
-rw-r--r--source/core/core.vcxproj.filters6
-rw-r--r--source/core/slang-downstream-compiler.cpp105
-rw-r--r--source/core/slang-downstream-compiler.h11
-rw-r--r--source/core/slang-type-text-util.cpp165
-rw-r--r--source/core/slang-type-text-util.h38
-rw-r--r--source/core/slang-writer.cpp5
-rw-r--r--source/core/slang-writer.h1
-rw-r--r--source/slang/slang-check.cpp4
-rw-r--r--source/slang/slang-emit-cpp.cpp327
-rw-r--r--source/slang/slang-emit-cpp.h3
-rw-r--r--source/slang/slang-emit-cuda.cpp16
-rw-r--r--source/slang/slang-hlsl-intrinsic-set.cpp34
-rw-r--r--source/slang/slang-hlsl-intrinsic-set.h26
-rw-r--r--source/slang/slang-options.cpp10
-rw-r--r--source/slang/slang-state-serialize.cpp3
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;
}
}