Skip to content

Commit 8499a0c

Browse files
committed
better outer-CL-type transitions
1 parent 17b5b45 commit 8499a0c

File tree

14 files changed

+245
-61
lines changed

14 files changed

+245
-61
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@ Features:
77
- DX12
88
- FrameGraph
99
- Easy resource binding
10+
- Automatic resource transitions
1011
- Async Compute
1112
- Asset System
1213
- GUI
1314
- Material Graphs
1415
- DXR
15-
- Sparse Voxel GI
16+
- Sparse Voxel GI with "infinite" bounces
1617

1718

1819
https://cheater.dev

sources/DirectXFramework/DX12/CommandList.cpp

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -699,20 +699,21 @@ namespace DX12
699699

700700
result.reserve(used_resources.size());
701701

702-
702+
703+
ResourceState states = ResourceState::COMMON;
703704
for (auto& r : used_resources)
704705
{
705706

706-
r->process_transitions(result, discards, r, id, global_id);
707+
states= states|r->process_transitions(result, discards, r, id, global_id);
707708

708709

709710
}
710711

712+
auto transition_type = GetBestType(states, type);
713+
711714
if (result.size())
712715
{
713-
if (!transition_list)
714-
transition_list.reset(new TransitionCommandList(type));
715-
716+
transition_list = Device::get().get_queue(transition_type)->get_transition_list();
716717
transition_list->create_transition_list(result, discards);
717718
return transition_list;
718719
}
@@ -1286,6 +1287,8 @@ namespace DX12
12861287
tracked_resources.clear();
12871288
tracked_psos.clear();
12881289
TrackedResource::allow_resource_delete = false;
1290+
1291+
transition_list = nullptr;
12891292
}
12901293
void Uploader::reset()
12911294
{
@@ -1305,9 +1308,9 @@ namespace DX12
13051308

13061309

13071310

1308-
TransitionCommandList::TransitionCommandList(CommandListType type)
1311+
TransitionCommandList::TransitionCommandList(CommandListType type):type(type)
13091312
{
1310-
D3D12_COMMAND_LIST_TYPE t = D3D12_COMMAND_LIST_TYPE::D3D12_COMMAND_LIST_TYPE_DIRECT;// static_cast<D3D12_COMMAND_LIST_TYPE>(type);
1313+
D3D12_COMMAND_LIST_TYPE t = static_cast<D3D12_COMMAND_LIST_TYPE>(type);
13111314

13121315
TEST(Device::get().get_native_device()->CreateCommandAllocator(t, IID_PPV_ARGS(&m_commandAllocator)));
13131316
TEST(Device::get().get_native_device()->CreateCommandList(0, t, m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&m_commandList)));
@@ -1328,7 +1331,7 @@ namespace DX12
13281331
m_commandList->Close();
13291332
}
13301333

1331-
ComPtr<ID3D12GraphicsCommandList> TransitionCommandList::get_native()
1334+
ComPtr<ID3D12GraphicsCommandList4> TransitionCommandList::get_native()
13321335
{
13331336
return m_commandList;
13341337
}

sources/DirectXFramework/DX12/CommandList.h

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,7 @@ namespace DX12
2323
class CommandList;
2424

2525
#define DEFAULT_ALIGN 256
26-
enum class CommandListType : int
27-
{
28-
DIRECT = D3D12_COMMAND_LIST_TYPE_DIRECT,
29-
BUNDLE = D3D12_COMMAND_LIST_TYPE_BUNDLE,
30-
COMPUTE = D3D12_COMMAND_LIST_TYPE_COMPUTE,
31-
COPY = D3D12_COMMAND_LIST_TYPE_COPY,
32-
33-
GENERATE_OPS
34-
};
26+
3527

3628
class BufferCache : public Singleton<BufferCache>
3729
{
@@ -1252,14 +1244,14 @@ namespace DX12
12521244

12531245
class TransitionCommandList
12541246
{
1255-
ComPtr<ID3D12GraphicsCommandList> m_commandList;
1247+
ComPtr<ID3D12GraphicsCommandList4> m_commandList;
12561248
ComPtr<ID3D12CommandAllocator> m_commandAllocator;
1257-
1249+
CommandListType type;
12581250
public:
12591251
using ptr = std::shared_ptr<TransitionCommandList>;
1260-
1252+
inline CommandListType get_type() { return type; }
12611253
TransitionCommandList(CommandListType type);
12621254
void create_transition_list(const std::vector<D3D12_RESOURCE_BARRIER>& transitions, std::vector<Resource*> &duscards);
1263-
ComPtr<ID3D12GraphicsCommandList> get_native();
1255+
ComPtr<ID3D12GraphicsCommandList4> get_native();
12641256
};
12651257
}

