Skip to content

Commit c1d5f34

Browse files
author
devsh
committed
push forgotten SIntendedSubmitInfo fixes
1 parent a9bd557 commit c1d5f34

File tree

2 files changed

+63
-63
lines changed

2 files changed

+63
-63
lines changed

include/nbl/video/utilities/SIntendedSubmitInfo.h

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,63 @@ namespace nbl::video
1414
//! MAKE SURE to do a submit to `queue` by yourself with the result of `popSubmit(...)` implicitly converted to `std::span<const IQueue::SSubmitInfo>` !
1515
struct SIntendedSubmitInfo final : core::Uncopyable
1616
{
17+
// All commandbuffers must be compatible with the queue we're about to submit to
18+
bool cmdbufNotSubmittableToQueue(const IGPUCommandBuffer* cmdbuf) const
19+
{
20+
return !cmdbuf || cmdbuf->getPool()->getQueueFamilyIndex()!=queue->getFamilyIndex();
21+
}
22+
23+
// Returns the scratch to use if valid, nullptr otherwise
24+
template<bool AllChecks>
25+
inline const IQueue::SSubmitInfo::SCommandBufferInfo* valid_impl() const
26+
{
27+
if (!queue || scratchCommandBuffers.empty() || !scratchSemaphore.semaphore)
28+
return nullptr;
29+
// the found scratch
30+
const IQueue::SSubmitInfo::SCommandBufferInfo* scratch = nullptr;
31+
// skip expensive stuff
32+
std::conditional_t<AllChecks,core::unordered_set<const IGPUCommandBuffer*>,const void*> uniqueCmdBufs;
33+
if constexpr (AllChecks)
34+
{
35+
// All commandbuffers before the scratch must be executable (ready to be submitted)
36+
for (const auto& info : prevCommandBuffers)
37+
if (cmdbufNotSubmittableToQueue(info.cmdbuf) || info.cmdbuf->getState()!=IGPUCommandBuffer::STATE::EXECUTABLE)
38+
return nullptr;
39+
//
40+
uniqueCmdBufs.reserve(scratchCommandBuffers.size());
41+
}
42+
for (auto& info : scratchCommandBuffers)
43+
{
44+
if constexpr (AllChecks)
45+
{
46+
// Must be resettable so we can end, submit, wait, reset and continue recording commands into it as-if nothing happened
47+
if (cmdbufNotSubmittableToQueue(info.cmdbuf) || !info.cmdbuf->isResettable())
48+
return nullptr;
49+
uniqueCmdBufs.insert(info.cmdbuf);
50+
}
51+
// not our scratch
52+
if (info.cmdbuf->getState()!=IGPUCommandBuffer::STATE::RECORDING)
53+
continue;
54+
// there can only be one scratch!
55+
if (scratch)
56+
return nullptr;
57+
scratch = &info;
58+
}
59+
// a commandbuffer repeats itself
60+
if constexpr (AllChecks)
61+
if (uniqueCmdBufs.size()!=scratchCommandBuffers.size())
62+
return nullptr;
63+
// there is no scratch cmdbuf at all!
64+
if (!scratch)
65+
return nullptr;
66+
// It makes no sense to reuse the same commands for a second submission.
67+
// Moreover its dangerous because the utilities record their own internal commands which might use subresources for which
68+
// frees have already been latched on the scratch semaphore you must signal anyway.
69+
if (!scratch->cmdbuf->getRecordingFlags().hasFlags(IGPUCommandBuffer::USAGE::ONE_TIME_SUBMIT_BIT))
70+
return nullptr;
71+
return scratch;
72+
}
73+
1774
public:
1875
// This parameter is required but may be unused if there is no need (no overflow) to do submit
1976
IQueue* queue = nullptr;
@@ -48,68 +105,11 @@ struct SIntendedSubmitInfo final : core::Uncopyable
48105
//
49106
inline ISemaphore::SWaitInfo getFutureScratchSemaphore() const {return {scratchSemaphore.semaphore,scratchSemaphore.value+1};}
50107

51-
// Returns the scratch to use if valid, nullptr otherwise
52-
inline const IQueue::SSubmitInfo::SCommandBufferInfo* getCommandBufferForRecording() const
53-
{
54-
if (!queue || scratchCommandBuffers.empty() || !scratchSemaphore.semaphore)
55-
return nullptr;
56-
// All commandbuffers must be compatible with the queue we're about to submit to
57-
auto cmdbufNotSubmittableToQueue = [this](const IGPUCommandBuffer* cmdbuf)->bool
58-
{
59-
return !cmdbuf || cmdbuf->getPool()->getQueueFamilyIndex()!=queue->getFamilyIndex();
60-
};
61-
// All commandbuffers before the scratch must be executable (ready to be submitted)
62-
for (const auto& info : prevCommandBuffers)
63-
if (cmdbufNotSubmittableToQueue(info.cmdbuf) || info.cmdbuf->getState()!=IGPUCommandBuffer::STATE::EXECUTABLE)
64-
return nullptr;
65-
// the found scratch
66-
const IQueue::SSubmitInfo::SCommandBufferInfo* scratch = nullptr;
67-
core::unordered_set<const IGPUCommandBuffer*> uniqueCmdBufs;
68-
uniqueCmdBufs.reserve(scratchCommandBuffers.size());
69-
for (auto& info : scratchCommandBuffers)
70-
{
71-
// Must be resettable so we can end, submit, wait, reset and continue recording commands into it as-if nothing happened
72-
if (cmdbufNotSubmittableToQueue(info.cmdbuf) || !info.cmdbuf->isResettable())
73-
return nullptr;
74-
uniqueCmdBufs.insert(info.cmdbuf);
75-
// not our scratch
76-
if (info.cmdbuf->getState()!=IGPUCommandBuffer::STATE::RECORDING)
77-
continue;
78-
// there can only be one scratch!
79-
if (scratch)
80-
return nullptr;
81-
scratch = &info;
82-
}
83-
// a commandbuffer repeats itself
84-
if (uniqueCmdBufs.size()!=scratchCommandBuffers.size())
85-
return nullptr;
86-
// there is no scratch cmdbuf at all!
87-
if (!scratch)
88-
return nullptr;
89-
// It makes no sense to reuse the same commands for a second submission.
90-
// Moreover its dangerous because the utilities record their own internal commands which might use subresources for which
91-
// frees have already been latched on the scratch semaphore you must signal anyway.
92-
if (!scratch->cmdbuf->getRecordingFlags().hasFlags(IGPUCommandBuffer::USAGE::ONE_TIME_SUBMIT_BIT))
93-
return nullptr;
94-
return scratch;
95-
}
108+
//
109+
inline const auto* getCommandBufferForRecording() const {return valid_impl<false>();}
96110

97-
// Returns the scratch to use if valid, nullptr otherwise
98-
inline const IQueue::SSubmitInfo::SCommandBufferInfo* valid() const
99-
{
100-
if (!queue || scratchCommandBuffers.empty() || !scratchSemaphore.semaphore)
101-
return nullptr;
102-
// All commandbuffers must be compatible with the queue we're about to submit to
103-
auto cmdbufNotSubmittableToQueue = [this](const IGPUCommandBuffer* cmdbuf)->bool
104-
{
105-
return !cmdbuf || cmdbuf->getPool()->getQueueFamilyIndex()!=queue->getFamilyIndex();
106-
};
107-
// All commandbuffers before the scratch must be executable (ready to be submitted)
108-
for (const auto& info : prevCommandBuffers)
109-
if (cmdbufNotSubmittableToQueue(info.cmdbuf) || info.cmdbuf->getState()!=IGPUCommandBuffer::STATE::EXECUTABLE)
110-
return nullptr;
111-
return getCommandBufferForRecording();
112-
}
111+
//
112+
inline const auto* valid() const {return valid_impl<true>();}
113113

114114
//! xxxx
115115
class CSubmitStorage final : core::Uncopyable
@@ -162,7 +162,7 @@ struct SIntendedSubmitInfo final : core::Uncopyable
162162
// - clear the `waitSemaphores` which we'll use in the future because they will already be awaited on this `queue`
163163
inline CSubmitStorage popSubmit(IGPUCommandBuffer* recordingCmdBuf, const std::span<const IQueue::SSubmitInfo::SSemaphoreInfo> signalSemaphores)
164164
{
165-
assert(scratch);
165+
assert(recordingCmdBuf);
166166
CSubmitStorage retval(*this,recordingCmdBuf,signalSemaphores);
167167

168168
// If you want to wait for the result of this popped submit, you need to wait for this new value

0 commit comments

Comments
 (0)