Skip to content

Commit 42080a5

Browse files
rework pipeline barriers and events to use std::spans
1 parent c63d568 commit 42080a5

File tree

4 files changed

+82
-85
lines changed

4 files changed

+82
-85
lines changed

include/nbl/video/IGPUCommandBuffer.h

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -146,18 +146,15 @@ class NBL_API2 IGPUCommandBuffer : public IBackendObject
146146
using image_barrier_t = SImageMemoryBarrier<ResourceBarrier>;
147147

148148
// no dependency flags because they must be 0 per the spec
149-
uint32_t memBarrierCount = 0;
150-
const asset::SMemoryBarrier* memBarriers = nullptr;
151-
uint32_t bufBarrierCount = 0;
152-
const buffer_barrier_t* bufBarriers = nullptr;
153-
uint32_t imgBarrierCount = 0;
154-
const image_barrier_t* imgBarriers = nullptr;
149+
std::span<const asset::SMemoryBarrier> memBarriers = {};
150+
std::span<const buffer_barrier_t> bufBarriers = {};
151+
std::span<const image_barrier_t> imgBarriers = {};
155152
};
156153

157154
using SEventDependencyInfo = SDependencyInfo<asset::SMemoryBarrier>;
158155
bool setEvent(IEvent* const _event, const SEventDependencyInfo& depInfo);
159156
bool resetEvent(IEvent* _event, const core::bitflag<stage_flags_t> stageMask);
160-
bool waitEvents(const uint32_t eventCount, IEvent* const* const pEvents, const SEventDependencyInfo* depInfos);
157+
bool waitEvents(const std::span<IEvent*> events, const SEventDependencyInfo* depInfos);
161158

