diff options
| author | Tim Foley <tfoleyNV@users.noreply.github.com> | 2021-01-26 13:32:03 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-01-26 13:32:03 -0800 |
| commit | a90c850735664e2928e4cc961442a126c6859b97 (patch) | |
| tree | 8b5e12113319ae87c57f5e616408eb955fe85a2c /tools/gfx | |
| parent | 50676c741e10ffe6f710c5de86387eaacd274a9a (diff) | |
Integrate reflection more deeply into gfx layer (#1677)
Diffstat (limited to 'tools/gfx')
| -rw-r--r-- | tools/gfx/cuda/render-cuda.cpp | 43 | ||||
| -rw-r--r-- | tools/gfx/d3d11/render-d3d11.cpp | 17 | ||||
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 16 | ||||
| -rw-r--r-- | tools/gfx/open-gl/render-gl.cpp | 19 | ||||
| -rw-r--r-- | tools/gfx/render-graphics-common.cpp | 70 | ||||
| -rw-r--r-- | tools/gfx/render-graphics-common.h | 28 | ||||
| -rw-r--r-- | tools/gfx/render.h | 35 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.cpp | 68 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.h | 3 | ||||
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 16 |
10 files changed, 233 insertions, 82 deletions
diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp index 0e4ee6c13..d1e320224 100644 --- a/tools/gfx/cuda/render-cuda.cpp +++ b/tools/gfx/cuda/render-cuda.cpp @@ -241,6 +241,8 @@ public: RefPtr<TextureCUDAResource> textureResource = nullptr; }; +class CUDAProgramLayout; + class CUDAShaderProgram : public IShaderProgram, public RefObject { public: @@ -255,6 +257,9 @@ public: CUmodule cudaModule = nullptr; CUfunction cudaKernel; String kernelName; + ComPtr<slang::IComponentType> slangProgram; + RefPtr<CUDAProgramLayout> layout; + ~CUDAShaderProgram() { if (cudaModule) @@ -1260,16 +1265,6 @@ private: return SLANG_OK; } - virtual SLANG_NO_THROW Result SLANG_MCALL createRootShaderObjectLayout( - slang::ProgramLayout* layout, IShaderObjectLayout** outLayout) override - { - RefPtr<CUDAProgramLayout> cudaLayout; - cudaLayout = new CUDAProgramLayout(layout); - cudaLayout->programLayout = layout; - *outLayout = cudaLayout.detach(); - return SLANG_OK; - } - virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObject(IShaderObjectLayout* layout, IShaderObject** outObject) override { @@ -1280,10 +1275,13 @@ private: } virtual SLANG_NO_THROW Result SLANG_MCALL - createRootShaderObject(IShaderObjectLayout* layout, IShaderObject** outObject) override + createRootShaderObject(IShaderProgram* program, IShaderObject** outObject) override { + auto cudaProgram = dynamic_cast<CUDAShaderProgram*>(program); + auto cudaLayout = cudaProgram->layout; + RefPtr<CUDARootShaderObject> result = new CUDARootShaderObject(); - SLANG_RETURN_ON_FAIL(result->init(this, dynamic_cast<CUDAShaderObjectLayout*>(layout))); + SLANG_RETURN_ON_FAIL(result->init(this, cudaLayout)); *outObject = result.detach(); return SLANG_OK; } @@ -1300,6 +1298,11 @@ private: virtual SLANG_NO_THROW Result SLANG_MCALL createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) override { + if( desc.kernelCount == 0 ) + { + return createProgramFromSlang(this, desc, outProgram); + } + if (desc.kernelCount != 1) return SLANG_E_INVALID_ARG; RefPtr<CUDAShaderProgram> cudaProgram = new CUDAShaderProgram(); @@ -1307,6 +1310,22 @@ private: SLANG_CUDA_RETURN_ON_FAIL( cuModuleGetFunction(&cudaProgram->cudaKernel, cudaProgram->cudaModule, desc.kernels[0].entryPointName)); cudaProgram->kernelName = desc.kernels[0].entryPointName; + + auto slangProgram = desc.slangProgram; + if( slangProgram ) + { + cudaProgram->slangProgram = slangProgram; + + auto slangProgramLayout = slangProgram->getLayout(); + if(!slangProgramLayout) + return SLANG_FAIL; + + RefPtr<CUDAProgramLayout> cudaLayout; + cudaLayout = new CUDAProgramLayout(slangProgramLayout); + cudaLayout->programLayout = slangProgramLayout; + cudaProgram->layout = cudaLayout; + } + *outProgram = cudaProgram.detach(); return SLANG_OK; } diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp index a2cf63a8f..40e617a1f 100644 --- a/tools/gfx/d3d11/render-d3d11.cpp +++ b/tools/gfx/d3d11/render-d3d11.cpp @@ -331,17 +331,9 @@ public: List<ComPtr<ID3D11SamplerState>> m_samplers; }; - class ShaderProgramImpl : public IShaderProgram, public RefObject + class ShaderProgramImpl : public GraphicsCommonShaderProgram { public: - SLANG_REF_OBJECT_IUNKNOWN_ALL - IShaderProgram* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IShaderProgram) - return static_cast<IShaderProgram*>(this); - return nullptr; - } - public: ComPtr<ID3D11VertexShader> m_vertexShader; ComPtr<ID3D11PixelShader> m_pixelShader; ComPtr<ID3D11ComputeShader> m_computeShader; @@ -1785,6 +1777,11 @@ void D3D11Renderer::drawIndexed(UInt indexCount, UInt startIndex, UInt baseVerte Result D3D11Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { + if( desc.kernelCount == 0 ) + { + return createProgramFromSlang(this, desc, outProgram); + } + if (desc.pipelineType == PipelineType::Compute) { auto computeKernel = desc.findKernel(StageType::Compute); @@ -1799,6 +1796,7 @@ Result D3D11Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderPro RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl(); shaderProgram->m_computeShader.swap(computeShader); + initProgramCommon(shaderProgram, desc); *outProgram = shaderProgram.detach(); return SLANG_OK; @@ -1822,6 +1820,7 @@ Result D3D11Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderPro RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl(); shaderProgram->m_vertexShader.swap(vertexShader); shaderProgram->m_pixelShader.swap(pixelShader); + initProgramCommon(shaderProgram, desc); *outProgram = shaderProgram.detach(); return SLANG_OK; diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index 74dc19dd7..648fc3052 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -202,17 +202,9 @@ protected: UINT64 m_fenceValue; ///< The fence value when rendering this Frame is complete }; - class ShaderProgramImpl : public IShaderProgram, public RefObject + class ShaderProgramImpl : public GraphicsCommonShaderProgram { public: - SLANG_REF_OBJECT_IUNKNOWN_ALL - IShaderProgram* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IShaderProgram) - return static_cast<IShaderProgram*>(this); - return nullptr; - } - public: PipelineType m_pipelineType; List<uint8_t> m_vertexShader; List<uint8_t> m_pixelShader; @@ -2955,6 +2947,11 @@ void D3D12Renderer::setDescriptorSet(PipelineType pipelineType, IPipelineLayout* Result D3D12Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { + if( desc.kernelCount == 0 ) + { + return createProgramFromSlang(this, desc, outProgram); + } + RefPtr<ShaderProgramImpl> program(new ShaderProgramImpl()); program->m_pipelineType = desc.pipelineType; @@ -2971,6 +2968,7 @@ Result D3D12Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderPro program->m_vertexShader.insertRange(0, (const uint8_t*) vertexKernel->codeBegin, vertexKernel->getCodeSize()); program->m_pixelShader.insertRange(0, (const uint8_t*) fragmentKernel->codeBegin, fragmentKernel->getCodeSize()); } + initProgramCommon(program, desc); *outProgram = program.detach(); return SLANG_OK; diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp index 7ee73366b..49fd6b005 100644 --- a/tools/gfx/open-gl/render-gl.cpp +++ b/tools/gfx/open-gl/render-gl.cpp @@ -381,16 +381,8 @@ public: List<RefPtr<SamplerStateImpl>> m_samplers; }; - class ShaderProgramImpl : public IShaderProgram, public RefObject + class ShaderProgramImpl : public GraphicsCommonShaderProgram { - public: - SLANG_REF_OBJECT_IUNKNOWN_ALL - IShaderProgram* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IShaderProgram) - return static_cast<IShaderProgram*>(this); - return nullptr; - } public: ShaderProgramImpl(WeakSink<GLRenderer>* renderer, GLuint id): m_renderer(renderer), @@ -1485,6 +1477,11 @@ SLANG_NO_THROW Result SLANG_MCALL Result GLRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { + if( desc.kernelCount == 0 ) + { + return createProgramFromSlang(this, desc, outProgram); + } + auto programID = glCreateProgram(); if(desc.pipelineType == PipelineType::Compute ) { @@ -1534,7 +1531,9 @@ Result GLRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgra return SLANG_FAIL; } - *outProgram = new ShaderProgramImpl(m_weakRenderer, programID); + RefPtr<ShaderProgramImpl> program = new ShaderProgramImpl(m_weakRenderer, programID); + initProgramCommon(program, desc); + *outProgram = program.detach(); return SLANG_OK; } diff --git a/tools/gfx/render-graphics-common.cpp b/tools/gfx/render-graphics-common.cpp index 747659d11..593d4708c 100644 --- a/tools/gfx/render-graphics-common.cpp +++ b/tools/gfx/render-graphics-common.cpp @@ -1287,27 +1287,36 @@ Result SLANG_MCALL } Result SLANG_MCALL GraphicsAPIRenderer::createRootShaderObject( - IShaderObjectLayout* rootLayout, IShaderObject** outObject) + IShaderProgram* program, + IShaderObject** outObject) { + auto commonProgram = dynamic_cast<GraphicsCommonShaderProgram*>(program); + RefPtr<ProgramVars> shaderObject; SLANG_RETURN_ON_FAIL(ProgramVars::create(this, - dynamic_cast<GraphicsCommonProgramLayout*>(rootLayout), + commonProgram->getLayout(), shaderObject.writeRef())); *outObject = shaderObject.detach(); return SLANG_OK; } -Result SLANG_MCALL GraphicsAPIRenderer::createRootShaderObjectLayout( - slang::ProgramLayout* layout, IShaderObjectLayout** outLayout) +Result GraphicsAPIRenderer::initProgramCommon( + GraphicsCommonShaderProgram* program, + IShaderProgram::Desc const& desc) { + auto slangProgram = desc.slangProgram; + if(!slangProgram) + return SLANG_OK; + + auto slangReflection = slangProgram->getLayout(0); + if(!slangReflection) + return SLANG_FAIL; + RefPtr<GraphicsCommonProgramLayout> programLayout; - auto slangReflection = layout; { GraphicsCommonProgramLayout::Builder builder(this); builder.addGlobalParams(slangReflection->getGlobalParamsVarLayout()); - // TODO: Also need to reflect entry points here. - SlangInt entryPointCount = slangReflection->getEntryPointCount(); for (SlangInt e = 0; e < entryPointCount; ++e) { @@ -1324,7 +1333,10 @@ Result SLANG_MCALL GraphicsAPIRenderer::createRootShaderObjectLayout( SLANG_RETURN_ON_FAIL(builder.build(programLayout.writeRef())); } - *outLayout = programLayout.detach(); + + program->m_slangProgram = slangProgram; + program->m_layout = programLayout; + return SLANG_OK; } @@ -1360,11 +1372,44 @@ SLANG_NO_THROW bool SLANG_MCALL gfx::GraphicsAPIRenderer::hasFeature(const char* return m_features.findFirstIndex([&](Slang::String x) { return x == featureName; }) != -1; } +GraphicsCommonShaderProgram::~GraphicsCommonShaderProgram() +{ + // Note: It might not seem like this destructor is needed at all, since + // it is empty. + // + // In pratice, though, it seems to be required because the `m_layout` + // field is declared in the coresponding header before the `GraphicsCommonProgramLayout` + // is declared (we only have a forward declaration). + // + // `m_layout` is a `RefPtr`, and it seems that the compiler (or at least + // the Visual Studio compiler) either cannot synthesize a destructor for + // the type that properly destructs the field, or it simply synthesizes + // an incorect destructor. + // + // I suspect that part of the problem stems from the way that `GraphicsCommonProgramLayout` + // inherits from `RefObject` via multiple inheritance. + // + // No matter what, defining the destructor here in a file where + // the declaration of `GraphicsCommonProgramLayout` is visible + // seems to result in a correct destructor being emitted. + // + // TODO: Ther simpler and more robust fix would be to move the declaration + // of `GraphicsCommonProgramLayout` and related types to the header. +} + +IShaderProgram* GraphicsCommonShaderProgram::getInterface(const Guid& guid) +{ + if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IShaderProgram) + return static_cast<IShaderProgram*>(this); + return nullptr; +} + void GraphicsAPIRenderer::preparePipelineDesc(GraphicsPipelineStateDesc& desc) { - if (desc.rootShaderObjectLayout) + if (!desc.pipelineLayout) { - auto rootLayout = dynamic_cast<GraphicsCommonProgramLayout*>(desc.rootShaderObjectLayout); + auto program = dynamic_cast<GraphicsCommonShaderProgram*>(desc.program); + auto rootLayout = program->getLayout(); desc.renderTargetCount = rootLayout->getRenderTargetCount(); desc.pipelineLayout = rootLayout->getPipelineLayout(); } @@ -1372,9 +1417,10 @@ void GraphicsAPIRenderer::preparePipelineDesc(GraphicsPipelineStateDesc& desc) void GraphicsAPIRenderer::preparePipelineDesc(ComputePipelineStateDesc& desc) { - if (desc.rootShaderObjectLayout) + if (!desc.pipelineLayout) { - auto rootLayout = dynamic_cast<GraphicsCommonProgramLayout*>(desc.rootShaderObjectLayout); + auto program = dynamic_cast<GraphicsCommonShaderProgram*>(desc.program); + auto rootLayout = program->getLayout(); desc.pipelineLayout = rootLayout->getPipelineLayout(); } } diff --git a/tools/gfx/render-graphics-common.h b/tools/gfx/render-graphics-common.h index 1c04302ce..3a07f2993 100644 --- a/tools/gfx/render-graphics-common.h +++ b/tools/gfx/render-graphics-common.h @@ -5,6 +5,25 @@ namespace gfx { +class GraphicsCommonProgramLayout; + +class GraphicsCommonShaderProgram : public IShaderProgram, public Slang::RefObject +{ +public: + SLANG_REF_OBJECT_IUNKNOWN_ALL + + IShaderProgram* getInterface(const Slang::Guid& guid); + + GraphicsCommonProgramLayout* getLayout() const { return m_layout; } + +protected: + ~GraphicsCommonShaderProgram(); + +private: + friend class GraphicsAPIRenderer; + ComPtr<slang::IComponentType> m_slangProgram; + Slang::RefPtr<GraphicsCommonProgramLayout> m_layout; +}; class GraphicsAPIRenderer : public IRenderer, public Slang::RefObject { @@ -15,18 +34,21 @@ public: virtual SLANG_NO_THROW bool SLANG_MCALL hasFeature(const char* featureName) SLANG_OVERRIDE; virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObjectLayout( slang::TypeLayoutReflection* typeLayout, IShaderObjectLayout** outLayout) SLANG_OVERRIDE; - virtual SLANG_NO_THROW Result SLANG_MCALL createRootShaderObjectLayout( - slang::ProgramLayout* programLayout, IShaderObjectLayout** outLayout) SLANG_OVERRIDE; virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObject(IShaderObjectLayout* layout, IShaderObject** outObject) SLANG_OVERRIDE; virtual SLANG_NO_THROW Result SLANG_MCALL createRootShaderObject( - IShaderObjectLayout* rootLayout, IShaderObject** outObject) SLANG_OVERRIDE; + IShaderProgram* program, + IShaderObject** outObject) SLANG_OVERRIDE; virtual SLANG_NO_THROW Result SLANG_MCALL bindRootShaderObject(PipelineType pipelineType, IShaderObject* object) SLANG_OVERRIDE; void preparePipelineDesc(GraphicsPipelineStateDesc& desc); void preparePipelineDesc(ComputePipelineStateDesc& desc); IRenderer* getInterface(const Slang::Guid& guid); + Result initProgramCommon( + GraphicsCommonShaderProgram* program, + IShaderProgram::Desc const& desc); + protected: Slang::List<Slang::String> m_features; }; diff --git a/tools/gfx/render.h b/tools/gfx/render.h index eeef00a8f..4c3b71645 100644 --- a/tools/gfx/render.h +++ b/tools/gfx/render.h @@ -71,6 +71,8 @@ enum class StageType ClosestHit, Miss, Callable, + Amplification, + Mesh, CountOf, }; @@ -124,9 +126,13 @@ public: struct Desc { PipelineType pipelineType; + KernelDesc const* kernels; Int kernelCount; + /// Use instead of `kernels`/`kernelCount` if loading a Slang program. + slang::IComponentType* slangProgram; + /// Find and return the kernel for `stage`, if present. KernelDesc const* findKernel(StageType stage) const { @@ -1026,14 +1032,15 @@ struct BlendDesc struct GraphicsPipelineStateDesc { IShaderProgram* program; - // Application should set either pipelineLayout or rootShaderObjectLayout, but not both. + + // If `pipelineLayout` is null, then layout information will be extracted + // from `program`, which must have been created with Slang reflection info. IPipelineLayout* pipelineLayout = nullptr; - // Application should set either pipelineLayout or rootShaderObjectLayout, but not both. - IShaderObjectLayout* rootShaderObjectLayout = nullptr; + IInputLayout* inputLayout; UInt framebufferWidth; UInt framebufferHeight; - UInt renderTargetCount = 0; // Not used if rootShaderObjectLayout is set. + UInt renderTargetCount = 0; // Only used if `pipelineLayout` is non-null DepthStencilDesc depthStencil; RasterizerDesc rasterizer; BlendDesc blend; @@ -1042,8 +1049,10 @@ struct GraphicsPipelineStateDesc struct ComputePipelineStateDesc { IShaderProgram* program; + + // If `pipelineLayout` is null, then layout information will be extracted + // from `program`, which must have been created with Slang reflection info. IPipelineLayout* pipelineLayout = nullptr; - IShaderObjectLayout* rootShaderObjectLayout = nullptr; }; class IPipelineState : public ISlangUnknown @@ -1197,16 +1206,6 @@ public: return layout; } - virtual SLANG_NO_THROW Result SLANG_MCALL createRootShaderObjectLayout( - slang::ProgramLayout* layout, IShaderObjectLayout** outLayout) = 0; - - inline ComPtr<IShaderObjectLayout> createRootShaderObjectLayout(slang::ProgramLayout* layout) - { - ComPtr<IShaderObjectLayout> result; - SLANG_RETURN_NULL_ON_FAIL(createRootShaderObjectLayout(layout, result.writeRef())); - return result; - } - virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObject(IShaderObjectLayout* layout, IShaderObject** outObject) = 0; inline ComPtr<IShaderObject> createShaderObject(IShaderObjectLayout* layout) @@ -1216,12 +1215,12 @@ public: return object; } - virtual SLANG_NO_THROW Result SLANG_MCALL createRootShaderObject(IShaderObjectLayout* layout, IShaderObject** outObject) = 0; + virtual SLANG_NO_THROW Result SLANG_MCALL createRootShaderObject(IShaderProgram* program, IShaderObject** outObject) = 0; - inline ComPtr<IShaderObject> createRootShaderObject(IShaderObjectLayout* layout) + inline ComPtr<IShaderObject> createRootShaderObject(IShaderProgram* program) { ComPtr<IShaderObject> object; - SLANG_RETURN_NULL_ON_FAIL(createRootShaderObject(layout, object.writeRef())); + SLANG_RETURN_NULL_ON_FAIL(createRootShaderObject(program, object.writeRef())); return object; } diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp index 94154bc42..2072d52ef 100644 --- a/tools/gfx/renderer-shared.cpp +++ b/tools/gfx/renderer-shared.cpp @@ -1,6 +1,8 @@ #include "renderer-shared.h" #include "render-graphics-common.h" +using namespace Slang; + namespace gfx { @@ -27,5 +29,71 @@ IResource* TextureResource::getInterface(const Slang::Guid& guid) SLANG_NO_THROW IResource::Type SLANG_MCALL TextureResource::getType() { return m_type; } SLANG_NO_THROW ITextureResource::Desc* SLANG_MCALL TextureResource::getDesc() { return &m_desc; } +gfx::StageType mapStage(SlangStage stage) +{ + switch( stage ) + { + default: + return gfx::StageType::Unknown; + + case SLANG_STAGE_AMPLIFICATION: return gfx::StageType::Amplification; + case SLANG_STAGE_ANY_HIT: return gfx::StageType::AnyHit; + case SLANG_STAGE_CALLABLE: return gfx::StageType::Callable; + case SLANG_STAGE_CLOSEST_HIT: return gfx::StageType::ClosestHit; + case SLANG_STAGE_COMPUTE: return gfx::StageType::Compute; + case SLANG_STAGE_DOMAIN: return gfx::StageType::Domain; + case SLANG_STAGE_FRAGMENT: return gfx::StageType::Fragment; + case SLANG_STAGE_GEOMETRY: return gfx::StageType::Geometry; + case SLANG_STAGE_HULL: return gfx::StageType::Hull; + case SLANG_STAGE_INTERSECTION: return gfx::StageType::Intersection; + case SLANG_STAGE_MESH: return gfx::StageType::Mesh; + case SLANG_STAGE_MISS: return gfx::StageType::Miss; + case SLANG_STAGE_RAY_GENERATION: return gfx::StageType::RayGeneration; + case SLANG_STAGE_VERTEX: return gfx::StageType::Vertex; + } +} + +Result createProgramFromSlang(IRenderer* renderer, IShaderProgram::Desc const& originalDesc, IShaderProgram** outProgram) +{ + SlangInt targetIndex = 0; + auto slangProgram = originalDesc.slangProgram; + + auto programLayout = slangProgram->getLayout(targetIndex); + if(!programLayout) + return SLANG_FAIL; + + Int entryPointCount = (Int) programLayout->getEntryPointCount(); + if(entryPointCount == 0) + return SLANG_FAIL; + + List<IShaderProgram::KernelDesc> kernelDescs; + List<ComPtr<slang::IBlob>> kernelBlobs; + for( Int i = 0; i < entryPointCount; ++i ) + { + ComPtr<slang::IBlob> entryPointCodeBlob; + SLANG_RETURN_ON_FAIL(slangProgram->getEntryPointCode(i, targetIndex, entryPointCodeBlob.writeRef())); + + auto entryPointLayout = programLayout->getEntryPointByIndex(i); + + kernelBlobs.add(entryPointCodeBlob); + + IShaderProgram::KernelDesc kernelDesc; + kernelDesc.codeBegin = entryPointCodeBlob->getBufferPointer(); + kernelDesc.codeEnd = (const char*) kernelDesc.codeBegin + entryPointCodeBlob->getBufferSize(); + kernelDesc.entryPointName = entryPointLayout->getName(); + kernelDesc.stage = mapStage(entryPointLayout->getStage()); + + kernelDescs.add(kernelDesc); + } + SLANG_ASSERT(kernelDescs.getCount() == entryPointCount); + + IShaderProgram::Desc programDesc; + programDesc.pipelineType = originalDesc.pipelineType; + programDesc.slangProgram = slangProgram; + programDesc.kernelCount = kernelDescs.getCount(); + programDesc.kernels = kernelDescs.getBuffer(); + + return renderer->createProgram(programDesc, outProgram); +} } // namespace gfx diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h index 47cc9328d..c2924a7fd 100644 --- a/tools/gfx/renderer-shared.h +++ b/tools/gfx/renderer-shared.h @@ -67,4 +67,7 @@ public: protected: Desc m_desc; }; + +Result createProgramFromSlang(IRenderer* renderer, IShaderProgram::Desc const& desc, IShaderProgram** outProgram); + } diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 88cd52ad7..5afe3e3b4 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -307,17 +307,9 @@ public: VkDeviceSize size; }; - class ShaderProgramImpl: public IShaderProgram, public RefObject + class ShaderProgramImpl: public GraphicsCommonShaderProgram { public: - SLANG_REF_OBJECT_IUNKNOWN_ALL - IShaderProgram* getInterface(const Guid& guid) - { - if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IShaderProgram) - return static_cast<IShaderProgram*>(this); - return nullptr; - } - public: ShaderProgramImpl(const VulkanApi& api, PipelineType pipelineType): m_api(&api), @@ -2835,6 +2827,11 @@ void VKRenderer::setDescriptorSet(PipelineType pipelineType, IPipelineLayout* la Result VKRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { + if( desc.kernelCount == 0 ) + { + return createProgramFromSlang(this, desc, outProgram); + } + RefPtr<ShaderProgramImpl> impl = new ShaderProgramImpl(m_api, desc.pipelineType); if( desc.pipelineType == PipelineType::Compute) { @@ -2849,6 +2846,7 @@ Result VKRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgra impl->m_vertex = compileEntryPoint(*vertexKernel, VK_SHADER_STAGE_VERTEX_BIT, impl->m_buffers[0], impl->m_modules[0]); impl->m_fragment = compileEntryPoint(*fragmentKernel, VK_SHADER_STAGE_FRAGMENT_BIT, impl->m_buffers[1], impl->m_modules[1]); } + initProgramCommon(impl, desc); *outProgram = impl.detach(); return SLANG_OK; } |
