Skip to content

Commit 5cb70ef

Browse files
committed
use SIntendedSubmitInfo instead of raw command buffer in UI's render call, add more validation & logs, multi_deallocate at then end of the render call with future scratch semaphore (we treating it as wait semaphore), temporary terminate application on scratch semaphore-spotted counter overflow, update examples_tests submodule
1 parent cb83a58 commit 5cb70ef

File tree

3 files changed

+44
-22
lines changed

3 files changed

+44
-22
lines changed

examples_tests

include/nbl/ext/ImGui/ImGui.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class UI final : public core::IReferenceCounted
1515
UI(core::smart_refctd_ptr<video::ILogicalDevice> _device, core::smart_refctd_ptr<video::IGPUDescriptorSetLayout> _descriptorSetLayout, video::IGPURenderpass* renderpass, video::IGPUPipelineCache* pipelineCache, core::smart_refctd_ptr<ui::IWindow> window);
1616
~UI() override;
1717

18-
bool render(nbl::video::IGPUCommandBuffer* commandBuffer, const nbl::video::IGPUDescriptorSet* const descriptorSet);
18+
bool render(nbl::video::SIntendedSubmitInfo& info, const nbl::video::IGPUDescriptorSet* const descriptorSet);
1919
void update(float deltaTimeInSec, const nbl::hlsl::float32_t2 mousePosition, const core::SRange<const nbl::ui::SMouseEvent> mouseEvents, const core::SRange<const nbl::ui::SKeyboardEvent> keyboardEvents);
2020
int registerListener(std::function<void()> const& listener);
2121
bool unregisterListener(uint32_t id);

src/nbl/ext/ImGui/ImGui.cpp

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -665,14 +665,28 @@ namespace nbl::ext::imgui
665665
m_mdi.streamingTDBufferST->getBuffer()->setObjectDebugName("MDI Upstream Buffer");
666666
}
667667

668-
bool UI::render(IGPUCommandBuffer* commandBuffer, const IGPUDescriptorSet* const descriptorSet)
668+
bool UI::render(SIntendedSubmitInfo& info, const IGPUDescriptorSet* const descriptorSet)
669669
{
670+
if (!info.valid())
671+
{
672+
logger->log("Invalid SIntendedSubmitInfo!", system::ILogger::ELL_ERROR);
673+
return false;
674+
}
675+
676+
struct
677+
{
678+
const uint64_t oldie;
679+
uint64_t newie;
680+
} scratchSemaphoreCounters = { .oldie = info.scratchSemaphore.value, .newie = 0u };
681+
682+
auto* commandBuffer = info.getScratchCommandBuffer();
683+
670684
ImGuiIO& io = ImGui::GetIO();
671685

672686
if (!io.Fonts->IsBuilt())
673687
{
674688
logger->log("Font atlas not built! It is generally built by the renderer backend. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame().", system::ILogger::ELL_ERROR);
675-
assert(false);
689+
return false;
676690
}
677691

678692
auto const* drawData = ImGui::GetDrawData();
@@ -774,6 +788,7 @@ namespace nbl::ext::imgui
774788
return requestedByteSize + padding;
775789
}();
776790

