diff options
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 189 |
1 files changed, 80 insertions, 109 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 6b7fc46bf..1ff5af4fb 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -500,6 +500,16 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S out << "void*"; return SLANG_OK; } + case kIROp_ConstantBufferType: + case kIROp_ParameterBlockType: + { + auto groupType = cast<IRParameterGroupType>(type); + auto elementType = groupType->getElementType(); + + SLANG_RETURN_ON_FAIL(calcTypeName(elementType, target, out)); + out << "*"; + return SLANG_OK; + } default: { if (isNominalOp(type->op)) @@ -2357,29 +2367,6 @@ void CPPSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPre switch (inst->op) { - case 0: // nothing yet - case kIROp_GlobalParam: - { - String name = getName(inst); - - if (inst->findDecorationImpl(kIROp_EntryPointParamDecoration)) - { - // It's an entry point parameter - // The parameter is held in a struct so always deref - m_writer->emit("(*"); - m_writer->emit(name); - m_writer->emit(")"); - } - else - { - // It's in UniformState - m_writer->emit("("); - m_writer->emit("uniformState->"); - m_writer->emit(name); - m_writer->emit(")"); - } - break; - } case kIROp_Param: { auto varLayout = getVarLayout(inst); @@ -2443,7 +2430,7 @@ static bool _isFunction(IROp op) return op == kIROp_Func; } -void CPPSourceEmitter::_emitEntryPointDefinitionStart(IRFunc* func, IRGlobalParam* entryPointGlobalParams, const String& funcName, const UnownedStringSlice& varyingTypeName) +void CPPSourceEmitter::_emitEntryPointDefinitionStart(IRFunc* func, IRGlobalParam* entryPointParams, IRGlobalParam* globalParams, const String& funcName, const UnownedStringSlice& varyingTypeName) { auto resultType = func->getResultType(); @@ -2456,27 +2443,35 @@ void CPPSourceEmitter::_emitEntryPointDefinitionStart(IRFunc* func, IRGlobalPara m_writer->emit("("); m_writer->emit(varyingTypeName); - m_writer->emit("* varyingInput, void* params, void* uniformState)"); + m_writer->emit("* varyingInput, void* entryPointParams, void* globalParams)"); emitSemantics(func); m_writer->emit("\n{\n"); m_writer->indent(); // Initialize when constructing so that globals are zeroed m_writer->emit("KernelContext context = {};\n"); - m_writer->emit("context.uniformState = (UniformState*)uniformState;\n"); - if (entryPointGlobalParams) + if (entryPointParams) { - auto varDecl = entryPointGlobalParams; - auto rawType = varDecl->getDataType(); + auto param = entryPointParams; + auto paramType = param->getDataType(); - auto varType = rawType; + m_writer->emit("context."); + m_writer->emit(getName(param)); + m_writer->emit(" = ("); + emitType(paramType); + m_writer->emit(")entryPointParams; \n"); + } + if (globalParams) + { + auto param = globalParams; + auto paramType = param->getDataType(); m_writer->emit("context."); - m_writer->emit(getName(varDecl)); + m_writer->emit(getName(param)); m_writer->emit(" = ("); - emitType(varType); - m_writer->emit("*)params; \n"); + emitType(paramType); + m_writer->emit(")globalParams; \n"); } } @@ -2677,71 +2672,53 @@ void CPPSourceEmitter::_emitForwardDeclarations(const List<EmitAction>& actions) } } -void CPPSourceEmitter::_calcGlobalParams(const List<EmitAction>& actions, List<GlobalParamInfo>& outParams, IRGlobalParam** outEntryPointGlobalParams) +void CPPSourceEmitter::_findShaderParams( + IRGlobalParam** outEntryPointParam, + IRGlobalParam** outGlobalParam) { - outParams.clear(); - *outEntryPointGlobalParams = nullptr; + SLANG_ASSERT(outEntryPointParam); + SLANG_ASSERT(outGlobalParam); - IRGlobalParam* entryPointGlobalParams = nullptr; - for (auto action : actions) - { - if (action.level == EmitAction::Level::Definition && action.inst->op == kIROp_GlobalParam) - { - auto inst = action.inst; + IRGlobalParam*& entryPointParam = *outEntryPointParam; + IRGlobalParam*& globalParam = *outGlobalParam; - if (inst->findDecorationImpl(kIROp_EntryPointParamDecoration)) - { - // Should only be one instruction marked this way - SLANG_ASSERT(entryPointGlobalParams == nullptr); - entryPointGlobalParams = as<IRGlobalParam>(inst); - continue; - } - - IRVarLayout* varLayout = CLikeSourceEmitter::getVarLayout(action.inst); - SLANG_ASSERT(varLayout); - - IRVarOffsetAttr* offsetAttr = varLayout->findOffsetAttr(LayoutResourceKind::Uniform); - IRTypeLayout* typeLayout = varLayout->getTypeLayout(); - IRTypeSizeAttr* sizeAttr = typeLayout->findSizeAttr(LayoutResourceKind::Uniform); - - GlobalParamInfo paramInfo; - paramInfo.inst = action.inst; - // Index is the byte offset for uniform - paramInfo.offset = offsetAttr ? offsetAttr->getOffset() : 0; - paramInfo.size = sizeAttr ? sizeAttr->getFiniteSize() : 0; + for(auto inst : m_irModule->getGlobalInsts()) + { + auto param = as<IRGlobalParam>(inst); + if(!param) + continue; - outParams.add(paramInfo); + // Currently, the entry-point parameters + // are represented as a single parameter + // at the global scope, and the same is + // true of the parameters that were + // originally declared as globals. + // + // We need to find capture each of these + // parameters, and we need to tell them + // apart. Luckily, the logic that + // moved the entry-point parameters to + // global scope will ahve also marked + // the entry-point parameters with + // a decoration that we can detect. + // + if (inst->findDecorationImpl(kIROp_EntryPointParamDecoration)) + { + // Should only be one instruction marked this way + SLANG_ASSERT(entryPointParam == nullptr); + entryPointParam = param; + continue; } - } - - // We want to sort by layout offset, and insert suitable padding - outParams.sort(); - - *outEntryPointGlobalParams = entryPointGlobalParams; -} - -void CPPSourceEmitter::_emitUniformStateMembers(const List<EmitAction>& actions, IRGlobalParam** outEntryPointGlobalParams) -{ - List<GlobalParamInfo> params; - _calcGlobalParams(actions, params, outEntryPointGlobalParams); - - int padIndex = 0; - size_t offset = 0; - for (const auto& paramInfo : params) - { - if (offset < paramInfo.offset) + else { - // We want to output some padding - StringBuilder builder; - builder << "uint8_t _pad" << (padIndex++) << "[" << (paramInfo.offset - offset) << "];\n"; - m_writer->emit(builder); + // There should only be one instruction representing + // the global-scope shader parameters. + // + SLANG_ASSERT(globalParam == nullptr); + globalParam = param; + continue; } - - emitGlobalInst(paramInfo.inst); - // Set offset after this - offset = paramInfo.offset + paramInfo.size; } - m_writer->emit("\n"); } void CPPSourceEmitter::emitModuleImpl(IRModule* module) @@ -2756,26 +2733,15 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) _emitForwardDeclarations(actions); - IRGlobalParam* entryPointGlobalParams = nullptr; - - // Output the global parameters in a 'UniformState' structure - { - m_writer->emit("struct UniformState\n{\n"); - m_writer->indent(); - - _emitUniformStateMembers(actions, &entryPointGlobalParams); - - m_writer->dedent(); - m_writer->emit("\n};\n\n"); - } + IRGlobalParam* entryPointParams = nullptr; + IRGlobalParam* globalParams = nullptr; + _findShaderParams(&entryPointParams, &globalParams); // Output the 'Context' which will be used for execution { m_writer->emit("struct KernelContext\n{\n"); m_writer->indent(); - m_writer->emit("UniformState* uniformState;\n"); - m_writer->emit("uint3 dispatchThreadID;\n"); //if (m_semanticUsedFlags & SemanticUsedFlag::GroupID) @@ -2797,9 +2763,14 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) m_writer->emit("}\n"); } - if (entryPointGlobalParams) + + if (globalParams) + { + emitGlobalInst(globalParams); + } + if (entryPointParams) { - emitGlobalInst(entryPointGlobalParams); + emitGlobalInst(entryPointParams); } // Output all the thread locals @@ -2865,7 +2836,7 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) String threadFuncName = builder; - _emitEntryPointDefinitionStart(func, entryPointGlobalParams, threadFuncName, UnownedStringSlice::fromLiteral("ComputeThreadVaryingInput")); + _emitEntryPointDefinitionStart(func, entryPointParams, globalParams, threadFuncName, UnownedStringSlice::fromLiteral("ComputeThreadVaryingInput")); if (m_semanticUsedFlags & SemanticUsedFlag::GroupThreadID) { @@ -2896,7 +2867,7 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) String groupFuncName = builder; - _emitEntryPointDefinitionStart(func, entryPointGlobalParams, groupFuncName, UnownedStringSlice::fromLiteral("ComputeVaryingInput")); + _emitEntryPointDefinitionStart(func, entryPointParams, globalParams, groupFuncName, UnownedStringSlice::fromLiteral("ComputeVaryingInput")); m_writer->emit("const uint3 start = "); _emitInitAxisValues(groupThreadSize, UnownedStringSlice::fromLiteral("varyingInput->startGroupID"), UnownedStringSlice()); @@ -2918,7 +2889,7 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) // Emit the main version - which takes a dispatch size { - _emitEntryPointDefinitionStart(func, entryPointGlobalParams, funcName, UnownedStringSlice::fromLiteral("ComputeVaryingInput")); + _emitEntryPointDefinitionStart(func, entryPointParams, globalParams, funcName, UnownedStringSlice::fromLiteral("ComputeVaryingInput")); m_writer->emit("const uint3 start = "); _emitInitAxisValues(groupThreadSize, UnownedStringSlice::fromLiteral("varyingInput->startGroupID"), UnownedStringSlice()); |
