summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/gfx/cuda/render-cuda.cpp69
-rw-r--r--tools/gfx/d3d11/render-d3d11.cpp14
-rw-r--r--tools/gfx/d3d12/render-d3d12.cpp82
-rw-r--r--tools/gfx/open-gl/render-gl.cpp9
-rw-r--r--tools/gfx/render-graphics-common.cpp15
-rw-r--r--tools/gfx/render.h4
-rw-r--r--tools/gfx/renderer-shared.cpp21
-rw-r--r--tools/gfx/renderer-shared.h14
-rw-r--r--tools/gfx/vulkan/render-vk.cpp9
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);