diff options
Diffstat (limited to 'source/slang')
| -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 |
8 files changed, 281 insertions, 142 deletions
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; } } |
