Skip to content

Commit 114c079

Browse files
committed
make it compile after saving work, update examples_tests - back to resolving following review comments
1 parent ddee91c commit 114c079

File tree

6 files changed

+93
-67
lines changed

6 files changed

+93
-67
lines changed

3rdparty/CMakeLists.txt

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -391,15 +391,29 @@ string(APPEND NBL_IMPL_IMCONFIG_CONTENT
391391
#include <cstdint>
392392
393393
//! Custom "ImTextureID" info struct for Nabla UI backend purposes about resource sampler & texture descriptor binding's array indicies
394+
//! must be 4 bytes size & alignment to pass imgui static asserts (it checks for contiguous blocks in memory to make sure it can do some memcpies)
394395
struct SImResourceInfo
395396
{
396397
//! 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;
398+
uint32_t textureID : 26;
399+
400+
//! sampler descriptor binding's array index
401+
uint32_t samplerIx : 6;
402+
403+
SImResourceInfo() : textureID(0u), samplerIx(0u) {}
404+
405+
SImResourceInfo(uint32_t texID)
406+
{
407+
textureID = texID;
408+
samplerIx = 0u;
409+
}
410+
411+
explicit operator intptr_t() const
412+
{
413+
return static_cast<intptr_t>(textureID);
414+
}
401415
402-
bool operator==(const SImResourceInfo& other) const
416+
bool operator==(const SImResourceInfo& other) const
403417
{
404418
return textureID == other.textureID;
405419
}

include/nbl/ext/ImGui/ImGui.h

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,18 @@ namespace nbl::ext::imgui
99
class UI final : public core::IReferenceCounted
1010
{
1111
public:
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
12+
//! Reserved font atlas indicies for default backend textures & samplers descriptor binding's array
1313
static constexpr auto FontAtlasTexId = 0u, FontAtlasSamplerId = 0u;
1414

15+
//! 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
16+
enum class DefaultSamplerIx : uint16_t
17+
{
18+
FONT_ATLAS = FontAtlasSamplerId,
19+
USER,
20+
21+
COUNT,
22+
};
23+
1524
struct SMdiBuffer
1625
{
1726
//! composes memory available for the general purpose allocator to suballocate memory ranges
@@ -52,15 +61,6 @@ class UI final : public core::IReferenceCounted
5261
bindingIx;
5362
};
5463

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
57-
{
58-
FONT_ATLAS = FontAtlasSamplerId,
59-
USER,
60-
61-
COUNT,
62-
};
63-
6464
using binding_flags_t = video::IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS;
6565

6666
//! required textures binding creation flags
@@ -90,13 +90,13 @@ class UI final : public core::IReferenceCounted
9090
core::smart_refctd_ptr<video::IUtilities> utilities;
9191

9292
//! optional, default MDI buffer allocated if not provided
93-
core::smart_refctd_ptr<typename SMdiBuffer::compose_t> const streamingBuffer = nullptr;
93+
core::smart_refctd_ptr<typename SMdiBuffer::compose_t> streamingBuffer = nullptr;
9494
};
9595

9696
struct SCreationParameters : public SCachedCreationParams
9797
{
9898
//! required
99-
video::IQueue* const transfer = nullptr;
99+
video::IQueue* transfer = nullptr;
100100

101101
//! required, must declare required UI resources such as textures (required font atlas + optional user defined textures) & samplers
102102
core::smart_refctd_ptr<video::IGPUPipelineLayout> pipelineLayout;
@@ -111,7 +111,7 @@ class UI final : public core::IReferenceCounted
111111
uint32_t subpassIx = 0u;
112112

113113
//! optional, no cache used if not provided
114-
core::smart_refctd_ptr<video::IGPUPipelineCache> const pipelineCache = nullptr;
114+
core::smart_refctd_ptr<video::IGPUPipelineCache> pipelineCache = nullptr;
115115
};
116116

117117
//! 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)
@@ -149,7 +149,7 @@ class UI final : public core::IReferenceCounted
149149
void setContext(void* imguiContext);
150150

151151
//! 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);
152+
static core::smart_refctd_ptr<video::IGPUPipelineLayout> createDefaultPipelineLayout(video::IUtilities* const utilities, const SResourceParameters::SBindingInfo texturesInfo, const SResourceParameters::SBindingInfo samplersInfo, uint32_t texturesCount = 0x45);
153153

154154
//! creation cached parametrs
155155
inline const SCachedCreationParams& getCreationParameters() const { return m_cachedCreationParams; }
@@ -158,7 +158,10 @@ class UI final : public core::IReferenceCounted
158158
inline const video::IGPUGraphicsPipeline* getPipeline() const { return m_pipeline.get(); }
159159

160160
//! image view default font texture
161-
inline const video::IGPUImageView* getFontAtlasView() const { return m_fontAtlasTexture.get(); }
161+
//! TODO: we cannot expose immutable view of our default font texture because user MUST be able to write a descriptor,
162+
//! we can have mutable getter or we can decide to not create any default font texture at all and force users
163+
//! to do it externally (have a static helper to do it which gives you mutable view)
164+
inline video::IGPUImageView* getFontAtlasView() const { return m_fontAtlasTexture.get(); }
162165

163166
//! mdi streaming buffer
164167
inline const typename SMdiBuffer::compose_t* getStreamingBuffer() const { return m_mdi.compose.get(); }

src/nbl/ext/ImGui/ImGui.cpp

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ namespace nbl::ext::imgui
4343
return nullptr;
4444

4545
if (texturesInfo.bindingIx == samplersInfo.bindingIx)
46-
return false;
46+
return nullptr;
4747

4848
if (!texturesCount)
4949
return nullptr;
@@ -75,9 +75,9 @@ namespace nbl::ext::imgui
7575
}
7676

7777
//! note we use immutable separate samplers and they are part of the descriptor set layout
78-
std::array<core::smart_refctd_ptr<IGPUSampler>, (uint32_t)SResourceParameters::DefaultSamplerIx::COUNT> immutableSamplers;
79-
immutableSamplers[(uint32_t)SResourceParameters::DefaultSamplerIx::FONT_ATLAS] = smart_refctd_ptr(fontAtlasUISampler);
80-
immutableSamplers[(uint32_t)SResourceParameters::DefaultSamplerIx::USER] = smart_refctd_ptr(userTexturesSampler);
78+
std::array<core::smart_refctd_ptr<IGPUSampler>, (uint32_t)DefaultSamplerIx::COUNT> immutableSamplers;
79+
immutableSamplers[(uint32_t)DefaultSamplerIx::FONT_ATLAS] = smart_refctd_ptr(fontAtlasUISampler);
80+
immutableSamplers[(uint32_t)DefaultSamplerIx::USER] = smart_refctd_ptr(userTexturesSampler);
8181

8282
auto textureBinding = IGPUDescriptorSetLayout::SBinding
8383
{
@@ -184,11 +184,12 @@ namespace nbl::ext::imgui
184184
std::stringstream stream;
185185

186186
stream << "// -> this code has been autogenerated with Nabla ImGUI extension\n"
187-
<< "#define NBL_TEXTURES_BINDING_IX " << creationParams.resources.textures.bindingIx << "\n"
188-
<< "#define NBL_SAMPLER_STATES_BINDING_IX " << creationParams.resources.samplers.bindingIx << "\n"
189-
<< "#define NBL_TEXTURES_SET_IX " << creationParams.resources.textures.setIx << "\n"
190-
<< "#define NBL_SAMPLER_STATES_SET_IX " << creationParams.resources.samplers.setIx << "\n"
191-
<< "#define NBL_RESOURCES_COUNT " << creationParams.resources.count << "\n"
187+
<< "#define NBL_TEXTURES_BINDING_IX " << creationParams.resources.texturesInfo.bindingIx << "\n"
188+
<< "#define NBL_SAMPLER_STATES_BINDING_IX " << creationParams.resources.samplersInfo.bindingIx << "\n"
189+
<< "#define NBL_TEXTURES_SET_IX " << creationParams.resources.texturesInfo.setIx << "\n"
190+
<< "#define NBL_SAMPLER_STATES_SET_IX " << creationParams.resources.samplersInfo.setIx << "\n"
191+
<< "#define NBL_TEXTURES_COUNT " << creationParams.resources.texturesCount << "\n"
192+
<< "#define NBL_SAMPLERS_COUNT " << creationParams.resources.samplersCount << "\n"
192193
<< "// <-\n\n";
193194

194195
const auto newCode = stream.str() + std::string(code);
@@ -329,7 +330,11 @@ namespace nbl::ext::imgui
329330
uint8_t* pixels = nullptr;
330331
int32_t width, height;
331332
io.Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
332-
io.Fonts->SetTexID({ .textureID = FontAtlasTexId, .samplerID = FontAtlasSamplerId });
333+
SImResourceInfo info;
334+
info.textureID = FontAtlasTexId;
335+
info.samplerIx = FontAtlasSamplerId;
336+
337+
io.Fonts->SetTexID(info);
333338

334339
if (!pixels || width<=0 || height<=0)
335340
return IQueue::RESULT::OTHER_ERROR;
@@ -381,15 +386,13 @@ namespace nbl::ext::imgui
381386
m_cachedCreationParams.utilities->getLogger()->log("Could not create font image!", system::ILogger::ELL_ERROR);
382387
return IQueue::RESULT::OTHER_ERROR;
383388
}
384-
image->setObjectDebugName("Nabla IMGUI extension Font Image");
389+
image->setObjectDebugName("Nabla ImGUI default font");
385390

386391
if (!m_cachedCreationParams.utilities->getLogicalDevice()->allocate(image->getMemoryReqs(), image.get()).isValid())
387392
{
388393
m_cachedCreationParams.utilities->getLogger()->log("Could not allocate memory for font image!", system::ILogger::ELL_ERROR);
389394
return IQueue::RESULT::OTHER_ERROR;
390395
}
391-
392-
image->setObjectDebugName("Nabla IMGUI extension Font Atlas");
393396

394397
SIntendedSubmitInfo sInfo;
395398
{
@@ -1023,15 +1026,15 @@ namespace nbl::ext::imgui
10231026
for (uint32_t i = 0; i < drawData->CmdListsCount; i++)
10241027
{
10251028
const ImDrawList* commandList = drawData->CmdLists[i];
1026-
params.bytesToFill[SMdiBuffer::Content::INDIRECT_STRUCTURES] += commandList->CmdBuffer.Size * sizeof(VkDrawIndexedIndirectCommand);
1027-
params.bytesToFill[SMdiBuffer::Content::ELEMENT_STRUCTURES] += commandList->CmdBuffer.Size * sizeof(PerObjectData);
1029+
params.bytesToFill[static_cast<std::underlying_type_t<SMdiBuffer::Content>>(SMdiBuffer::Content::INDIRECT_STRUCTURES)] += commandList->CmdBuffer.Size * sizeof(VkDrawIndexedIndirectCommand);
1030+
params.bytesToFill[static_cast<std::underlying_type_t<SMdiBuffer::Content>>(SMdiBuffer::Content::ELEMENT_STRUCTURES)] += commandList->CmdBuffer.Size * sizeof(PerObjectData);
10281031
}
1029-
params.bytesToFill[SMdiBuffer::Content::VERTEX_BUFFERS] = drawData->TotalVtxCount * sizeof(ImDrawVert);
1030-
params.bytesToFill[SMdiBuffer::Content::INDEX_BUFFERS] = drawData->TotalIdxCount * sizeof(ImDrawIdx);
1032+
params.bytesToFill[static_cast<std::underlying_type_t<SMdiBuffer::Content>>(SMdiBuffer::Content::VERTEX_BUFFERS)] = drawData->TotalVtxCount * sizeof(ImDrawVert);
1033+
params.bytesToFill[static_cast<std::underlying_type_t<SMdiBuffer::Content>>(SMdiBuffer::Content::INDEX_BUFFERS)] = drawData->TotalIdxCount * sizeof(ImDrawIdx);
10311034

10321035
// calculate upper bound byte size limit for mdi buffer
10331036
params.totalByteSizeRequest = std::reduce(std::begin(params.bytesToFill), std::end(params.bytesToFill));
1034-
params.drawCount = params.bytesToFill[SMdiBuffer::Content::INDIRECT_STRUCTURES] / sizeof(VkDrawIndexedIndirectCommand);
1037+
params.drawCount = params.bytesToFill[static_cast<std::underlying_type_t<SMdiBuffer::Content>>(SMdiBuffer::Content::INDIRECT_STRUCTURES)] / sizeof(VkDrawIndexedIndirectCommand);
10351038

10361039
return std::move(params);
10371040
}();
@@ -1092,9 +1095,10 @@ namespace nbl::ext::imgui
10921095

10931096
auto fillDrawBuffers = [&]<SMdiBuffer::Content type>()
10941097
{
1095-
const mdi_size_t globalBlockOffset = offsets[type];
1098+
const auto underlying_type = static_cast<std::underlying_type_t<SMdiBuffer::Content>>(type);
1099+
const mdi_size_t globalBlockOffset = offsets[underlying_type];
10961100

1097-
if (globalBlockOffset == InvalidAddress or mdiBytesFilled[type])
1101+
if (globalBlockOffset == InvalidAddress or mdiBytesFilled[underlying_type])
10981102
return 0u;
10991103

11001104
auto* data = mdiData + globalBlockOffset;
@@ -1117,16 +1121,17 @@ namespace nbl::ext::imgui
11171121
}
11181122
}
11191123

