Skip to content

Commit aa2cf2b

Browse files
committed
fix some block offset bugs, add debug checks, remove wait info from .render call, update examples_tests submodule
1 parent 1fbbc06 commit aa2cf2b

File tree

3 files changed

+35
-21
lines changed

3 files changed

+35
-21
lines changed

examples_tests

include/nbl/ext/ImGui/ImGui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ class UI final : public core::IReferenceCounted
9393
bool update(const S_UPDATE_PARAMETERS& params);
9494

9595
//! updates mapped mdi buffer & records *gpu* draw command, you are required to bind UI's graphics pipeline & descriptor sets before calling this function - use getPipeline() to get the pipeline & getCreationParameters() to get info about your set resources
96-
bool render(nbl::video::IGPUCommandBuffer* commandBuffer, nbl::video::ISemaphore::SWaitInfo waitInfo, const std::span<const VkRect2D> scissors = {});
96+
bool render(nbl::video::IGPUCommandBuffer* commandBuffer, const std::span<const VkRect2D> scissors = {});
9797

9898
//! registers lambda listener in which ImGUI calls should be recorded
9999
size_t registerListener(std::function<void()> const& listener);

src/nbl/ext/ImGui/ImGui.cpp

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -894,7 +894,7 @@ namespace nbl::ext::imgui
894894
template<typename T>
895895
concept ImDrawBufferType = std::same_as<T, ImDrawVert> || std::same_as<T, ImDrawIdx>;
896896

