@@ -300,34 +300,51 @@ auto IGPUObjectFromAssetConverter::create(const asset::ICPUBuffer** const _begin
300
300
std::max<uint64_t >(m_driver->getRequiredTBOAlignment (), m_driver->getRequiredUBOAlignment ()),
301
301
std::max<uint64_t >(m_driver->getRequiredSSBOAlignment (), _NBL_SIMD_ALIGNMENT)
302
302
);
303
-
304
-
305
- core::LinearAddressAllocator<uint64_t > addrAllctr (nullptr , 0u , 0u , alignment, m_driver->getMaxBufferSize ());
306
- uint64_t addr = 0ull ;
307
- for (auto i=0u ; i<assetCount; i++)
308
- {
309
- const uint64_t addr = addrAllctr.alloc_addr (_begin[i]->getSize (), alignment);
310
- assert (addr != decltype (addrAllctr)::invalid_address); // fix this to work better with really large buffers in the future
311
- if (addr == decltype (addrAllctr)::invalid_address)
312
- return {};
313
- res->operator [](i) = core::make_smart_refctd_ptr<typename video::asset_traits<asset::ICPUBuffer>::GPUObjectType>(addr);
314
- }
303
+
315
304
316
305
auto reqs = m_driver->getDeviceLocalGPUMemoryReqs ();
317
- reqs.vulkanReqs .size = addrAllctr.get_allocated_size ();
318
306
reqs.vulkanReqs .alignment = alignment;
319
-
320
- auto gpubuffer = m_driver-> createGPUBufferOnDedMem (reqs );
321
-
322
- for ( size_t i = 0u ; i < res-> size (); ++i)
307
+ const uint64_t maxBufferSize = m_driver-> getMaxBufferSize ();
308
+ auto out = res-> begin ( );
309
+ auto firstInBlock = out;
310
+ auto newBlock = [&]() -> auto
323
311
{
324
- auto & output = res->operator [](i);
325
- if (!output)
326
- continue ;
312
+ return core::LinearAddressAllocator<uint64_t >(nullptr , 0u , 0u , alignment, maxBufferSize);
313
+ };
314
+ auto addrAllctr = newBlock ();
315
+ auto finalizeBlock = [&]() -> void
316
+ {
317
+ reqs.vulkanReqs .size = addrAllctr.get_allocated_size ();
318
+ if (reqs.vulkanReqs .size ==0u )
319
+ return ;
320
+
321
+ auto gpubuffer = m_driver->createGPUBufferOnDedMem (reqs);
322
+ for (auto it=firstInBlock; it!=out; it++)
323
+ if (auto output = *it)
324
+ {
325
+ auto cpubuffer = _begin[std::distance (res->begin (),it)];
326
+ m_driver->updateBufferRangeViaStagingBuffer (gpubuffer.get (),output->getOffset (),cpubuffer->getSize (),cpubuffer->getPointer ());
327
+ output->setBuffer (core::smart_refctd_ptr (gpubuffer));
328
+ }
329
+ };
330
+ for (auto it=_begin; it!=_end; it++,out++)
331
+ {
332
+ auto cpubuffer = *it;
333
+ if (cpubuffer->getSize ()>maxBufferSize)
334
+ continue ;
327
335
328
- m_driver->updateBufferRangeViaStagingBuffer (gpubuffer.get (), output->getOffset (), _begin[i]->getSize (), _begin[i]->getPointer ());
329
- output->setBuffer (core::smart_refctd_ptr (gpubuffer));
336
+ uint64_t addr = addrAllctr.alloc_addr (cpubuffer->getSize (),alignment);
337
+ if (addr==decltype (addrAllctr)::invalid_address)
338
+ {
339
+ finalizeBlock ();
340
+ firstInBlock = out;
341
+ addrAllctr = newBlock ();
342
+ addr = addrAllctr.alloc_addr (cpubuffer->getSize (),alignment);
343
+ }
344
+ assert (addr != decltype (addrAllctr)::invalid_address);
345
+ *out = core::make_smart_refctd_ptr<typename video::asset_traits<asset::ICPUBuffer>::GPUObjectType>(addr);
330
346
}
347
+ finalizeBlock ();
331
348
332
349
return res;
333
350
}
0 commit comments