1120-
mdiBytesFilled[type] = true;
1121-
mdiOffsets[type] = globalBlockOffset;
1122-
return mdiParams.bytesToFill[type];
1124+
mdiBytesFilled[underlying_type] = true;
1125+
mdiOffsets[underlying_type] = globalBlockOffset;
1126+
return mdiParams.bytesToFill[underlying_type];
11231127
};
11241128

11251129
auto fillIndirectStructures = [&]<SMdiBuffer::Content type>()
11261130
{
1127-
const mdi_size_t globalBlockOffset = offsets[type];
1131+
const auto underlying_type = static_cast<std::underlying_type_t<SMdiBuffer::Content>>(type);
1132+
const mdi_size_t globalBlockOffset = offsets[underlying_type];
11281133

1129-
if (globalBlockOffset == InvalidAddress or mdiBytesFilled[type])
1134+
if (globalBlockOffset == InvalidAddress or mdiBytesFilled[underlying_type])
11301135
return 0u;
11311136

11321137
auto* const data = mdiData + globalBlockOffset;
@@ -1169,7 +1174,8 @@ namespace nbl::ext::imgui
11691174
element->aabbMin.y = packSnorm16(vMin.y);
11701175
element->aabbMax.x = packSnorm16(vMax.x);
11711176
element->aabbMax.y = packSnorm16(vMax.y);
1172-
element->texId = pcmd->TextureId;
1177+
element->texId = pcmd->TextureId.textureID;
1178+
element->samplerIx = pcmd->TextureId.samplerIx;
11731179
}
11741180

