Skip to content

Commit

Permalink
update Nabla IMGUI backend to use separated immutable sampler with fo…
Browse files Browse the repository at this point in the history
…nt atlas as 2D array texture, use BDA for requesting texture index. Add comments regarding our base instance indexing as replacement for gl_DrawID and a few more comments + minor changes
  • Loading branch information
AnastaZIuk committed Jul 11, 2024
1 parent e9ac293 commit a7102f0
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 49 deletions.
6 changes: 3 additions & 3 deletions include/nbl/ext/ImGui/ImGui.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ class UI final : public core::IReferenceCounted
private:
core::smart_refctd_ptr<video::IGPUDescriptorSetLayout> createDescriptorSetLayout();
void createPipeline(video::IGPURenderpass* renderpass, video::IGPUPipelineCache* pipelineCache);
void createFontTexture(video::IGPUCommandBuffer* cmdBuffer, video::IQueue* queue);
void createFontAtlas2DArrayTexture(video::IGPUCommandBuffer* cmdBuffer, video::IQueue* queue);
void updateDescriptorSets();
void createSystem();
void createFontSampler();
void createFontAtlasSampler();
void createDescriptorPool();
void handleMouseEvents(float mousePosX, float mousePosY, size_t mouseEventsCount, ui::SMouseEvent const * mouseEvents) const;

