summaryrefslogtreecommitdiffstats
path: root/tools/gfx/render-graphics-common.cpp
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-03-04 16:25:58 -0800
committerGitHub <noreply@github.com>2021-03-04 16:25:58 -0800
commita5ac4999b4dea546a7ef824669ab1809224b6448 (patch)
tree15bb22eb98a94f7f81489deef55396461501d3dc /tools/gfx/render-graphics-common.cpp
parent13ff0bd345990c0fdfb7b52ebd5339cddb04889e (diff)
Refactor `gfx` to surface `CommandBuffer` interface. (#1735)
* Refactor `gfx` to surface `CommandBuffer` interface. * Fixes. * Fix code review issues, and make vulkan runnable on devices without VK_EXT_extended_dynamic_states. * Update solution files * Move out-of-date examples to examples/experimental Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'tools/gfx/render-graphics-common.cpp')
-rw-r--r--tools/gfx/render-graphics-common.cpp111
1 files changed, 63 insertions, 48 deletions
diff --git a/tools/gfx/render-graphics-common.cpp b/tools/gfx/render-graphics-common.cpp
index 7bdaddf73..2e460982e 100644
--- a/tools/gfx/render-graphics-common.cpp
+++ b/tools/gfx/render-graphics-common.cpp
@@ -644,27 +644,29 @@ protected:
m_renderTargetCount = fragmentEntryPoint.layout->getVaryingOutputs().getCount();
}
- IPipelineLayout::Desc pipelineLayoutDesc;
-
- // HACK: we set `renderTargetCount` to zero here becasue otherwise the D3D12
- // render back-end will adjust all UAV registers by this value to account
- // for the `SV_Target<N>` outputs implicitly consuming `u<N>` registers for
- // Shader Model 5.0.
- //
- // When using the shader object path, all registers are being set via Slang
- // reflection information, and we do not need/want the automatic adjustment.
- //
- // TODO: Once we eliminate the non-shader-object path, this whole issue should
- // be moot, because the `ProgramLayout` should own/be the pipeline layout anyway.
- //
- pipelineLayoutDesc.renderTargetCount = 0;
+ if (m_program->getSpecializationParamCount() == 0)
+ {
+ IPipelineLayout::Desc pipelineLayoutDesc;
- pipelineLayoutDesc.descriptorSetCount = pipelineDescriptorSets.getCount();
- pipelineLayoutDesc.descriptorSets = pipelineDescriptorSets.getBuffer();
+ // HACK: we set `renderTargetCount` to zero here becasue otherwise the D3D12
+ // render back-end will adjust all UAV registers by this value to account
+ // for the `SV_Target<N>` outputs implicitly consuming `u<N>` registers for
+ // Shader Model 5.0.
+ //
+ // When using the shader object path, all registers are being set via Slang
+ // reflection information, and we do not need/want the automatic adjustment.
+ //
+ // TODO: Once we eliminate the non-shader-object path, this whole issue should
+ // be moot, because the `ProgramLayout` should own/be the pipeline layout anyway.
+ //
+ pipelineLayoutDesc.renderTargetCount = 0;
- SLANG_RETURN_ON_FAIL(
- renderer->createPipelineLayout(pipelineLayoutDesc, m_pipelineLayout.writeRef()));
+ pipelineLayoutDesc.descriptorSetCount = pipelineDescriptorSets.getCount();
+ pipelineLayoutDesc.descriptorSets = pipelineDescriptorSets.getBuffer();
+ SLANG_RETURN_ON_FAIL(
+ renderer->createPipelineLayout(pipelineLayoutDesc, m_pipelineLayout.writeRef()));
+ }
return SLANG_OK;
}
@@ -1082,7 +1084,8 @@ protected:
}
Result apply(
- IRenderer* renderer,
+ RendererBase* renderer,
+ GraphicsComputeCommandEncoderBase* encoder,
PipelineType pipelineType,
IPipelineLayout* pipelineLayout,
Index& ioRootIndex)
@@ -1100,11 +1103,11 @@ protected:
descriptorSets.add(descriptorSet);
}
- SLANG_RETURN_ON_FAIL(_bindIntoDescriptorSets(descriptorSets.getBuffer()));
+ SLANG_RETURN_ON_FAIL(_bindIntoDescriptorSets(encoder, descriptorSets.getBuffer()));
for (auto descriptorSet : descriptorSets)
{
- renderer->setDescriptorSet(pipelineType, pipelineLayout, ioRootIndex++, descriptorSet);
+ encoder->setDescriptorSetImpl(pipelineType, pipelineLayout, ioRootIndex++, descriptorSet);
}
return SLANG_OK;
@@ -1112,7 +1115,9 @@ protected:
/// Write the uniform/ordinary data of this object into the given `dest` buffer at the given `offset`
Result _writeOrdinaryData(
- char* dest,
+ GraphicsComputeCommandEncoderBase* encoder,
+ IBufferResource* buffer,
+ size_t offset,
size_t destSize,
GraphicsCommonShaderObjectLayout* specializedLayout)
{
@@ -1121,7 +1126,7 @@ protected:
SLANG_ASSERT(srcSize <= destSize);
- memcpy(dest, src, srcSize);
+ encoder->uploadBufferDataImpl(buffer, offset, srcSize, src);
// In the case where this object has any sub-objects of
// existential/interface type, we need to recurse on those objects
@@ -1197,7 +1202,7 @@ protected:
auto subObjectOffset = subObjectRangePendingDataOffset + i*subObjectRangePendingDataStride;
- subObject->_writeOrdinaryData(dest + subObjectOffset, destSize - subObjectOffset, subObjectLayout);
+ subObject->_writeOrdinaryData(encoder, buffer, offset + subObjectOffset, destSize - subObjectOffset, subObjectLayout);
}
}
@@ -1211,7 +1216,7 @@ protected:
size_t _getSubObjectRangePendingDataStride(GraphicsCommonShaderObjectLayout* specializedLayout, Index subObjectRangeIndex) { return 0; }
/// Ensure that the `m_ordinaryDataBuffer` has been created, if it is needed
- Result _ensureOrdinaryDataBufferCreatedIfNeeded()
+ Result _ensureOrdinaryDataBufferCreatedIfNeeded(GraphicsComputeCommandEncoderBase* encoder)
{
// If we have already created a buffer to hold ordinary data, then we should
// simply re-use that buffer rather than re-create it.
@@ -1259,15 +1264,17 @@ protected:
// where this object contains interface/existential-type fields, so we
// don't need or want to inline it into this call site.
//
- char* dest = (char*)renderer->map(m_ordinaryDataBuffer, MapFlavor::HostWrite);
- SLANG_RETURN_ON_FAIL(_writeOrdinaryData(dest, specializedOrdinaryDataSize, specializedLayout));
- renderer->unmap(m_ordinaryDataBuffer);
-
+ SLANG_RETURN_ON_FAIL(_writeOrdinaryData(
+ encoder, m_ordinaryDataBuffer, 0, specializedOrdinaryDataSize, specializedLayout));
return SLANG_OK;
}
/// Bind the buffer for ordinary/uniform data, if needed
- Result _bindOrdinaryDataBufferIfNeeded(IDescriptorSet* descriptorSet, Index* ioBaseRangeIndex, Index subObjectRangeArrayIndex)
+ Result _bindOrdinaryDataBufferIfNeeded(
+ GraphicsComputeCommandEncoderBase* encoder,
+ IDescriptorSet* descriptorSet,
+ Index* ioBaseRangeIndex,
+ Index subObjectRangeArrayIndex)
{
// We are going to need to tweak the base binding range index
// used for descriptor-set writes if and only if we actually
@@ -1277,7 +1284,7 @@ protected:
// We start by ensuring that the buffer is created, if it is needed.
//
- SLANG_RETURN_ON_FAIL(_ensureOrdinaryDataBufferCreatedIfNeeded());
+ SLANG_RETURN_ON_FAIL(_ensureOrdinaryDataBufferCreatedIfNeeded(encoder));
// If we did indeed need/create a buffer, then we must bind it into
// the given `descriptorSet` and update the base range index for
@@ -1293,11 +1300,15 @@ protected:
}
Result _bindIntoDescriptorSet(
- IDescriptorSet* descriptorSet, Index baseRangeIndex, Index subObjectRangeArrayIndex)
+ GraphicsComputeCommandEncoderBase* encoder,
+ IDescriptorSet* descriptorSet,
+ Index baseRangeIndex,
+ Index subObjectRangeArrayIndex)
{
GraphicsCommonShaderObjectLayout* layout = getLayout();
- _bindOrdinaryDataBufferIfNeeded(descriptorSet, &baseRangeIndex, subObjectRangeArrayIndex);
+ _bindOrdinaryDataBufferIfNeeded(
+ encoder, descriptorSet, &baseRangeIndex, subObjectRangeArrayIndex);
for (auto bindingRangeInfo : layout->getBindingRanges())
{
@@ -1373,12 +1384,12 @@ protected:
}
public:
- virtual Result _bindIntoDescriptorSets(ComPtr<IDescriptorSet>* descriptorSets)
+ virtual Result _bindIntoDescriptorSets(GraphicsComputeCommandEncoderBase* encoder, ComPtr<IDescriptorSet>* descriptorSets)
{
GraphicsCommonShaderObjectLayout* layout = getLayout();
Index baseRangeIndex = 0;
- _bindOrdinaryDataBufferIfNeeded(descriptorSets[0], &baseRangeIndex, 0);
+ _bindOrdinaryDataBufferIfNeeded(encoder, descriptorSets[0], &baseRangeIndex, 0);
// Fill in the descriptor sets based on binding ranges
//
@@ -1396,7 +1407,7 @@ public:
{
GraphicsCommonShaderObject* subObject = m_objects[baseIndex + i];
- subObject->_bindIntoDescriptorSet(descriptorSet, rangeIndex, i);
+ subObject->_bindIntoDescriptorSet(encoder, descriptorSet, rangeIndex, i);
}
break;
@@ -1428,7 +1439,7 @@ public:
{
GraphicsCommonShaderObject* subObject = m_objects[baseIndex + i];
- subObject->_bindIntoDescriptorSet(descriptorSet, rangeIndex, i);
+ subObject->_bindIntoDescriptorSet(encoder, descriptorSet, rangeIndex, i);
}
break;
@@ -1541,12 +1552,12 @@ public:
GraphicsCommonProgramLayout* getLayout() { return static_cast<GraphicsCommonProgramLayout*>(m_layout.Ptr()); }
- void apply(IRenderer* renderer, PipelineType pipelineType)
+ void apply(RendererBase* renderer, GraphicsComputeCommandEncoderBase* encoder, PipelineType pipelineType)
{
- auto pipelineLayout = getLayout()->getPipelineLayout();
+ auto pipelineLayout = encoder->m_currentPipeline->m_pipelineLayout.get();
Index rootIndex = 0;
- GraphicsCommonShaderObject::apply(renderer, pipelineType, pipelineLayout, rootIndex);
+ GraphicsCommonShaderObject::apply(renderer, encoder, pipelineType, pipelineLayout, rootIndex);
#if 0
@@ -1587,9 +1598,10 @@ public:
}
protected:
- virtual Result _bindIntoDescriptorSets(ComPtr<IDescriptorSet>* descriptorSets) override
+ virtual Result _bindIntoDescriptorSets(
+ GraphicsComputeCommandEncoderBase* encoder, ComPtr<IDescriptorSet>* descriptorSets) override
{
- SLANG_RETURN_ON_FAIL(Super::_bindIntoDescriptorSets(descriptorSets));
+ SLANG_RETURN_ON_FAIL(Super::_bindIntoDescriptorSets(encoder, descriptorSets));
auto entryPointCount = m_entryPoints.getCount();
for (Index i = 0; i < entryPointCount; ++i)
@@ -1598,7 +1610,7 @@ protected:
auto& entryPointInfo = getLayout()->getEntryPoint(i);
SLANG_RETURN_ON_FAIL(entryPoint->_bindIntoDescriptorSet(
- descriptorSets[0], entryPointInfo.rangeOffset, 0));
+ encoder, descriptorSets[0], entryPointInfo.rangeOffset, 0));
}
return SLANG_OK;
@@ -1760,17 +1772,20 @@ Result GraphicsAPIRenderer::initProgramCommon(
return SLANG_OK;
}
-Result SLANG_MCALL
- GraphicsAPIRenderer::bindRootShaderObject(PipelineType pipelineType, IShaderObject* object)
+Result GraphicsComputeCommandEncoderBase::bindRootShaderObjectImpl(
+ PipelineType pipelineType,
+ IShaderObject* object)
{
auto programVars = dynamic_cast<ProgramVars*>(object);
if (!programVars)
return SLANG_E_INVALID_HANDLE;
- SLANG_RETURN_ON_FAIL(maybeSpecializePipeline(programVars));
-
+ RefPtr<PipelineStateBase> specializedPipeline;
+ SLANG_RETURN_ON_FAIL(m_rendererBase->maybeSpecializePipeline(m_currentPipeline, programVars, specializedPipeline));
+ m_currentPipeline = specializedPipeline;
+
// Apply shader parameter bindings.
- programVars->apply(this, pipelineType);
+ programVars->apply(m_rendererBase, this, pipelineType);
return SLANG_OK;
}