-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDirectX12ResourceBarrier.cpp
More file actions
205 lines (158 loc) · 8.8 KB
/
Copy pathDirectX12ResourceBarrier.cpp
File metadata and controls
205 lines (158 loc) · 8.8 KB
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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include "DirectX12Resource.h"
#include "DirectX12GraphicsDevice.h"
#include "DirectX12CommandList.h"
#include "SystemFunctions.h"
#include "SystemMemory.h"
D3D12_BARRIER_SYNC ConvertToDirectX12BarrierSync(ElemGraphicsResourceBarrierSyncType syncType, bool isDepthStencil)
{
switch (syncType)
{
case ElemGraphicsResourceBarrierSyncType_None:
return D3D12_BARRIER_SYNC_NONE;
case ElemGraphicsResourceBarrierSyncType_Compute:
return D3D12_BARRIER_SYNC_COMPUTE_SHADING;
case ElemGraphicsResourceBarrierSyncType_Copy:
return D3D12_BARRIER_SYNC_COPY;
case ElemGraphicsResourceBarrierSyncType_BuildRaytracingAccelerationStructure:
return D3D12_BARRIER_SYNC_BUILD_RAYTRACING_ACCELERATION_STRUCTURE;
case ElemGraphicsResourceBarrierSyncType_RenderTarget:
return !isDepthStencil ? D3D12_BARRIER_SYNC_RENDER_TARGET : D3D12_BARRIER_SYNC_DEPTH_STENCIL;
}
}
D3D12_BARRIER_ACCESS ConvertToDirectX12BarrierAccess(ElemGraphicsResourceBarrierAccessType accessType, bool isAccelerationStructure)
{
// TODO: Recheck the correct accesses
// Maybe we can pass more info to the function to compute more precides accesses (or in the common code)
switch (accessType)
{
case ElemGraphicsResourceBarrierAccessType_NoAccess:
return D3D12_BARRIER_ACCESS_NO_ACCESS;
case ElemGraphicsResourceBarrierAccessType_Read:
return isAccelerationStructure ? D3D12_BARRIER_ACCESS_RAYTRACING_ACCELERATION_STRUCTURE_READ : D3D12_BARRIER_ACCESS_COMMON;
case ElemGraphicsResourceBarrierAccessType_RenderTarget:
return D3D12_BARRIER_ACCESS_RENDER_TARGET;
case ElemGraphicsResourceBarrierAccessType_DepthStencilWrite:
return D3D12_BARRIER_ACCESS_DEPTH_STENCIL_WRITE;
case ElemGraphicsResourceBarrierAccessType_Write:
return isAccelerationStructure ? D3D12_BARRIER_ACCESS_RAYTRACING_ACCELERATION_STRUCTURE_WRITE : D3D12_BARRIER_ACCESS_UNORDERED_ACCESS;
case ElemGraphicsResourceBarrierAccessType_Copy:
return D3D12_BARRIER_ACCESS_COPY_DEST;
}
}
D3D12_BARRIER_LAYOUT ConvertToDirectX12BarrierLayout(ElemGraphicsResourceBarrierLayoutType layoutType)
{
// TODO: Recheck the correct layouts
// Maybe we can pass more info to the function to compute more precides layouts (or in the common code)
// It would be better for common layout to specialize that base on the current queue type???
switch (layoutType)
{
case ElemGraphicsResourceBarrierLayoutType_Undefined:
return D3D12_BARRIER_LAYOUT_UNDEFINED;
case ElemGraphicsResourceBarrierLayoutType_Read:
return D3D12_BARRIER_LAYOUT_COMMON;
case ElemGraphicsResourceBarrierLayoutType_Write:
return D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS;
case ElemGraphicsResourceBarrierLayoutType_RenderTarget:
return D3D12_BARRIER_LAYOUT_RENDER_TARGET;
case ElemGraphicsResourceBarrierLayoutType_DepthStencilWrite:
return D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE;
case ElemGraphicsResourceBarrierLayoutType_Present:
return D3D12_BARRIER_LAYOUT_PRESENT;
}
}
void InsertDirectX12ResourceBarriersIfNeeded(ElemCommandList commandList, ElemGraphicsResourceBarrierSyncType currentStage)
{
auto stackMemoryArena = SystemGetStackMemoryArena();
SystemAssert(commandList != ELEM_HANDLE_NULL);
auto commandListData = GetDirectX12CommandListData(commandList);
SystemAssert(commandListData);
auto barriersInfo = GenerateBarrierCommands(stackMemoryArena, commandListData->ResourceBarrierPool, currentStage, DirectX12DebugBarrierInfoEnabled);
if (barriersInfo.BufferBarriers.Length == 0 && barriersInfo.TextureBarriers.Length == 0)
{
return;
}
D3D12_BARRIER_GROUP barrierGroups[2];
uint32_t barrierGroupCount = 0;
if (barriersInfo.BufferBarriers.Length > 0)
{
auto directX12BufferBarriers = SystemPushArray<D3D12_BUFFER_BARRIER>(stackMemoryArena, barriersInfo.BufferBarriers.Length);
D3D12_BARRIER_GROUP directX12BufferBarriersGroup =
{
.Type = D3D12_BARRIER_TYPE_BUFFER,
.NumBarriers = (uint32_t)barriersInfo.BufferBarriers.Length,
.pBufferBarriers = directX12BufferBarriers.Pointer
};
barrierGroups[barrierGroupCount++] = directX12BufferBarriersGroup;
for (uint32_t i = 0; i < barriersInfo.BufferBarriers.Length; i++)
{
auto barrier = barriersInfo.BufferBarriers[i];
auto directX12BufferBarrier = &directX12BufferBarriers[i];
auto graphicsResourceData = GetDirectX12GraphicsResourceData(barrier.Resource);
SystemAssert(graphicsResourceData);
directX12BufferBarrier->pResource = graphicsResourceData->DeviceObject.Get();
// D3D12 enhanced buffer barriers are resource-wide: Offset must be 0
// and Size must be UINT64_MAX or the full native buffer size. This is
// especially important for acceleration-structure handles that alias a
// range inside a shared storage buffer.
directX12BufferBarrier->Offset = 0;
directX12BufferBarrier->Size = UINT64_MAX;
directX12BufferBarrier->SyncBefore = ConvertToDirectX12BarrierSync(barrier.BeforeSync, false);
directX12BufferBarrier->SyncAfter = ConvertToDirectX12BarrierSync(barrier.AfterSync, false);
directX12BufferBarrier->AccessBefore = ConvertToDirectX12BarrierAccess(barrier.BeforeAccess, graphicsResourceData->DirectX12Flags & D3D12_RESOURCE_FLAG_RAYTRACING_ACCELERATION_STRUCTURE);
directX12BufferBarrier->AccessAfter = ConvertToDirectX12BarrierAccess(barrier.AfterAccess, graphicsResourceData->DirectX12Flags & D3D12_RESOURCE_FLAG_RAYTRACING_ACCELERATION_STRUCTURE);
}
}
if (barriersInfo.TextureBarriers.Length > 0)
{
auto directX12TextureBarriers = SystemPushArray<D3D12_TEXTURE_BARRIER>(stackMemoryArena, barriersInfo.TextureBarriers.Length);
D3D12_BARRIER_GROUP directX12TextureBarriersGroup =
{
.Type = D3D12_BARRIER_TYPE_TEXTURE,
.NumBarriers = (uint32_t)barriersInfo.TextureBarriers.Length,
.pTextureBarriers = directX12TextureBarriers.Pointer
};
barrierGroups[barrierGroupCount++] = directX12TextureBarriersGroup;
for (uint32_t i = 0; i < barriersInfo.TextureBarriers.Length; i++)
{
auto barrier = barriersInfo.TextureBarriers[i];
auto directX12TextureBarrier = &directX12TextureBarriers[i];
auto graphicsResourceData = GetDirectX12GraphicsResourceData(barrier.Resource);
SystemAssert(graphicsResourceData);
directX12TextureBarrier->pResource = graphicsResourceData->DeviceObject.Get();
directX12TextureBarrier->SyncBefore = ConvertToDirectX12BarrierSync(barrier.BeforeSync, barrier.IsDepthStencil);
directX12TextureBarrier->SyncAfter = ConvertToDirectX12BarrierSync(barrier.AfterSync, barrier.IsDepthStencil);
directX12TextureBarrier->AccessBefore = ConvertToDirectX12BarrierAccess(barrier.BeforeAccess, false);
directX12TextureBarrier->AccessAfter = ConvertToDirectX12BarrierAccess(barrier.AfterAccess, false);
directX12TextureBarrier->LayoutBefore = ConvertToDirectX12BarrierLayout(barrier.BeforeLayout);
directX12TextureBarrier->LayoutAfter = ConvertToDirectX12BarrierLayout(barrier.AfterLayout);
directX12TextureBarrier->Subresources =
{
.IndexOrFirstMipLevel = UINT32_MAX
};
directX12TextureBarrier->Flags = D3D12_TEXTURE_BARRIER_FLAG_NONE;
}
}
commandListData->DeviceObject->Barrier(barrierGroupCount, barrierGroups);
}
void DirectX12GraphicsResourceBarrier(ElemCommandList commandList, ElemGraphicsResourceDescriptor descriptor, const ElemGraphicsResourceBarrierOptions* options)
{
SystemAssert(commandList != ELEM_HANDLE_NULL);
auto commandListData = GetDirectX12CommandListData(commandList);
SystemAssert(commandListData);
EnqueueBarrier(commandListData->ResourceBarrierPool, descriptor, options);
}
void DirectX12GraphicsResourceBarrierResource(ElemCommandList commandList, ElemGraphicsResource resource, ElemGraphicsResourceBarrierAccessType accessType)
{
SystemAssert(commandList != ELEM_HANDLE_NULL);
SystemAssert(resource != ELEM_HANDLE_NULL);
auto commandListData = GetDirectX12CommandListData(commandList);
SystemAssert(commandListData);
auto resourceInfo = DirectX12GetGraphicsResourceInfo(resource);
ResourceBarrierItem resourceBarrier =
{
.Type = resourceInfo.Type,
.Resource = resource,
.AfterAccess = accessType
};
EnqueueBarrier(commandListData->ResourceBarrierPool, &resourceBarrier);
}