Expand All @@ -36,7 +36,7 @@ class UI final : public core::IReferenceCounted
core::smart_refctd_ptr<video::IDescriptorPool> m_descriptorPool;
core::smart_refctd_ptr<video::IGPUDescriptorSet> m_gpuDescriptorSet;
core::smart_refctd_ptr<video::IGPUGraphicsPipeline> pipeline;
core::smart_refctd_ptr<video::IGPUImageView> m_fontTexture;
core::smart_refctd_ptr<video::IGPUImageView> m_fontAtlas2DArrayTexture;
core::smart_refctd_ptr<ui::IWindow> m_window;
std::vector<core::smart_refctd_ptr<video::IGPUBuffer>> m_mdiBuffers;
const uint32_t maxFramesInFlight;
Expand Down
87 changes: 45 additions & 42 deletions src/nbl/ext/ImGui/ImGui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,23 @@ namespace nbl::ext::imgui
{
smart_refctd_ptr<IGPUDescriptorSetLayout> UI::createDescriptorSetLayout()
{
nbl::video::IGPUDescriptorSetLayout::SBinding bindings[] =
{
const IGPUDescriptorSetLayout::SBinding bindings[] =
{
{
.binding = 0u,
.type = asset::IDescriptor::E_TYPE::ET_COMBINED_IMAGE_SAMPLER,
.type = IDescriptor::E_TYPE::ET_SAMPLED_IMAGE,
.createFlags = IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_NONE,
.stageFlags = IShader::ESS_FRAGMENT,
.count = 1u,
.immutableSamplers = &m_fontSampler
},
{
.binding = 1u,
.type = IDescriptor::E_TYPE::ET_SAMPLER,
.createFlags = IGPUDescriptorSetLayout::SBinding::E_CREATE_FLAGS::ECF_NONE,
.stageFlags = IShader::ESS_FRAGMENT,
.count = 1,
.samplers = nullptr // TODO: m_fontSampler?
.count = 1u,
.immutableSamplers = &m_fontSampler
}
};

Expand All @@ -45,7 +53,7 @@ namespace nbl::ext::imgui
{
{
.stageFlags = IShader::ESS_VERTEX | IShader::ESS_FRAGMENT,
.offset = 0,
.offset = 0u,
.size = sizeof(PushConstants)
}
};
Expand Down Expand Up @@ -141,7 +149,7 @@ namespace nbl::ext::imgui

IGPUGraphicsPipeline::SCreationParams params[1];
{
auto& param = params[0];
auto& param = params[0u];
param.layout = pipelineLayout.get();
param.shaders = specs;
param.renderpass = renderpass;
Expand All @@ -156,7 +164,7 @@ namespace nbl::ext::imgui
}
}

void UI::createFontTexture(video::IGPUCommandBuffer* cmdBuffer, video::IQueue* transfer)
void UI::createFontAtlas2DArrayTexture(video::IGPUCommandBuffer* cmdBuffer, video::IQueue* transfer)
{
// Load Fonts
// - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them.
Expand Down Expand Up @@ -215,7 +223,7 @@ namespace nbl::ext::imgui
region->imageSubresource = {};
region->imageSubresource.aspectMask = IImage::EAF_COLOR_BIT;
region->imageSubresource.layerCount = 1u;
region->imageOffset = { 0, 0, 0 };
region->imageOffset = { 0u, 0u, 0u };
region->imageExtent = { params.extent.width, params.extent.height, 1u };
}

Expand All @@ -233,7 +241,7 @@ namespace nbl::ext::imgui
assert(false);
}

image->setObjectDebugName("Nabla IMGUI extension Font Image");
image->setObjectDebugName("Nabla IMGUI extension Font Atlas");
{
IQueue::SSubmitInfo::SCommandBufferInfo cmdInfo = { cmdBuffer };
SIntendedSubmitInfo sInfo;
Expand All @@ -248,11 +256,11 @@ namespace nbl::ext::imgui

sInfo.queue = transfer;
sInfo.waitSemaphores = {};
sInfo.commandBuffers = { &cmdInfo, 1 };
sInfo.commandBuffers = { &cmdInfo, 1u };
sInfo.scratchSemaphore =
{
.semaphore = scratchSemaphore.get(),
.value = 0,
.value = 0u,
.stageMask = PIPELINE_STAGE_FLAGS::ALL_TRANSFER_BITS
};

Expand Down Expand Up @@ -312,11 +320,11 @@ namespace nbl::ext::imgui
{
IGPUImageView::SCreationParams params;
params.format = image->getCreationParameters().format;
params.viewType = IImageView<IGPUImage>::ET_2D;
params.viewType = IImageView<IGPUImage>::ET_2D_ARRAY;
params.subresourceRange = regions.subresource;
params.image = core::smart_refctd_ptr(image);

m_fontTexture = m_device->createImageView(std::move(params));
m_fontAtlas2DArrayTexture = m_device->createImageView(std::move(params));
}
}

Expand Down Expand Up @@ -357,32 +365,26 @@ namespace nbl::ext::imgui

void UI::updateDescriptorSets()
{
_NBL_STATIC_INLINE_CONSTEXPR auto NBL_RESOURCES_AMOUNT = 1u;

IGPUDescriptorSet::SDescriptorInfo info[NBL_RESOURCES_AMOUNT];
{
auto& font = info[0u];
font.desc = m_fontTexture;
font.info.image.sampler = m_fontSampler;
font.info.image.imageLayout = nbl::asset::IImage::LAYOUT::READ_ONLY_OPTIMAL;
}

IGPUDescriptorSet::SWriteDescriptorSet write[NBL_RESOURCES_AMOUNT];
for (auto i = 0u; i < NBL_RESOURCES_AMOUNT; ++i)
{
auto& w = write[i];

w.dstSet = m_gpuDescriptorSet.get();
w.binding = 0;
w.arrayElement = 0;
w.count = 1;
w.info = info + i;
}
// texture atlas, note we don't create info & write for the font sampler because ours is immutable and baked into DS layout
IGPUDescriptorSet::SDescriptorInfo iInfo = {};
iInfo.info.image.imageLayout = IImage::LAYOUT::READ_ONLY_OPTIMAL;
iInfo.desc = m_fontAtlas2DArrayTexture;

const IGPUDescriptorSet::SWriteDescriptorSet writes[] =
{
{
.dstSet = m_gpuDescriptorSet.get(),
.binding = 0u,
.arrayElement = 0u,
.count = 1u,
.info = &iInfo
}
};

m_device->updateDescriptorSets(NBL_RESOURCES_AMOUNT, write, 0u, nullptr);
m_device->updateDescriptorSets(writes, {});
}

void UI::createFontSampler()
void UI::createFontAtlasSampler()
{
// TODO: Recheck this settings
IGPUSampler::SParams params{};
Expand All @@ -394,14 +396,15 @@ namespace nbl::ext::imgui
params.TextureWrapW = ISampler::ETC_REPEAT;

m_fontSampler = m_device->createSampler(params);
m_fontSampler->setObjectDebugName("Nabla Font Atlas Sampler");
}

void UI::createDescriptorPool()
{
IDescriptorPool::SCreateInfo createInfo = {};
createInfo.maxDescriptorCount[static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_COMBINED_IMAGE_SAMPLER)] = 1u;
createInfo.maxDescriptorCount[static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_STORAGE_BUFFER)] = 1u;
createInfo.maxSets = 1;
createInfo.maxDescriptorCount[static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_SAMPLER)] = 1u;
createInfo.maxDescriptorCount[static_cast<uint32_t>(asset::IDescriptor::E_TYPE::ET_SAMPLED_IMAGE)] = 1u;
createInfo.maxSets = 1u;
createInfo.flags = IDescriptorPool::E_CREATE_FLAGS::ECF_NONE;