162159
struct SOwnershipTransferBarrier
163160
{
@@ -539,7 +536,7 @@ class NBL_API2 IGPUCommandBuffer : public IBackendObject
539536

540537
virtual bool setEvent_impl(IEvent* const _event, const SEventDependencyInfo& depInfo) = 0;
541538
virtual bool resetEvent_impl(IEvent* const _event, const core::bitflag<stage_flags_t> stageMask) = 0;
542-
virtual bool waitEvents_impl(const uint32_t eventCount, IEvent* const* const pEvents, const SEventDependencyInfo* depInfos) = 0;
539+
virtual bool waitEvents_impl(const std::span<IEvent*> events, const SEventDependencyInfo* depInfos) = 0;
543540
virtual bool pipelineBarrier_impl(const core::bitflag<asset::E_DEPENDENCY_FLAGS> dependencyFlags, const SPipelineBarrierDependencyInfo& depInfo) = 0;
544541

545542
virtual bool fillBuffer_impl(const asset::SBufferRange<IGPUBuffer>& range, const uint32_t data) = 0;

src/nbl/video/CVulkanCommandBuffer.cpp

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -98,57 +98,57 @@ static inline auto getVkImageSubresourceFrom(const SubresourceRange& range) -> s
9898

9999
template<typename ResourceBarrier>
100100
VkDependencyInfoKHR fill(
101-
VkMemoryBarrier2* memoryBarriers, VkBufferMemoryBarrier2* bufferBarriers, VkImageMemoryBarrier2* imageBarriers,
101+
VkMemoryBarrier2* const memoryBarriers, VkBufferMemoryBarrier2* const bufferBarriers, VkImageMemoryBarrier2* const imageBarriers,
102102
const IGPUCommandBuffer::SDependencyInfo<ResourceBarrier>& depInfo, const uint32_t selfQueueFamilyIndex=IQueue::FamilyIgnored
103103
) {
104104
VkDependencyInfoKHR info = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR,nullptr };
105-
for (auto i=0; i<depInfo.memBarrierCount; i++)
105+
auto outMem = memoryBarriers;
106+
for (const auto& in : depInfo.memBarriers)
106107
{
107-
auto& out = memoryBarriers[i];
108-
out.sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR;
109-
out.pNext = nullptr;
110-
fill(out,depInfo.memBarriers[i],selfQueueFamilyIndex);
108+
outMem->sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2_KHR;
109+
outMem->pNext = nullptr;
110+
fill(*(outMem++),in,selfQueueFamilyIndex);
111111
}
112-
for (auto i=0; i<depInfo.bufBarrierCount; i++)
112+
auto outBuf = bufferBarriers;
113+
for (const auto& in : depInfo.bufBarriers)
113114
{
114-
auto& out = bufferBarriers[i];
115-
out.sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR;
116-
out.pNext = nullptr; // VkExternalMemoryAcquireUnmodifiedEXT
117-
118-
const auto& in = depInfo.bufBarriers[i];
119-
fill(out,in.barrier,selfQueueFamilyIndex,in.range.buffer->getCachedCreationParams().isConcurrentSharing());
120-
out.buffer = static_cast<const CVulkanBuffer*>(in.range.buffer.get())->getInternalObject();
121-
out.offset = in.range.offset;
122-
out.size = in.range.size;
115+
outBuf->sType = VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER_2_KHR;
116+
outBuf->pNext = nullptr; // VkExternalMemoryAcquireUnmodifiedEXT
117+
118+
fill(*outBuf,in.barrier,selfQueueFamilyIndex,in.range.buffer->getCachedCreationParams().isConcurrentSharing());
119+
outBuf->buffer = static_cast<const CVulkanBuffer*>(in.range.buffer.get())->getInternalObject();
120+
outBuf->offset = in.range.offset;
121+
outBuf->size = in.range.size;
122+
outBuf++;
123123
}
124-
for (auto i=0; i<depInfo.imgBarrierCount; i++)
124+
auto outImg = imageBarriers;
125+
for (const auto& in : depInfo.imgBarriers)
125126
{
126-
auto& out = imageBarriers[i];
127-
out.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR;
128-
out.pNext = nullptr; // VkExternalMemoryAcquireUnmodifiedEXT or VkSampleLocationsInfoEXT
129-
130-
const auto& in = depInfo.imgBarriers[i];
131-
out.oldLayout = getVkImageLayoutFromImageLayout(in.oldLayout);
132-
out.newLayout = getVkImageLayoutFromImageLayout(in.newLayout);
133-
fill(out,in.barrier,selfQueueFamilyIndex,in.image->getCachedCreationParams().isConcurrentSharing());
134-
out.image = static_cast<const CVulkanImage*>(in.image)->getInternalObject();
135-
out.subresourceRange = getVkImageSubresourceFrom(in.subresourceRange);
127+
outImg->sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2_KHR;
128+
outImg->pNext = nullptr; // VkExternalMemoryAcquireUnmodifiedEXT or VkSampleLocationsInfoEXT
129+
130+
outImg->oldLayout = getVkImageLayoutFromImageLayout(in.oldLayout);
131+
outImg->newLayout = getVkImageLayoutFromImageLayout(in.newLayout);
132+
fill(*outImg,in.barrier,selfQueueFamilyIndex,in.image->getCachedCreationParams().isConcurrentSharing());
133+
outImg->image = static_cast<const CVulkanImage*>(in.image)->getInternalObject();
134+
outImg->subresourceRange = getVkImageSubresourceFrom(in.subresourceRange);
135+
outImg++;
136136
}
137137
info.dependencyFlags = 0u;
138-
info.memoryBarrierCount = depInfo.memBarrierCount;
138+
info.memoryBarrierCount = depInfo.memBarriers.size();
139139
info.pMemoryBarriers = memoryBarriers;
140-
info.bufferMemoryBarrierCount = depInfo.bufBarrierCount;
140+
info.bufferMemoryBarrierCount = depInfo.bufBarriers.size();
141141
info.pBufferMemoryBarriers = bufferBarriers;
142-
info.imageMemoryBarrierCount = depInfo.imgBarrierCount;
142+
info.imageMemoryBarrierCount = depInfo.imgBarriers.size();
143143
info.pImageMemoryBarriers = imageBarriers;
144144
return info;
145145
}
146146

