aboutsummaryrefslogtreecommitdiff
path: root/demo/d3d12/NvCoDx12Resource.h
diff options
context:
space:
mode:
authorMiles Macklin <[email protected]>2017-06-09 13:41:15 +1200
committerMiles Macklin <[email protected]>2017-06-09 13:41:15 +1200
commit688b5f42e9bfe498d7af7075d4d8f4429867f3a3 (patch)
tree7e0d0e7c95298f0418723abd92f61ac6e16b055e /demo/d3d12/NvCoDx12Resource.h
parentUpdate README.md (diff)
downloadflex-688b5f42e9bfe498d7af7075d4d8f4429867f3a3.tar.xz
flex-688b5f42e9bfe498d7af7075d4d8f4429867f3a3.zip
1.2.0.beta.11.2.0.beta.1
Diffstat (limited to 'demo/d3d12/NvCoDx12Resource.h')
-rw-r--r--demo/d3d12/NvCoDx12Resource.h140
1 files changed, 140 insertions, 0 deletions
diff --git a/demo/d3d12/NvCoDx12Resource.h b/demo/d3d12/NvCoDx12Resource.h
new file mode 100644
index 0000000..9bb8dab
--- /dev/null
+++ b/demo/d3d12/NvCoDx12Resource.h
@@ -0,0 +1,140 @@
+#ifndef NV_CO_DX12_RESOURCE_H
+#define NV_CO_DX12_RESOURCE_H
+
+#include <NvResult.h>
+#include <NvCoDxFormatUtil.h>
+
+#define NOMINMAX
+#include <d3d12.h>
+#include <string>
+#include <wrl.h>
+
+using namespace Microsoft::WRL;
+
+namespace nvidia {
+namespace Common {
+
+// Enables more conservative barriers - restoring the state of resources after they are used.
+// Should not need to be enabled in normal builds, as the barriers should correctly sync resources
+// If enabling fixes an issue it implies regular barriers are not correctly used.
+#define NV_CO_ENABLE_CONSERVATIVE_RESOURCE_BARRIERS 0
+
+struct Dx12BarrierSubmitter
+{
+ enum { MAX_BARRIERS = 8 };
+
+ /// Expand one space to hold a barrier
+ inline D3D12_RESOURCE_BARRIER& expandOne() { return (m_numBarriers < MAX_BARRIERS) ? m_barriers[m_numBarriers++] : _expandOne(); }
+ /// Flush barriers to command list
+ inline void flush() { if (m_numBarriers > 0) _flush(); }
+
+ /// Ctor
+ inline Dx12BarrierSubmitter(ID3D12GraphicsCommandList* commandList):m_numBarriers(0), m_commandList(commandList) { }
+ /// Dtor
+ inline ~Dx12BarrierSubmitter() { flush(); }
+
+ protected:
+ D3D12_RESOURCE_BARRIER& _expandOne();
+ void _flush();
+
+ ID3D12GraphicsCommandList* m_commandList;
+ ptrdiff_t m_numBarriers;
+ D3D12_RESOURCE_BARRIER m_barriers[MAX_BARRIERS];
+};
+
+/** The base class for resource types allows for tracking of state. It does not allow for setting of the resource though, such that
+an interface can return a Dx12ResourceBase, and a client cant manipulate it's state, but it cannot replace/change the actual resource */
+struct Dx12ResourceBase
+{
+ /// Add a transition if necessary to the list
+ void transition(D3D12_RESOURCE_STATES nextState, Dx12BarrierSubmitter& submitter);
+ /// Get the current state
+ inline D3D12_RESOURCE_STATES getState() const { return m_state; }
+
+ /// Get the associated resource
+ inline ID3D12Resource* getResource() const { return m_resource; }
+
+ /// True if a resource is set
+ inline bool isSet() const { return m_resource != nullptr; }
+
+ /// Coercable into ID3D12Resource
+ inline operator ID3D12Resource*() const { return m_resource; }
+
+ /// restore previous state
+#if NV_CO_ENABLE_CONSERVATIVE_RESOURCE_BARRIERS
+ inline void restore(Dx12BarrierSubmitter& submitter) { transition(m_prevState, submitter); }
+#else
+ inline void restore(Dx12BarrierSubmitter& submitter) { (void)submitter; }
+#endif
+
+ /// Given the usage, flags, and format will return the most suitable format. Will return DXGI_UNKNOWN if combination is not possible
+ static DXGI_FORMAT calcFormat(DxFormatUtil::UsageType usage, ID3D12Resource* resource);
+
+ /// Ctor
+ inline Dx12ResourceBase() :
+ m_state(D3D12_RESOURCE_STATE_COMMON),
+ m_prevState(D3D12_RESOURCE_STATE_COMMON),
+ m_resource(nullptr)
+ {}
+
+ protected:
+ /// This is protected so as clients cannot slice the class, and so state tracking is lost
+ ~Dx12ResourceBase() {}
+
+ ID3D12Resource* m_resource;
+ D3D12_RESOURCE_STATES m_state;
+ D3D12_RESOURCE_STATES m_prevState;
+};
+
+struct Dx12Resource: public Dx12ResourceBase
+{
+
+ /// Dtor
+ ~Dx12Resource()
+ {
+ if (m_resource)
+ {
+ m_resource->Release();
+ }
+ }
+
+ /// Initialize as committed resource
+ int initCommitted(ID3D12Device* device, const D3D12_HEAP_PROPERTIES& heapProps, D3D12_HEAP_FLAGS heapFlags, const D3D12_RESOURCE_DESC& resourceDesc, D3D12_RESOURCE_STATES initState, const D3D12_CLEAR_VALUE * clearValue);
+
+ /// Set a resource with an initial state
+ void setResource(ID3D12Resource* resource, D3D12_RESOURCE_STATES initialState);
+ /// Make the resource null
+ void setResourceNull();
+ /// Returns the attached resource (with any ref counts) and sets to nullptr on this.
+ ID3D12Resource* detach();
+
+ /// Swaps the resource contents with the contents of the smart pointer
+ void swap(ComPtr<ID3D12Resource>& resourceInOut);
+
+ /// Sets the current state of the resource (the current state is taken to be the future state once the command list has executed)
+ /// NOTE! This must be used with care, otherwise state tracking can be made incorrect.
+ void setState(D3D12_RESOURCE_STATES state);
+
+ /// Set the debug name on a resource
+ static void setDebugName(ID3D12Resource* resource, const std::wstring& name);
+
+ /// Set the the debug name on the resource
+ void setDebugName(const wchar_t* name);
+ /// Set the debug name
+ void setDebugName(const std::wstring& name);
+};
+
+/// Convenient way to set blobs
+struct Dx12Blob : public D3D12_SHADER_BYTECODE
+{
+ template <size_t SIZE>
+ inline Dx12Blob(const BYTE(&in)[SIZE]) { pShaderBytecode = in; BytecodeLength = SIZE; }
+ inline Dx12Blob(const BYTE* in, size_t size) { pShaderBytecode = in; BytecodeLength = size; }
+ inline Dx12Blob() { pShaderBytecode = nullptr; BytecodeLength = 0; }
+ inline Dx12Blob(ID3DBlob* blob) { pShaderBytecode = blob->GetBufferPointer(); BytecodeLength = blob->GetBufferSize(); }
+};
+
+} // namespace Common
+} // namespace nvidia
+
+#endif // NV_CO_DX12_RESOURCE_H