summaryrefslogtreecommitdiffstats
path: root/source/slang/slang-emit-cpp.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
-rw-r--r--source/slang/slang-emit-cpp.cpp327
1 files changed, 213 insertions, 114 deletions
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);
+ }
+
}
}