Skip to content

Commit 82e89a5

Browse files
Merge pull request #782 from Devsh-Graphics-Programming/ali_pmr3
ICPUBuffer v2.0 3
2 parents 971a1ed + afe18dd commit 82e89a5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+341
-283
lines changed

include/nbl/asset/CVectorCPUBuffer.h

Lines changed: 0 additions & 34 deletions
This file was deleted.

include/nbl/asset/ICPUBuffer.h

Lines changed: 79 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@
66

77
#include <type_traits>
88

9-
#include "nbl/core/alloc/null_allocator.h"
10-
119
#include "nbl/asset/IBuffer.h"
1210
#include "nbl/asset/IAsset.h"
1311
#include "nbl/asset/IPreHashed.h"
1412

13+
#include "nbl/core/alloc/refctd_memory_resource.h"
14+
1515
namespace nbl::asset
1616
{
1717

@@ -22,57 +22,80 @@ namespace nbl::asset
2222
2323
@see IAsset
2424
*/
25-
class ICPUBuffer : public asset::IBuffer, public IPreHashed
25+
class ICPUBuffer final : public asset::IBuffer, public IPreHashed
2626
{
27-
protected:
28-
//! Non-allocating constructor for CCustormAllocatorCPUBuffer derivative
29-
ICPUBuffer(size_t sizeInBytes, void* dat) : asset::IBuffer({ dat ? sizeInBytes : 0,EUF_TRANSFER_DST_BIT }), data(dat) {}
30-
3127
public:
32-
//! Constructor. TODO: remove, alloc can fail, should be a static create method instead!
33-
/** @param sizeInBytes Size in bytes. If `dat` argument is present, it denotes size of data pointed by `dat`, otherwise - size of data to be allocated.
34-
*/
35-
ICPUBuffer(size_t sizeInBytes) : asset::IBuffer({0,EUF_TRANSFER_DST_BIT})
28+
struct SCreationParams : asset::IBuffer::SCreationParams
3629
{
37-
data = _NBL_ALIGNED_MALLOC(sizeInBytes,_NBL_SIMD_ALIGNMENT);
38-
if (!data) // FIXME: cannot fail like that, need factory `create` methods
39-
return;
30+
size_t size;
31+
void* data = nullptr;
32+
size_t alignment = _NBL_SIMD_ALIGNMENT;
33+
core::smart_refctd_ptr<core::refctd_memory_resource> memoryResource = nullptr;
34+
35+
SCreationParams& operator =(const asset::IBuffer::SCreationParams& rhs)
36+
{
37+
static_cast<asset::IBuffer::SCreationParams&>(*this) = rhs;
38+
return *this;
39+
}
40+
};
41+
42+
//! allocates uninitialized memory, copies `data` into allocation if `!data` not nullptr
43+
core::smart_refctd_ptr<ICPUBuffer> static create(SCreationParams&& params)
44+
{
45+
if (!params.memoryResource)
46+
params.memoryResource = core::getDefaultMemoryResource();
47+
48+
auto data = params.memoryResource->allocate(params.size, params.alignment);
49+
if (!data)
50+
return nullptr;
51+
if (params.data)
52+
memcpy(data, params.data, params.size);
53+
params.data = data;
54+
55+
return core::smart_refctd_ptr<ICPUBuffer>(new ICPUBuffer(std::move(params)), core::dont_grab);
56+
}
4057

41-
m_creationParams.size = sizeInBytes;
58+
//! does not allocate memory, adopts the `data` pointer, no copies done
59+
core::smart_refctd_ptr<ICPUBuffer> static create(SCreationParams&& params, core::adopt_memory_t)
60+
{
61+
if (!params.data)
62+
return nullptr;
63+
if (!params.memoryResource)
64+
params.memoryResource = core::getDefaultMemoryResource();
65+
return core::smart_refctd_ptr<ICPUBuffer>(new ICPUBuffer(std::move(params)), core::dont_grab);
4266
}
4367

4468
core::smart_refctd_ptr<IAsset> clone(uint32_t = ~0u) const override final
4569
{
46-
auto cp = core::make_smart_refctd_ptr<ICPUBuffer>(m_creationParams.size);
47-
memcpy(cp->getPointer(), data, m_creationParams.size);
70+
auto cp = create({ .size = m_creationParams.size, .data = m_data, .alignment = m_alignment });
71+
memcpy(cp->getPointer(), m_data, m_creationParams.size);
4872
cp->setContentHash(getContentHash());
4973
return cp;
5074
}
5175

5276
constexpr static inline auto AssetType = ET_BUFFER;
5377
inline IAsset::E_TYPE getAssetType() const override final { return AssetType; }
5478

55-
inline size_t getDependantCount() const override {return 0;}
79+
inline size_t getDependantCount() const override { return 0; }
5680

57-
//
5881
inline core::blake3_hash_t computeContentHash() const override
5982
{
60-
core::blake3_hasher hasher;
61-
if (data)
62-
hasher.update(data,m_creationParams.size);
63-
return static_cast<core::blake3_hash_t>(hasher);
83+
core::blake3_hasher hasher;
84+
if (m_data)
85+
hasher.update(m_data, m_creationParams.size);
86+
return static_cast<core::blake3_hash_t>(hasher);
6487
}
6588

66-
inline bool missingContent() const override {return !data;}
89+
inline bool missingContent() const override { return !m_data; }
6790

6891
//! Returns pointer to data.
69-
const void* getPointer() const {return data;}
70-
void* getPointer()
71-
{
92+
const void* getPointer() const { return m_data; }
93+
void* getPointer()
94+
{
7295
assert(isMutable());
73-
return data;
96+
return m_data;
7497
}
75-
98+
7699
inline core::bitflag<E_USAGE_FLAGS> getUsageFlags() const
77100
{
78101
return m_creationParams.usage;
@@ -90,93 +113,33 @@ class ICPUBuffer : public asset::IBuffer, public IPreHashed
90113
return true;
91114
}
92115

93-
protected:
94-
inline IAsset* getDependant_impl(const size_t ix) override
95-
{
96-
return nullptr;
97-
}
98-
99-
inline void discardContent_impl() override
100-
{
101-
return freeData();
102-
}
103-
104-
// REMEMBER TO CALL FROM DTOR!
105-
// TODO: idea, make the `ICPUBuffer` an ADT, and use the default allocator CCPUBuffer instead for consistency
106-
// TODO: idea make a macro for overriding all `delete` operators of a class to enforce a finalizer that runs in reverse order to destructors (to allow polymorphic cleanups)
107-
virtual inline void freeData()
108-
{
109-
if (data)
110-
_NBL_ALIGNED_FREE(data);
111-
data = nullptr;
112-
m_creationParams.size = 0ull;
113-
}
114-
115-
void* data;
116-
};
117-
118-
119-
template<
120-
typename Allocator = _NBL_DEFAULT_ALLOCATOR_METATYPE<uint8_t>,
121-
bool = std::is_same<Allocator, core::null_allocator<typename Allocator::value_type> >::value
122-
>
123-
class CCustomAllocatorCPUBuffer;
124-
125-
using CDummyCPUBuffer = CCustomAllocatorCPUBuffer<core::null_allocator<uint8_t>, true>;
126-
127-
//! Specialization of ICPUBuffer capable of taking custom allocators
128-
/*
129-
Take a look that with this usage you have to specify custom alloctor
130-
passing an object type for allocation and a pointer to allocated
131-
data for it's storage by ICPUBuffer.
132-
133-
So the need for the class existence is for common following tricks - among others creating an
134-
\bICPUBuffer\b over an already existing \bvoid*\b array without any \imemcpy\i or \itaking over the memory ownership\i.
135-
You can use it with a \bnull_allocator\b that adopts memory (it is a bit counter intuitive because \badopt = take\b ownership,
136-
but a \inull allocator\i doesn't do anything, even free the memory, so you're all good).
137-
*/
138-
139-
template<typename Allocator>
140-
class CCustomAllocatorCPUBuffer<Allocator,true> : public ICPUBuffer
141-
{
142-
static_assert(sizeof(typename Allocator::value_type) == 1u, "Allocator::value_type must be of size 1");
143-
protected:
144-
Allocator m_allocator;
145-
146-
virtual ~CCustomAllocatorCPUBuffer() final
147-
{
148-
freeData();
149-
}
150-
inline void freeData() override
151-
{
152-
if (ICPUBuffer::data)
153-
m_allocator.deallocate(reinterpret_cast<typename Allocator::pointer>(ICPUBuffer::data), ICPUBuffer::m_creationParams.size);
154-
ICPUBuffer::data = nullptr; // so that ICPUBuffer won't try deallocating
155-
}
156-
157-
public:
158-
CCustomAllocatorCPUBuffer(size_t sizeInBytes, void* dat, core::adopt_memory_t, Allocator&& alctr = Allocator()) : ICPUBuffer(sizeInBytes,dat), m_allocator(std::move(alctr))
159-
{
160-
}
161-
};
162-
163-
template<typename Allocator>
164-
class CCustomAllocatorCPUBuffer<Allocator, false> : public CCustomAllocatorCPUBuffer<Allocator, true>
165-
{
166-
using Base = CCustomAllocatorCPUBuffer<Allocator, true>;
167-
168-
protected:
169-
virtual ~CCustomAllocatorCPUBuffer() = default;
170-
inline void freeData() override {}
171-
172-
public:
173-
using Base::Base;
174-
175-
// TODO: remove, alloc can fail, should be a static create method instead!
176-
CCustomAllocatorCPUBuffer(size_t sizeInBytes, const void* dat, Allocator&& alctr = Allocator()) : Base(sizeInBytes, alctr.allocate(sizeInBytes), core::adopt_memory, std::move(alctr))
177-
{
178-
memcpy(Base::data,dat,sizeInBytes);
179-
}
116+
protected:
117+
inline IAsset* getDependant_impl(const size_t ix) override
118+
{
119+
return nullptr;
120+
}
121+
122+
inline void discardContent_impl() override
123+
{
124+
if (m_data)
125+
m_mem_resource->deallocate(m_data, m_creationParams.size, m_alignment);
126+
m_data = nullptr;
127+
m_mem_resource = nullptr;
128+
m_creationParams.size = 0ull;
129+
}
130+
131+
private:
132+
ICPUBuffer(SCreationParams&& params) :
133+
asset::IBuffer({ params.size, EUF_TRANSFER_DST_BIT }), m_data(params.data),
134+
m_mem_resource(params.memoryResource), m_alignment(params.alignment) {}
135+
136+
~ICPUBuffer() override {
137+
discardContent_impl();
138+
}
139+
140+
void* m_data;
141+
core::smart_refctd_ptr<core::refctd_memory_resource> m_mem_resource;
142+
size_t m_alignment;
180143
};
181144

182145
} // end namespace nbl::asset

include/nbl/asset/ICPUMeshBuffer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ class ICPUMeshBuffer final : public IMeshBuffer<ICPUBuffer,ICPUDescriptorSet,ICP
544544
const bool scaled = isScaledFormat(format);
545545
if (!dst || !(scaled || isIntegerFormat(format)))
546546
return false;
547-
uint8_t* vxPtr = (uint8_t*)dst;
547+
uint8_t* vxPtr = reinterpret_cast<uint8_t*>(dst);
548548

549549
if (isSignedFormat(format))
550550
{

include/nbl/asset/ICPUShader.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class ICPUShader : public IAsset, public IShader
3333
: IShader(stage, std::move(filepathHint)), m_code(std::move(code)), m_contentType(contentType) {}
3434

3535
ICPUShader(const char* code, const E_SHADER_STAGE stage, const E_CONTENT_TYPE contentType, std::string&& filepathHint)
36-
: ICPUShader(core::make_smart_refctd_ptr<ICPUBuffer>(strlen(code) + 1u), stage, contentType, std::move(filepathHint))
36+
: ICPUShader(ICPUBuffer::create({ .size = strlen(code) + 1u }), stage, contentType, std::move(filepathHint))
3737
{
3838
assert(contentType != E_CONTENT_TYPE::ECT_SPIRV); // because using strlen needs `code` to be null-terminated
3939
memcpy(m_code->getPointer(), code, m_code->getSize());

include/nbl/asset/filters/CFlattenRegionsImageFilter.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ class CFlattenRegionsImageFilter : public CImageFilter<CFlattenRegionsImageFilte
8989
assert(memsize.getNumerator()%memsize.getDenominator()==0u);
9090
bufferSize += memsize.getIntegerApprox();
9191
}
92-
auto buffer = core::make_smart_refctd_ptr<ICPUBuffer>(bufferSize);
92+
auto buffer = ICPUBuffer::create({ .size = bufferSize });
9393
state->outImage->setBufferAndRegions(std::move(buffer),std::move(regions));
9494
};
9595

include/nbl/asset/filters/dithering/CPrecomputedDither.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ namespace nbl
5858
const size_t newDecodeBufferSize = extent.x * extent.y * extent.z * creationParams.arrayLayers * decodeTexelByteSize;
5959

6060
const core::vector3du32_SIMD decodeBufferByteStrides = TexelBlockInfo(decodeFormat).convert3DTexelStridesTo1DByteStrides(core::vector3du32_SIMD(extent.x, extent.y, extent.z));
61-
auto decodeFlattenBuffer = core::make_smart_refctd_ptr<ICPUBuffer>(newDecodeBufferSize);
61+
auto decodeFlattenBuffer = ICPUBuffer::create({ .size = newDecodeBufferSize });
6262
decodeFlattenBuffer->setContentHash(IPreHashed::INVALID_HASH);
6363

6464
auto* inData = reinterpret_cast<uint8_t*>(flattenDitheringImage->getBuffer()->getPointer());

include/nbl/asset/interchange/IImageAssetHandlerBase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ class IImageAssetHandlerBase : public virtual core::IReferenceCounted
110110
bufferSize += memsize.getIntegerApprox();
111111
}
112112

