Skip to content

Commit ddee91c

Browse files
committed
save work, resolved 19 comments
1 parent db8248e commit ddee91c

File tree

3 files changed

+383
-267
lines changed

3 files changed

+383
-267
lines changed

3rdparty/CMakeLists.txt

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,48 @@ string(APPEND NBL_IMPL_IMCONFIG_CONTENT
389389
390390
// note we override it with default imguis (void*) type
391391
#include <cstdint>
392-
#define ImTextureID uint32_t
392+
393+
//! Custom "ImTextureID" info struct for Nabla UI backend purposes about resource sampler & texture descriptor binding's array indicies
394+
struct SImResourceInfo
395+
{
396+
//! texture descriptor binding's array index
397+
uint16_t textureID : 14,
398+
399+
//! sampler descriptor binding's array index, note its only meta for the texture for which we define operators to compare to (so you can specify which sampler ID should be used from the binding array)
400+
samplerID : 2;
401+
402+
bool operator==(const SImResourceInfo& other) const
403+
{
404+
return textureID == other.textureID;
405+
}
406+
407+
bool operator!=(const SImResourceInfo& other) const
408+
{
409+
return textureID != other.textureID;
410+
}
411+
412+
bool operator<(const SImResourceInfo& other) const
413+
{
414+
return textureID < other.textureID;
415+
}
416+
417+
bool operator>(const SImResourceInfo& other) const
418+
{
419+
return textureID > other.textureID;
420+
}
421+
422+
bool operator<=(const SImResourceInfo& other) const
423+
{
424+
return textureID <= other.textureID;
425+
}
426+
427+
bool operator>=(const SImResourceInfo& other) const
428+
{
429+
return textureID >= other.textureID;
430+
}
431+
};
432+
433+
#define ImTextureID SImResourceInfo
393434
#define IMGUI_ENABLE_FREETYPE
394435
#define IMGUI_DISABLE_OBSOLETE_KEYIO
395436
#undef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // but remove this cuz it break things

include/nbl/ext/ImGui/ImGui.h

Lines changed: 115 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -9,124 +9,175 @@ namespace nbl::ext::imgui
99
class UI final : public core::IReferenceCounted
1010
{
1111
public:
12-
struct MDI
12+
//! Reserved font atlas indicies for backend textures & samplers descriptor binding's array, any attempt to hook user defined texture ID == FontAtlasTexId will result in undefined behaviour
13+
static constexpr auto FontAtlasTexId = 0u, FontAtlasSamplerId = 0u;
14+
15+
struct SMdiBuffer
1316
{
14-
using COMPOSE_T = nbl::video::StreamingTransientDataBufferST<nbl::core::allocator<uint8_t>>; //! composes memory available for the general purpose allocator to suballocate memory ranges
15-
using SUBALLOCATOR_TRAITS_T = nbl::core::address_allocator_traits<nbl::core::LinearAddressAllocatorST<uint32_t>>; //! traits for MDI buffer suballocator - fills the data given the mdi allocator memory request
17+
//! composes memory available for the general purpose allocator to suballocate memory ranges
18+
using compose_t = video::StreamingTransientDataBufferST<core::allocator<uint8_t>>;
19+
20+
//! traits for MDI buffer suballocator - fills the data given the mdi allocator memory request
21+
using suballocator_traits_t = core::address_allocator_traits<core::LinearAddressAllocatorST<uint32_t>>;
1622

17-
enum E_BUFFER_CONTENT : uint8_t
23+
enum class Content : uint16_t
1824
{
19-
EBC_DRAW_INDIRECT_STRUCTURES,
20-
EBC_ELEMENT_STRUCTURES,
21-
EBC_INDEX_BUFFERS,
22-
EBC_VERTEX_BUFFERS,
25+
INDIRECT_STRUCTURES,
26+
ELEMENT_STRUCTURES,
27+
INDEX_BUFFERS,
28+
VERTEX_BUFFERS,
2329

24-
EBC_COUNT,
30+
COUNT,
2531
};
2632

27-
nbl::core::smart_refctd_ptr<typename COMPOSE_T> buffer; //! streaming mdi buffer
33+
//! streaming mdi buffer
34+
core::smart_refctd_ptr<typename compose_t> compose;
2835

29-
static constexpr auto MDI_BUFFER_REQUIRED_ALLOCATE_FLAGS = nbl::core::bitflag<nbl::video::IDeviceMemoryAllocation::E_MEMORY_ALLOCATE_FLAGS>(nbl::video::IDeviceMemoryAllocation::EMAF_DEVICE_ADDRESS_BIT); //! required flags
30-
static constexpr auto MDI_BUFFER_REQUIRED_USAGE_FLAGS = nbl::core::bitflag(nbl::asset::IBuffer::EUF_INDIRECT_BUFFER_BIT) | nbl::asset::IBuffer::EUF_INDEX_BUFFER_BIT | nbl::asset::IBuffer::EUF_VERTEX_BUFFER_BIT | nbl::asset::IBuffer::EUF_SHADER_DEVICE_ADDRESS_BIT; //! required flags
36+
//! required buffer allocate flags
37+
static constexpr auto RequiredAllocateFlags = core::bitflag<video::IDeviceMemoryAllocation::E_MEMORY_ALLOCATE_FLAGS>(video::IDeviceMemoryAllocation::EMAF_DEVICE_ADDRESS_BIT);
38+
39+
//! required buffer usage flags
40+
static constexpr auto RequiredUsageFlags = core::bitflag(asset::IBuffer::EUF_INDIRECT_BUFFER_BIT) | asset::IBuffer::EUF_INDEX_BUFFER_BIT | asset::IBuffer::EUF_VERTEX_BUFFER_BIT | asset::IBuffer::EUF_SHADER_DEVICE_ADDRESS_BIT;
3141
};
3242

33-
struct S_CREATION_PARAMETERS
43+
struct SResourceParameters
3444
{
35-
struct S_RESOURCE_PARAMETERS
45+
//! for a given pipeline layout we need to know what is intended for UI resources
46+
struct SBindingInfo
47+
{
48+
//! descriptor set index for a resource
49+
uint32_t setIx,
50+
51+
//! binding index for a given resource
52+
bindingIx;
53+
};
54+
55+
//! Reserved indexes for default backend samplers descriptor binding's array - use only if you created your pipeline layout with createDefaultPipelineLayout. If you need more or custom samplers then create the pipeline layout yourself
56+
enum class DefaultSamplerIx : uint16_t
3657
{
37-
nbl::video::IGPUPipelineLayout* const pipelineLayout = nullptr; //! optional, default layout used if not provided declaring required UI resources such as textures (required font atlas + optional user defined textures) & corresponding samplers
38-
uint32_t count = 0x45u; //! amount of total UI textures (and corresponding samplers)
39-
40-
struct S_BINDING_REQUEST_INFO //! for a given pipeline layout we need to know what is intended for UI resources
41-
{
42-
uint32_t setIx, //! descriptor set index for a resource
43-
bindingIx; //! binding index for a given resource
44-
};
45-
46-
const S_BINDING_REQUEST_INFO textures = { .setIx = 0u, .bindingIx = 0u }, //! optional, default texture binding request info used if not provided (set & binding index)
47-
samplers = { .setIx = 0u, .bindingIx = 1u }; //! optional, default sampler binding request info used if not provided (set & binding index)
48-
49-
using binding_flags_t = nbl::video::IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS;
50-
static constexpr auto TEXTURES_REQUIRED_CREATE_FLAGS = nbl::core::bitflag(binding_flags_t::ECF_UPDATE_AFTER_BIND_BIT) | binding_flags_t::ECF_PARTIALLY_BOUND_BIT | binding_flags_t::ECF_UPDATE_UNUSED_WHILE_PENDING_BIT; //! required flags
51-
static constexpr auto SAMPLERS_REQUIRED_CREATE_FLAGS = nbl::core::bitflag(binding_flags_t::ECF_NONE); //! required flags
52-
static constexpr auto RESOURCES_REQUIRED_STAGE_FLAGS = nbl::asset::IShader::E_SHADER_STAGE::ESS_FRAGMENT; //! required stage
58+
FONT_ATLAS = FontAtlasSamplerId,
59+
USER,
60+
61+
COUNT,
5362
};
5463

55-
nbl::asset::IAssetManager* const assetManager; //! required
56-
nbl::video::IUtilities* const utilities; //! required
57-
nbl::video::IQueue* const transfer; //! required
58-
nbl::video::IGPURenderpass* const renderpass; //! required
59-
uint32_t subpassIx = 0u; //! optional, default value used if not provided
60-
S_RESOURCE_PARAMETERS resources; //! optional, default parameters used if not provided
61-
nbl::video::IGPUPipelineCache* const pipelineCache = nullptr; //! optional, no cache used if not provided
62-
typename MDI::COMPOSE_T* const streamingBuffer = nullptr; //! optional, default MDI buffer allocated if not provided
64+
using binding_flags_t = video::IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS;
65+
66+
//! required textures binding creation flags
67+
static constexpr auto TexturesRequiredCreateFlags = core::bitflag(binding_flags_t::ECF_UPDATE_AFTER_BIND_BIT) | binding_flags_t::ECF_PARTIALLY_BOUND_BIT | binding_flags_t::ECF_UPDATE_UNUSED_WHILE_PENDING_BIT;
68+
69+
//! required samplers binding creation flags
70+
static constexpr auto SamplersRequiredCreateFlags = core::bitflag(binding_flags_t::ECF_UPDATE_AFTER_BIND_BIT);
71+
72+
//! required shader stage flags
73+
static constexpr auto RequiredShaderStageFlags = asset::IShader::E_SHADER_STAGE::ESS_FRAGMENT;
74+
75+
//! required, fill the info to instruct the backend about the required UI resources
76+
SBindingInfo texturesInfo, samplersInfo;
77+
78+
private:
79+
uint32_t texturesCount, samplersCount;
80+
81+
friend class UI;
82+
};
83+
84+
struct SCachedCreationParams
85+
{
86+
//! required, you provide us information about your required UI binding resources which we validate at creation time
87+
SResourceParameters resources;
88+
89+
//! required
90+
core::smart_refctd_ptr<video::IUtilities> utilities;
91+
92+
//! optional, default MDI buffer allocated if not provided
93+
core::smart_refctd_ptr<typename SMdiBuffer::compose_t> const streamingBuffer = nullptr;
94+
};
95+
96+
struct SCreationParameters : public SCachedCreationParams
97+
{
98+
//! required
99+
video::IQueue* const transfer = nullptr;
100+
101+
//! required, must declare required UI resources such as textures (required font atlas + optional user defined textures) & samplers
102+
core::smart_refctd_ptr<video::IGPUPipelineLayout> pipelineLayout;
103+
104+
//! required
105+
core::smart_refctd_ptr<asset::IAssetManager> assetManager = nullptr;
106+
107+
//! required
108+
core::smart_refctd_ptr<video::IGPURenderpass> renderpass = nullptr;
109+
110+
//! optional, default value used if not provided
111+
uint32_t subpassIx = 0u;
112+
113+
//! optional, no cache used if not provided
114+
core::smart_refctd_ptr<video::IGPUPipelineCache> const pipelineCache = nullptr;
63115
};
64116

65117
//! parameters which may change every frame, used with the .update call to interact with ImGuiIO; we require a very *required* minimum - if you need to cover more IO options simply get the IO with ImGui::GetIO() to customize them (they all have default values you can change before calling the .update)
66-
struct S_UPDATE_PARAMETERS
118+
struct SUpdateParameters
67119
{
68120
//! what we pass to ImGuiIO::AddMousePosEvent
69-
nbl::hlsl::float32_t2 mousePosition,
121+
hlsl::float32_t2 mousePosition,
70122

71123
//! main display size in pixels
72124
displaySize;
73125

74-
//! Nabla events you want to be handled with the backend
75-
struct S_EVENTS
76-
{
77-
core::SRange<const nbl::ui::SMouseEvent> mouse;
78-
core::SRange<const nbl::ui::SKeyboardEvent> keyboard;
79-
};
126+
//! Nabla mouse events you want to be handled with the backend
127+
std::span<const ui::SMouseEvent> mouseEvents = {};
80128

81-
S_EVENTS events;
129+
//! Nabla keyboard events you want to be handled with the backend
130+
std::span<const ui::SKeyboardEvent> keyboardEvents = {};
82131
};
83132

84-
UI(S_CREATION_PARAMETERS&& params);
133+
UI(SCreationParameters&& params);
85134
~UI() override;
86135

87-
//! Nabla ImGUI backend reserves this index for font atlas, any attempt to hook user defined texture within the index will result in undefined behaviour
88-
static constexpr auto NBL_FONT_ATLAS_TEX_ID = 0u;
89-
90136
//! updates ImGuiIO & records ImGUI *cpu* draw command lists, you have to call it before .render
91-
bool update(const S_UPDATE_PARAMETERS& params);
137+
bool update(const SUpdateParameters& params);
92138

93139
//! 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
94-
bool render(nbl::video::IGPUCommandBuffer* const commandBuffer, nbl::video::ISemaphore::SWaitInfo waitInfo, const std::span<const VkRect2D> scissors = {});
140+
bool render(video::IGPUCommandBuffer* const commandBuffer, video::ISemaphore::SWaitInfo waitInfo, const std::span<const VkRect2D> scissors = {});
95141

96-
//! registers lambda listener in which ImGUI calls should be recorded
142+
//! registers lambda listener in which ImGUI calls should be recorded, use the returned id to unregister the listener
97143
size_t registerListener(std::function<void()> const& listener);
144+
145+
//! unregisters listener with the given id
98146
std::optional<size_t> unregisterListener(size_t id);
99147

100148
//! sets ImGUI context, you are supposed to pass valid ImGuiContext* context
101149
void setContext(void* imguiContext);
102150

103-
//! creation parametrs
104-
inline const S_CREATION_PARAMETERS& getCreationParameters() const { return m_creationParams; }
151+
//! creates default pipeline layout for the UI resources, "texturesCount" argument is textures descriptor binding's array size. Samplers are immutable and part of the created layout, SResourceParameters::DefaultSamplerIx::COUNT is the size of the samplers descriptor binding's array
152+
static core::smart_refctd_ptr<video::IGPUPipelineLayout> createDefaultPipelineLayout(video::IUtilities* const utilities, const SResourceParameters::SBindingInfo texturesInfo = { .setIx = 0u, .bindingIx = 0u }, const SResourceParameters::SBindingInfo samplersInfo = { .setIx = 0u, .bindingIx = 1u }, uint32_t texturesCount = 0x45);
153+
154+
//! creation cached parametrs
155+
inline const SCachedCreationParams& getCreationParameters() const { return m_cachedCreationParams; }
105156

106157
//! ImGUI graphics pipeline
107-
inline nbl::video::IGPUGraphicsPipeline* getPipeline() { return pipeline.get(); }
158+
inline const video::IGPUGraphicsPipeline* getPipeline() const { return m_pipeline.get(); }
108159

109160
//! image view default font texture
110-
inline nbl::video::IGPUImageView* getFontAtlasView() { return m_fontAtlasTexture.get(); }
161+
inline const video::IGPUImageView* getFontAtlasView() const { return m_fontAtlasTexture.get(); }
111162

112163
//! mdi streaming buffer
113-
inline typename MDI::COMPOSE_T* getStreamingBuffer() { return m_mdi.buffer.get(); }
164+
inline const typename SMdiBuffer::compose_t* getStreamingBuffer() const { return m_mdi.compose.get(); }
114165

115166
//! ImGUI context, you are supposed to cast it, eg. reinterpret_cast<ImGuiContext*>(this->getContext());
116167
void* getContext();
117168
private:
118169
void createPipeline();
119170
void createMDIBuffer();
120-
void handleMouseEvents(const S_UPDATE_PARAMETERS& params) const;
121-
void handleKeyEvents(const S_UPDATE_PARAMETERS& params) const;
171+
void handleMouseEvents(const SUpdateParameters& params) const;
172+
void handleKeyEvents(const SUpdateParameters& params) const;
122173
video::ISemaphore::future_t<video::IQueue::RESULT> createFontAtlasTexture(video::IGPUCommandBuffer* cmdBuffer);
123174

124-
S_CREATION_PARAMETERS m_creationParams;
175+
SCachedCreationParams m_cachedCreationParams;
125176

126-
core::smart_refctd_ptr<video::IGPUGraphicsPipeline> pipeline;
177+
core::smart_refctd_ptr<video::IGPUGraphicsPipeline> m_pipeline;
127178
core::smart_refctd_ptr<video::IGPUImageView> m_fontAtlasTexture;
128179

129-
MDI m_mdi;
180+
SMdiBuffer m_mdi;
130181
std::vector<std::function<void()>> m_subscribers {};
131182
};
132183
}

0 commit comments

Comments
 (0)