897-
bool UI::render(nbl::video::IGPUCommandBuffer* commandBuffer, nbl::video::ISemaphore::SWaitInfo waitInfo, const std::span<const VkRect2D> scissors)
897+
bool UI::render(nbl::video::IGPUCommandBuffer* commandBuffer, const std::span<const VkRect2D> scissors)
898898
{
899899
if (!commandBuffer)
900900
{
@@ -1063,7 +1063,10 @@ namespace nbl::ext::imgui
10631063
{
10641064
static constexpr auto ALIGN_OFFSET_NEEDED = 0u;
10651065
MDI::SUBALLOCATOR_TRAITS_T::allocator_type fillSubAllocator(mdiData, requestState.offset, ALIGN_OFFSET_NEEDED, MDI_MAX_ALIGNMENT, requestState.multiAllocationSize);
1066-
MDI::SUBALLOCATOR_TRAITS_T::multi_alloc_addr(fillSubAllocator, mdiOffsets.size(), mdiOffsets.data(), mdiParams.bytesToFill.data(), MDI_ALIGNMENTS.data());
1066+
1067+
std::array<typename MDI::ALLOCATOR_TRAITS_T::size_type, MDI_COMPONENT_COUNT> offsets;
1068+
std::fill(offsets.data(), offsets.data() + MDI_COMPONENT_COUNT, MDI::ALLOCATOR_TRAITS_T::allocator_type::invalid_address);
1069+
MDI::SUBALLOCATOR_TRAITS_T::multi_alloc_addr(fillSubAllocator, offsets.size(), offsets.data(), mdiParams.bytesToFill.data(), MDI_ALIGNMENTS.data());
10671070

10681071
//! linear allocator is used to fill the mdi data within suballocation memory range,
10691072
//! there are a few restrictions regarding how MDI::E_BUFFER_CONTENT(s) can be packed,
@@ -1073,45 +1076,46 @@ namespace nbl::ext::imgui
10731076

10741077
auto fillDrawBuffers = [&]<MDI::E_BUFFER_CONTENT type>()
10751078
{
1076-
const typename MDI::ALLOCATOR_TRAITS_T::size_type blockOffset = mdiOffsets[type];
1079+
const typename MDI::ALLOCATOR_TRAITS_T::size_type globalBlockOffset = offsets[type];
10771080

1078-
if (blockOffset == MDI::ALLOCATOR_TRAITS_T::allocator_type::invalid_address or mdiBytesFilled[type])
1081+
if (globalBlockOffset == MDI::ALLOCATOR_TRAITS_T::allocator_type::invalid_address or mdiBytesFilled[type])
10791082
return 0u;
10801083

1081-
auto* const data = mdiData + blockOffset;
1082-
size_t localOffset = {};
1084+
auto* data = mdiData + globalBlockOffset;
10831085

10841086
for (int n = 0; n < drawData->CmdListsCount; n++)
10851087
{
10861088
auto* cmd_list = drawData->CmdLists[n];
10871089

10881090
if constexpr (type == MDI::EBC_INDEX_BUFFERS)
10891091
{
1090-
::memcpy(data + localOffset, cmd_list->IdxBuffer.Data, cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx));
1091-
localOffset += cmd_list->IdxBuffer.Size;
1092+
const auto localInputBlockOffset = cmd_list->IdxBuffer.Size * sizeof(ImDrawIdx);
1093+
::memcpy(data, cmd_list->IdxBuffer.Data, localInputBlockOffset);
1094+
data += localInputBlockOffset;
10921095
}
10931096
else if (type == MDI::EBC_VERTEX_BUFFERS)
10941097
{
1095-
::memcpy(data, cmd_list->VtxBuffer.Data, cmd_list->VtxBuffer.Size * sizeof(ImDrawVert));
1096-
localOffset += cmd_list->VtxBuffer.Size;
1098+
const auto localInputBlockOffset = cmd_list->VtxBuffer.Size * sizeof(ImDrawVert);
1099+
::memcpy(data, cmd_list->VtxBuffer.Data, localInputBlockOffset);
1100+
data += localInputBlockOffset;
10971101
}
10981102
}
10991103

11001104
mdiBytesFilled[type] = true;
1105+
mdiOffsets[type] = globalBlockOffset;
11011106
return mdiParams.bytesToFill[type];
11021107
};
11031108

11041109
auto fillIndirectStructures = [&]<MDI::E_BUFFER_CONTENT type>()
11051110
{
1106-
const typename MDI::ALLOCATOR_TRAITS_T::size_type blockOffset = mdiOffsets[type];
1111+
const typename MDI::ALLOCATOR_TRAITS_T::size_type globalBlockOffset = offsets[type];
11071112

1108-
if (blockOffset == MDI::ALLOCATOR_TRAITS_T::allocator_type::invalid_address or mdiBytesFilled[type])
1113+
if (globalBlockOffset == MDI::ALLOCATOR_TRAITS_T::allocator_type::invalid_address or mdiBytesFilled[type])
11091114
return 0u;
11101115

1111-
auto* const data = mdiData + blockOffset;
1112-
size_t localOffset = {};
1116+
auto* const data = mdiData + globalBlockOffset;
11131117

1114-
size_t cmdListIndexOffset = {}, cmdListVertexOffset = {}, drawID = {};
1118+
size_t cmdListIndexObjectOffset = {}, cmdListVertexObjectOffset = {}, drawID = {};
11151119

11161120
for (int n = 0; n < drawData->CmdListsCount; n++)
11171121
{
@@ -1127,8 +1131,8 @@ namespace nbl::ext::imgui
11271131
indirect->firstInstance = drawID; // use base instance as draw ID
11281132
indirect->indexCount = pcmd->ElemCount;
11291133
indirect->instanceCount = 1u;
1130-
indirect->firstIndex = pcmd->IdxOffset + cmdListIndexOffset;
1131-
indirect->vertexOffset = pcmd->VtxOffset + cmdListVertexOffset;
1134+
indirect->firstIndex = pcmd->IdxOffset + cmdListIndexObjectOffset;
1135+
indirect->vertexOffset = pcmd->VtxOffset + cmdListVertexObjectOffset;
11321136
}
11331137
else if (type == MDI::EBC_ELEMENT_STRUCTURES)
11341138
{
@@ -1155,11 +1159,12 @@ namespace nbl::ext::imgui
11551159
++drawID;
11561160
}
11571161

1158-
cmdListIndexOffset += cmd_list->IdxBuffer.Size;
1159-
cmdListVertexOffset += cmd_list->VtxBuffer.Size;
1162+
cmdListIndexObjectOffset += cmd_list->IdxBuffer.Size;
1163+
cmdListVertexObjectOffset += cmd_list->VtxBuffer.Size;
11601164
}
11611165

11621166
mdiBytesFilled[type] = true;
1167+
mdiOffsets[type] = globalBlockOffset;
11631168
return mdiParams.bytesToFill[type];
11641169
};
11651170

@@ -1175,6 +1180,15 @@ namespace nbl::ext::imgui
11751180
}
11761181
}
11771182

1183+
assert([&mdiOffsets]() -> bool
1184+
{
1185+
for (const auto& offset : mdiOffsets)
1186+
if (offset == MDI::ALLOCATOR_TRAITS_T::allocator_type::invalid_address)
1187+
return false; // we should never hit this at this point
1188+
1189+
return true;
1190+
}()); // debug check only
1191+
11781192
const auto offset = mdiBuffer->getBoundMemory().offset;
11791193
{
11801194
const asset::SBufferBinding<const video::IGPUBuffer> binding =

0 commit comments

Comments
 (0)