Skip to content

Commit dc04722

Browse files
committed
add asset manager to nbl::ext::imgui::UI::S_CREATION_PARAMETERS, remove NSC from the ImGUI extension build system & embed shader sources instead (leave some comments), codegen & compile shaders on fly with respect to new optional S_RESOURCE_PARAMETERS (leave user freedom to specify set & resource bindings with certain required constraints), add more validation to the UI creation, update examples_tests submodule
1 parent 9e7cbe2 commit dc04722

File tree

5 files changed

+162
-84
lines changed

5 files changed

+162
-84
lines changed

include/nbl/ext/ImGui/ImGui.h

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define _NBL_EXT_IMGUI_UI_H_
33

44
#include "nbl/video/declarations.h"
5+
#include "nbl/asset/IAssetManager.h"
56

67
namespace nbl::ext::imgui
78
{
@@ -27,13 +28,21 @@ class UI final : public core::IReferenceCounted
2728

2829
struct S_CREATION_PARAMETERS
2930
{
30-
video::IUtilities* const utilities; //! required
31-
video::IQueue* const transfer; //! required
32-
video::IGPURenderpass* const renderpass; //! required
33-
uint32_t subpassIx = 0u; //! optional, default value if not provided
34-
video::IGPUDescriptorSetLayout* const descriptorSetLayout = nullptr; //! optional, default layout used if not provided [STILL TODO, currently its assumed its not nullptr!]
35-
video::IGPUPipelineCache* const pipelineCache = nullptr; //! optional, no cache used if not provided
36-
typename MDI::COMPOSE_T* const streamingMDIBuffer = nullptr; //! optional, default MDI buffer allocated if not provided
31+
struct S_RESOURCE_PARAMETERS
32+
{
33+
uint32_t setIx, bindingIx;
34+
};
35+
36+
nbl::asset::IAssetManager* const assetManager; //! required
37+
nbl::video::IUtilities* const utilities; //! required
38+
nbl::video::IQueue* const transfer; //! required
39+
nbl::video::IGPURenderpass* const renderpass; //! required
40+
uint32_t subpassIx = 0u; //! optional, default value used if not provided
41+
nbl::video::IGPUDescriptorSetLayout* const descriptorSetLayout = nullptr; //! optional, default layout used if not provided [STILL TODO, currently its assumed its not nullptr!]
42+
nbl::video::IGPUPipelineCache* const pipelineCache = nullptr; //! optional, no cache used if not provided
43+
typename MDI::COMPOSE_T* const streamingMDIBuffer = nullptr; //! optional, default MDI buffer allocated if not provided
44+
S_RESOURCE_PARAMETERS texturesInfo = { .setIx = 0u, .bindingIx = 0u }, //! optional, default values used if not provided
45+
samplerStateInfo = { .setIx = 0u, .bindingIx = 1u }; //! optional, default values used if not provided
3746
};
3847

3948
//! 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)

src/nbl/ext/ImGui/CMakeLists.txt

Lines changed: 11 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -23,62 +23,17 @@ nbl_create_ext_library_project(
2323

2424
target_link_libraries(${LIB_NAME} PUBLIC imtestengine)
2525

26-
# shaders IO directories
27-
set(NBL_EXT_IMGUI_INPUT_SHADERS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/shaders")
28-
get_filename_component(_EXT_IMGUI_SPIRV_BR_BUNDLE_SEARCH_DIRECTORY_ "${CMAKE_CURRENT_BINARY_DIR}/shaders/include" ABSOLUTE)
29-
get_filename_component(_EXT_IMGUI_SPIRV_BR_OUTPUT_DIRECTORY_HEADER_ "${CMAKE_CURRENT_BINARY_DIR}/builtin/include" ABSOLUTE)
30-
get_filename_component(_EXT_IMGUI_SPIRV_BR_OUTPUT_DIRECTORY_SOURCE_ "${CMAKE_CURRENT_BINARY_DIR}/builtin/src" ABSOLUTE)
31-
set(NBL_EXT_IMGUI_OUTPUT_SPIRV_DIRECTORY "${_EXT_IMGUI_SPIRV_BR_BUNDLE_SEARCH_DIRECTORY_}/nbl/ext/imgui/spirv")
26+
# (*) -> I wish we could just take NSC, offline-precompile to SPIRV, embed into builtin resource library (as we did!) but then be smart & adjust at runtime OpDecorate of our resources according to wishes - unfortunately no linker yet we have and we are not going to make one ourselves so we compile imgui shaders at runtime
27+
set(_BR_TARGET_ extImguibuiltinResourceData)
28+
set(_RESOURCE_DIR_ "shaders")
3229

33-
# list of input source shaders
34-
set(NBL_EXT_IMGUI_INPUT_SHADERS
35-
"${NBL_EXT_IMGUI_INPUT_SHADERS_DIRECTORY}/vertex.hlsl"
36-
"${NBL_EXT_IMGUI_INPUT_SHADERS_DIRECTORY}/fragment.hlsl"
37-
)
38-
39-
set(NBL_EXT_IMGUI_INPUT_COMMONS
40-
"${NBL_EXT_IMGUI_INPUT_SHADERS_DIRECTORY}/common.hlsl"
41-
)
42-
43-
include("${NBL_ROOT_PATH}/src/nbl/builtin/utils.cmake")
44-
45-
foreach(NBL_INPUT_SHADER IN LISTS NBL_EXT_IMGUI_INPUT_SHADERS)
46-
cmake_path(GET NBL_INPUT_SHADER STEM NBL_SHADER_STEM)
47-
set(NBL_OUTPUT_SPIRV_FILENAME "${NBL_SHADER_STEM}.spv")
48-
set(NBL_OUTPUT_SPIRV_PATH "${NBL_EXT_IMGUI_OUTPUT_SPIRV_DIRECTORY}/${NBL_OUTPUT_SPIRV_FILENAME}")
30+
get_filename_component(_SEARCH_DIRECTORIES_ "${CMAKE_CURRENT_SOURCE_DIR}" ABSOLUTE)
31+
get_filename_component(_OUTPUT_DIRECTORY_SOURCE_ "${CMAKE_CURRENT_BINARY_DIR}/src" ABSOLUTE)
32+
get_filename_component(_OUTPUT_DIRECTORY_HEADER_ "${CMAKE_CURRENT_BINARY_DIR}/include" ABSOLUTE)
4933

50-
if(NBL_SHADER_STEM STREQUAL vertex)
51-
set(NBL_NSC_COMPILE_OPTIONS -T vs_6_7 -E VSMain)
52-
elseif(NBL_SHADER_STEM STREQUAL fragment)
53-
set(NBL_NSC_COMPILE_OPTIONS -T ps_6_7 -E PSMain)
54-
else()
55-
message(FATAL_ERROR "internal error")
56-
endif()
57-
58-
set(NBL_NSC_COMPILE_COMMAND
59-
"$<TARGET_FILE:nsc>"
60-
-Fc "${NBL_OUTPUT_SPIRV_PATH}"
61-
${NBL_NSC_COMPILE_OPTIONS} # this should come from shader's [#pragma WAVE <compile options>] but our NSC doesn't seem to work properly currently
62-
"${NBL_INPUT_SHADER}"
63-
)
64-
65-
set(NBL_DEPENDS
66-
"${NBL_INPUT_SHADER}"
67-
${NBL_EXT_IMGUI_INPUT_COMMONS}
68-
)
69-
70-
add_custom_command(OUTPUT "${NBL_OUTPUT_SPIRV_PATH}"
71-
COMMAND ${NBL_NSC_COMPILE_COMMAND}
72-
DEPENDS ${NBL_DEPENDS}
73-
WORKING_DIRECTORY "${NBL_EXT_IMGUI_INPUT_SHADERS_DIRECTORY}"
74-
COMMENT "Generating \"${NBL_OUTPUT_SPIRV_PATH}\""
75-
VERBATIM
76-
COMMAND_EXPAND_LISTS
77-
)
78-
79-
list(APPEND NBL_EXT_IMGUI_OUTPUT_SPIRV_BUILTINS "${NBL_OUTPUT_SPIRV_PATH}")
80-
LIST_BUILTIN_RESOURCE(IMGUI_EXT_SPIRV_RESOURCES_TO_EMBED "ext/imgui/spirv/${NBL_OUTPUT_SPIRV_FILENAME}")
81-
endforeach()
34+
LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "common.hlsl")
35+
LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "vertex.hlsl") # (*) -> this we could precompile [no resources for which set/binding Ixs could be adjusted] but I'm not going to mix stuff
36+
LIST_BUILTIN_RESOURCE(RESOURCES_TO_EMBED "fragment.hlsl") # (*) -> but this we could not since we let users to provide pipeline layout + set/binding Ixs at runtime
8237

83-
ADD_CUSTOM_BUILTIN_RESOURCES(extImguiSpirvBuiltinResourceData IMGUI_EXT_SPIRV_RESOURCES_TO_EMBED "${_EXT_IMGUI_SPIRV_BR_BUNDLE_SEARCH_DIRECTORY_}" "nbl" "ext::imgui::spirv::builtin" "${_EXT_IMGUI_SPIRV_BR_OUTPUT_DIRECTORY_HEADER_}" "${_EXT_IMGUI_SPIRV_BR_OUTPUT_DIRECTORY_SOURCE_}" "STATIC" "INTERNAL")
84-
LINK_BUILTIN_RESOURCES_TO_TARGET(${LIB_NAME} extImguiSpirvBuiltinResourceData)
38+
ADD_CUSTOM_BUILTIN_RESOURCES(${_BR_TARGET_} RESOURCES_TO_EMBED "${_SEARCH_DIRECTORIES_}" "${_RESOURCE_DIR_}" "nbl::ext::imgui::builtin" "${_OUTPUT_DIRECTORY_HEADER_}" "${_OUTPUT_DIRECTORY_SOURCE_}")
39+
LINK_BUILTIN_RESOURCES_TO_TARGET(${LIB_NAME} ${_BR_TARGET_})

src/nbl/ext/ImGui/ImGui.cpp

Lines changed: 115 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@
88
#include "nbl/system/CStdoutLogger.h"
99
#include "nbl/ext/ImGui/ImGui.h"
1010
#include "shaders/common.hlsl"
11-
#include "ext/imgui/spirv/builtin/builtinResources.h"
12-
#include "ext/imgui/spirv/builtin/CArchive.h"
13-
11+
#include "nbl/ext/ImGui/builtin/builtinResources.h"
12+
#include "nbl/ext/ImGui/builtin/CArchive.h"
1413
#include "imgui/imgui.h"
1514
#include "imgui/misc/cpp/imgui_stdlib.h"
1615

@@ -33,30 +32,123 @@ namespace nbl::ext::imgui
3332
}
3433
};
3534

