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
141
142
143
144
145
146
|
// d3d12-resource.h
#pragma once
#pragma push_macro("WIN32_LEAN_AND_MEAN")
#pragma push_macro("NOMINMAX")
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#undef NOMINMAX
#define NOMINMAX
#include <windows.h>
#pragma pop_macro("NOMINMAX")
#pragma pop_macro("WIN32_LEAN_AND_MEAN")
#include "../d3d/d3d-util.h"
#include "slang-com-ptr.h"
#include <d3d12.h>
#include <dxgi1_4.h>
namespace gfx
{
// 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 SLANG_ENABLE_CONSERVATIVE_RESOURCE_BARRIERS 0
struct D3D12BarrierSubmitter
{
enum
{
MAX_BARRIERS = 8
};
/// Expand one space to hold a barrier
SLANG_FORCE_INLINE D3D12_RESOURCE_BARRIER& expandOne()
{
return (m_numBarriers < MAX_BARRIERS) ? m_barriers[m_numBarriers++] : _expandOne();
}
/// Flush barriers to command list
SLANG_FORCE_INLINE void flush()
{
if (m_numBarriers > 0)
_flush();
}
/// Transition resource from prevState to nextState
void transition(
ID3D12Resource* resource,
D3D12_RESOURCE_STATES prevState,
D3D12_RESOURCE_STATES nextState);
/// Ctor
SLANG_FORCE_INLINE D3D12BarrierSubmitter(ID3D12GraphicsCommandList* commandList)
: m_numBarriers(0), m_commandList(commandList)
{
}
/// Dtor
SLANG_FORCE_INLINE ~D3D12BarrierSubmitter() { flush(); }
protected:
D3D12_RESOURCE_BARRIER& _expandOne();
void _flush();
ID3D12GraphicsCommandList* m_commandList;
int 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 D3D12ResourceBase, and a client cant
manipulate it's state, but it cannot replace/change the actual resource */
struct D3D12ResourceBase
{
/// Add a transition if necessary to the list
void transition(
D3D12_RESOURCE_STATES currentState,
D3D12_RESOURCE_STATES nextState,
D3D12BarrierSubmitter& submitter);
/// Get the associated resource
SLANG_FORCE_INLINE ID3D12Resource* getResource() const { return m_resource; }
/// True if a resource is set
SLANG_FORCE_INLINE bool isSet() const { return m_resource != nullptr; }
/// Coercible into ID3D12Resource
SLANG_FORCE_INLINE operator ID3D12Resource*() const { return m_resource; }
/// 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(D3DUtil::UsageType usage, ID3D12Resource* resource);
/// Ctor
SLANG_FORCE_INLINE D3D12ResourceBase()
: m_resource(nullptr)
{
}
protected:
/// This is protected so as clients cannot slice the class, and so state tracking is lost
~D3D12ResourceBase() {}
ID3D12Resource* m_resource; ///< The resource (ref counted)
};
struct D3D12Resource : public D3D12ResourceBase
{
/// Dtor
~D3D12Resource()
{
if (m_resource)
{
m_resource->Release();
}
}
/// Initialize as committed resource
Slang::Result 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.
void setResource(ID3D12Resource* resource);
/// 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(Slang::ComPtr<ID3D12Resource>& resourceInOut);
/// Set the debug name on a resource
static void setDebugName(ID3D12Resource* resource, const char* name);
/// Set the the debug name on the resource
void setDebugName(const wchar_t* name);
/// Set the debug name
void setDebugName(const char* name);
};
} // namespace gfx
|