summaryrefslogtreecommitdiffstats
path: root/tools/gfx/d3d11
diff options
context:
space:
mode:
authorYong He <yonghe@outlook.com>2021-10-18 12:19:45 -0700
committerGitHub <noreply@github.com>2021-10-18 12:19:45 -0700
commit2f44d9e01234911dd563f0456b9d861fd8db286d (patch)
treee2727f31654ebc93bae6a1de4b25586be6fb9d10 /tools/gfx/d3d11
parent87e7c49fbfccd54be0d1cee61fba8f309b1f792e (diff)
GFX: implement mutable shader objects. (#1963)
* GFX: implement mutable shader objects. * Revert unnecessary changes * Revert more changes. * Fix clang errors. * Fix clang/gcc errors. * Fix clang errors. * Remove CPU test. * Fix after merge. * Fix after merge. * Remove gl test * Code review fixes. * Fixing all vk validation errors. * Flush test output more often. * Fix a crash in `specializeDynamicAssociatedTypeLookup`. * temporarily disable std-lib-serialize test to see what happens * Fix crashes. * Make sure cpu gfx unit tests are properly disabled on TeamCity. * Disable cpu test. * Fix. * Fix cuda. * Disable nv-ray-tracing-motion-blur Co-authored-by: Yong He <yhe@nvidia.com>
Diffstat (limited to 'tools/gfx/d3d11')
-rw-r--r--tools/gfx/d3d11/render-d3d11.cpp134
1 files changed, 62 insertions, 72 deletions
diff --git a/tools/gfx/d3d11/render-d3d11.cpp b/tools/gfx/d3d11/render-d3d11.cpp
index 8c1c6be1e..ec89c0879 100644
--- a/tools/gfx/d3d11/render-d3d11.cpp
+++ b/tools/gfx/d3d11/render-d3d11.cpp
@@ -10,6 +10,7 @@
#include "../d3d/d3d-util.h"
#include "../d3d/d3d-swapchain.h"
#include "../nvapi/nvapi-util.h"
+#include "../mutable-shader-object.h"
// In order to use the Slang API, we need to include its header
@@ -108,6 +109,7 @@ public:
ShaderObjectLayoutBase** outLayout) override;
virtual Result createShaderObject(ShaderObjectLayoutBase* layout, IShaderObject** outObject)
override;
+ virtual Result createMutableShaderObject(ShaderObjectLayoutBase* layout, IShaderObject** outObject) override;
virtual Result createRootShaderObject(IShaderProgram* program, ShaderObjectBase** outObject)
override;
virtual void bindRootShaderObject(IShaderObject* shaderObject) override;
@@ -229,17 +231,9 @@ protected:
};
- class SamplerStateImpl : public ISamplerState, public ComObject
+ class SamplerStateImpl : public SamplerStateBase
{
public:
- SLANG_COM_OBJECT_IUNKNOWN_ALL
- ISamplerState* getInterface(const Guid& guid)
- {
- if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_ISamplerState)
- return static_cast<ISamplerState*>(this);
- return nullptr;
- }
- public:
ComPtr<ID3D11SamplerState> m_sampler;
};
@@ -291,20 +285,9 @@ protected:
IFramebufferLayout::AttachmentLayout m_depthStencil;
};
- class FramebufferImpl
- : public IFramebuffer
- , public ComObject
+ class FramebufferImpl : public FramebufferBase
{
public:
- SLANG_COM_OBJECT_IUNKNOWN_ALL
- IFramebuffer* getInterface(const Guid& guid)
- {
- if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IFramebuffer)
- return static_cast<IFramebuffer*>(this);
- return nullptr;
- }
-
- public:
ShortList<RefPtr<RenderTargetViewImpl>, kMaxRTVs> renderTargetViews;
ShortList<ID3D11RenderTargetView*, kMaxRTVs> d3dRenderTargetViews;
RefPtr<DepthStencilViewImpl> depthStencilView;
@@ -367,17 +350,9 @@ protected:
ComPtr<ID3D11InputLayout> m_layout;
};
- class QueryPoolImpl : public IQueryPool, public ComObject
+ class QueryPoolImpl : public QueryPoolBase
{
public:
- SLANG_COM_OBJECT_IUNKNOWN_ALL;
- IQueryPool* getInterface(const Guid& guid)
- {
- if (guid == GfxGUID::IID_ISlangUnknown || guid == GfxGUID::IID_IQueryPool)
- return static_cast<IQueryPool*>(this);
- return nullptr;
- }
- public:
List<ComPtr<ID3D11Query>> m_queries;
RefPtr<D3D11Device> m_device;
D3D11_QUERY_DESC m_queryDesc;
@@ -1290,6 +1265,8 @@ protected:
memcpy(dest + offset, data, size);
+ m_isConstantBufferDirty = true;
+
return SLANG_OK;
}
@@ -1510,49 +1487,43 @@ protected:
D3D11Device* device,
ShaderObjectLayoutImpl* specializedLayout)
{
- // If we have already created a buffer to hold ordinary data, then we should
- // simply re-use that buffer rather than re-create it.
- //
- // TODO: Simply re-using the buffer without any kind of validation checks
- // means that we are assuming that users cannot or will not perform any `set`
- // operations on a shader object once an operation has requested this buffer
- // be created. We need to enforce that rule if we want to rely on it.
- //
- if (m_ordinaryDataBuffer)
- return SLANG_OK;
-
auto specializedOrdinaryDataSize = specializedLayout->getTotalOrdinaryDataSize();
if (specializedOrdinaryDataSize == 0)
return SLANG_OK;
- // Once we have computed how large the buffer should be, we can allocate
- // it using the existing public `IDevice` API.
- //
+ // If we have already created a buffer to hold ordinary data, then we should
+ // simply re-use that buffer rather than re-create it.
+ if (!m_ordinaryDataBuffer)
+ {
+ ComPtr<IBufferResource> bufferResourcePtr;
+ IBufferResource::Desc bufferDesc = {};
+ bufferDesc.type = IResource::Type::Buffer;
+ bufferDesc.sizeInBytes = specializedOrdinaryDataSize;
+ bufferDesc.defaultState = ResourceState::ConstantBuffer;
+ bufferDesc.allowedStates =
+ ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination);
+ bufferDesc.cpuAccessFlags |= AccessFlag::Write;
+ SLANG_RETURN_ON_FAIL(
+ device->createBufferResource(bufferDesc, nullptr, bufferResourcePtr.writeRef()));
+ m_ordinaryDataBuffer = static_cast<BufferResourceImpl*>(bufferResourcePtr.get());
+ }
- ComPtr<IBufferResource> bufferResourcePtr;
- IBufferResource::Desc bufferDesc = {};
- bufferDesc.type = IResource::Type::Buffer;
- bufferDesc.sizeInBytes = specializedOrdinaryDataSize;
- bufferDesc.defaultState = ResourceState::ConstantBuffer;
- bufferDesc.allowedStates =
- ResourceStateSet(ResourceState::ConstantBuffer, ResourceState::CopyDestination);
- bufferDesc.cpuAccessFlags |= AccessFlag::Write;
- SLANG_RETURN_ON_FAIL(
- device->createBufferResource(bufferDesc, nullptr, bufferResourcePtr.writeRef()));
- m_ordinaryDataBuffer = static_cast<BufferResourceImpl*>(bufferResourcePtr.get());
-
- // Once the buffer is allocated, we can use `_writeOrdinaryData` to fill it in.
- //
- // Note that `_writeOrdinaryData` is potentially recursive in the case
- // where this object contains interface/existential-type fields, so we
- // don't need or want to inline it into this call site.
- //
+ if (m_isConstantBufferDirty)
+ {
+ // Once the buffer is allocated, we can use `_writeOrdinaryData` to fill it in.
+ //
+ // Note that `_writeOrdinaryData` is potentially recursive in the case
+ // where this object contains interface/existential-type fields, so we
+ // don't need or want to inline it into this call site.
+ //
- auto ordinaryData = device->map(m_ordinaryDataBuffer, gfx::MapFlavor::WriteDiscard);
- auto result = _writeOrdinaryData(ordinaryData, specializedOrdinaryDataSize, specializedLayout);
- device->unmap(m_ordinaryDataBuffer, 0, specializedOrdinaryDataSize);
-
- return result;
+ auto ordinaryData = device->map(m_ordinaryDataBuffer, gfx::MapFlavor::WriteDiscard);
+ auto result = _writeOrdinaryData(ordinaryData, specializedOrdinaryDataSize, specializedLayout);
+ device->unmap(m_ordinaryDataBuffer, 0, specializedOrdinaryDataSize);
+ m_isConstantBufferDirty = false;
+ return result;
+ }
+ return SLANG_OK;
}
/// Bind the buffer for ordinary/uniform data, if needed
@@ -1776,6 +1747,8 @@ protected:
/// Created on demand with `_createOrdinaryDataBufferIfNeeded()`
RefPtr<BufferResourceImpl> m_ordinaryDataBuffer;
+ bool m_isConstantBufferDirty = true;
+
/// Get the layout of this shader object with specialization arguments considered
///
/// This operation should only be called after the shader object has been
@@ -1814,16 +1787,20 @@ protected:
RefPtr<ShaderObjectLayoutImpl> m_specializedLayout;
};
+ class MutableShaderObjectImpl
+ : public MutableShaderObject<
+ MutableShaderObjectImpl,
+ ShaderObjectLayoutImpl>
+ {};
+
class RootShaderObjectImpl : public ShaderObjectImpl
{
typedef ShaderObjectImpl Super;
public:
- // Override default reference counting behavior to disable lifetime management via ComPtr.
- // Root objects are managed by command buffer and does not need to be freed by the user.
- SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; }
- SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; }
- public:
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef() override { return 1; }
+ virtual SLANG_NO_THROW uint32_t SLANG_MCALL release() override { return 1; }
+
static Result create(IDevice* device, RootShaderObjectLayoutImpl* layout, RootShaderObjectImpl** outShaderObject)
{
RefPtr<RootShaderObjectImpl> object = new RootShaderObjectImpl();
@@ -3567,6 +3544,19 @@ Result D3D11Device::createShaderObject(ShaderObjectLayoutBase* layout, IShaderOb
return SLANG_OK;
}
+Result D3D11Device::createMutableShaderObject(
+ ShaderObjectLayoutBase* layout,
+ IShaderObject** outObject)
+{
+ auto layoutImpl = static_cast<ShaderObjectLayoutImpl*>(layout);
+
+ RefPtr<MutableShaderObjectImpl> result = new MutableShaderObjectImpl();
+ SLANG_RETURN_ON_FAIL(result->init(this, layoutImpl));
+ returnComPtr(outObject, result);
+
+ return SLANG_OK;
+}
+
Result D3D11Device::createRootShaderObject(IShaderProgram* program, ShaderObjectBase** outObject)
{
auto programImpl = static_cast<ShaderProgramImpl*>(program);