sources/DirectXFramework/DX12/Device12.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ namespace DX12
113113
CComPtr<ID3D12Debug1> spDebugController1;
114114

115115
#ifdef NDEBUG
116-
//if(false)
116+
if(false)
117117
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugController))))
118118
{
119119
debugController->QueryInterface(IID_PPV_ARGS(&spDebugController1));

sources/DirectXFramework/DX12/Queue.cpp

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@ namespace DX12
7777
lists.emplace(list, del_func);
7878
}
7979
};
80+
81+
del_transition = [this](TransitionCommandList* list)
82+
{
83+
if (stop)
84+
delete list;
85+
else
86+
{
87+
std::lock_guard<std::mutex> g(list_mutex);
88+
transition_lists.emplace(list, del_transition);
89+
}
90+
};
8091
}
8192

8293
void Queue::stop_all()
@@ -127,6 +138,21 @@ namespace DX12
127138
res_ptr.reset(new CommandList(type), del_func);
128139
return res_ptr;
129140
}
141+
std::shared_ptr<TransitionCommandList> Queue::get_transition_list()
142+
{
143+
std::lock_guard<std::mutex> g(list_mutex);
144+
145+
if (!transition_lists.empty())
146+
{
147+
auto e = transition_lists.front();
148+
transition_lists.pop();
149+
return e;
150+
}
151+
152+
std::shared_ptr<TransitionCommandList> res_ptr;
153+
res_ptr.reset(new TransitionCommandList(type), del_transition);
154+
return res_ptr;
155+
}
130156

131157
void Queue::signal_and_wait()
132158
{
@@ -195,29 +221,33 @@ namespace DX12
195221

196222
if (transition_list)
197223
{
198-
ID3D12CommandList* s[2] = { transition_list->get_native().Get(), list->get_native_list().Get() };
199-
200-
if (type == CommandListType::COMPUTE)
224+
if (transition_list->get_type() == list->get_type())
201225
{
202-
auto direct_queue = Device::get().get_queue(CommandListType::DIRECT)->get_native();
203-
204-
direct_queue->ExecuteCommandLists(1, &s[0]);
205-
auto waiter = Device::get().get_queue(CommandListType::DIRECT)->signal();
206-
gpu_wait(waiter);
207-
// native->Wait(waiter.fence->m_fence.Get(), waiter.value);
226+
ID3D12CommandList* s[] = { transition_list->get_native().Get(), list->get_native_list().Get() };
227+
native->ExecuteCommandLists(_countof(s), s);
208228
}
209229
else
210230
{
231+
auto queue = Device::get().get_queue(transition_list->get_type());
232+
233+
{
234+
ID3D12CommandList* s[] = { transition_list->get_native().Get() };
235+
queue->get_native()->ExecuteCommandLists(_countof(s), s);
236+
}
237+
auto waiter = queue->signal();
238+
gpu_wait(waiter);
211239

212-
native->ExecuteCommandLists(1, &s[0]);
240+
{
241+
ID3D12CommandList* s[] = { list->get_native_list().Get() };
242+
native->ExecuteCommandLists(_countof(s), s);
243+
}
213244
}
214245

215-
native->ExecuteCommandLists(1, &s[1]);
216246
}
217247
else
218248
{
219-
ID3D12CommandList* s = list->get_native_list().Get();
220-
native->ExecuteCommandLists(1, &s);
249+
ID3D12CommandList* s[] = { list->get_native_list().Get() };
250+
native->ExecuteCommandLists(_countof(s), s);
221251
}
222252
}
223253

sources/DirectXFramework/DX12/Queue.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ namespace DX12
1616
UINT64 m_fenceValue;
1717
std::thread queue_thread;;
1818
std::function<void(CommandList*)> del_func;
19-
19+
std::function<void(TransitionCommandList*)> del_transition;
20+
2021
std::queue<std::shared_ptr<TransitionCommandList>> transition_lists;
2122

2223
std::queue<std::shared_ptr<CommandList>> lists;
@@ -39,6 +40,7 @@ namespace DX12
3940
~Queue();
4041

4142
std::shared_ptr<CommandList> get_free_list();
43+
std::shared_ptr<TransitionCommandList> get_transition_list();
4244
using ptr = std::shared_ptr<Queue>;
4345

4446
ComPtr<ID3D12CommandQueue> get_native();

