forked from NVIDIAGameWorks/FleX
-
Notifications
You must be signed in to change notification settings - Fork 0
/
NvCoDx12Resource.h
140 lines (110 loc) · 4.79 KB
/
NvCoDx12Resource.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
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