diff options
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/gfx/cuda/render-cuda.cpp | 69 | ||||
| -rw-r--r-- | tools/gfx/d3d11/render-d3d11.cpp | 14 | ||||
| -rw-r--r-- | tools/gfx/d3d12/render-d3d12.cpp | 82 | ||||
| -rw-r--r-- | tools/gfx/open-gl/render-gl.cpp | 9 | ||||
| -rw-r--r-- | tools/gfx/render-graphics-common.cpp | 15 | ||||
| -rw-r--r-- | tools/gfx/render.h | 4 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.cpp | 21 | ||||
| -rw-r--r-- | tools/gfx/renderer-shared.h | 14 | ||||
| -rw-r--r-- | tools/gfx/vulkan/render-vk.cpp | 9 |
9 files changed, 138 insertions, 99 deletions
diff --git a/tools/gfx/cuda/render-cuda.cpp b/tools/gfx/cuda/render-cuda.cpp index 7d7ee8eb9..4f87bdfc9 100644 --- a/tools/gfx/cuda/render-cuda.cpp +++ b/tools/gfx/cuda/render-cuda.cpp @@ -242,36 +242,6 @@ public: RefPtr<TextureCUDAResource> textureResource = nullptr; }; -class CUDAProgramLayout; - -class CUDAShaderProgram : public ShaderProgramBase -{ -public: - CUmodule cudaModule = nullptr; - CUfunction cudaKernel; - String kernelName; - RefPtr<CUDAProgramLayout> layout; - - ~CUDAShaderProgram() - { - if (cudaModule) - cuModuleUnload(cudaModule); - } -}; - -class CUDAPipelineState : public PipelineStateBase -{ -public: - RefPtr<CUDAShaderProgram> shaderProgram; - void init(const ComputePipelineStateDesc& inDesc) - { - PipelineStateDesc pipelineDesc; - pipelineDesc.type = PipelineType::Compute; - pipelineDesc.compute = inDesc; - initializeBase(pipelineDesc); - } -}; - class CUDAShaderObjectLayout : public ShaderObjectLayoutBase { public: @@ -578,8 +548,6 @@ public: // TODO: the logic here is a copy-paste of `GraphicsCommonShaderObject::collectSpecializationArgs`, // consider moving the implementation to `ShaderObjectBase` and share the logic among different implementations. - if (!m_bindingFinalized) - return SLANG_FAIL; auto& subObjectRanges = getLayout()->subObjectRanges; // The following logic is built on the assumption that all fields that involve existential types (and // therefore require specialization) will results in a sub-object range in the type layout. @@ -677,7 +645,42 @@ public: entryPointObjects[index]->addRef(); return SLANG_OK; } + virtual Result collectSpecializationArgs(ExtendedShaderObjectTypeList& args) override + { + SLANG_RETURN_ON_FAIL(CUDAShaderObject::collectSpecializationArgs(args)); + for (auto& entryPoint : entryPointObjects) + { + SLANG_RETURN_ON_FAIL(entryPoint->collectSpecializationArgs(args)); + } + return SLANG_OK; + } +}; +class CUDAShaderProgram : public ShaderProgramBase +{ +public: + CUmodule cudaModule = nullptr; + CUfunction cudaKernel; + String kernelName; + RefPtr<CUDAProgramLayout> layout; + ~CUDAShaderProgram() + { + if (cudaModule) + cuModuleUnload(cudaModule); + } +}; + +class CUDAPipelineState : public PipelineStateBase +{ +public: + RefPtr<CUDAShaderProgram> shaderProgram; + void init(const ComputePipelineStateDesc& inDesc) + { + PipelineStateDesc pipelineDesc; + pipelineDesc.type = PipelineType::Compute; + pipelineDesc.compute = inDesc; + initializeBase(pipelineDesc); + } }; class CUDARenderer : public RendererBase @@ -802,7 +805,6 @@ private: CUcontext m_context = nullptr; RefPtr<CUDAPipelineState> currentPipeline = nullptr; RefPtr<CUDARootShaderObject> currentRootObject = nullptr; - SlangContext slangContext; public: ~CUDARenderer() { @@ -1332,6 +1334,7 @@ private: { RefPtr<CUDAShaderProgram> cudaProgram = new CUDAShaderProgram(); cudaProgram->slangProgram = desc.slangProgram; + cudaProgram->layout = new CUDAProgramLayout(this, desc.slangProgram->getLayout()); *outProgram = cudaProgram.detach(); return SLANG_OK; } diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp index 079d89a59..49fe101fb 100644 --- a/tools/gfx/d3d11/render-d3d11.cpp +++ b/tools/gfx/d3d11/render-d3d11.cpp @@ -1173,7 +1173,8 @@ Result D3D11Renderer::createBufferResource(IResource::Usage initialUsage, const bufferDesc.Usage = D3D11_USAGE_DEFAULT; // If written by CPU, make it dynamic - if (descIn.cpuAccessFlags & IResource::AccessFlag::Write) + if ((descIn.cpuAccessFlags & IResource::AccessFlag::Write) && + ((descIn.bindFlags & IResource::BindFlag::UnorderedAccess) == 0)) { bufferDesc.Usage = D3D11_USAGE_DYNAMIC; } @@ -1203,7 +1204,7 @@ Result D3D11Renderer::createBufferResource(IResource::Usage initialUsage, const } } - if( bufferDesc.Usage == D3D11_USAGE_DYNAMIC ) + if (srcDesc.cpuAccessFlags & IResource::AccessFlag::Write) { bufferDesc.CPUAccessFlags |= D3D11_CPU_ACCESS_WRITE; } @@ -1791,6 +1792,15 @@ void D3D11Renderer::drawIndexed(UInt indexCount, UInt startIndex, UInt baseVerte Result D3D11Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { + if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) + { + // For a specializable program, we don't invoke any actual slang compilation yet. + RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl(); + initProgramCommon(shaderProgram, desc); + *outProgram = shaderProgram.detach(); + return SLANG_OK; + } + if( desc.kernelCount == 0 ) { return createProgramFromSlang(this, desc, outProgram); diff --git a/tools/gfx/d3d12/render-d3d12.cpp b/tools/gfx/d3d12/render-d3d12.cpp index de7cbd2e2..0ab07c262 100644 --- a/tools/gfx/d3d12/render-d3d12.cpp +++ b/tools/gfx/d3d12/render-d3d12.cpp @@ -2960,6 +2960,15 @@ void D3D12Renderer::setDescriptorSet(PipelineType pipelineType, IPipelineLayout* Result D3D12Renderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { + if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) + { + // For a specializable program, we don't invoke any actual slang compilation yet. + RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl(); + initProgramCommon(shaderProgram, desc); + *outProgram = shaderProgram.detach(); + return SLANG_OK; + } + if( desc.kernelCount == 0 ) { return createProgramFromSlang(this, desc, outProgram); @@ -3740,43 +3749,54 @@ Result D3D12Renderer::createComputePipelineState(const ComputePipelineStateDesc& auto pipelineLayoutImpl = (PipelineLayoutImpl*) desc.pipelineLayout; auto programImpl = (ShaderProgramImpl*) desc.program; - // Describe and create the compute pipeline state object - D3D12_COMPUTE_PIPELINE_STATE_DESC computeDesc = {}; - computeDesc.pRootSignature = pipelineLayoutImpl->m_rootSignature; - computeDesc.CS = { programImpl->m_computeShader.getBuffer(), SIZE_T(programImpl->m_computeShader.getCount()) }; - + // Only actually create a D3D12 pipeline state if the pipeline is fully specialized. ComPtr<ID3D12PipelineState> pipelineState; - -#ifdef GFX_NVAPI - if (m_nvapi) + if (!programImpl->slangProgram || programImpl->slangProgram->getSpecializationParamCount() == 0) { - // Also fill the extension structure. - // Use the same UAV slot index and register space that are declared in the shader. - - // For simplicities sake we just use u0 - NVAPI_D3D12_PSO_SET_SHADER_EXTENSION_SLOT_DESC extensionDesc; - extensionDesc.baseVersion = NV_PSO_EXTENSION_DESC_VER; - extensionDesc.version = NV_SET_SHADER_EXTENSION_SLOT_DESC_VER; - extensionDesc.uavSlot = 0; - extensionDesc.registerSpace = 0; - - // Put the pointer to the extension into an array - there can be multiple extensions enabled at once. - const NVAPI_D3D12_PSO_EXTENSION_DESC* extensions[] = { &extensionDesc }; + // Describe and create the compute pipeline state object + D3D12_COMPUTE_PIPELINE_STATE_DESC computeDesc = {}; + computeDesc.pRootSignature = pipelineLayoutImpl->m_rootSignature; + computeDesc.CS = { + programImpl->m_computeShader.getBuffer(), + SIZE_T(programImpl->m_computeShader.getCount())}; - // Now create the PSO. - const NvAPI_Status nvapiStatus = NvAPI_D3D12_CreateComputePipelineState(m_device, &computeDesc, SLANG_COUNT_OF(extensions), extensions, pipelineState.writeRef()); - - if (nvapiStatus != NVAPI_OK) - { - return SLANG_FAIL; +#ifdef GFX_NVAPI + if (m_nvapi) + { + // Also fill the extension structure. + // Use the same UAV slot index and register space that are declared in the shader. + + // For simplicities sake we just use u0 + NVAPI_D3D12_PSO_SET_SHADER_EXTENSION_SLOT_DESC extensionDesc; + extensionDesc.baseVersion = NV_PSO_EXTENSION_DESC_VER; + extensionDesc.version = NV_SET_SHADER_EXTENSION_SLOT_DESC_VER; + extensionDesc.uavSlot = 0; + extensionDesc.registerSpace = 0; + + // Put the pointer to the extension into an array - there can be multiple extensions + // enabled at once. + const NVAPI_D3D12_PSO_EXTENSION_DESC* extensions[] = {&extensionDesc}; + + // Now create the PSO. + const NvAPI_Status nvapiStatus = NvAPI_D3D12_CreateComputePipelineState( + m_device, + &computeDesc, + SLANG_COUNT_OF(extensions), + extensions, + pipelineState.writeRef()); + + if (nvapiStatus != NVAPI_OK) + { + return SLANG_FAIL; + } } - } - else + else #endif - { - SLANG_RETURN_ON_FAIL(m_device->CreateComputePipelineState(&computeDesc, IID_PPV_ARGS(pipelineState.writeRef()))); + { + SLANG_RETURN_ON_FAIL(m_device->CreateComputePipelineState( + &computeDesc, IID_PPV_ARGS(pipelineState.writeRef()))); + } } - RefPtr<PipelineStateImpl> pipelineStateImpl = new PipelineStateImpl(); pipelineStateImpl->m_pipelineLayout = pipelineLayoutImpl; pipelineStateImpl->m_pipelineState = pipelineState; diff --git a/tools/gfx/open-gl/render-gl.cpp b/tools/gfx/open-gl/render-gl.cpp index b84db44b6..03736cfa4 100644 --- a/tools/gfx/open-gl/render-gl.cpp +++ b/tools/gfx/open-gl/render-gl.cpp @@ -1489,6 +1489,15 @@ SLANG_NO_THROW Result SLANG_MCALL Result GLRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { + if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) + { + // For a specializable program, we don't invoke any actual slang compilation yet. + RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl(m_weakRenderer, 0); + initProgramCommon(shaderProgram, desc); + *outProgram = shaderProgram.detach(); + return SLANG_OK; + } + if( desc.kernelCount == 0 ) { return createProgramFromSlang(this, desc, outProgram); diff --git a/tools/gfx/render-graphics-common.cpp b/tools/gfx/render-graphics-common.cpp index fb01867d8..5f083538d 100644 --- a/tools/gfx/render-graphics-common.cpp +++ b/tools/gfx/render-graphics-common.cpp @@ -724,8 +724,6 @@ public: return SLANG_E_INVALID_ARG; auto subObject = static_cast<GraphicsCommonShaderObject*>(object); - if (!subObject->m_bindingFinalized) - return SLANG_E_INVALID_ARG; auto& bindingRange = layout->getBindingRange(offset.bindingRangeIndex); @@ -815,8 +813,6 @@ public: // Appends all types that are used to specialize the element type of this shader object in `args` list. virtual Result collectSpecializationArgs(ExtendedShaderObjectTypeList& args) override { - if (!m_bindingFinalized) - return SLANG_FAIL; auto& subObjectRanges = getLayout()->getSubObjectRanges(); // The following logic is built on the assumption that all fields that involve existential types (and // therefore require specialization) will results in a sub-object range in the type layout. @@ -914,7 +910,7 @@ protected: // In the case where the sub-object range represents an // existential-type leaf field (e.g., an `IBar`), we - // cannot pre-allocate the objet(s) to go into that + // cannot pre-allocate the object(s) to go into that // range, since we can't possibly know what to allocate // at this point. // @@ -1218,6 +1214,15 @@ public: return SLANG_OK; } + virtual Result collectSpecializationArgs(ExtendedShaderObjectTypeList& args) override + { + SLANG_RETURN_ON_FAIL(GraphicsCommonShaderObject::collectSpecializationArgs(args)); + for (auto& entryPoint : m_entryPoints) + { + SLANG_RETURN_ON_FAIL(entryPoint->collectSpecializationArgs(args)); + } + return SLANG_OK; + } protected: virtual Result _bindIntoDescriptorSets(ComPtr<IDescriptorSet>* descriptorSets) override diff --git a/tools/gfx/render.h b/tools/gfx/render.h index 13af56550..e783273ee 100644 --- a/tools/gfx/render.h +++ b/tools/gfx/render.h @@ -282,7 +282,8 @@ public: case Usage::DepthWrite: return BindFlag::DepthStencil; case Usage::UnorderedAccess: - return BindFlag::UnorderedAccess; + return BindFlag::Enum(BindFlag::UnorderedAccess | BindFlag::PixelShaderResource | + BindFlag::NonPixelShaderResource); case Usage::PixelShaderResource: return BindFlag::PixelShaderResource; case Usage::NonPixelShaderResource: @@ -880,7 +881,6 @@ public: setSampler(ShaderOffset const& offset, ISamplerState* sampler) = 0; virtual SLANG_NO_THROW Result SLANG_MCALL setCombinedTextureSampler( ShaderOffset const& offset, IResourceView* textureView, ISamplerState* sampler) = 0; - virtual SLANG_NO_THROW Result SLANG_MCALL finalizeBindings() = 0; }; #define SLANG_UUID_IShaderObject \ { \ diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp index a2e1751fd..741b1eba5 100644 --- a/tools/gfx/renderer-shared.cpp +++ b/tools/gfx/renderer-shared.cpp @@ -319,7 +319,7 @@ void ShaderCache::addShaderBinary(ShaderComponentID componentId, ShaderBinary* b shaderBinaries[componentId] = binary; } -void ShaderCache::addSpecializedPipeline(PipelineKey key, Slang::RefPtr<PipelineStateBase> specializedPipeline) +void ShaderCache::addSpecializedPipeline(PipelineKey key, Slang::ComPtr<IPipelineState> specializedPipeline) { specializedPipelines[key] = specializedPipeline; } @@ -377,21 +377,8 @@ void ShaderObjectLayoutBase::initBase(RendererBase* renderer, slang::TypeLayoutR m_componentID = m_renderer->shaderCache.getComponentId(m_elementTypeLayout->getType()); } -SLANG_NO_THROW Result SLANG_MCALL ShaderObjectBase::finalizeBindings() -{ - m_bindingFinalized = true; - - // With all binding fixed, the shader object's type can be determined by specializing the - // shader object's type with the type of bound sub objects. - // Now obtain a componentID for the specialized shader object type from the shader cache. - SLANG_RETURN_ON_FAIL(getSpecializedShaderObjectType(&shaderObjectType)); - return SLANG_OK; -} - - // Get the final type this shader object represents. If the shader object's type has existential fields, // this function will return a specialized type using the bound sub-objects' type as specialization argument. - Result ShaderObjectBase::getSpecializedShaderObjectType(ExtendedShaderObjectType* outType) { if (shaderObjectType.slangType) @@ -432,7 +419,7 @@ Result RendererBase::maybeSpecializePipeline(ShaderObjectBase* rootObject) pipelineKey.specializationArgs.addRange(specializationArgs.componentIDs); pipelineKey.updateHash(); - auto specializedPipelineState = shaderCache.getSpecializedPipelineState(pipelineKey); + ComPtr<gfx::IPipelineState> specializedPipelineState = shaderCache.getSpecializedPipelineState(pipelineKey); // Try to find specialized pipeline from shader cache. if (!specializedPipelineState) { @@ -493,6 +480,7 @@ Result RendererBase::maybeSpecializePipeline(ShaderObjectBase* rootObject) IShaderProgram::Desc specializedProgramDesc = {}; specializedProgramDesc.kernelCount = unspecializedProgramLayout->getEntryPointCount(); ShortList<IShaderProgram::KernelDesc> kernelDescs; + kernelDescs.setCount(entryPointBinaries.getCount()); for (Slang::Index i = 0; i < entryPointBinaries.getCount(); i++) { auto entryPoint = unspecializedProgramLayout->getEntryPointByIndex(i);; @@ -507,7 +495,6 @@ Result RendererBase::maybeSpecializePipeline(ShaderObjectBase* rootObject) SLANG_RETURN_ON_FAIL(createProgram(specializedProgramDesc, specializedProgram.writeRef())); // Create specialized pipeline state. - ComPtr<IPipelineState> specializedPipelineState; switch (pipelineType) { case PipelineType::Compute: @@ -529,7 +516,7 @@ Result RendererBase::maybeSpecializePipeline(ShaderObjectBase* rootObject) } auto specializedPipelineStateBase = static_cast<PipelineStateBase*>(specializedPipelineState.get()); specializedPipelineStateBase->unspecializedPipelineState = currentPipeline; - shaderCache.addSpecializedPipeline(pipelineKey, specializedPipelineStateBase); + shaderCache.addSpecializedPipeline(pipelineKey, specializedPipelineState); } setPipelineState(specializedPipelineState); } diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h index c4a000e87..26ed5b040 100644 --- a/tools/gfx/renderer-shared.h +++ b/tools/gfx/renderer-shared.h @@ -161,9 +161,6 @@ protected: // The shader object layout used to create this shader object. Slang::RefPtr<ShaderObjectLayoutBase> m_layout = nullptr; - // Indicates whether all bindings have been finalized. - bool m_bindingFinalized = false; - // The specialized shader object type. ExtendedShaderObjectType shaderObjectType = { nullptr, kInvalidComponentID }; public: @@ -201,8 +198,6 @@ public: return m_layout->getElementTypeLayout(); } - SLANG_NO_THROW Result SLANG_MCALL finalizeBindings() SLANG_OVERRIDE; - virtual Result collectSpecializationArgs(ExtendedShaderObjectTypeList& args) = 0; }; @@ -338,20 +333,21 @@ public: void init(ISlangFileSystem* cacheFileSystem); void writeToFileSystem(ISlangMutableFileSystem* outputFileSystem); - Slang::RefPtr<PipelineStateBase> getSpecializedPipelineState(PipelineKey programKey) + Slang::ComPtr<IPipelineState> getSpecializedPipelineState(PipelineKey programKey) { - Slang::RefPtr<PipelineStateBase> result; + Slang::ComPtr<IPipelineState> result; if (specializedPipelines.TryGetValue(programKey, result)) return result; return nullptr; } Slang::RefPtr<ShaderBinary> tryLoadShaderBinary(ShaderComponentID componentId); void addShaderBinary(ShaderComponentID componentId, ShaderBinary* binary); - void addSpecializedPipeline(PipelineKey key, Slang::RefPtr<PipelineStateBase> specializedPipeline); + void addSpecializedPipeline(PipelineKey key, Slang::ComPtr<IPipelineState> specializedPipeline); + protected: Slang::ComPtr<ISlangFileSystem> fileSystem; Slang::OrderedDictionary<OwningComponentKey, ShaderComponentID> componentIds; - Slang::OrderedDictionary<PipelineKey, Slang::RefPtr<PipelineStateBase>> specializedPipelines; + Slang::OrderedDictionary<PipelineKey, Slang::ComPtr<IPipelineState>> specializedPipelines; Slang::OrderedDictionary<ShaderComponentID, Slang::RefPtr<ShaderBinary>> shaderBinaries; }; diff --git a/tools/gfx/vulkan/render-vk.cpp b/tools/gfx/vulkan/render-vk.cpp index 565a8e96f..f58a81b8d 100644 --- a/tools/gfx/vulkan/render-vk.cpp +++ b/tools/gfx/vulkan/render-vk.cpp @@ -2841,6 +2841,15 @@ void VKRenderer::setDescriptorSet(PipelineType pipelineType, IPipelineLayout* la Result VKRenderer::createProgram(const IShaderProgram::Desc& desc, IShaderProgram** outProgram) { + if (desc.slangProgram && desc.slangProgram->getSpecializationParamCount() != 0) + { + // For a specializable program, we don't invoke any actual slang compilation yet. + RefPtr<ShaderProgramImpl> shaderProgram = new ShaderProgramImpl(m_api, desc.pipelineType); + initProgramCommon(shaderProgram, desc); + *outProgram = shaderProgram.detach(); + return SLANG_OK; + } + if( desc.kernelCount == 0 ) { return createProgramFromSlang(this, desc, outProgram); |