sources/DirectXFramework/DX12/States.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@
33
namespace DX12
44
{
55

6-
void ResourceStateManager::process_transitions(std::vector<D3D12_RESOURCE_BARRIER>& target, std::vector<Resource*>& discards, const Resource* resource, int id, uint64_t full_id)
6+
ResourceState ResourceStateManager::process_transitions(std::vector<D3D12_RESOURCE_BARRIER>& target, std::vector<Resource*>& discards, const Resource* resource, int id, uint64_t full_id)
77
{
8-
if (!resource) return;
8+
ResourceState states = ResourceState::COMMON;
9+
10+
if (!resource) return states;
911

1012
auto cpu_state = get_state(id);
1113

14+
1215
for (int i = 0; i < gpu_state.subres.size(); i++)
1316
{
1417
auto& gpu = gpu_state.subres[i];
@@ -29,6 +32,9 @@ namespace DX12
2932
static_cast<D3D12_RESOURCE_STATES>(cpu.first_state),
3033
i));
3134

35+
36+
states = states | gpu.state | cpu.first_state;
37+
3238
for (int j = 0; j < target.size() - 1; j++)
3339
{
3440
if (target.back().Type == target[j].Type)
@@ -41,8 +47,6 @@ namespace DX12
4147

4248
gpu_state.subres[i].state = cpu.state;
4349

44-
45-
4650
}
4751

4852

@@ -51,7 +55,7 @@ namespace DX12
5155
discards.emplace_back(const_cast<Resource*>(resource));
5256
}
5357

54-
58+
return states;
5559
}
5660

5761

sources/DirectXFramework/DX12/States.h

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,15 @@
22
namespace DX12
33
{
44
class Resource;
5+
enum class CommandListType : int
6+
{
7+
DIRECT = D3D12_COMMAND_LIST_TYPE_DIRECT,
8+
BUNDLE = D3D12_COMMAND_LIST_TYPE_BUNDLE,
9+
COMPUTE = D3D12_COMMAND_LIST_TYPE_COMPUTE,
10+
COPY = D3D12_COMMAND_LIST_TYPE_COPY,
511

12+
GENERATE_OPS
13+
};
614
enum class ResourceState: int
715
{
816
COMMON = D3D12_RESOURCE_STATE_COMMON,
@@ -31,6 +39,47 @@ namespace DX12
3139
};
3240

3341

42+
static const ResourceState COPY_STATES = ResourceState::COPY_DEST
43+
| ResourceState::COPY_SOURCE;
44+
45+
static const ResourceState COMPUTE_STATES = COPY_STATES
46+
| ResourceState::UNORDERED_ACCESS
47+
| ResourceState::NON_PIXEL_SHADER_RESOURCE;
48+
49+
static const ResourceState GRAPHIC_STATES = COMPUTE_STATES
50+
| ResourceState::VERTEX_AND_CONSTANT_BUFFER
51+
| ResourceState::INDEX_BUFFER
52+
| ResourceState::RENDER_TARGET
53+
| ResourceState::DEPTH_WRITE
54+
| ResourceState::DEPTH_READ
55+
| ResourceState::PIXEL_SHADER_RESOURCE
56+
| ResourceState::STREAM_OUT
57+
| ResourceState::INDIRECT_ARGUMENT
58+
| ResourceState::RESOLVE_DEST
59+
| ResourceState::RESOLVE_SOURCE;
60+
61+
static inline const ResourceState& GetSupportedStates(CommandListType type)
62+
{
63+
if (type == CommandListType::COPY) return COPY_STATES;
64+
if (type == CommandListType::COMPUTE) return COMPUTE_STATES;
65+
return GRAPHIC_STATES;
66+
}
67+
68+
static inline CommandListType GetBestType(const ResourceState &states, CommandListType preferred_type)
69+
{
70+
if ((states & COPY_STATES) == states && preferred_type == CommandListType::COPY)
71+
{
72+
return CommandListType::COPY;
73+
}
74+
75+
if ((states & COMPUTE_STATES) == states && (preferred_type == CommandListType::COMPUTE || preferred_type == CommandListType::COPY))
76+
{
77+
return CommandListType::COMPUTE;
78+
}
79+
80+
return CommandListType::DIRECT;
81+
}
82+
3483
class ResourceStateManager
3584
{
3685

@@ -139,7 +188,7 @@ namespace DX12
139188
s.need_discard = true;
140189
}
141190

142-
void process_transitions(std::vector<D3D12_RESOURCE_BARRIER>& target, std::vector<Resource*> &discards, const Resource* resource, int id, uint64_t full_id);
191+
ResourceState process_transitions(std::vector<D3D12_RESOURCE_BARRIER>& target, std::vector<Resource*> &discards, const Resource* resource, int id, uint64_t full_id);
143192

144193
void transition(std::vector<D3D12_RESOURCE_BARRIER>& target,const Resource* resource, ResourceState state, unsigned int subres, int id, uint64_t full_id) const;
145194

0 commit comments

Comments
 (0)