147147
bool CVulkanCommandBuffer::setEvent_impl(IEvent* const _event, const SEventDependencyInfo& depInfo)
148148
{
149-
IGPUCommandPool::StackAllocation<VkMemoryBarrier2KHR> memoryBarriers(m_cmdpool,depInfo.memBarrierCount);
150-
IGPUCommandPool::StackAllocation<VkBufferMemoryBarrier2KHR> bufferBarriers(m_cmdpool,depInfo.bufBarrierCount);
151-
IGPUCommandPool::StackAllocation<VkImageMemoryBarrier2KHR> imageBarriers(m_cmdpool,depInfo.imgBarrierCount);
149+
IGPUCommandPool::StackAllocation<VkMemoryBarrier2KHR> memoryBarriers(m_cmdpool,depInfo.memBarriers.size());
150+
IGPUCommandPool::StackAllocation<VkBufferMemoryBarrier2KHR> bufferBarriers(m_cmdpool,depInfo.bufBarriers.size());
151+
IGPUCommandPool::StackAllocation<VkImageMemoryBarrier2KHR> imageBarriers(m_cmdpool,depInfo.imgBarriers.size());
152152
if (!memoryBarriers || !bufferBarriers || !imageBarriers)
153153
return false;
154154

@@ -163,21 +163,22 @@ bool CVulkanCommandBuffer::resetEvent_impl(IEvent* const _event, const core::bit
163163
return true;
164164
}
165165

166-
bool CVulkanCommandBuffer::waitEvents_impl(const uint32_t eventCount, IEvent* const* const pEvents, const SEventDependencyInfo* depInfos)
166+
bool CVulkanCommandBuffer::waitEvents_impl(const std::span<IEvent*> events, const SEventDependencyInfo* depInfos)
167167
{
168-
IGPUCommandPool::StackAllocation<VkEvent> events(m_cmdpool,eventCount);
168+
const uint32_t eventCount = events.size();
169+
IGPUCommandPool::StackAllocation<VkEvent> vk_events(m_cmdpool,eventCount);
169170
IGPUCommandPool::StackAllocation<VkDependencyInfoKHR> infos(m_cmdpool,eventCount);
170-
if (!events || !infos)
171+
if (!vk_events || !infos)
171172
return false;
172173

173174
uint32_t memBarrierCount = 0u;
174175
uint32_t bufBarrierCount = 0u;
175176
uint32_t imgBarrierCount = 0u;
176177
for (auto i=0u; i<eventCount; i++)
177178
{
178-
memBarrierCount += depInfos[i].memBarrierCount;
179-
bufBarrierCount += depInfos[i].bufBarrierCount;
180-
imgBarrierCount += depInfos[i].imgBarrierCount;
179+
memBarrierCount += depInfos[i].memBarriers.size();
180+
bufBarrierCount += depInfos[i].bufBarriers.size();
181+
imgBarrierCount += depInfos[i].imgBarriers.size();
181182
}
182183
IGPUCommandPool::StackAllocation<VkMemoryBarrier2KHR> memoryBarriers(m_cmdpool,memBarrierCount);
183184
IGPUCommandPool::StackAllocation<VkBufferMemoryBarrier2KHR> bufferBarriers(m_cmdpool,bufBarrierCount);
@@ -190,21 +191,21 @@ bool CVulkanCommandBuffer::waitEvents_impl(const uint32_t eventCount, IEvent* co
190191
imgBarrierCount = 0u;
191192
for (auto i=0u; i<eventCount; i++)
192193
{
193-
events[i] = static_cast<CVulkanEvent*>(pEvents[i])->getInternalObject();
194+
vk_events[i] = static_cast<CVulkanEvent*>(events[i])->getInternalObject();
194195
infos[i] = fill(memoryBarriers.data()+memBarrierCount,bufferBarriers.data()+bufBarrierCount,imageBarriers.data()+imgBarrierCount,depInfos[i]);
195196
memBarrierCount += infos[i].memoryBarrierCount;
196197
bufBarrierCount += infos[i].bufferMemoryBarrierCount;
197198
imgBarrierCount += infos[i].imageMemoryBarrierCount;
198199
}
199-
getFunctionTable().vkCmdWaitEvents2(m_cmdbuf,eventCount,events.data(),infos.data());
200+
getFunctionTable().vkCmdWaitEvents2(m_cmdbuf,eventCount,vk_events.data(),infos.data());
200201
return true;
201202
}
202203

203204
bool CVulkanCommandBuffer::pipelineBarrier_impl(const core::bitflag<asset::E_DEPENDENCY_FLAGS> dependencyFlags, const SPipelineBarrierDependencyInfo& depInfo)
204205
{
205-
IGPUCommandPool::StackAllocation<VkMemoryBarrier2KHR> memoryBarriers(m_cmdpool,depInfo.memBarrierCount);
206-
IGPUCommandPool::StackAllocation<VkBufferMemoryBarrier2KHR> bufferBarriers(m_cmdpool,depInfo.bufBarrierCount);
207-
IGPUCommandPool::StackAllocation<VkImageMemoryBarrier2KHR> imageBarriers(m_cmdpool,depInfo.imgBarrierCount);
206+
IGPUCommandPool::StackAllocation<VkMemoryBarrier2KHR> memoryBarriers(m_cmdpool,depInfo.memBarriers.size());
207+
IGPUCommandPool::StackAllocation<VkBufferMemoryBarrier2KHR> bufferBarriers(m_cmdpool,depInfo.bufBarriers.size());
208+
IGPUCommandPool::StackAllocation<VkImageMemoryBarrier2KHR> imageBarriers(m_cmdpool,depInfo.imgBarriers.size());
208209
if (!memoryBarriers || !bufferBarriers || !imageBarriers)
209210
return false;
210211

src/nbl/video/CVulkanCommandBuffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class CVulkanCommandBuffer final : public IGPUCommandBuffer
4848

4949
bool setEvent_impl(IEvent* const _event, const SEventDependencyInfo& depInfo) override;
5050
bool resetEvent_impl(IEvent* const _event, const core::bitflag<stage_flags_t> stageMask) override;
51-
bool waitEvents_impl(const uint32_t eventCount, IEvent* const* const pEvents, const SEventDependencyInfo* depInfos) override;
51+
bool waitEvents_impl(const std::span<IEvent*> events, const SEventDependencyInfo* depInfos) override;
5252
bool pipelineBarrier_impl(const core::bitflag<asset::E_DEPENDENCY_FLAGS> dependencyFlags, const SPipelineBarrierDependencyInfo& depInfo) override;
5353

5454
bool fillBuffer_impl(const asset::SBufferRange<IGPUBuffer>& range, const uint32_t data) override;

src/nbl/video/IGPUCommandBuffer.cpp

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -195,18 +195,18 @@ bool IGPUCommandBuffer::invalidDependency(const SDependencyInfo<ResourceBarrier>
195195
// TODO: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdPipelineBarrier2-None-07891
196196
// TODO: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdPipelineBarrier2-None-07892
197197
// TODO: https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-VkBufferMemoryBarrier2-srcStageMask-03851
198-
for (auto j=0u; j<depInfo.memBarrierCount; j++)
199-
if (!device->validateMemoryBarrier(m_cmdpool->getQueueFamilyIndex(),depInfo.memBarriers[j]))
198+
for (const auto& barrier : depInfo.memBarriers)
199+
if (!device->validateMemoryBarrier(m_cmdpool->getQueueFamilyIndex(),barrier))
200200
return true;
201-
for (auto j=0u; j<depInfo.bufBarrierCount; j++)
201+
for (const auto& barrier : depInfo.bufBarriers)
202202
{
203203
// AFAIK, no special constraints on alignment or usage here
204-
if (invalidBufferRange(depInfo.bufBarriers[j].range,1u,IGPUBuffer::EUF_NONE))
205-
if (!device->validateMemoryBarrier(m_cmdpool->getQueueFamilyIndex(),depInfo.bufBarriers[j]))
204+
if (invalidBufferRange(barrier.range,1u,IGPUBuffer::EUF_NONE))
205+
if (!device->validateMemoryBarrier(m_cmdpool->getQueueFamilyIndex(),barrier))
206206
return true;
207207
}
208-
for (auto j=0u; j<depInfo.imgBarrierCount; j++)
209-
if (!device->validateMemoryBarrier(m_cmdpool->getQueueFamilyIndex(),depInfo.imgBarriers[j]))
208+
for (const auto& barrier : depInfo.imgBarriers)
209+
if (!device->validateMemoryBarrier(m_cmdpool->getQueueFamilyIndex(),barrier))
210210
return true;
211211
#endif // _NBL_DEBUG
212212
return false;
@@ -261,19 +261,19 @@ bool IGPUCommandBuffer::resetEvent(IEvent* _event, const core::bitflag<stage_fla
261261
return resetEvent_impl(_event,stageMask);
262262
}
263263

264-
bool IGPUCommandBuffer::waitEvents(const uint32_t eventCount, IEvent* const* const pEvents, const SEventDependencyInfo* depInfos)
264+
bool IGPUCommandBuffer::waitEvents(const std::span<IEvent*> events, const SEventDependencyInfo* depInfos)
265265
{
266266
if (!checkStateBeforeRecording(queue_flags_t::COMPUTE_BIT|queue_flags_t::GRAPHICS_BIT,RENDERPASS_SCOPE::BOTH))
267267
return false;
268268

269-
if (eventCount==0u)
269+
if (events.empty())
270270
return false;
271271

272272
uint32_t totalBufferCount = 0u;
273273
uint32_t totalImageCount = 0u;
274-
for (auto i=0u; i<eventCount; ++i)
274+
for (auto i=0u; i<events.size(); ++i)
275275
{
276-
if (!pEvents[i] || !this->isCompatibleDevicewise(pEvents[i]))
276+
if (!events[i] || !this->isCompatibleDevicewise(events[i]))
277277
return false;
278278

279279
const auto& depInfo = depInfos[i];
@@ -283,32 +283,32 @@ bool IGPUCommandBuffer::waitEvents(const uint32_t eventCount, IEvent* const* con
283283
if (invalidDependency(depInfo))
284284
return false;
285285

286-
totalBufferCount += depInfo.bufBarrierCount;
287-
totalImageCount += depInfo.imgBarrierCount;
286+
totalBufferCount += depInfo.bufBarriers.size();
287+
totalImageCount += depInfo.imgBarriers.size();
288288
}
289289

290-
auto* cmd = m_cmdpool->m_commandListPool.emplace<IGPUCommandPool::CWaitEventsCmd>(m_commandList,eventCount,pEvents,totalBufferCount,totalImageCount);
290+
auto* cmd = m_cmdpool->m_commandListPool.emplace<IGPUCommandPool::CWaitEventsCmd>(m_commandList,events.size(),events.data(),totalBufferCount,totalImageCount);
291291
if (!cmd)
292292
return false;
293293

294294
auto outIt = cmd->getDeviceMemoryBacked();
295-
for (auto i=0u; i<eventCount; ++i)
295+
for (auto i=0u; i<events.size(); ++i)
296296
{
297297
const auto& depInfo = depInfos[i];
298-
for (auto j=0u; j<depInfo.bufBarrierCount; j++)
299-
*(outIt++) = depInfo.bufBarriers[j].range.buffer;
300-
for (auto j=0u; j<depInfo.imgBarrierCount; j++)
301-
*(outIt++) = core::smart_refctd_ptr<const IGPUImage>(depInfo.imgBarriers[j].image);
298+
for (const auto& barrier : depInfo.bufBarriers)
299+
*(outIt++) = barrier.range.buffer;
300+
for (const auto& barrier : depInfo.imgBarriers)
301+
*(outIt++) = core::smart_refctd_ptr<const IGPUImage>(barrier.image);
302302
}
303-
return waitEvents_impl(eventCount,pEvents,depInfos);
303+
return waitEvents_impl(events,depInfos);
304304
}
305305

306306
bool IGPUCommandBuffer::pipelineBarrier(const core::bitflag<asset::E_DEPENDENCY_FLAGS> dependencyFlags, const SPipelineBarrierDependencyInfo& depInfo)
307307
{
308308
if (!checkStateBeforeRecording(/*everything is allowed*/))
309309
return false;
310310

311-
if (depInfo.memBarrierCount==0u && depInfo.bufBarrierCount==0u && depInfo.imgBarrierCount==0u)
311+
if (depInfo.memBarriers.empty() && depInfo.bufBarriers.empty() && depInfo.imgBarriers.empty())
312312
return false;
313313

314314
if (invalidDependency(depInfo))
@@ -318,7 +318,7 @@ bool IGPUCommandBuffer::pipelineBarrier(const core::bitflag<asset::E_DEPENDENCY_
318318
if (withinSubpass)
319319
{
320320
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#VUID-vkCmdPipelineBarrier2-bufferMemoryBarrierCount-01178
321-
if (depInfo.bufBarrierCount)
321+
if (!depInfo.bufBarriers.empty())
322322
return false;
323323

324324
auto invalidSubpassMemoryBarrier = [dependencyFlags](const asset::SMemoryBarrier& barrier) -> bool
@@ -338,15 +338,14 @@ bool IGPUCommandBuffer::pipelineBarrier(const core::bitflag<asset::E_DEPENDENCY_
338338
return true;
339339
return false;
340340
};
341-
for (auto i=0u; i<depInfo.memBarrierCount; i++)
341+
for (const auto& barrier : depInfo.memBarriers)
342342
{
343-
if (invalidSubpassMemoryBarrier(depInfo.memBarriers[i]))
343+
if (invalidSubpassMemoryBarrier(barrier))
344344
return false;
345345
}
346-
for (auto i=0u; i<depInfo.imgBarrierCount; i++)
346+
for (const auto& barrier : depInfo.imgBarriers)
347347
{
348-
const auto& barrier = depInfo.imgBarriers[i];
349-
if (invalidSubpassMemoryBarrier(depInfo.memBarriers[i]))
348+
if (invalidSubpassMemoryBarrier(barrier.barrier.dep))
350349
return false;
351350

352351
// TODO: under NBL_DEBUG, cause waay too expensive to validate
@@ -370,15 +369,15 @@ bool IGPUCommandBuffer::pipelineBarrier(const core::bitflag<asset::E_DEPENDENCY_
370369
else if (dependencyFlags.hasFlags(asset::EDF_VIEW_LOCAL_BIT))
371370
return false;
372371

373-
auto* cmd = m_cmdpool->m_commandListPool.emplace<IGPUCommandPool::CPipelineBarrierCmd>(m_commandList,depInfo.bufBarrierCount,depInfo.imgBarrierCount);
372+
auto* cmd = m_cmdpool->m_commandListPool.emplace<IGPUCommandPool::CPipelineBarrierCmd>(m_commandList,depInfo.bufBarriers.size(),depInfo.imgBarriers.size());
374373
if (!cmd)
375374
return false;
376375

377376
auto outIt = cmd->getVariableCountResources();
378-
for (auto j=0u; j<depInfo.bufBarrierCount; j++)
379-
*(outIt++) = depInfo.bufBarriers[j].range.buffer;
380-
for (auto j=0u; j<depInfo.imgBarrierCount; j++)
381-
*(outIt++) = core::smart_refctd_ptr<const IGPUImage>(depInfo.imgBarriers[j].image);
377+
for (const auto& barrier : depInfo.bufBarriers)
378+
*(outIt++) = barrier.range.buffer;
379+
for (const auto& barrier : depInfo.imgBarriers)
380+
*(outIt++) = core::smart_refctd_ptr<const IGPUImage>(barrier.image);
382381
return pipelineBarrier_impl(dependencyFlags,depInfo);
383382
}
384383

0 commit comments

Comments
 (0)