113-
auto texelBuffer = core::make_smart_refctd_ptr<ICPUBuffer>(bufferSize);
113+
auto texelBuffer = ICPUBuffer::create({ .size = bufferSize });
114114
newImage->setBufferAndRegions(std::move(texelBuffer), newRegions);
115115
newImage->setContentHash(IPreHashed::INVALID_HASH);
116116
}

include/nbl/asset/utils/CDirQuantCacheBase.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,7 @@ class CDirQuantCacheBase : public impl::CDirQuantCacheBase
297297
if (!file)
298298
return false;
299299

300-
auto buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(file->getSize());
300+
auto buffer = asset::ICPUBuffer::create({ .size = file->getSize() });
301301

302302
system::IFile::success_t succ;
303303
file->read(succ, buffer->getPointer(), 0, file->getSize());
@@ -346,7 +346,7 @@ class CDirQuantCacheBase : public impl::CDirQuantCacheBase
346346
asset::SBufferRange<asset::ICPUBuffer> bufferRange;
347347
bufferRange.offset = 0;
348348
bufferRange.size = getSerializedCacheSizeInBytes<CacheFormat>();
349-
bufferRange.buffer = core::make_smart_refctd_ptr<asset::ICPUBuffer>(bufferRange.size);
349+
bufferRange.buffer = asset::ICPUBuffer::create({ .size = bufferRange.size });
350350