36-
auto pipelineLayout = m_creationParams.utilities->getLogicalDevice()->createPipelineLayout(pushConstantRanges, core::smart_refctd_ptr<video::IGPUDescriptorSetLayout>(m_creationParams.descriptorSetLayout));
35+
auto createPipelineLayout = [&](const uint32_t setIx) -> core::smart_refctd_ptr<IGPUPipelineLayout>
36+
{
37+
switch (setIx)
38+
{
39+
case 0u:
40+
return m_creationParams.utilities->getLogicalDevice()->createPipelineLayout(pushConstantRanges, core::smart_refctd_ptr<video::IGPUDescriptorSetLayout>(m_creationParams.descriptorSetLayout));
41+
case 1u:
42+
return m_creationParams.utilities->getLogicalDevice()->createPipelineLayout(pushConstantRanges, nullptr, core::smart_refctd_ptr<video::IGPUDescriptorSetLayout>(m_creationParams.descriptorSetLayout));
43+
case 2u:
44+
return m_creationParams.utilities->getLogicalDevice()->createPipelineLayout(pushConstantRanges, nullptr, nullptr, core::smart_refctd_ptr<video::IGPUDescriptorSetLayout>(m_creationParams.descriptorSetLayout));
45+
case 3u:
46+
return m_creationParams.utilities->getLogicalDevice()->createPipelineLayout(pushConstantRanges, nullptr, nullptr, nullptr, core::smart_refctd_ptr<video::IGPUDescriptorSetLayout>(m_creationParams.descriptorSetLayout));
47+
default:
48+
assert(false);
49+
return nullptr;
50+
}
51+
};
52+
53+
auto pipelineLayout = createPipelineLayout(m_creationParams.texturesInfo.setIx); //! its okay to take the Ix from textures info because we force user to use the same set for both textures and samplers [also validated at this point]
3754