m_descriptorPool = m_device->createDescriptorPool(std::move(createInfo));
Expand Down Expand Up @@ -514,11 +517,11 @@ namespace nbl::ext::imgui
IMGUI_CHECKVERSION();
ImGui::CreateContext();

createFontSampler();
createFontAtlasSampler();
createDescriptorPool();
createDescriptorSetLayout();
createPipeline(renderpass, pipelineCache);
createFontTexture(transistentCMD.get(), tQueue);
createFontAtlas2DArrayTexture(transistentCMD.get(), tQueue);
prepareKeyMapForDesktop();
adjustGlobalFontScale();
updateDescriptorSets();
Expand Down
2 changes: 1 addition & 1 deletion src/nbl/ext/ImGui/shaders/common.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
struct PSInput
{
float4 position : SV_Position;
float4 color : COLOR0;
float2 uv : TEXCOORD0;
float4 color : COLOR0;
float clip[4] : SV_ClipDistance;
};

Expand Down
16 changes: 13 additions & 3 deletions src/nbl/ext/ImGui/shaders/fragment.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,20 @@

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

[[vk::combinedImageSampler]][[vk::binding(0, 0)]] Texture2D sampleTexture : register(t0);
[[vk::combinedImageSampler]][[vk::binding(0, 0)]] SamplerState linearSampler : register(s0);
// separable image samplers, one to handle all textures
[[vk::binding(0,0)]] Texture2DArray texture;
[[vk::binding(1,0)]] SamplerState samplerState;

/*
we use Indirect Indexed draw call to render whole GUI, note we do a cross
platform trick and use base instance index as replacement for gl_DrawID
to request per object data with BDA
*/

float4 PSMain(PSInput input, uint drawID : SV_InstanceID) : SV_Target0
{
return input.color * sampleTexture.Sample(linearSampler, input.uv);
// BDA for requesting object data
const PerObjectData self = vk::RawBufferLoad<PerObjectData>(pc.elementBDA + sizeof(PerObjectData)* drawID);

return input.color * texture.Sample(samplerState, float32_t3(input.uv, self.texId));
}
7 changes: 7 additions & 0 deletions src/nbl/ext/ImGui/shaders/vertex.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

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

/*
we use Indirect Indexed draw call to render whole GUI, note we do a cross
platform trick and use base instance index as replacement for gl_DrawID
to request per object data with BDA
*/

PSInput VSMain(VSInput input, uint drawID : SV_InstanceID)
{
PSInput output;
Expand All @@ -16,6 +22,7 @@ PSInput VSMain(VSInput input, uint drawID : SV_InstanceID)
const float2 vMin = self.aabbMin.unpack();
const float2 vMax = self.aabbMax.unpack();

// clip planes calculations, axis aligned
output.clip[0] = output.position.x - vMin.x;
output.clip[1] = output.position.y - vMin.y;
output.clip[2] = vMax.x - output.position.x;
Expand Down

0 comments on commit a7102f0

Please sign in to comment.