From b5b3a8d36c09631cbd4cf236c0280a314436748d Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Tue, 3 Sep 2019 14:36:55 -0400 Subject: CPU uniform entry point params (#1041) * * Made entry point parameters a separate entry point * Made CPUMemoryBinding work with entry point parameters/initialize constant buffers * Added isCPUOnly to bindings, because entry point parameters do not layout like constant buffer * entry-point-uniform.slang works on CPU * EntryPointParams -> UniformEntryPointParams Updated CPU documentation. * Update cpu-target.md to removed completed issues. * Only allocate CPU buffers if the size is > 0. Small update to cpu-target doc. --- source/slang/slang-emit-cpp.cpp | 73 +++++++++++++++++++++----- source/slang/slang-ir-entry-point-uniforms.cpp | 3 ++ source/slang/slang-ir-inst-defs.h | 1 + 3 files changed, 63 insertions(+), 14 deletions(-) (limited to 'source') diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index 194ebfa2c..a5173549a 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -2358,24 +2358,38 @@ void CPPSourceEmitter::emitOperandImpl(IRInst* inst, EmitOpInfo const& outerPre { case 0: // nothing yet case kIROp_GlobalParam: - { - // It's in UniformState + { String name = getName(inst); - m_writer->emit("("); - switch (inst->getDataType()->op) + + if (inst->findDecorationImpl(kIROp_EntryPointDecoration)) + { + // 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 { - case kIROp_ParameterBlockType: - case kIROp_ConstantBufferType: - case kIROp_StructType: + // It's in UniformState + m_writer->emit("("); + + switch (inst->getDataType()->op) { - m_writer->emit("*"); - break; + case kIROp_ParameterBlockType: + case kIROp_ConstantBufferType: + case kIROp_StructType: + { + m_writer->emit("*"); + break; + } + default: break; } - default: break; + + m_writer->emit("uniformState->"); + m_writer->emit(name); + m_writer->emit(")"); } - m_writer->emit("uniformState->"); - m_writer->emit(name); - m_writer->emit(")"); break; } case kIROp_Param: @@ -2476,6 +2490,8 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) } } + IRGlobalParam* entryPointGlobalParams = nullptr; + // Output the global parameters in a 'UniformState' structure { m_writer->emit("struct UniformState\n{\n"); @@ -2487,6 +2503,16 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) { if (action.level == EmitAction::Level::Definition && action.inst->op == kIROp_GlobalParam) { + auto inst = action.inst; + + if (inst->findDecorationImpl(kIROp_EntryPointDecoration)) + { + // Should only be one instruction marked this way + SLANG_ASSERT(entryPointGlobalParams == nullptr); + entryPointGlobalParams = as(inst); + continue; + } + VarLayout* varLayout = CLikeSourceEmitter::getVarLayout(action.inst); SLANG_ASSERT(varLayout); const VarLayout::ResourceInfo* varInfo = varLayout->FindResourceInfo(LayoutResourceKind::Uniform); @@ -2536,6 +2562,11 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) m_writer->emit("ComputeVaryingInput varyingInput;\n"); m_writer->emit("uint3 dispatchThreadID;\n"); + if (entryPointGlobalParams) + { + emitGlobalInst(entryPointGlobalParams); + } + // Output all the thread locals for (auto action : actions) { @@ -2576,7 +2607,7 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) emitEntryPointAttributes(func, entryPointLayout); emitType(resultType, name); - m_writer->emit("(ComputeVaryingInput* varyingInput, UniformState* uniformState)\n{\n"); + m_writer->emit("(ComputeVaryingInput* varyingInput, UniformEntryPointParams* params, UniformState* uniformState)\n{\n"); emitSemantics(func); m_writer->indent(); @@ -2585,6 +2616,20 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module) m_writer->emit("context.uniformState = uniformState;\n"); m_writer->emit("context.varyingInput = *varyingInput;\n"); + if (entryPointGlobalParams) + { + auto varDecl = entryPointGlobalParams; + auto rawType = varDecl->getDataType(); + + auto varType = rawType; + + m_writer->emit("context."); + m_writer->emit(getName(varDecl)); + m_writer->emit(" = ("); + emitType(varType); + m_writer->emit("*)params; \n"); + } + // Emit dispatchThreadID if (entryPointLayout->profile.GetStage() == Stage::Compute) { diff --git a/source/slang/slang-ir-entry-point-uniforms.cpp b/source/slang/slang-ir-entry-point-uniforms.cpp index 822174620..670327446 100644 --- a/source/slang/slang-ir-entry-point-uniforms.cpp +++ b/source/slang/slang-ir-entry-point-uniforms.cpp @@ -248,6 +248,9 @@ struct MoveEntryPointUniformParametersToGlobalScope // an instance of `paramStructType`. // globalParam = builder->createGlobalParam(paramStructType); + + // Mark that this global comes from the entry point + builder->addEntryPointDecoration(globalParam); } // No matter what, the global shader parameter should have the layout diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index f9c157465..131393ea6 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -403,6 +403,7 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) INST(PatchConstantFuncDecoration, patchConstantFunc, 1, 0) /// An `[entryPoint]` decoration marks a function that represents a shader entry point. + /// Also used in some scenarios mark parameters that are moved from entry point parameters to global params as coming from the entry point. INST(EntryPointDecoration, entryPoint, 0, 0) /// A `[dependsOn(x)]` decoration indicates that the parent instruction depends on `x` -- cgit v1.2.3