3855
struct
3956
{
4057
core::smart_refctd_ptr<video::IGPUShader> vertex, fragment;
4158
} shaders;
4259

4360
{
44-
struct
61+
constexpr std::string_view NBL_ARCHIVE_ALIAS = "nbl/ext/imgui/shaders";
62+
63+
auto system = smart_refctd_ptr<system::ISystem>(m_creationParams.assetManager->getSystem()); //! proxy the system, we will touch it gently
64+
auto archive = make_smart_refctd_ptr<nbl::ext::imgui::builtin::CArchive>(smart_refctd_ptr<system::ILogger>(m_creationParams.utilities->getLogger())); //! we should never assume user will mount our internal archive since its the extension and not user's job to do it, hence we mount only to compile our extension sources then unmount the archive
65+
auto compiler = make_smart_refctd_ptr<CHLSLCompiler>(smart_refctd_ptr(system)); //! note we are out of default logical device's compiler set scope so also a few special steps are required to compile our extension shaders to SPIRV
66+
auto includeFinder = make_smart_refctd_ptr<IShaderCompiler::CIncludeFinder>(smart_refctd_ptr(system));
67+
auto includeLoader = includeFinder->getDefaultFileSystemLoader();
68+
includeFinder->addSearchPath(NBL_ARCHIVE_ALIAS.data(), includeLoader);
69+
70+
auto createShader = [&]<core::StringLiteral key, asset::IShader::E_SHADER_STAGE stage>() -> core::smart_refctd_ptr<video::IGPUShader>
4571
{
46-
const system::SBuiltinFile vertex = ::ext::imgui::spirv::builtin::get_resource<"ext/imgui/spirv/vertex.spv">();
47-
const system::SBuiltinFile fragment = ::ext::imgui::spirv::builtin::get_resource<"ext/imgui/spirv/fragment.spv">();
48-
} spirv;
72+
asset::IAssetLoader::SAssetLoadParams params = {};
73+
params.logger = m_creationParams.utilities->getLogger();
74+
params.workingDirectory = NBL_ARCHIVE_ALIAS.data();
4975

50-
auto createShader = [&](const system::SBuiltinFile& in, asset::IShader::E_SHADER_STAGE stage) -> core::smart_refctd_ptr<video::IGPUShader>
51-
{
52-
const auto buffer = core::make_smart_refctd_ptr<asset::CCustomAllocatorCPUBuffer<core::null_allocator<uint8_t>, true> >(in.size, /*this cast is awful but my custom buffer won't free it's memory*/ (void*)in.contents, core::adopt_memory); // no copy
53-
const auto shader = make_smart_refctd_ptr<ICPUShader>(core::smart_refctd_ptr(buffer), stage, IShader::E_CONTENT_TYPE::ECT_SPIRV, "");
54-
55-
return m_creationParams.utilities->getLogicalDevice()->createShader(shader.get());
76+
auto bundle = m_creationParams.assetManager->getAsset(key.value, params);
77+
const auto assets = bundle.getContents();
78+
79+
if (assets.empty())
80+
{
81+
m_creationParams.utilities->getLogger()->log("Could not load \"%s\" shader!", system::ILogger::ELL_ERROR, key.value);
82+
return nullptr;
83+
}
84+
85+
const auto shader = IAsset::castDown<asset::ICPUShader>(assets[0]);
86+
87+
CHLSLCompiler::SOptions options = {};
88+
options.stage = stage;
89+
options.preprocessorOptions.sourceIdentifier = key.value;
90+
options.preprocessorOptions.logger = m_creationParams.utilities->getLogger();
91+
options.preprocessorOptions.includeFinder = includeFinder.get();
92+
93+
auto compileToSPIRV = [&]() -> core::smart_refctd_ptr<ICPUShader>
94+
{
95+
#define NBL_DEFAULT_OPTIONS "-spirv", "-Zpr", "-enable-16bit-types", "-fvk-use-scalar-layout", "-Wno-c++11-extensions", "-Wno-c++1z-extensions", "-Wno-c++14-extensions", "-Wno-gnu-static-float-init", "-fspv-target-env=vulkan1.3", "-HV", "202x" /* default required params, just to not throw warnings */
96+
const std::string_view code (reinterpret_cast<const char*>(shader->getContent()->getPointer()), shader->getContent()->getSize());
97+
98+
if constexpr (stage == IShader::E_SHADER_STAGE::ESS_VERTEX)
99+
{
100+
const auto VERTEX_COMPILE_OPTIONS = std::to_array<std::string>({NBL_DEFAULT_OPTIONS, "-T", "vs_6_7", "-E", "VSMain", "-O3"});
101+
options.dxcOptions = VERTEX_COMPILE_OPTIONS;
102+
103+
return compiler->compileToSPIRV(code.data(), options); // we good here - no code patching
104+
}
105+
else if (stage == IShader::E_SHADER_STAGE::ESS_FRAGMENT)
106+
{
107+
const auto FRAGMENT_COMPILE_OPTIONS = std::to_array<std::string>({NBL_DEFAULT_OPTIONS, "-T", "ps_6_7", "-E", "PSMain", "-O3"});
108+
options.dxcOptions = FRAGMENT_COMPILE_OPTIONS;
109+
110+
std::stringstream stream;
111+
112+
stream << "// -> this code has been autogenerated with Nabla ImGUI extension\n"
113+
<< "#define NBL_TEXTURES_BINDING " << m_creationParams.texturesInfo.bindingIx << "\n"
114+
<< "#define NBL_TEXTURES_SET " << m_creationParams.texturesInfo.setIx << "\n"
115+
<< "#define NBL_SAMPLER_STATES_BINDING " << m_creationParams.samplerStateInfo.bindingIx << "\n"
116+
<< "#define NBL_SAMPLER_STATES_SET " << m_creationParams.samplerStateInfo.setIx << "\n"
117+
<< "// <-\n\n";
118+
119+
const auto newCode = stream.str() + std::string(code);
120+
return compiler->compileToSPIRV(newCode.c_str(), options); // but here we do patch the code with additional define directives for which values are taken from the creation parameters
121+
}
122+
else
123+
{
124+
static_assert(stage != IShader::E_SHADER_STAGE::ESS_UNKNOWN, "Unknown shader stage!");
125+
return nullptr;
126+
}
127+
};
128+
129+
auto spirv = compileToSPIRV();
130+
131+
if (!spirv)
132+
{
133+
m_creationParams.utilities->getLogger()->log("Could not compile \"%s\" shader!", system::ILogger::ELL_ERROR, key.value);
134+
return nullptr;
135+
}
136+
137+
auto gpu = m_creationParams.utilities->getLogicalDevice()->createShader(spirv.get());
138+
139+
if (!gpu)
140+
m_creationParams.utilities->getLogger()->log("Could not create GPU shader for \"%s\"!", system::ILogger::ELL_ERROR, key.value);
141+
142+
return gpu;
56143
};
57144

58-
shaders.vertex = createShader(spirv.vertex, IShader::E_SHADER_STAGE::ESS_VERTEX);
59-
shaders.fragment = createShader(spirv.fragment, IShader::E_SHADER_STAGE::ESS_FRAGMENT);
145+
system->mount(smart_refctd_ptr(archive), NBL_ARCHIVE_ALIAS.data());
146+
shaders.vertex = createShader.template operator() < NBL_CORE_UNIQUE_STRING_LITERAL_TYPE("vertex.hlsl"), IShader::E_SHADER_STAGE::ESS_VERTEX > ();
147+
shaders.fragment = createShader.template operator() < NBL_CORE_UNIQUE_STRING_LITERAL_TYPE("fragment.hlsl"), IShader::E_SHADER_STAGE::ESS_FRAGMENT > ();
148+
system->unmount(archive.get(), NBL_ARCHIVE_ALIAS.data());
149+
150+
assert(shaders.vertex);
151+
assert(shaders.fragment);
60152
}
61153