11751181
++drawID;
@@ -1179,9 +1185,9 @@ namespace nbl::ext::imgui
11791185
cmdListVertexObjectOffset += cmd_list->VtxBuffer.Size;
11801186
}
11811187

1182-
mdiBytesFilled[type] = true;
1183-
mdiOffsets[type] = globalBlockOffset;
1184-
return mdiParams.bytesToFill[type];
1188+
mdiBytesFilled[underlying_type] = true;
1189+
mdiOffsets[underlying_type] = globalBlockOffset;
1190+
return mdiParams.bytesToFill[underlying_type];
11851191
};
11861192

11871193
//! from biggest requests to smallest
@@ -1203,12 +1209,12 @@ namespace nbl::ext::imgui
12031209
return true;
12041210
}()); // debug check only
12051211

1206-
auto mdiBuffer = smart_refctd_ptr<IGPUBuffer>(m_mdi.buffer->getBuffer());
1212+
auto mdiBuffer = smart_refctd_ptr<IGPUBuffer>(m_mdi.compose->getBuffer());
12071213
const auto offset = mdiBuffer->getBoundMemory().offset;
12081214
{
12091215
const asset::SBufferBinding<const video::IGPUBuffer> binding =
12101216
{
1211-
.offset = mdiOffsets[MDI::EBC_INDEX_BUFFERS],
1217+
.offset = mdiOffsets[static_cast<std::underlying_type_t<SMdiBuffer::Content>>(SMdiBuffer::Content::INDEX_BUFFERS)],
12121218
.buffer = smart_refctd_ptr(mdiBuffer)
12131219
};
12141220

@@ -1222,7 +1228,7 @@ namespace nbl::ext::imgui
12221228
{
12231229
const asset::SBufferBinding<const video::IGPUBuffer> bindings[] =
12241230
{{
1225-
.offset = mdiOffsets[MDI::EBC_VERTEX_BUFFERS],
1231+
.offset = mdiOffsets[static_cast<std::underlying_type_t<SMdiBuffer::Content>>(SMdiBuffer::Content::VERTEX_BUFFERS)],
12261232
.buffer = smart_refctd_ptr(mdiBuffer)
12271233
}};
12281234

@@ -1262,19 +1268,19 @@ namespace nbl::ext::imgui
12621268
{
12631269
PushConstants constants
12641270
{
1265-
.elementBDA = { mdiBuffer->getDeviceAddress() + mdiOffsets[MDI::EBC_ELEMENT_STRUCTURES]},
1271+
.elementBDA = { mdiBuffer->getDeviceAddress() + mdiOffsets[static_cast<std::underlying_type_t<SMdiBuffer::Content>>( SMdiBuffer::Content::ELEMENT_STRUCTURES )]},
12661272
.elementCount = { mdiParams.drawCount },
12671273
.scale = { trs.scale[0u], trs.scale[1u] },
12681274
.translate = { trs.translate[0u], trs.translate[1u] },
12691275
.viewport = { viewport.x, viewport.y, viewport.width, viewport.height }
12701276
};
12711277

1272-
commandBuffer->pushConstants(pipeline->getLayout(), IShader::E_SHADER_STAGE::ESS_VERTEX | IShader::E_SHADER_STAGE::ESS_FRAGMENT, 0u, sizeof(constants), &constants);
1278+
commandBuffer->pushConstants(m_pipeline->getLayout(), IShader::E_SHADER_STAGE::ESS_VERTEX | IShader::E_SHADER_STAGE::ESS_FRAGMENT, 0u, sizeof(constants), &constants);
12731279
}
12741280

12751281
const asset::SBufferBinding<const video::IGPUBuffer> binding =
12761282
{
1277-
.offset = mdiOffsets[MDI::EBC_DRAW_INDIRECT_STRUCTURES],
1283+
.offset = mdiOffsets[static_cast<std::underlying_type_t<SMdiBuffer::Content>>(SMdiBuffer::Content::INDIRECT_STRUCTURES)],
12781284
.buffer = core::smart_refctd_ptr(mdiBuffer)
12791285
};
12801286

@@ -1284,7 +1290,7 @@ namespace nbl::ext::imgui
12841290
return true;
12851291
}
12861292

1287-
bool UI::update(const S_UPDATE_PARAMETERS& params)
1293+
bool UI::update(const SUpdateParameters& params)
12881294
{
12891295
auto & io = ImGui::GetIO();
12901296

src/nbl/ext/ImGui/shaders/common.hlsl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,12 @@ struct emulated_snorm16_t2
4444
}
4545
#endif
4646

47-
int16_t x;
48-
int16_t y;
47+
int16_t x, y;
4948
};
5049

