Skip to content

Commit 9ac14bc

Browse files
Merge pull request #615 from Devsh-Graphics-Programming/examples_rewrite
Bugfixes
2 parents 1188f14 + 4d02095 commit 9ac14bc

15 files changed

+111
-93
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ if(MSVC)
2222
if(NBL_SANITIZE_ADDRESS)
2323
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>")
2424
else()
25-
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>")
25+
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<$<CONFIG:Debug>:EditAndContinue>$<$<CONFIG:RelWithDebInfo>:ProgramDatabase>")
2626
endif()
2727
endif()
2828

cmake/common.cmake

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -231,17 +231,9 @@ macro(nbl_create_ext_library_project EXT_NAME LIB_HEADERS LIB_SOURCES LIB_INCLUD
231231
project(${LIB_NAME})
232232

233233
add_library(${LIB_NAME} ${LIB_SOURCES})
234-
get_target_property(_NBL_NABLA_TARGET_BINARY_DIR_ Nabla BINARY_DIR)
235234

236-
# TODO: correct those bugs, use generator expressions
237235
target_include_directories(${LIB_NAME}
238-
PUBLIC ${_NBL_NABLA_TARGET_BINARY_DIR_}/build/import
239-
PUBLIC ${CMAKE_BINARY_DIR}/include/nbl/config/debug
240-
PUBLIC ${CMAKE_BINARY_DIR}/include/nbl/config/release
241-
PUBLIC ${CMAKE_BINARY_DIR}/include/nbl/config/relwithdebinfo
242-
PUBLIC ${CMAKE_SOURCE_DIR}/include
243-
PUBLIC ${CMAKE_SOURCE_DIR}/src
244-
PUBLIC ${CMAKE_SOURCE_DIR}/source/Nabla
236+
PUBLIC $<TARGET_PROPERTY:Nabla,INCLUDE_DIRECTORIES>
245237
PRIVATE ${LIB_INCLUDES}
246238
)
247239

examples_tests

include/nbl/asset/ICPUBuffer.h

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,23 @@ namespace nbl::asset
2727
class ICPUBuffer : public asset::IBuffer, public asset::IAsset
2828
{
2929
protected:
30-
virtual ~ICPUBuffer()
31-
{
32-
this->convertToDummyObject();
33-
}
34-
3530
//! Non-allocating constructor for CCustormAllocatorCPUBuffer derivative
3631
ICPUBuffer(size_t sizeInBytes, void* dat) : asset::IBuffer({ dat ? sizeInBytes : 0,EUF_TRANSFER_DST_BIT }), data(dat) {}
32+
3733
public:
3834
//! Constructor. TODO: remove, alloc can fail, should be a static create method instead!
3935
/** @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.
4036
*/
4137
ICPUBuffer(size_t sizeInBytes) : asset::IBuffer({0,EUF_TRANSFER_DST_BIT})
4238
{
4339
data = _NBL_ALIGNED_MALLOC(sizeInBytes,_NBL_SIMD_ALIGNMENT);
44-
if (!data)
40+
if (!data) // FIXME: cannot fail like that, need factory `create` methods
4541
return;
4642

4743
m_creationParams.size = sizeInBytes;
4844
}
4945

50-
core::smart_refctd_ptr<IAsset> clone(uint32_t = ~0u) const override
46+
core::smart_refctd_ptr<IAsset> clone(uint32_t = ~0u) const override final
5147
{
5248
auto cp = core::make_smart_refctd_ptr<ICPUBuffer>(m_creationParams.size);
5349
clone_common(cp.get());
@@ -56,33 +52,29 @@ class ICPUBuffer : public asset::IBuffer, public asset::IAsset
5652
return cp;
5753
}
5854

59-
virtual void convertToDummyObject(uint32_t referenceLevelsBelowToConvert = 0u) override
55+
void convertToDummyObject(uint32_t referenceLevelsBelowToConvert = 0u) override final
6056
{
6157
if (!canBeConvertedToDummy())
6258
return;
6359
convertToDummyObject_common(referenceLevelsBelowToConvert);
64-
65-
if (data)
66-
_NBL_ALIGNED_FREE(data);
67-
data = nullptr;
68-
m_creationParams.size = 0ull;
60+
freeData();
6961
isDummyObjectForCacheAliasing = true;
7062
}
7163

7264
_NBL_STATIC_INLINE_CONSTEXPR auto AssetType = ET_BUFFER;
73-
inline IAsset::E_TYPE getAssetType() const override { return AssetType; }
65+
inline IAsset::E_TYPE getAssetType() const override final { return AssetType; }
7466

75-
virtual size_t conservativeSizeEstimate() const override { return getSize(); }
67+
size_t conservativeSizeEstimate() const override final { return getSize(); }
7668

7769
//! Returns pointer to data.
78-
virtual const void* getPointer() const {return data;}
79-
virtual void* getPointer()
70+
const void* getPointer() const {return data;}
71+
void* getPointer()
8072
{
8173
assert(!isImmutable_debug());
8274
return data;
8375
}
8476

85-
bool canBeRestoredFrom(const IAsset* _other) const override
77+
bool canBeRestoredFrom(const IAsset* _other) const override final
8678
{
8779
auto* other = static_cast<const ICPUBuffer*>(_other);
8880
if (m_creationParams.size != other->m_creationParams.size)
@@ -108,14 +100,27 @@ class ICPUBuffer : public asset::IBuffer, public asset::IAsset
108100
}
109101

110102
protected:
111-
void restoreFromDummy_impl(IAsset* _other, uint32_t _levelsBelow) override
103+
void restoreFromDummy_impl(IAsset* _other, uint32_t _levelsBelow) override final
112104
{
113105
auto* other = static_cast<ICPUBuffer*>(_other);
114106

107+
// NO THIS IS A NIGHTMARE!
108+
// FIXME: ONLY SWAP FOR COMPATIBLE ALLOCATORS! OTHERWISE MEMCPY!
115109
if (willBeRestoredFrom(_other))
116110
std::swap(data, other->data);
117111
}
118112

113+
// REMEMBER TO CALL FROM DTOR!
114+
// TODO: idea, make the `ICPUBuffer` an ADT, and use the default allocator CCPUBuffer instead for consistency
115+
// 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)
116+
virtual void freeData()
117+
{
118+
if (data)
119+
_NBL_ALIGNED_FREE(data);
120+
data = nullptr;
121+
m_creationParams.size = 0ull;
122+
}
123+
119124
void* data;
120125
};
121126

@@ -140,42 +145,37 @@ using CDummyCPUBuffer = CCustomAllocatorCPUBuffer<core::null_allocator<uint8_t>,
140145
*/
141146

142147
template<typename Allocator>
143-
class CCustomAllocatorCPUBuffer<Allocator, true> : public ICPUBuffer
148+
class CCustomAllocatorCPUBuffer<Allocator,true> : public ICPUBuffer
144149
{
145150
static_assert(sizeof(typename Allocator::value_type) == 1u, "Allocator::value_type must be of size 1");
146151
protected:
147152
Allocator m_allocator;
148153

149-
virtual ~CCustomAllocatorCPUBuffer()
154+
virtual ~CCustomAllocatorCPUBuffer() final
150155
{
151-
this->convertToDummyObject();
156+
freeData();
152157
}
153-
154-
public:
155-
CCustomAllocatorCPUBuffer(size_t sizeInBytes, void* dat, core::adopt_memory_t, Allocator&& alctr = Allocator()) : ICPUBuffer(sizeInBytes, dat), m_allocator(std::move(alctr))
156-
{
157-
}
158-
159-
virtual void convertToDummyObject(uint32_t referenceLevelsBelowToConvert = 0u) override
158+
inline void freeData() override
160159
{
161-
if (isDummyObjectForCacheAliasing)
162-
return;
163-
convertToDummyObject_common(referenceLevelsBelowToConvert);
164-
if (!canBeConvertedToDummy())
165-
return;
166-
167160
if (ICPUBuffer::data)
168161
m_allocator.deallocate(reinterpret_cast<typename Allocator::pointer>(ICPUBuffer::data), ICPUBuffer::m_creationParams.size);
169162
ICPUBuffer::data = nullptr; // so that ICPUBuffer won't try deallocating
170163
}
164+
165+
public:
166+
CCustomAllocatorCPUBuffer(size_t sizeInBytes, void* dat, core::adopt_memory_t, Allocator&& alctr = Allocator()) : ICPUBuffer(sizeInBytes,dat), m_allocator(std::move(alctr))
167+
{
168+
}
171169
};
172170

173171
template<typename Allocator>
174172
class CCustomAllocatorCPUBuffer<Allocator, false> : public CCustomAllocatorCPUBuffer<Allocator, true>
175173
{
176174
using Base = CCustomAllocatorCPUBuffer<Allocator, true>;
175+
177176
protected:
178177
virtual ~CCustomAllocatorCPUBuffer() = default;
178+
inline void freeData() override {}
179179

180180
public:
181181
using Base::Base;

include/nbl/asset/utils/IShaderCompiler.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
210210
template<typename... Args>
211211
static core::smart_refctd_ptr<ICPUShader> createOverridenCopy(const ICPUShader* original, uint32_t position, const char* fmt, Args... args)
212212
{
213-
assert(original == nullptr || (!original->isADummyObjectForCache() && original->isContentHighLevelLanguage()));
213+
if (!original || original->isADummyObjectForCache() || !original->isContentHighLevelLanguage())
214+
return nullptr;
214215

215216
constexpr auto getMaxSize = [](auto num) -> size_t
216217
{
@@ -230,12 +231,13 @@ class NBL_API2 IShaderCompiler : public core::IReferenceCounted
230231
}
231232
};
232233
constexpr size_t templateArgsCount = sizeof...(Args);
233-
size_t origLen = original ? original->getContent()->getSize():0u;
234-
size_t formatArgsCharSize = (getMaxSize(args) + ...);
235-
size_t formatSize = strlen(fmt);
234+
const size_t origLen = original ? original->getContent()->getSize():0u;
235+
const size_t formatArgsCharSize = (getMaxSize(args) + ...);
236+
const size_t formatSize = strlen(fmt);
236237
// 2 is an average size of a format (% and a letter) in chars.
237238
// Assuming the format contains only one letter, but if it's 2, the outSize is gonna be a touch bigger.
238-
size_t outSize = origLen + formatArgsCharSize + formatSize - 2 * templateArgsCount;
239+
constexpr size_t nullTerminatorSize = 1u;
240+
size_t outSize = origLen + formatArgsCharSize + formatSize + nullTerminatorSize - 2 * templateArgsCount;
239241

240242
nbl::core::smart_refctd_ptr<ICPUBuffer> outBuffer = nbl::core::make_smart_refctd_ptr<ICPUBuffer>(outSize);
241243

include/nbl/core/alloc/address_allocator_traits.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ namespace nbl::core
155155
_NBL_STATIC_INLINE_CONSTEXPR bool supportsArbitraryOrderFrees = resolve_supportsArbitraryOrderFrees<AddressAlloc>::value;
156156
_NBL_STATIC_INLINE_CONSTEXPR uint32_t maxMultiOps = resolve_maxMultiOps<AddressAlloc>::value;
157157

158+
// TODO: make the printer customizable without making a `core`->`system` circular dep
158159
static inline void printDebugInfo()
159160
{
160161
printf("has_func_multi_alloc_addr : %s\n", has_func_multi_alloc_addr<AddressAlloc>::value ? "true":"false");

include/nbl/video/IGPUCommandBuffer.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -126,15 +126,17 @@ class NBL_API2 IGPUCommandBuffer :
126126

127127
IGPUCommandBuffer(core::smart_refctd_ptr<const ILogicalDevice>&& dev, E_LEVEL lvl, core::smart_refctd_ptr<IGPUCommandPool>&& _cmdpool, system::logger_opt_smart_ptr&& logger) : base_t(lvl), IBackendObject(std::move(dev)), m_cmdpool(_cmdpool), m_logger(std::move(logger))
128128
{
129+
// prevent false positives on first `begin()`
130+
m_resetCheckedStamp = m_cmdpool->getResetCounter();
129131
}
130132

131-
virtual ~IGPUCommandBuffer()
133+
// meant to be invoked by most derived class
134+
// 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)
135+
inline void out_of_order_dtor()
132136
{
133137
// Only release the resources if the parent pool has not been reset because if it has been then the resources will already be released.
134138
if (!checkForParentPoolReset())
135-
{
136139
releaseResourcesBackToPool();
137-
}
138140
}
139141

140142
system::logger_opt_smart_ptr m_logger;
@@ -252,9 +254,7 @@ class NBL_API2 IGPUCommandBuffer :
252254
m_commandList.head = nullptr;
253255
m_commandList.tail = nullptr;
254256

255-
// Example 05 crashes here, with assert in `ucrt` maybe vtable gets lost or something?
256-
// For now commented out because we only have a Vulkan backend and function doesn't do anything.
257-
//checkForParentPoolReset_impl();
257+
checkForParentPoolReset_impl();
258258

259259
return true;
260260
}
@@ -288,7 +288,7 @@ class NBL_API2 IGPUCommandBuffer :
288288
return true;
289289
}
290290

291-
uint64_t m_resetCheckedStamp = 0;
291+
uint64_t m_resetCheckedStamp;
292292

293293
// This bound descriptor set record doesn't include the descriptor sets whose layout has _any_ one of its bindings
294294
// created with IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_UPDATE_AFTER_BIND_BIT

include/nbl/video/IGPUQueue.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,19 @@ class IGPUQueue : public core::Interface, public core::Unmovable
6464
uint32_t getFamilyIndex() const { return m_familyIndex; }
6565
E_CREATE_FLAGS getFlags() const { return m_flags; }
6666

67+
// When dealing with external/foreign queues treat `other` as nullptr
68+
inline bool needsOwnershipTransfer(const IGPUQueue* other) const
69+
{
70+
if (!other)
71+
return true;
72+
73+
if (m_familyIndex==other->m_familyIndex)
74+
return false;
75+
76+
// TODO: take into account concurrent sharing indices, but then we'll need to remember the concurrent sharing family indices
77+
return true;
78+
}
79+
6780
inline constexpr static float DEFAULT_QUEUE_PRIORITY = 1.f;
6881

6982
// OpenGL: const egl::CEGL::Context*

include/nbl/video/IPhysicalDevice.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -392,7 +392,7 @@ class NBL_API2 IPhysicalDevice : public core::Interface, public core::Unmovable
392392
uint16_t transferDst : 1u;
393393
uint16_t log2MaxSamples : 3u; // 0 means cant use as a multisample image format
394394

395-
SUsage()
395+
constexpr SUsage()
396396
: sampledImage(0)
397397
, storageImage(0)
398398
, storageImageAtomic(0)
@@ -405,7 +405,7 @@ class NBL_API2 IPhysicalDevice : public core::Interface, public core::Unmovable
405405
, log2MaxSamples(0)
406406
{}
407407

408-
SUsage(core::bitflag<asset::IImage::E_USAGE_FLAGS> usages):
408+
constexpr SUsage(core::bitflag<asset::IImage::E_USAGE_FLAGS> usages) :
409409
log2MaxSamples(0),
410410
sampledImage(usages.hasFlags(asset::IImage::EUF_SAMPLED_BIT)),
411411
storageImage(usages.hasFlags(asset::IImage::EUF_STORAGE_BIT)),
@@ -419,7 +419,7 @@ class NBL_API2 IPhysicalDevice : public core::Interface, public core::Unmovable
419419
storageImageAtomic(0)
420420
{}
421421

422-
inline SUsage operator & (const SUsage& other) const
422+
constexpr SUsage operator&(const SUsage& other) const
423423
{
424424
SUsage result;
425425
result.sampledImage = sampledImage & other.sampledImage;
@@ -435,7 +435,7 @@ class NBL_API2 IPhysicalDevice : public core::Interface, public core::Unmovable
435435
return result;
436436
}
437437

438-
inline SUsage operator | (const SUsage& other) const
438+
constexpr SUsage operator|(const SUsage& other) const
439439
{
440440
SUsage result;
441441
result.sampledImage = sampledImage | other.sampledImage;
@@ -451,7 +451,7 @@ class NBL_API2 IPhysicalDevice : public core::Interface, public core::Unmovable
451451
return result;
452452
}
453453

454-
inline SUsage operator ^ (const SUsage& other) const
454+
constexpr SUsage operator^(const SUsage& other) const
455455
{
456456
SUsage result;
457457
result.sampledImage = sampledImage ^ other.sampledImage;
@@ -467,7 +467,7 @@ class NBL_API2 IPhysicalDevice : public core::Interface, public core::Unmovable
467467
return result;
468468
}
469469

470-
inline bool operator<(const SUsage& other) const
470+
constexpr bool operator<(const SUsage& other) const
471471
{
472472
if (sampledImage && !other.sampledImage) return false;
473473
if (storageImage && !other.storageImage) return false;
@@ -482,7 +482,7 @@ class NBL_API2 IPhysicalDevice : public core::Interface, public core::Unmovable
482482
return true;
483483
}
484484

485-
inline bool operator == (const SUsage& other) const
485+
constexpr bool operator==(const SUsage& other) const
486486
{
487487
return
488488
(sampledImage == other.sampledImage) &&
@@ -528,7 +528,7 @@ class NBL_API2 IPhysicalDevice : public core::Interface, public core::Unmovable
528528
EQF_NONE = 0,
529529
EQF_GRAPHICS_BIT = 0x01,
530530
EQF_COMPUTE_BIT = 0x02,
531-
EQF_TRANSFER_BIT = 0x04,
531+
EQF_TRANSFER_BIT = 0x04, // TODO: investigate whether GRAPHICS or COMPUTE can NOT report TRANSFER at the same time
532532
EQF_SPARSE_BINDING_BIT = 0x08,
533533
EQF_PROTECTED_BIT = 0x10
534534
};

0 commit comments

Comments
 (0)