62154
SVertexInputParams vertexInputParams{};
@@ -516,10 +608,16 @@ namespace nbl::ext::imgui
516608
{
517609
const auto validation = std::to_array
518610
({
611+
std::make_pair(bool(m_creationParams.assetManager), "Invalid `m_creationParams.assetManager` is nullptr!"),
612+
std::make_pair(bool(m_creationParams.assetManager->getSystem()), "Invalid `m_creationParams.assetManager->getSystem()` is nullptr!"),
519613
std::make_pair(bool(m_creationParams.utilities), "Invalid `m_creationParams.utilities` is nullptr!"),
520614
std::make_pair(bool(m_creationParams.transfer), "Invalid `m_creationParams.transfer` is nullptr!"),
521615
std::make_pair(bool(m_creationParams.renderpass), "Invalid `m_creationParams.renderpass` is nullptr!"),
522-
(m_creationParams.utilities && m_creationParams.transfer && m_creationParams.renderpass) ? std::make_pair(bool(m_creationParams.utilities->getLogicalDevice()->getPhysicalDevice()->getQueueFamilyProperties()[m_creationParams.transfer->getFamilyIndex()].queueFlags.hasFlags(IQueue::FAMILY_FLAGS::TRANSFER_BIT)), "Invalid `m_creationParams.transfer` is not capable of transfer operations!") : std::make_pair(false, "Pass valid required UI::S_CREATION_PARAMETERS!")
616+
(m_creationParams.assetManager && m_creationParams.utilities && m_creationParams.transfer && m_creationParams.renderpass) ? std::make_pair(bool(m_creationParams.utilities->getLogicalDevice()->getPhysicalDevice()->getQueueFamilyProperties()[m_creationParams.transfer->getFamilyIndex()].queueFlags.hasFlags(IQueue::FAMILY_FLAGS::TRANSFER_BIT)), "Invalid `m_creationParams.transfer` is not capable of transfer operations!") : std::make_pair(false, "Pass valid required UI::S_CREATION_PARAMETERS!"),
617+
std::make_pair(bool(m_creationParams.texturesInfo.setIx <= 3u), "Invalid `m_creationParams.texturesInfo.setIx` is outside { 0u, 1u, 2u, 3u } set!"),
618+
std::make_pair(bool(m_creationParams.samplerStateInfo.setIx <= 3u), "Invalid `m_creationParams.samplerStateInfo.setIx` is outside { 0u, 1u, 2u, 3u } set!"),
619+
std::make_pair(bool(m_creationParams.texturesInfo.setIx == m_creationParams.samplerStateInfo.setIx), "Invalid `m_creationParams.texturesInfo.setIx` is not equal to `m_creationParams.samplerStateInfo.setIx`!"),
620+
std::make_pair(bool(m_creationParams.texturesInfo.bindingIx != m_creationParams.samplerStateInfo.bindingIx), "Invalid `m_creationParams.texturesInfo.bindingIx` is equal to `m_creationParams.samplerStateInfo.bindingIx`!")
523621
});
524622

525623
for (const auto& [ok, error] : validation)

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

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,26 @@
1+
#ifndef NBL_TEXTURES_BINDING
2+
#error "NBL_TEXTURES_BINDING must be defined!"
3+
#endif
4+
5+
#ifndef NBL_TEXTURES_SET
6+
#error "NBL_TEXTURES_SET must be defined!"
7+
#endif
8+
9+
#ifndef NBL_SAMPLER_STATES_BINDING
10+
#error "NBL_SAMPLER_STATES_BINDING must be defined!"
11+
#endif
12+
13+
#ifndef NBL_SAMPLER_STATES_SET
14+
#error "NBL_SAMPLER_STATES_SET must be defined!"
15+
#endif
16+
117
#include "common.hlsl"
218

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

5-
// single separable image sampler to handle all textures we descriptor-index
6-
[[vk::binding(0,0)]] Texture2D textures[NBL_MAX_IMGUI_TEXTURES];
7-
[[vk::binding(1,0)]] SamplerState samplerStates[NBL_MAX_IMGUI_TEXTURES];
21+
// separable image samplers to handle textures we do descriptor-index
22+
[[vk::binding(NBL_TEXTURES_BINDING, NBL_TEXTURES_SET)]] Texture2D textures[NBL_MAX_IMGUI_TEXTURES];
23+
[[vk::binding(NBL_SAMPLER_STATES_BINDING, NBL_SAMPLER_STATES_SET)]] SamplerState samplerStates[NBL_MAX_IMGUI_TEXTURES];
824

925
/*
1026
we use Indirect Indexed draw call to render whole GUI, note we do a cross

0 commit comments

Comments
 (0)