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
|
// resource-d3d12.h
#pragma once
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <Windows.h>
#undef WIN32_LEAN_AND_MEAN
#undef NOMINMAX
#include <dxgi1_4.h>
#include <d3d12.h>
#include "slang-com-ptr.h"
#include "../d3d/d3d-util.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);
};
} // renderer_test
|