diff options
| author | Yong He <yonghe@outlook.com> | 2022-03-28 22:14:33 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-03-28 22:14:33 -0700 |
| commit | 255fd5873f65a6b01d5385c277d55612dc3cc587 (patch) | |
| tree | 54eda0ae98bc9c1b30ca75e534ca203d8e03f241 /source/slang/slang-emit-cpp.cpp | |
| parent | 79b81083b75dc0abdbb8184568dbe36d082e04f3 (diff) | |
Allow slangc to generate exe from .slang file. (#2170)
Diffstat (limited to 'source/slang/slang-emit-cpp.cpp')
| -rw-r--r-- | source/slang/slang-emit-cpp.cpp | 183 |
1 files changed, 48 insertions, 135 deletions
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index e06aa8372..e7b7af991 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -2,7 +2,7 @@ #include "slang-emit-cpp.h" #include "../core/slang-writer.h" - +#include "../core/slang-token-reader.h" #include "slang-emit-source-writer.h" #include "slang-mangled-lexer.h" @@ -167,6 +167,31 @@ static UnownedStringSlice _getCTypeVecPostFix(IROp op) } } +static bool _isCppTarget(CodeGenTarget target) +{ + switch (target) + { + case CodeGenTarget::CPPSource: + case CodeGenTarget::HostCPPSource: + return true; + default: + return false; + } +} + +static bool _isCppOrCudaTarget(CodeGenTarget target) +{ + switch (target) + { + case CodeGenTarget::CPPSource: + case CodeGenTarget::HostCPPSource: + case CodeGenTarget::CUDASource: + return true; + default: + return false; + } +} + /* !!!!!!!!!!!!!!!!!!!!!!!! CPPEmitHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ /* static */ UnownedStringSlice CPPSourceEmitter::getBuiltinTypeName(IROp op) @@ -198,7 +223,7 @@ static UnownedStringSlice _getCTypeVecPostFix(IROp op) void CPPSourceEmitter::emitTypeDefinition(IRType* inType) { - if (m_target == CodeGenTarget::CPPSource) + if (_isCppTarget(m_target)) { // All types are templates in C++ return; @@ -432,7 +457,7 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S auto vecCount = int(getIntVal(vecType->getElementCount())); auto elemType = vecType->getElementType(); - if (target == CodeGenTarget::CPPSource || target == CodeGenTarget::CUDASource) + if (_isCppOrCudaTarget(target)) { out << "Vector<" << _getTypeName(elemType) << ", " << vecCount << ">"; } @@ -458,7 +483,7 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S const auto rowCount = int(getIntVal(matType->getRowCount())); const auto colCount = int(getIntVal(matType->getColumnCount())); - if (target == CodeGenTarget::CPPSource || target == CodeGenTarget::CUDASource) + if (_isCppOrCudaTarget(target)) { out << "Matrix<" << _getTypeName(elementType) << ", " << rowCount << ", " << colCount << ">"; } @@ -542,6 +567,11 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S out << "TypeInfo*"; return SLANG_OK; } + case kIROp_StringType: + { + out << "String"; + return SLANG_OK; + } default: { if (isNominalOp(type->getOp())) @@ -2326,6 +2356,14 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut m_writer->emit("))"); return true; } + case kIROp_StringLit: + { + m_writer->emit("String("); + m_writer->emit(Slang::Misc::EscapeStringLiteral(as<IRStringLit>(inst)->getStringSlice())); + m_writer->emit(")"); + return true; + } + } } @@ -2361,10 +2399,9 @@ void CPPSourceEmitter::emitPreprocessorDirectivesImpl() if (m_target == CodeGenTarget::CPPSource) { - // Put all into an anonymous namespace - // This includes any generated types, and generated intrinsics - if (!m_compileRequest->getLinkage()->m_heterogeneous) - m_writer->emit("namespace { // anonymous \n\n"); + // When generating kernel code in C++, put all into an anonymous namespace + // This includes any generated types, and generated intrinsics. + m_writer->emit("namespace { // anonymous \n\n"); m_writer->emit("#ifdef SLANG_PRELUDE_NAMESPACE\n"); m_writer->emit("using namespace SLANG_PRELUDE_NAMESPACE;\n"); m_writer->emit("#endif\n\n"); @@ -2629,130 +2666,7 @@ void CPPSourceEmitter::_emitForwardDeclarations(const List<EmitAction>& actions) void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink) { - // If we are emitting a heterogeneous program - // Emit the binary blob of each non-CPP target - ComponentType* program = m_compileRequest->getProgram(); - auto linkage = m_compileRequest->getLinkage(); - if (linkage->m_heterogeneous) - { - for (auto inst : module->getGlobalInsts()) - { - auto func = as<IRFunc>(inst); - if (!func) - continue; - if (auto entryPointDecoration = func->findDecoration<IREntryPointDecoration>()) - { - String entryPointName = entryPointDecoration->getName()->getStringSlice(); - String moduleName = entryPointDecoration->getModuleName()->getStringSlice(); - for (int index = 0; index < program->getEntryPointCount(); index++) - { - auto entryPoint = program->getEntryPoint(index); - if (entryPointName == entryPoint->getName()->text) - { - for (auto targetRequest : linkage->targets) - { - // Emit for all non-CPU targets - switch (targetRequest->getTarget()) - { - case(CodeGenTarget::CPPSource): - case(CodeGenTarget::CSource): - case(CodeGenTarget::HostCallable): - case(CodeGenTarget::CUDASource): - - break; - - default: - - auto targetProgram = program->getTargetProgram(targetRequest); - CompileResult result = - targetProgram->getOrCreateEntryPointResult(index, sink); - - Slang::ComPtr<ISlangBlob> blob; - if (SLANG_FAILED(result.getBlob(blob))) - { - sink->diagnoseRaw(Severity::Error, - "Slang heterogeneous error: No blob to emit\n"); - m_writer->emit("size_t __"); - m_writer->emit(entryPointName); - m_writer->emit("Size = 0;\n"); - m_writer->emit("unsigned char __"); - m_writer->emit(entryPointName); - m_writer->emit("[1];\n"); - } - - else - { - // auto ptr = (const unsigned char*)blob->getBufferPointer(); - - // m_writer->emit("size_t __"); - // m_writer->emit(entryPointName); - // m_writer->emit("Size = "); - // m_writer->emitInt64(blob->getBufferSize()); - // m_writer->emit(";\n"); - - // m_writer->emit("unsigned char __"); - // m_writer->emit(entryPointName); - // m_writer->emit("[] = {"); - // every 20 bytes, emit a newline - // size_t j = 0; - // for (size_t i = 0; i < blob->getBufferSize(); i++) { - // m_writer->emitUInt64(ptr[i]); - // m_writer->emit(", "); - // if (j == 20) - // { - // m_writer->emit("\n"); - // j = 0; - // } - // j++; - // } - // m_writer->emit("};\n"); - } - } - } - // Hardcode in (for now) an include for slang-gfx.h so that we can make use - // of the gfx namespace - // - // TODO: Aside from making sure this approach is viable, it would also be - // much better to allow this to be done by the programmer in the Slang file. - m_writer->emit("#include \"slang-gfx.h\"\n\n"); - - // Emit boilerplate that requires gfx. - // This is required by the wrapper, so that will be the next place to look - // as far as removing boilerplate goes. - m_writer->emit("gfx::IShaderProgram* loadShaderProgram(gfx::IDevice* _0, char* _1, char* _2);\n"); - m_writer->emit("gfx::ITransientResourceHeap* buildTransientHeap(gfx::IDevice* _0);\n"); - m_writer->emit("gfx::IPipelineState* buildPipelineState(gfx::IDevice* _0, gfx::IShaderProgram* _1);\n"); - m_writer->emit("void dispatchComputation(gfx::IDevice* _0, gfx::ITransientResourceHeap* _1, gfx::IPipelineState* _2, gfx::IResourceView* _3, uint32_t gridDimsX, uint32_t gridDimsY, uint32_t gridDimsZ);\n"); - m_writer->emit("gfx::IResourceView* createBufferView(gfx::IDevice* _0, gfx::IBufferResource* _1);\n"); - m_writer->emit("gfx::IBufferResource* unconvertBuffer(RWStructuredBuffer<float> _0);\n\n"); - - // Emit a wrapper function for calling the shader blob - m_writer->emit("void "); - m_writer->emit(entryPointName); - m_writer->emit("_wrapper(gfx::IDevice* device, Vector<uint32_t, 3> gridDims, \n"); - m_writer->emit("\tRWStructuredBuffer<float> buffer)\n{"); - /* m_writer->emit("\n\tgfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(device, __"); - m_writer->emit(entryPointName); - m_writer->emit(", __"); - m_writer->emit(entryPointName); - m_writer->emit("Size);");*/ - m_writer->emit("\n\tgfx::IShaderProgram* shaderProgram = loadShaderProgram(device, \""); - m_writer->emit(entryPointName); - m_writer->emit("\", \""); - m_writer->emit(moduleName); - m_writer->emit("\");"); - m_writer->emit("\n\tgfx::ITransientResourceHeap* transientHeap = buildTransientHeap(device);"); - m_writer->emit("\n\tgfx::IPipelineState* pipelineState = "); - m_writer->emit("buildPipelineState(device, shaderProgram);"); - m_writer->emit("\n\tgfx::IResourceView* bufferView = createBufferView(device, unconvertBuffer(buffer));"); - m_writer->emit("\n\tdispatchComputation(device, transientHeap, pipelineState, "); - m_writer->emit("bufferView, gridDims.x, gridDims.y, gridDims.z);"); - m_writer->emit("\n}\n"); - } - } - } - } - } + SLANG_UNUSED(sink); // Setup all built in types used in the module m_typeSet.addAllBuiltinTypes(module); @@ -2790,9 +2704,8 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink) if (m_target == CodeGenTarget::CPPSource) { - // Need to close the anonymous namespace when outputting for C++ - if (!linkage->m_heterogeneous) - m_writer->emit("} // anonymous\n\n"); + // Need to close the anonymous namespace when outputting for C++ kernel. + m_writer->emit("} // anonymous\n\n"); } // Finally we need to output dll entry points |