5150
struct PerObjectData
5251
{
53-
emulated_snorm16_t2 aabbMin;
54-
emulated_snorm16_t2 aabbMax;
55-
uint16_t texId;
52+
emulated_snorm16_t2 aabbMin, aabbMax;
53+
uint16_t texId : 14;
54+
uint16_t samplerIx : 2;
5655
};

src/nbl/ext/ImGui/shaders/fragment.hlsl

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@
1414
#error "NBL_SAMPLER_STATES_SET_IX must be defined!"
1515
#endif
1616

17-
#ifndef NBL_RESOURCES_COUNT
18-
#error "NBL_RESOURCES_COUNT must be defined!"
17+
#ifndef NBL_TEXTURES_COUNT
18+
#error "NBL_TEXTURES_COUNT must be defined!"
19+
#endif
20+
21+
#ifndef NBL_SAMPLERS_COUNT
22+
#error "NBL_SAMPLERS_COUNT must be defined!"
1923
#endif
2024

2125
#include "common.hlsl"
2226

2327
[[vk::push_constant]] struct PushConstants pc;
2428

2529
// separable image samplers to handle textures we do descriptor-index
26-
[[vk::binding(NBL_TEXTURES_BINDING_IX, NBL_TEXTURES_SET_IX)]] Texture2D textures[NBL_RESOURCES_COUNT];
27-
[[vk::binding(NBL_SAMPLER_STATES_BINDING_IX, NBL_SAMPLER_STATES_SET_IX)]] SamplerState samplerStates[NBL_RESOURCES_COUNT];
30+
[[vk::binding(NBL_TEXTURES_BINDING_IX, NBL_TEXTURES_SET_IX)]] Texture2D textures[NBL_TEXTURES_COUNT];
31+
[[vk::binding(NBL_SAMPLER_STATES_BINDING_IX, NBL_SAMPLER_STATES_SET_IX)]] SamplerState samplerStates[NBL_SAMPLERS_COUNT];
2832

2933
/*
3034
we use Indirect Indexed draw call to render whole GUI, note we do a cross
@@ -37,5 +41,5 @@ float4 PSMain(PSInput input) : SV_Target0
3741
// BDA for requesting object data
3842
const PerObjectData self = vk::RawBufferLoad<PerObjectData>(pc.elementBDA + sizeof(PerObjectData)* input.drawID);
3943

40-
return textures[NonUniformResourceIndex(self.texId)].Sample(samplerStates[self.texId], input.uv) * input.color;
44+
return textures[NonUniformResourceIndex(self.texId)].Sample(samplerStates[self.samplerIx], input.uv) * input.color;
4145
}

0 commit comments

Comments
 (0)