351351
saveCacheToBuffer<CacheFormat>(bufferRange);
352352

include/nbl/asset/utils/IMeshManipulator.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ class NBL_API2 IMeshManipulator : public virtual core::IReferenceCounted
557557
core::smart_refctd_ptr<ICPUBuffer> iotaUint32Buffer;
558558
if (iotaLength)
559559
{
560-
iotaUint32Buffer = core::make_smart_refctd_ptr<ICPUBuffer>(sizeof(uint32_t)*iotaLength);
560+
iotaUint32Buffer = ICPUBuffer::create({ .size = sizeof(uint32_t)*iotaLength });
561561
auto ptr = reinterpret_cast<uint32_t*>(iotaUint32Buffer->getPointer());
562562
std::iota(ptr,ptr+iotaLength,0u);
563563
}
@@ -599,13 +599,13 @@ class NBL_API2 IMeshManipulator : public virtual core::IReferenceCounted
599599
if (indexType==EIT_16BIT)
600600
{
601601
auto inPtr = reinterpret_cast<const uint16_t*>(correctlyOffsetIndexBufferPtr);
602-
newIndexBuffer = core::make_smart_refctd_ptr<ICPUBuffer>(sizeof(uint32_t)*indexCount);
602+
newIndexBuffer = ICPUBuffer::create({ .size = sizeof(uint32_t)*indexCount });
603603
std::copy(inPtr,inPtr+indexCount,reinterpret_cast<uint32_t*>(newIndexBuffer->getPointer()));
604604
}
605605
else
606606
{
607607
auto inPtr = reinterpret_cast<const uint32_t*>(correctlyOffsetIndexBufferPtr);
608-
newIndexBuffer = core::make_smart_refctd_ptr<ICPUBuffer>(sizeof(uint16_t)*indexCount);
608+
newIndexBuffer = ICPUBuffer::create({ .size = sizeof(uint16_t)*indexCount });
609609
std::copy(inPtr,inPtr+indexCount,reinterpret_cast<uint16_t*>(newIndexBuffer->getPointer()));
610610
}
611611
}

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
219219
core::blake3_hash_t hash = {};
220220
// If true, then `getIncludeStandard` was used to find, otherwise `getIncludeRelative`
221221
bool standardInclude = false;
222+
222223
};
223224

224225
struct SCompilerArgs; // Forward declaration for SPreprocessorArgs's friend declaration
@@ -525,7 +526,7 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
525526
constexpr size_t nullTerminatorSize = 1u;
526527
size_t outSize = origLen + formatArgsCharSize + formatSize + nullTerminatorSize - 2 * templateArgsCount;
527528

528-
nbl::core::smart_refctd_ptr<ICPUBuffer> outBuffer = nbl::core::make_smart_refctd_ptr<ICPUBuffer>(outSize);
529+
nbl::core::smart_refctd_ptr<ICPUBuffer> outBuffer = ICPUBuffer::create({ .size = outSize });
529530

530531
auto origCode = std::string_view(reinterpret_cast<const char*>(original->getContent()->getPointer()), origLen);
531532
auto outCode = reinterpret_cast<char*>(outBuffer->getPointer());

0 commit comments

Comments
 (0)