791+
auto mdiBuffer = smart_refctd_ptr<IGPUBuffer>(m_mdi.streamingTDBufferST->getBuffer());
777792
{
778793
std::chrono::steady_clock::time_point timeout(std::chrono::seconds(0x45));
779794

@@ -785,23 +800,23 @@ namespace nbl::ext::imgui
785800
{
786801
logger->log("Could not multi alloc mdi buffer!", system::ILogger::ELL_ERROR);
787802

788-
auto callback = [&](const std::string_view section, const MDI::MULTI_ALLOC_PARAMS::COMPOSE_T::value_type offset)
803+
auto getOffsetStr = [&](const MDI::MULTI_ALLOC_PARAMS::COMPOSE_T::value_type offset) -> std::string
789804
{
790-
std::string value = offset == MDI::MULTI_ALLOC_PARAMS::COMPOSE_T::invalid_value ? "invalid_value" : std::to_string(offset);
791-
logger->log("%s offset = %s", system::ILogger::ELL_ERROR, section.data(), value.c_str());
805+
return offset == MDI::MULTI_ALLOC_PARAMS::COMPOSE_T::invalid_value ? "invalid_value" : std::to_string(offset);
792806
};
793807

794-
callback("MDI::EBC_DRAW_INDIRECT_STRUCTURES", multiAllocParams.offsets[MDI::EBC_DRAW_INDIRECT_STRUCTURES]);
795-
callback("MDI::EBC_ELEMENT_STRUCTURES", multiAllocParams.offsets[MDI::EBC_ELEMENT_STRUCTURES]);
796-
callback("MDI::EBC_INDEX_BUFFERS", multiAllocParams.offsets[MDI::EBC_INDEX_BUFFERS]);
797-
callback("MDI::EBC_VERTEX_BUFFERS", multiAllocParams.offsets[MDI::EBC_VERTEX_BUFFERS]);
808+
logger->log("[mdi streaming buffer size] = \"%s\" bytes", system::ILogger::ELL_ERROR, std::to_string(mdiBuffer->getSize()).c_str());
809+
logger->log("[unallocated size] = \"%s\" bytes", system::ILogger::ELL_ERROR, std::to_string(unallocatedSize).c_str());
810+
811+
logger->log("[MDI::EBC_DRAW_INDIRECT_STRUCTURES offset] = \"%s\" bytes", system::ILogger::ELL_ERROR, getOffsetStr(multiAllocParams.offsets[MDI::EBC_DRAW_INDIRECT_STRUCTURES]).c_str());
812+
logger->log("[MDI::EBC_ELEMENT_STRUCTURES offset] = \"%s\" bytes", system::ILogger::ELL_ERROR, getOffsetStr(multiAllocParams.offsets[MDI::EBC_ELEMENT_STRUCTURES]).c_str());
813+
logger->log("[MDI::EBC_INDEX_BUFFERS offset] = \"%s\" bytes", system::ILogger::ELL_ERROR, getOffsetStr(multiAllocParams.offsets[MDI::EBC_INDEX_BUFFERS]).c_str());
814+
logger->log("[MDI::EBC_VERTEX_BUFFERS offset] = \"%s\" bytes", system::ILogger::ELL_ERROR, getOffsetStr(multiAllocParams.offsets[MDI::EBC_VERTEX_BUFFERS]).c_str());
798815

799-
exit(0x45); // TODO: handle overflows, unallocatedSize tells how much is missing
816+
exit(0x45); // TODO: handle OOB memory requests
800817
}
801818
}
802819

803-
auto mdiBuffer = smart_refctd_ptr<IGPUBuffer>(m_mdi.streamingTDBufferST->getBuffer());
804-
805820
const uint32_t drawCount = multiAllocParams.byteSizes[MDI::EBC_DRAW_INDIRECT_STRUCTURES] / sizeof(VkDrawIndexedIndirectCommand);
806821
{
807822
auto binding = mdiBuffer->getBoundMemory();
@@ -817,12 +832,6 @@ namespace nbl::ext::imgui
817832
auto* indicesMappedPointer = reinterpret_cast<ImDrawIdx*>(reinterpret_cast<uint8_t*>(m_mdi.streamingTDBufferST->getBufferPointer()) + multiAllocParams.offsets[MDI::EBC_INDEX_BUFFERS]);
818833
auto* verticesMappedPointer = reinterpret_cast<ImDrawVert*>(reinterpret_cast<uint8_t*>(m_mdi.streamingTDBufferST->getBufferPointer()) + multiAllocParams.offsets[MDI::EBC_VERTEX_BUFFERS]);
819834

820-
/*
821-
IMGUI Render command lists. We merged all buffers into a single one so we
822-
maintain our own offset into them, we pre-loop to get request data for
823-
MDI buffer alocation request/update.
824-
*/
825-
826835
size_t globalIOffset = {}, globalVOffset = {}, drawID = {};
827836

828837
for (int n = 0; n < drawData->CmdListsCount; n++)
@@ -945,9 +954,22 @@ namespace nbl::ext::imgui
945954
};
946955

947956
commandBuffer->drawIndexedIndirect(binding, drawCount, sizeof(VkDrawIndexedIndirectCommand));
948-
}
949-
assert(m_mdi.streamingTDBufferST->getBuffer()); // make sure no drop
950957

958+
scratchSemaphoreCounters.newie = info.scratchSemaphore.value;
959+
960+
if (scratchSemaphoreCounters.newie != scratchSemaphoreCounters.oldie)
961+
{
962+
const auto overflows = scratchSemaphoreCounters.newie - scratchSemaphoreCounters.oldie;
963+
logger->log("%d overflows when rendering UI!\n", nbl::system::ILogger::ELL_PERFORMANCE, overflows);
964+
965+
// TODO: handle them?
966+
exit(0x45);
967+
}
968+
969+
auto waitInfo = info.getFutureScratchSemaphore();
970+
m_mdi.streamingTDBufferST->multi_deallocate(MDI::MULTI_ALLOC_PARAMS::ALLOCATION_COUNT, multiAllocParams.offsets.data(), multiAllocParams.byteSizes.data(), waitInfo);
971+
}
972+
951973
return true;
952974
}
953975

0 commit comments

Comments
 (0)