diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 3b757eb6670c..b3baff468517 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -56,7 +56,7 @@ // 2021-03-22: Vulkan: Fix mapped memory validation error when buffer sizes are not multiple of VkPhysicalDeviceLimits::nonCoherentAtomSize. // 2021-02-18: Vulkan: Change blending equation to preserve alpha in output buffer. // 2021-01-27: Vulkan: Added support for custom function load and IMGUI_IMPL_VULKAN_NO_PROTOTYPES by using ImGui_ImplVulkan_LoadFunctions(). -// 2020-11-11: Vulkan: Added support for specifying which subpass to reference during VkPipeline creation. +// 2020-11-11: Vulkan: Added support for specifying which Subpass to reference during VkPipeline creation. // 2020-09-07: Vulkan: Added VkPipeline parameter to ImGui_ImplVulkan_RenderDrawData (default to one passed to ImGui_ImplVulkan_Init). // 2020-05-04: Vulkan: Fixed crash if initial frame has no vertices. // 2020-04-26: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData didn't have vertices. @@ -314,44 +314,165 @@ static uint32_t __glsl_shader_vert_spv[] = }; // backends/vulkan/glsl_shader.frag, compiled with: -// # glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag -/* -#version 450 core -layout(location = 0) out vec4 fColor; -layout(set=0, binding=0) uniform sampler2D sTexture; -layout(location = 0) in struct { vec4 Color; vec2 UV; } In; -void main() +// # glslangValidator -V -x -DUSE_SPEC_CONSTANT_PARAMS=1 -o glsl_shader.frag.u32 glsl_shader.frag +static uint32_t __glsl_shader_frag_static_spv[] = { - fColor = In.Color * texture(sTexture, In.UV.st); -} -*/ -static uint32_t __glsl_shader_frag_spv[] = + 0x07230203,0x00010000,0x0008000b,0x00000053,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000039,0x0000003d,0x00030010, + 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, + 0x00000000,0x00090005,0x0000000b,0x6c707041,0x6c6f4379,0x6f43726f,0x63657272,0x6e6f6974, + 0x34667628,0x0000003b,0x00030005,0x0000000a,0x00637273,0x00030005,0x0000000d,0x00736572, + 0x00080005,0x00000010,0x6f6c6f63,0x6f635f72,0x63657272,0x6e6f6974,0x74656d5f,0x00646f68, + 0x00080005,0x00000019,0x6f6c6f63,0x6f635f72,0x63657272,0x6e6f6974,0x7261705f,0x00326d61, + 0x00050005,0x00000019,0x6f707865,0x65727573,0x00000000,0x00080005,0x0000001d,0x6f6c6f63, + 0x6f635f72,0x63657272,0x6e6f6974,0x7261705f,0x00316d61,0x00040005,0x0000001d,0x6d6d6167, + 0x00000061,0x00080005,0x00000032,0x6f6c6f63,0x6f635f72,0x63657272,0x6e6f6974,0x7261705f, + 0x00336d61,0x00050005,0x00000032,0x68706c61,0x61675f61,0x00616d6d,0x00040005,0x00000039, + 0x6c6f4366,0x0000726f,0x00030005,0x0000003b,0x00000000,0x00050006,0x0000003b,0x00000000, + 0x6f6c6f43,0x00000072,0x00040006,0x0000003b,0x00000001,0x00005655,0x00030005,0x0000003d, + 0x00006e49,0x00050005,0x00000045,0x78655473,0x65727574,0x00000000,0x00040005,0x0000004f, + 0x61726170,0x0000006d,0x00080005,0x00000052,0x6f6c6f63,0x6f635f72,0x63657272,0x6e6f6974, + 0x7261705f,0x00346d61,0x00040047,0x00000010,0x00000001,0x00000000,0x00040047,0x00000019, + 0x00000001,0x00000002,0x00040047,0x0000001d,0x00000001,0x00000001,0x00040047,0x00000032, + 0x00000001,0x00000003,0x00040047,0x00000039,0x0000001e,0x00000000,0x00040047,0x0000003d, + 0x0000001e,0x00000000,0x00040047,0x00000045,0x00000022,0x00000000,0x00040047,0x00000045, + 0x00000021,0x00000000,0x00040047,0x00000052,0x00000001,0x00000004,0x00020013,0x00000002, + 0x00030021,0x00000003,0x00000002,0x00030016,0x00000006,0x00000020,0x00040017,0x00000007, + 0x00000006,0x00000004,0x00040020,0x00000008,0x00000007,0x00000007,0x00040021,0x00000009, + 0x00000007,0x00000008,0x00040015,0x0000000f,0x00000020,0x00000001,0x00040032,0x0000000f, + 0x00000010,0x00000000,0x0004002b,0x0000000f,0x00000011,0x00000001,0x00020014,0x00000012, + 0x00060034,0x00000012,0x00000013,0x000000aa,0x00000010,0x00000011,0x0004002b,0x0000000f, + 0x00000014,0x00000002,0x00060034,0x00000012,0x00000015,0x000000aa,0x00000010,0x00000014, + 0x00060034,0x00000012,0x00000016,0x000000a6,0x00000013,0x00000015,0x00040032,0x00000006, + 0x00000019,0x3f800000,0x00040017,0x0000001a,0x00000006,0x00000003,0x00040032,0x00000006, + 0x0000001d,0x3f800000,0x00060033,0x0000001a,0x0000001e,0x0000001d,0x0000001d,0x0000001d, + 0x00040015,0x00000021,0x00000020,0x00000000,0x0004002b,0x00000021,0x00000022,0x00000000, + 0x00040020,0x00000023,0x00000007,0x00000006,0x0004002b,0x00000021,0x00000026,0x00000001, + 0x0004002b,0x00000021,0x00000029,0x00000002,0x00060034,0x00000012,0x0000002c,0x000000aa, + 0x00000010,0x00000014,0x0004002b,0x00000021,0x0000002f,0x00000003,0x00040032,0x00000006, + 0x00000032,0x3f800000,0x00040020,0x00000038,0x00000003,0x00000007,0x0004003b,0x00000038, + 0x00000039,0x00000003,0x00040017,0x0000003a,0x00000006,0x00000002,0x0004001e,0x0000003b, + 0x00000007,0x0000003a,0x00040020,0x0000003c,0x00000001,0x0000003b,0x0004003b,0x0000003c, + 0x0000003d,0x00000001,0x0004002b,0x0000000f,0x0000003e,0x00000000,0x00040020,0x0000003f, + 0x00000001,0x00000007,0x00090019,0x00000042,0x00000006,0x00000001,0x00000000,0x00000000, + 0x00000000,0x00000001,0x00000000,0x0003001b,0x00000043,0x00000042,0x00040020,0x00000044, + 0x00000000,0x00000043,0x0004003b,0x00000044,0x00000045,0x00000000,0x00040020,0x00000047, + 0x00000001,0x0000003a,0x00060034,0x00000012,0x0000004c,0x000000ab,0x00000010,0x0000003e, + 0x00040032,0x00000006,0x00000052,0x3f800000,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,0x0000004f,0x00000007,0x00050041, + 0x0000003f,0x00000040,0x0000003d,0x0000003e,0x0004003d,0x00000007,0x00000041,0x00000040, + 0x0004003d,0x00000043,0x00000046,0x00000045,0x00050041,0x00000047,0x00000048,0x0000003d, + 0x00000011,0x0004003d,0x0000003a,0x00000049,0x00000048,0x00050057,0x00000007,0x0000004a, + 0x00000046,0x00000049,0x00050085,0x00000007,0x0000004b,0x00000041,0x0000004a,0x0003003e, + 0x00000039,0x0000004b,0x000300f7,0x0000004e,0x00000000,0x000400fa,0x0000004c,0x0000004d, + 0x0000004e,0x000200f8,0x0000004d,0x0004003d,0x00000007,0x00000050,0x00000039,0x0003003e, + 0x0000004f,0x00000050,0x00050039,0x00000007,0x00000051,0x0000000b,0x0000004f,0x0003003e, + 0x00000039,0x00000051,0x000200f9,0x0000004e,0x000200f8,0x0000004e,0x000100fd,0x00010038, + 0x00050036,0x00000007,0x0000000b,0x00000000,0x00000009,0x00030037,0x00000008,0x0000000a, + 0x000200f8,0x0000000c,0x0004003b,0x00000008,0x0000000d,0x00000007,0x0004003d,0x00000007, + 0x0000000e,0x0000000a,0x0003003e,0x0000000d,0x0000000e,0x000300f7,0x00000018,0x00000000, + 0x000400fa,0x00000016,0x00000017,0x00000018,0x000200f8,0x00000017,0x0004003d,0x00000007, + 0x0000001b,0x0000000a,0x0008004f,0x0000001a,0x0000001c,0x0000001b,0x0000001b,0x00000000, + 0x00000001,0x00000002,0x0007000c,0x0000001a,0x0000001f,0x00000001,0x0000001a,0x0000001c, + 0x0000001e,0x0005008e,0x0000001a,0x00000020,0x0000001f,0x00000019,0x00050041,0x00000023, + 0x00000024,0x0000000d,0x00000022,0x00050051,0x00000006,0x00000025,0x00000020,0x00000000, + 0x0003003e,0x00000024,0x00000025,0x00050041,0x00000023,0x00000027,0x0000000d,0x00000026, + 0x00050051,0x00000006,0x00000028,0x00000020,0x00000001,0x0003003e,0x00000027,0x00000028, + 0x00050041,0x00000023,0x0000002a,0x0000000d,0x00000029,0x00050051,0x00000006,0x0000002b, + 0x00000020,0x00000002,0x0003003e,0x0000002a,0x0000002b,0x000300f7,0x0000002e,0x00000000, + 0x000400fa,0x0000002c,0x0000002d,0x0000002e,0x000200f8,0x0000002d,0x00050041,0x00000023, + 0x00000030,0x0000000a,0x0000002f,0x0004003d,0x00000006,0x00000031,0x00000030,0x0007000c, + 0x00000006,0x00000033,0x00000001,0x0000001a,0x00000031,0x00000032,0x00050041,0x00000023, + 0x00000034,0x0000000d,0x0000002f,0x0003003e,0x00000034,0x00000033,0x000200f9,0x0000002e, + 0x000200f8,0x0000002e,0x000200f9,0x00000018,0x000200f8,0x00000018,0x0004003d,0x00000007, + 0x00000035,0x0000000d,0x000200fe,0x00000035,0x00010038 + +}; + +// # glslangValidator -V -x -DUSE_SPEC_CONSTANT_PARAMS=0 -o glsl_shader.frag.u32 glsl_shader.frag +static uint32_t __glsl_shader_frag_dynamic_spv[] = { - 0x07230203,0x00010000,0x00080001,0x0000001e,0x00000000,0x00020011,0x00000001,0x0006000b, + 0x07230203,0x00010000,0x0008000b,0x0000005f,0x00000000,0x00020011,0x00000001,0x0006000b, 0x00000001,0x4c534c47,0x6474732e,0x3035342e,0x00000000,0x0003000e,0x00000000,0x00000001, - 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000009,0x0000000d,0x00030010, + 0x0007000f,0x00000004,0x00000004,0x6e69616d,0x00000000,0x00000047,0x0000004b,0x00030010, 0x00000004,0x00000007,0x00030003,0x00000002,0x000001c2,0x00040005,0x00000004,0x6e69616d, - 0x00000000,0x00040005,0x00000009,0x6c6f4366,0x0000726f,0x00030005,0x0000000b,0x00000000, - 0x00050006,0x0000000b,0x00000000,0x6f6c6f43,0x00000072,0x00040006,0x0000000b,0x00000001, - 0x00005655,0x00030005,0x0000000d,0x00006e49,0x00050005,0x00000016,0x78655473,0x65727574, - 0x00000000,0x00040047,0x00000009,0x0000001e,0x00000000,0x00040047,0x0000000d,0x0000001e, - 0x00000000,0x00040047,0x00000016,0x00000022,0x00000000,0x00040047,0x00000016,0x00000021, - 0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016,0x00000006, - 0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008,0x00000003, - 0x00000007,0x0004003b,0x00000008,0x00000009,0x00000003,0x00040017,0x0000000a,0x00000006, - 0x00000002,0x0004001e,0x0000000b,0x00000007,0x0000000a,0x00040020,0x0000000c,0x00000001, - 0x0000000b,0x0004003b,0x0000000c,0x0000000d,0x00000001,0x00040015,0x0000000e,0x00000020, - 0x00000001,0x0004002b,0x0000000e,0x0000000f,0x00000000,0x00040020,0x00000010,0x00000001, - 0x00000007,0x00090019,0x00000013,0x00000006,0x00000001,0x00000000,0x00000000,0x00000000, - 0x00000001,0x00000000,0x0003001b,0x00000014,0x00000013,0x00040020,0x00000015,0x00000000, - 0x00000014,0x0004003b,0x00000015,0x00000016,0x00000000,0x0004002b,0x0000000e,0x00000018, - 0x00000001,0x00040020,0x00000019,0x00000001,0x0000000a,0x00050036,0x00000002,0x00000004, - 0x00000000,0x00000003,0x000200f8,0x00000005,0x00050041,0x00000010,0x00000011,0x0000000d, - 0x0000000f,0x0004003d,0x00000007,0x00000012,0x00000011,0x0004003d,0x00000014,0x00000017, - 0x00000016,0x00050041,0x00000019,0x0000001a,0x0000000d,0x00000018,0x0004003d,0x0000000a, - 0x0000001b,0x0000001a,0x00050057,0x00000007,0x0000001c,0x00000017,0x0000001b,0x00050085, - 0x00000007,0x0000001d,0x00000012,0x0000001c,0x0003003e,0x00000009,0x0000001d,0x000100fd, - 0x00010038 + 0x00000000,0x00090005,0x0000000b,0x6c707041,0x6c6f4379,0x6f43726f,0x63657272,0x6e6f6974, + 0x34667628,0x0000003b,0x00030005,0x0000000a,0x00637273,0x00030005,0x0000000d,0x00736572, + 0x00080005,0x00000010,0x6f6c6f63,0x6f635f72,0x63657272,0x6e6f6974,0x74656d5f,0x00646f68, + 0x00040005,0x0000001a,0x6d6d6167,0x00000061,0x00060005,0x0000001b,0x73755075,0x6e6f4368, + 0x6e617473,0x00000074,0x00090006,0x0000001b,0x00000000,0x6f6c6f63,0x6f635f72,0x63657272, + 0x6e6f6974,0x7261705f,0x00316d61,0x00090006,0x0000001b,0x00000001,0x6f6c6f63,0x6f635f72, + 0x63657272,0x6e6f6974,0x7261705f,0x00326d61,0x00090006,0x0000001b,0x00000002,0x6f6c6f63, + 0x6f635f72,0x63657272,0x6e6f6974,0x7261705f,0x00336d61,0x00090006,0x0000001b,0x00000003, + 0x6f6c6f63,0x6f635f72,0x63657272,0x6e6f6974,0x7261705f,0x00346d61,0x00030005,0x0000001d, + 0x00000000,0x00050005,0x00000022,0x6f707865,0x65727573,0x00000000,0x00050005,0x0000003a, + 0x68706c61,0x61675f61,0x00616d6d,0x00040005,0x00000047,0x6c6f4366,0x0000726f,0x00030005, + 0x00000049,0x00000000,0x00050006,0x00000049,0x00000000,0x6f6c6f43,0x00000072,0x00040006, + 0x00000049,0x00000001,0x00005655,0x00030005,0x0000004b,0x00006e49,0x00050005,0x00000052, + 0x78655473,0x65727574,0x00000000,0x00040005,0x0000005c,0x61726170,0x0000006d,0x00040047, + 0x00000010,0x00000001,0x00000000,0x00050048,0x0000001b,0x00000000,0x00000023,0x00000010, + 0x00050048,0x0000001b,0x00000001,0x00000023,0x00000014,0x00050048,0x0000001b,0x00000002, + 0x00000023,0x00000018,0x00050048,0x0000001b,0x00000003,0x00000023,0x0000001c,0x00030047, + 0x0000001b,0x00000002,0x00040047,0x00000047,0x0000001e,0x00000000,0x00040047,0x0000004b, + 0x0000001e,0x00000000,0x00040047,0x00000052,0x00000022,0x00000000,0x00040047,0x00000052, + 0x00000021,0x00000000,0x00020013,0x00000002,0x00030021,0x00000003,0x00000002,0x00030016, + 0x00000006,0x00000020,0x00040017,0x00000007,0x00000006,0x00000004,0x00040020,0x00000008, + 0x00000007,0x00000007,0x00040021,0x00000009,0x00000007,0x00000008,0x00040015,0x0000000f, + 0x00000020,0x00000001,0x00040032,0x0000000f,0x00000010,0x00000000,0x0004002b,0x0000000f, + 0x00000011,0x00000001,0x00020014,0x00000012,0x00060034,0x00000012,0x00000013,0x000000aa, + 0x00000010,0x00000011,0x0004002b,0x0000000f,0x00000014,0x00000002,0x00060034,0x00000012, + 0x00000015,0x000000aa,0x00000010,0x00000014,0x00060034,0x00000012,0x00000016,0x000000a6, + 0x00000013,0x00000015,0x00040020,0x00000019,0x00000007,0x00000006,0x0006001e,0x0000001b, + 0x00000006,0x00000006,0x00000006,0x00000006,0x00040020,0x0000001c,0x00000009,0x0000001b, + 0x0004003b,0x0000001c,0x0000001d,0x00000009,0x0004002b,0x0000000f,0x0000001e,0x00000000, + 0x00040020,0x0000001f,0x00000009,0x00000006,0x00040017,0x00000026,0x00000006,0x00000003, + 0x00040015,0x0000002d,0x00000020,0x00000000,0x0004002b,0x0000002d,0x0000002e,0x00000000, + 0x0004002b,0x0000002d,0x00000031,0x00000001,0x0004002b,0x0000002d,0x00000034,0x00000002, + 0x00060034,0x00000012,0x00000037,0x000000aa,0x00000010,0x00000014,0x0004002b,0x0000002d, + 0x0000003d,0x00000003,0x00040020,0x00000046,0x00000003,0x00000007,0x0004003b,0x00000046, + 0x00000047,0x00000003,0x00040017,0x00000048,0x00000006,0x00000002,0x0004001e,0x00000049, + 0x00000007,0x00000048,0x00040020,0x0000004a,0x00000001,0x00000049,0x0004003b,0x0000004a, + 0x0000004b,0x00000001,0x00040020,0x0000004c,0x00000001,0x00000007,0x00090019,0x0000004f, + 0x00000006,0x00000001,0x00000000,0x00000000,0x00000000,0x00000001,0x00000000,0x0003001b, + 0x00000050,0x0000004f,0x00040020,0x00000051,0x00000000,0x00000050,0x0004003b,0x00000051, + 0x00000052,0x00000000,0x00040020,0x00000054,0x00000001,0x00000048,0x00060034,0x00000012, + 0x00000059,0x000000ab,0x00000010,0x0000001e,0x00050036,0x00000002,0x00000004,0x00000000, + 0x00000003,0x000200f8,0x00000005,0x0004003b,0x00000008,0x0000005c,0x00000007,0x00050041, + 0x0000004c,0x0000004d,0x0000004b,0x0000001e,0x0004003d,0x00000007,0x0000004e,0x0000004d, + 0x0004003d,0x00000050,0x00000053,0x00000052,0x00050041,0x00000054,0x00000055,0x0000004b, + 0x00000011,0x0004003d,0x00000048,0x00000056,0x00000055,0x00050057,0x00000007,0x00000057, + 0x00000053,0x00000056,0x00050085,0x00000007,0x00000058,0x0000004e,0x00000057,0x0003003e, + 0x00000047,0x00000058,0x000300f7,0x0000005b,0x00000000,0x000400fa,0x00000059,0x0000005a, + 0x0000005b,0x000200f8,0x0000005a,0x0004003d,0x00000007,0x0000005d,0x00000047,0x0003003e, + 0x0000005c,0x0000005d,0x00050039,0x00000007,0x0000005e,0x0000000b,0x0000005c,0x0003003e, + 0x00000047,0x0000005e,0x000200f9,0x0000005b,0x000200f8,0x0000005b,0x000100fd,0x00010038, + 0x00050036,0x00000007,0x0000000b,0x00000000,0x00000009,0x00030037,0x00000008,0x0000000a, + 0x000200f8,0x0000000c,0x0004003b,0x00000008,0x0000000d,0x00000007,0x0004003b,0x00000019, + 0x0000001a,0x00000007,0x0004003b,0x00000019,0x00000022,0x00000007,0x0004003b,0x00000019, + 0x0000003a,0x00000007,0x0004003d,0x00000007,0x0000000e,0x0000000a,0x0003003e,0x0000000d, + 0x0000000e,0x000300f7,0x00000018,0x00000000,0x000400fa,0x00000016,0x00000017,0x00000018, + 0x000200f8,0x00000017,0x00050041,0x0000001f,0x00000020,0x0000001d,0x0000001e,0x0004003d, + 0x00000006,0x00000021,0x00000020,0x0003003e,0x0000001a,0x00000021,0x00050041,0x0000001f, + 0x00000023,0x0000001d,0x00000011,0x0004003d,0x00000006,0x00000024,0x00000023,0x0003003e, + 0x00000022,0x00000024,0x0004003d,0x00000006,0x00000025,0x00000022,0x0004003d,0x00000007, + 0x00000027,0x0000000a,0x0008004f,0x00000026,0x00000028,0x00000027,0x00000027,0x00000000, + 0x00000001,0x00000002,0x0004003d,0x00000006,0x00000029,0x0000001a,0x00060050,0x00000026, + 0x0000002a,0x00000029,0x00000029,0x00000029,0x0007000c,0x00000026,0x0000002b,0x00000001, + 0x0000001a,0x00000028,0x0000002a,0x0005008e,0x00000026,0x0000002c,0x0000002b,0x00000025, + 0x00050041,0x00000019,0x0000002f,0x0000000d,0x0000002e,0x00050051,0x00000006,0x00000030, + 0x0000002c,0x00000000,0x0003003e,0x0000002f,0x00000030,0x00050041,0x00000019,0x00000032, + 0x0000000d,0x00000031,0x00050051,0x00000006,0x00000033,0x0000002c,0x00000001,0x0003003e, + 0x00000032,0x00000033,0x00050041,0x00000019,0x00000035,0x0000000d,0x00000034,0x00050051, + 0x00000006,0x00000036,0x0000002c,0x00000002,0x0003003e,0x00000035,0x00000036,0x000300f7, + 0x00000039,0x00000000,0x000400fa,0x00000037,0x00000038,0x00000039,0x000200f8,0x00000038, + 0x00050041,0x0000001f,0x0000003b,0x0000001d,0x00000014,0x0004003d,0x00000006,0x0000003c, + 0x0000003b,0x0003003e,0x0000003a,0x0000003c,0x00050041,0x00000019,0x0000003e,0x0000000a, + 0x0000003d,0x0004003d,0x00000006,0x0000003f,0x0000003e,0x0004003d,0x00000006,0x00000040, + 0x0000003a,0x0007000c,0x00000006,0x00000041,0x00000001,0x0000001a,0x0000003f,0x00000040, + 0x00050041,0x00000019,0x00000042,0x0000000d,0x0000003d,0x0003003e,0x00000042,0x00000041, + 0x000200f9,0x00000039,0x000200f8,0x00000039,0x000200f9,0x00000018,0x000200f8,0x00000018, + 0x0004003d,0x00000007,0x00000043,0x0000000d,0x000200fe,0x00000043,0x00010038 }; //----------------------------------------------------------------------------- @@ -428,7 +549,7 @@ static void CreateOrResizeBuffer(VkBuffer& buffer, VkDeviceMemory& buffer_memory buffer_size = buffer_size_aligned; } -static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkan_FrameRenderBuffers* rb, int fb_width, int fb_height) +static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline pipeline, VkCommandBuffer command_buffer, ImGui_ImplVulkan_FrameRenderBuffers* rb, int fb_width, int fb_height, const ImGui_ImplVulkan_ColorCorrectionParameters* color_correction_params = nullptr) { ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); @@ -470,10 +591,15 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 0, sizeof(float) * 2, scale); vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, sizeof(float) * 2, sizeof(float) * 2, translate); } + + if(color_correction_params) + { + vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 4 * sizeof(float), sizeof(ImGui_ImplVulkan_ColorCorrectionParameters), color_correction_params); + } } // Render function -void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline) +void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline, const ImGui_ImplVulkan_ColorCorrectionParameters* color_correction_params) { // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates) int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x); @@ -485,6 +611,12 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; if (pipeline == VK_NULL_HANDLE) pipeline = bd->Pipeline; + if(!color_correction_params) + color_correction_params = &v->ColorCorrectionParams; + if(v->UseStaticColorCorrectionsParams) + { + color_correction_params = nullptr; + } // Allocate array to store enough vertex/index buffers ImGui_ImplVulkan_WindowRenderBuffers* wrb = &bd->MainWindowRenderBuffers; @@ -538,7 +670,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm } // Setup desired Vulkan state - ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height); + ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height, color_correction_params); // Will project scissor/clipping rectangles into framebuffer space ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports @@ -559,7 +691,7 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm // User callback, registered via ImDrawList::AddCallback() // (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.) if (pcmd->UserCallback == ImDrawCallback_ResetRenderState) - ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height); + ImGui_ImplVulkan_SetupRenderState(draw_data, pipeline, command_buffer, rb, fb_width, fb_height, color_correction_params); else pcmd->UserCallback(cmd_list, pcmd); } @@ -845,27 +977,85 @@ static void ImGui_ImplVulkan_CreateShaderModules(VkDevice device, const VkAlloca { VkShaderModuleCreateInfo frag_info = {}; frag_info.sType = VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO; - frag_info.codeSize = sizeof(__glsl_shader_frag_spv); - frag_info.pCode = (uint32_t*)__glsl_shader_frag_spv; + const ImGui_ImplVulkan_InitInfo * v = &bd->VulkanInitInfo; + if(v->UseStaticColorCorrectionsParams) + { + frag_info.codeSize = sizeof(__glsl_shader_frag_static_spv); + frag_info.pCode = (uint32_t*)__glsl_shader_frag_static_spv; + } + else + { + frag_info.codeSize = sizeof(__glsl_shader_frag_dynamic_spv); + frag_info.pCode = (uint32_t*)__glsl_shader_frag_dynamic_spv; + } + VkResult err = vkCreateShaderModule(device, &frag_info, allocator, &bd->ShaderModuleFrag); check_vk_result(err); } } -static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationCallbacks* allocator, VkPipelineCache pipelineCache, VkRenderPass renderPass, VkSampleCountFlagBits MSAASamples, VkPipeline* pipeline, uint32_t subpass) +struct ImGui_ImplVulkan_PipelineCreateInfo +{ + VkDevice Device = VK_NULL_HANDLE; + const VkAllocationCallbacks * Allocator = nullptr; + VkPipelineCache PipelineCache = VK_NULL_HANDLE; + VkRenderPass RenderPass = VK_NULL_HANDLE; + uint32_t Subpass = 0; + VkSampleCountFlagBits MSAASamples = {}; + const ImGui_ImplVulkan_PipelineRenderingInfo * pRenderingInfo = nullptr; + ImGui_ImplVulkan_ColorCorrectionMethod ColorCorrectionMethod = {}; + const ImGui_ImplVulkan_ColorCorrectionParameters * ColorCorrectionParams = nullptr; +}; + +static VkPipeline ImGui_ImplVulkan_CreatePipeline(ImGui_ImplVulkan_PipelineCreateInfo const& pci) { ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); - ImGui_ImplVulkan_CreateShaderModules(device, allocator); + ImGui_ImplVulkan_CreateShaderModules(pci.Device, pci.Allocator); VkPipelineShaderStageCreateInfo stage[2] = {}; + stage[0].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stage[0].stage = VK_SHADER_STAGE_VERTEX_BIT; stage[0].module = bd->ShaderModuleVert; stage[0].pName = "main"; + stage[1].sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; stage[1].stage = VK_SHADER_STAGE_FRAGMENT_BIT; stage[1].module = bd->ShaderModuleFrag; stage[1].pName = "main"; + VkSpecializationInfo frag_specialization_info = {}; + VkSpecializationMapEntry frag_spec_constants[1 + 4] = {}; + struct SpecConstantData + { + uint32_t method; + ImGui_ImplVulkan_ColorCorrectionParameters params; + }; + SpecConstantData frag_spec_constant_data = {}; + frag_spec_constant_data.method = (uint32_t)pci.ColorCorrectionMethod; + frag_spec_constants[0].constantID = 0; + frag_spec_constants[0].offset = offsetof(SpecConstantData, method); + frag_spec_constants[0].size = sizeof(uint32_t); + if(pci.ColorCorrectionParams) + { + frag_specialization_info.mapEntryCount = 3; + frag_specialization_info.dataSize = sizeof(SpecConstantData); + frag_spec_constant_data.params = *pci.ColorCorrectionParams; + for (unsigned int i = 0; i < 4; ++i) + { + frag_spec_constants[1 + i].constantID = 1 + i; + frag_spec_constants[1 + i].offset = offsetof(SpecConstantData, params) + i * sizeof(float); + frag_spec_constants[1 + i].size = sizeof(float); + } + } + else + { + frag_specialization_info.mapEntryCount = 1; + frag_specialization_info.dataSize = sizeof(uint32_t); + } + frag_specialization_info.pMapEntries = frag_spec_constants; + frag_specialization_info.pData = &frag_spec_constant_data; + stage[1].pSpecializationInfo = &frag_specialization_info; + VkVertexInputBindingDescription binding_desc[1] = {}; binding_desc[0].stride = sizeof(ImDrawVert); @@ -910,7 +1100,7 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC VkPipelineMultisampleStateCreateInfo ms_info = {}; ms_info.sType = VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO; - ms_info.rasterizationSamples = (MSAASamples != 0) ? MSAASamples : VK_SAMPLE_COUNT_1_BIT; + ms_info.rasterizationSamples = (pci.MSAASamples != 0) ? pci.MSAASamples : VK_SAMPLE_COUNT_1_BIT; VkPipelineColorBlendAttachmentState color_attachment[1] = {}; color_attachment[0].blendEnable = VK_TRUE; @@ -950,21 +1140,24 @@ static void ImGui_ImplVulkan_CreatePipeline(VkDevice device, const VkAllocationC info.pColorBlendState = &blend_info; info.pDynamicState = &dynamic_state; info.layout = bd->PipelineLayout; - info.renderPass = renderPass; - info.subpass = subpass; + info.renderPass = pci.RenderPass; + info.subpass = pci.Subpass; #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING if (bd->VulkanInitInfo.UseDynamicRendering) { - IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR"); - IM_ASSERT(bd->VulkanInitInfo.PipelineRenderingCreateInfo.pNext == nullptr && "PipelineRenderingCreateInfo pNext must be NULL"); - info.pNext = &bd->VulkanInitInfo.PipelineRenderingCreateInfo; info.renderPass = VK_NULL_HANDLE; // Just make sure it's actually nullptr. + IM_ASSERT(!!pci.pRenderingInfo && "Dynamic Rendering requires a PipelineRenderingCreateInfo"); + IM_ASSERT(pci.pRenderingInfo->sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR && "PipelineRenderingCreateInfo::sType must be VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR"); + IM_ASSERT(pci.pRenderingInfo->pNext == nullptr && "PipelineRenderingCreateInfo::pNext must be NULL"); + info.pNext = pci.pRenderingInfo; } #endif - VkResult err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &info, allocator, pipeline); + VkPipeline result; + VkResult err = vkCreateGraphicsPipelines(pci.Device, pci.PipelineCache, 1, &info, pci.Allocator, &result); check_vk_result(err); + return result; } bool ImGui_ImplVulkan_CreateDeviceObjects() @@ -1008,26 +1201,85 @@ bool ImGui_ImplVulkan_CreateDeviceObjects() if (!bd->PipelineLayout) { // Constants: we are using 'vec2 offset' and 'vec2 scale' instead of a full 3d projection matrix - VkPushConstantRange push_constants[1] = {}; + VkPushConstantRange push_constants[2] = {}; push_constants[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; push_constants[0].offset = sizeof(float) * 0; push_constants[0].size = sizeof(float) * 4; + uint32_t push_constants_count = 1; + if(!v->UseStaticColorCorrectionsParams) + { + push_constants[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + push_constants[1].offset = 4 * sizeof(float); + push_constants[1].size = sizeof(ImGui_ImplVulkan_ColorCorrectionParameters); + ++push_constants_count; + } VkDescriptorSetLayout set_layout[1] = { bd->DescriptorSetLayout }; VkPipelineLayoutCreateInfo layout_info = {}; layout_info.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO; layout_info.setLayoutCount = 1; layout_info.pSetLayouts = set_layout; - layout_info.pushConstantRangeCount = 1; + layout_info.pushConstantRangeCount = push_constants_count; layout_info.pPushConstantRanges = push_constants; err = vkCreatePipelineLayout(v->Device, &layout_info, v->Allocator, &bd->PipelineLayout); check_vk_result(err); } - ImGui_ImplVulkan_CreatePipeline(v->Device, v->Allocator, v->PipelineCache, v->RenderPass, v->MSAASamples, &bd->Pipeline, v->Subpass); - return true; } +void ImGui_ImplVulkan_ReCreateMainPipeline(ImGui_ImplVulkan_MainPipelineCreateInfo const& info) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + if (bd->Pipeline) + { + vkDestroyPipeline(v->Device, bd->Pipeline, v->Allocator); + bd->Pipeline = VK_NULL_HANDLE; + } + v->RenderPass = info.RenderPass; + v->MSAASamples = info.MSAASamples; + v->Subpass = info.Subpass; + + v->ColorCorrectionMethod = info.ColorCorrectionMethod; + if(v->UseStaticColorCorrectionsParams && info.ColorCorrectionParams) + { + v->ColorCorrectionParams = *info.ColorCorrectionParams; + } + +#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING + if (info.pDynamicRendering) + { + v->PipelineRenderingCreateInfo = *info.pDynamicRendering; + } +#else + IM_ASSERT(info.pDynamicRendering == nullptr); +#endif + + ImGui_ImplVulkan_PipelineCreateInfo pci; + pci.Device = v->Device; + pci.Allocator = v->Allocator; + pci.PipelineCache = v->PipelineCache; + pci.RenderPass = v->RenderPass; + pci.Subpass = v->Subpass; + pci.MSAASamples = v->MSAASamples; + pci.pRenderingInfo = info.pDynamicRendering; + + pci.ColorCorrectionMethod = v->ColorCorrectionMethod; + if (v->UseStaticColorCorrectionsParams) + { + pci.ColorCorrectionParams = &v->ColorCorrectionParams; + } + + bd->Pipeline = ImGui_ImplVulkan_CreatePipeline(pci); +} + +void ImGui_ImplVulkan_SetMainColorCorrectionParams(const ImGui_ImplVulkan_ColorCorrectionParameters& params) +{ + ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); + ImGui_ImplVulkan_InitInfo* v = &bd->VulkanInitInfo; + v->ColorCorrectionParams = params; +} + void ImGui_ImplVulkan_DestroyDeviceObjects() { ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData(); @@ -1108,13 +1360,48 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info) IM_ASSERT(info->DescriptorPool != VK_NULL_HANDLE); IM_ASSERT(info->MinImageCount >= 2); IM_ASSERT(info->ImageCount >= info->MinImageCount); - if (info->UseDynamicRendering == false) - IM_ASSERT(info->RenderPass != VK_NULL_HANDLE); + //if (info->UseDynamicRendering == false) + // IM_ASSERT(info->RenderPass != VK_NULL_HANDLE); - bd->VulkanInitInfo = *info; + ImGui_ImplVulkan_InitInfo * v = &bd->VulkanInitInfo; + *v = *info; ImGui_ImplVulkan_CreateDeviceObjects(); + + { + bool create_pipeline = false; + const ImGui_ImplVulkan_PipelineRenderingInfo * p_dynamic_rendering = nullptr; + if (v->RenderPass) + { + create_pipeline = true; + } + else + { + #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING + if (v->UseDynamicRendering && v->PipelineRenderingCreateInfo.sType == VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR) + { + p_dynamic_rendering = &v->PipelineRenderingCreateInfo; + create_pipeline = true; + } + #endif + } + if (create_pipeline) + { + ImGui_ImplVulkan_MainPipelineCreateInfo mp_info = {}; + mp_info.RenderPass = v->RenderPass; + mp_info.Subpass = v->Subpass; + mp_info.MSAASamples = info->MSAASamples; + mp_info.pDynamicRendering = p_dynamic_rendering; + mp_info.ColorCorrectionMethod = v->ColorCorrectionMethod; + if(v->UseStaticColorCorrectionsParams) + { + mp_info.ColorCorrectionParams = &v->ColorCorrectionParams; + } + ImGui_ImplVulkan_ReCreateMainPipeline(mp_info); + } + } + return true; } diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index 1c7f7695183f..1f7c5cfa5d3c 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -63,6 +63,38 @@ #define IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING #endif +#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING +typedef VkPipelineRenderingCreateInfoKHR ImGui_ImplVulkan_PipelineRenderingInfo; +#else +typedef void ImGui_ImplVulkan_PipelineRenderingInfo; +#endif + +enum ImGui_ImplVulkan_ColorCorrectionMethod : uint32_t +{ + ImGui_ImplVulkan_ColorCorrection_None = 0, // Pass Through, no color correction + ImGui_ImplVulkan_ColorCorrection_Gamma = 1, // RGB gamma correction + ImGui_ImplVulkan_ColorCorrection_GammaAlpha = 2, // RGB Gamma correction + Alpha Gamma correction (with separate gamma factor) +}; +struct ImGui_ImplVulkan_ColorCorrectionParameters +{ + // Gamma, GammaAlpha: gamma exponent + float param1; + // Gamma, GammaAlpha: exposure multiplier + float param2; + // GammaAlpha: alpha channel gamma + float param3; + float param4; + + static inline ImGui_ImplVulkan_ColorCorrectionParameters MakeGamma(float gamma, float exposure = 1.0f, float alpha_gamma = 1.0f) + { + ImGui_ImplVulkan_ColorCorrectionParameters res = {}; + res.param1 = gamma; + res.param2 = exposure; + res.param3 = alpha_gamma; + return res; + } +}; + // Initialization data, for ImGui_ImplVulkan_Init() // - VkDescriptorPool should be created with VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // and must contain a pool size large enough to hold an ImGui VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor. @@ -80,11 +112,13 @@ struct ImGui_ImplVulkan_InitInfo uint32_t MinImageCount; // >= 2 uint32_t ImageCount; // >= MinImageCount VkSampleCountFlagBits MSAASamples; // 0 defaults to VK_SAMPLE_COUNT_1_BIT - + ImGui_ImplVulkan_ColorCorrectionMethod ColorCorrectionMethod; + ImGui_ImplVulkan_ColorCorrectionParameters ColorCorrectionParams; // (Optional) VkPipelineCache PipelineCache; uint32_t Subpass; + bool UseStaticColorCorrectionsParams; // (Optional) Dynamic Rendering // Need to explicitly enable VK_KHR_dynamic_rendering extension to use this, even for Vulkan 1.3. bool UseDynamicRendering; @@ -99,10 +133,21 @@ struct ImGui_ImplVulkan_InitInfo }; // Follow "Getting Started" link and check examples/ folder to learn about using backends! -IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info); +IMGUI_IMPL_API bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info); // The main pipeline will be created if possible (RenderPass xor (UseDynamicRendering && PipelineRenderingCreateInfo->sType is correct)) +struct ImGui_ImplVulkan_MainPipelineCreateInfo +{ + VkRenderPass RenderPass = VK_NULL_HANDLE; + uint32_t Subpass = 0; + VkSampleCountFlagBits MSAASamples = {}; + const ImGui_ImplVulkan_PipelineRenderingInfo * pDynamicRendering = nullptr; + ImGui_ImplVulkan_ColorCorrectionMethod ColorCorrectionMethod = {}; + const ImGui_ImplVulkan_ColorCorrectionParameters * ColorCorrectionParams = nullptr; +}; +IMGUI_IMPL_API void ImGui_ImplVulkan_ReCreateMainPipeline(ImGui_ImplVulkan_MainPipelineCreateInfo const& info); +IMGUI_IMPL_API void ImGui_ImplVulkan_SetMainColorCorrectionParams(const ImGui_ImplVulkan_ColorCorrectionParameters& params); IMGUI_IMPL_API void ImGui_ImplVulkan_Shutdown(); IMGUI_IMPL_API void ImGui_ImplVulkan_NewFrame(); -IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE); +IMGUI_IMPL_API void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline = VK_NULL_HANDLE, const ImGui_ImplVulkan_ColorCorrectionParameters * color_correction_params = nullptr); IMGUI_IMPL_API bool ImGui_ImplVulkan_CreateFontsTexture(); IMGUI_IMPL_API void ImGui_ImplVulkan_DestroyFontsTexture(); IMGUI_IMPL_API void ImGui_ImplVulkan_SetMinImageCount(uint32_t min_image_count); // To override MinImageCount after initialization (e.g. if swap chain is recreated) diff --git a/backends/vulkan/generate_spv.sh b/backends/vulkan/generate_spv.sh index 948ef773d6e1..8ee79ed2fc2b 100755 --- a/backends/vulkan/generate_spv.sh +++ b/backends/vulkan/generate_spv.sh @@ -2,5 +2,6 @@ ## -V: create SPIR-V binary ## -x: save binary output as text-based 32-bit hexadecimal numbers ## -o: output file -glslangValidator -V -x -o glsl_shader.frag.u32 glsl_shader.frag +glslangValidator -V -x -DUSE_SPEC_CONSTANT_PARAMS=1 -o glsl_shader_static.frag.u32 glsl_shader.frag +glslangValidator -V -x -DUSE_SPEC_CONSTANT_PARAMS=0 -o glsl_shader_dynamic.frag.u32 glsl_shader.frag glslangValidator -V -x -o glsl_shader.vert.u32 glsl_shader.vert diff --git a/backends/vulkan/glsl_shader.frag b/backends/vulkan/glsl_shader.frag index ce7e6f72b25d..2ff1ba665de7 100644 --- a/backends/vulkan/glsl_shader.frag +++ b/backends/vulkan/glsl_shader.frag @@ -1,4 +1,9 @@ #version 450 core + +#ifndef USE_SPEC_CONSTANT_PARAMS +#define USE_SPEC_CONSTANT_PARAMS 0 +#endif + layout(location = 0) out vec4 fColor; layout(set=0, binding=0) uniform sampler2D sTexture; @@ -8,7 +13,43 @@ layout(location = 0) in struct { vec2 UV; } In; +layout(constant_id = 0) const int color_correction_method = 0; +#if USE_SPEC_CONSTANT_PARAMS +layout(constant_id = 1) const float color_correction_param1 = 1.0f; +layout(constant_id = 2) const float color_correction_param2 = 1.0f; +layout(constant_id = 3) const float color_correction_param3 = 1.0f; +layout(constant_id = 4) const float color_correction_param4 = 1.0f; +#else +layout(push_constant) uniform uPushConstant { + layout(offset = 16 + 4 * 0) float color_correction_param1; + layout(offset = 16 + 4 * 1) float color_correction_param2; + layout(offset = 16 + 4 * 2) float color_correction_param3; + layout(offset = 16 + 4 * 3) float color_correction_param4; +}; +#endif + +vec4 ApplyColorCorrection(vec4 src) +{ + vec4 res = src; + if(color_correction_method == 1 || color_correction_method == 2) + { + const float gamma = color_correction_param1; + const float exposure = color_correction_param2; + res.rgb = exposure * pow(src.rgb, gamma.xxx); + if(color_correction_method == 2) + { + const float alpha_gamma = color_correction_param3; + res.a = pow(src.a, alpha_gamma); + } + } + return res; +} + void main() { fColor = In.Color * texture(sTexture, In.UV.st); + if(color_correction_method != 0) + { + fColor = ApplyColorCorrection(fColor); + } } diff --git a/examples/example_sdl3_vulkan/main.cpp b/examples/example_sdl3_vulkan/main.cpp new file mode 100644 index 000000000000..abae7d35e310 --- /dev/null +++ b/examples/example_sdl3_vulkan/main.cpp @@ -0,0 +1,593 @@ +// Dear ImGui: standalone example application for SDL2 + Vulkan + +// Learn about Dear ImGui: +// - FAQ https://dearimgui.com/faq +// - Getting Started https://dearimgui.com/getting-started +// - Documentation https://dearimgui.com/docs (same as your local docs/ folder). +// - Introduction, links and more at the top of imgui.cpp + +// Important note to the reader who wish to integrate imgui_impl_vulkan.cpp/.h in their own engine/app. +// - Common ImGui_ImplVulkan_XXX functions and structures are used to interface with imgui_impl_vulkan.cpp/.h. +// You will use those if you want to use this rendering backend in your engine/app. +// - Helper ImGui_ImplVulkanH_XXX functions and structures are only used by this example (main.cpp) and by +// the backend itself (imgui_impl_vulkan.cpp), but should PROBABLY NOT be used by your own engine/app code. +// Read comments in imgui_impl_vulkan.h. + +#include "imgui.h" +#include "imgui_impl_sdl3.h" +#include "imgui_impl_vulkan.h" +#include // printf, fprintf +#include // abort +#include +#include + +// Volk headers +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK +#define VOLK_IMPLEMENTATION +#include +#endif + +//#define APP_USE_UNLIMITED_FRAME_RATE +#ifdef _DEBUG +#define APP_USE_VULKAN_DEBUG_REPORT +#endif + +#ifdef SDL_ENABLE_OLD_NAMES +#undef SDL_ENABLE_OLD_NAMES +#endif + +// Data +static VkAllocationCallbacks* g_Allocator = nullptr; +static VkInstance g_Instance = VK_NULL_HANDLE; +static VkPhysicalDevice g_PhysicalDevice = VK_NULL_HANDLE; +static VkDevice g_Device = VK_NULL_HANDLE; +static uint32_t g_QueueFamily = (uint32_t)-1; +static VkQueue g_Queue = VK_NULL_HANDLE; +static VkDebugReportCallbackEXT g_DebugReport = VK_NULL_HANDLE; +static VkPipelineCache g_PipelineCache = VK_NULL_HANDLE; +static VkDescriptorPool g_DescriptorPool = VK_NULL_HANDLE; + +static ImGui_ImplVulkanH_Window g_MainWindowData; +static uint32_t g_MinImageCount = 2; +static bool g_SwapChainRebuild = false; + +static void check_vk_result(VkResult err) +{ + if (err == 0) + return; + fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); + if (err < 0) + abort(); +} + +#ifdef APP_USE_VULKAN_DEBUG_REPORT +static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) +{ + (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments + fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); + return VK_FALSE; +} +#endif // APP_USE_VULKAN_DEBUG_REPORT + +static bool IsExtensionAvailable(const ImVector& properties, const char* extension) +{ + for (const VkExtensionProperties& p : properties) + if (strcmp(p.extensionName, extension) == 0) + return true; + return false; +} + +static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice() +{ + uint32_t gpu_count; + VkResult err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, nullptr); + check_vk_result(err); + IM_ASSERT(gpu_count > 0); + + ImVector gpus; + gpus.resize(gpu_count); + err = vkEnumeratePhysicalDevices(g_Instance, &gpu_count, gpus.Data); + check_vk_result(err); + + // If a number >1 of GPUs got reported, find discrete GPU if present, or use first one available. This covers + // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple + // dedicated GPUs) is out of scope of this sample. + for (VkPhysicalDevice& device : gpus) + { + VkPhysicalDeviceProperties properties; + vkGetPhysicalDeviceProperties(device, &properties); + if (properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) + return device; + } + + // Use first GPU (Integrated) is a Discrete one is not available. + if (gpu_count > 0) + return gpus[0]; + return VK_NULL_HANDLE; +} + +static void SetupVulkan(ImVector instance_extensions) +{ + VkResult err; +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK + volkInitialize(); +#endif + + // Create Vulkan Instance + { + VkInstanceCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO; + + // Enumerate available extensions + uint32_t properties_count; + ImVector properties; + vkEnumerateInstanceExtensionProperties(nullptr, &properties_count, nullptr); + properties.resize(properties_count); + err = vkEnumerateInstanceExtensionProperties(nullptr, &properties_count, properties.Data); + check_vk_result(err); + + // Enable required extensions + if (IsExtensionAvailable(properties, VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME)) + instance_extensions.push_back(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); +#ifdef VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME + if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME)) + { + instance_extensions.push_back(VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME); + create_info.flags |= VK_INSTANCE_CREATE_ENUMERATE_PORTABILITY_BIT_KHR; + } +#endif + + // Enabling validation layers +#ifdef APP_USE_VULKAN_DEBUG_REPORT + const char* layers[] = { "VK_LAYER_KHRONOS_validation" }; + create_info.enabledLayerCount = 1; + create_info.ppEnabledLayerNames = layers; + instance_extensions.push_back("VK_EXT_debug_report"); +#endif + + // Create Vulkan Instance + create_info.enabledExtensionCount = (uint32_t)instance_extensions.Size; + create_info.ppEnabledExtensionNames = instance_extensions.Data; + err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); + check_vk_result(err); +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK + volkLoadInstance(g_Instance); +#endif + + // Setup the debug report callback +#ifdef APP_USE_VULKAN_DEBUG_REPORT + auto f_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); + IM_ASSERT(f_vkCreateDebugReportCallbackEXT != nullptr); + VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; + debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; + debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; + debug_report_ci.pfnCallback = debug_report; + debug_report_ci.pUserData = nullptr; + err = f_vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); + check_vk_result(err); +#endif + } + + // Select Physical Device (GPU) + g_PhysicalDevice = SetupVulkan_SelectPhysicalDevice(); + + // Select graphics queue family + { + uint32_t count; + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, nullptr); + VkQueueFamilyProperties* queues = (VkQueueFamilyProperties*)malloc(sizeof(VkQueueFamilyProperties) * count); + vkGetPhysicalDeviceQueueFamilyProperties(g_PhysicalDevice, &count, queues); + for (uint32_t i = 0; i < count; i++) + if (queues[i].queueFlags & VK_QUEUE_GRAPHICS_BIT) + { + g_QueueFamily = i; + break; + } + free(queues); + IM_ASSERT(g_QueueFamily != (uint32_t)-1); + } + + // Create Logical Device (with 1 queue) + { + ImVector device_extensions; + device_extensions.push_back("VK_KHR_swapchain"); + + // Enumerate physical device extension + uint32_t properties_count; + ImVector properties; + vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, nullptr); + properties.resize(properties_count); + vkEnumerateDeviceExtensionProperties(g_PhysicalDevice, nullptr, &properties_count, properties.Data); +#ifdef VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME + if (IsExtensionAvailable(properties, VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME)) + device_extensions.push_back(VK_KHR_PORTABILITY_SUBSET_EXTENSION_NAME); +#endif + + const float queue_priority[] = { 1.0f }; + VkDeviceQueueCreateInfo queue_info[1] = {}; + queue_info[0].sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; + queue_info[0].queueFamilyIndex = g_QueueFamily; + queue_info[0].queueCount = 1; + queue_info[0].pQueuePriorities = queue_priority; + VkDeviceCreateInfo create_info = {}; + create_info.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO; + create_info.queueCreateInfoCount = sizeof(queue_info) / sizeof(queue_info[0]); + create_info.pQueueCreateInfos = queue_info; + create_info.enabledExtensionCount = (uint32_t)device_extensions.Size; + create_info.ppEnabledExtensionNames = device_extensions.Data; + err = vkCreateDevice(g_PhysicalDevice, &create_info, g_Allocator, &g_Device); + check_vk_result(err); + vkGetDeviceQueue(g_Device, g_QueueFamily, 0, &g_Queue); + } + + // Create Descriptor Pool + // The example only requires a single combined image sampler descriptor for the font image and only uses one descriptor set (for that) + // If you wish to load e.g. additional textures you may need to alter pools sizes. + { + VkDescriptorPoolSize pool_sizes[] = + { + { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1 }, + }; + VkDescriptorPoolCreateInfo pool_info = {}; + pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; + pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; + pool_info.maxSets = 1; + pool_info.poolSizeCount = (uint32_t)IM_ARRAYSIZE(pool_sizes); + pool_info.pPoolSizes = pool_sizes; + err = vkCreateDescriptorPool(g_Device, &pool_info, g_Allocator, &g_DescriptorPool); + check_vk_result(err); + } +} + +// All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo. +// Your real engine/app may not use them. +static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface, int width, int height) +{ + wd->Surface = surface; + + // Check for WSI support + VkBool32 res; + vkGetPhysicalDeviceSurfaceSupportKHR(g_PhysicalDevice, g_QueueFamily, wd->Surface, &res); + if (res != VK_TRUE) + { + fprintf(stderr, "Error no WSI support on physical device 0\n"); + exit(-1); + } + + // Select Surface Format + const VkFormat requestSurfaceImageFormat[] = { VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_B8G8R8_UNORM, VK_FORMAT_R8G8B8_UNORM }; + const VkColorSpaceKHR requestSurfaceColorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR; + wd->SurfaceFormat = ImGui_ImplVulkanH_SelectSurfaceFormat(g_PhysicalDevice, wd->Surface, requestSurfaceImageFormat, (size_t)IM_ARRAYSIZE(requestSurfaceImageFormat), requestSurfaceColorSpace); + + // Select Present Mode +#ifdef APP_UNLIMITED_FRAME_RATE + VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_MAILBOX_KHR, VK_PRESENT_MODE_IMMEDIATE_KHR, VK_PRESENT_MODE_FIFO_KHR }; +#else + VkPresentModeKHR present_modes[] = { VK_PRESENT_MODE_FIFO_KHR }; +#endif + wd->PresentMode = ImGui_ImplVulkanH_SelectPresentMode(g_PhysicalDevice, wd->Surface, &present_modes[0], IM_ARRAYSIZE(present_modes)); + //printf("[vulkan] Selected PresentMode = %d\n", wd->PresentMode); + + // Create SwapChain, RenderPass, Framebuffer, etc. + IM_ASSERT(g_MinImageCount >= 2); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); +} + +static void CleanupVulkan() +{ + vkDestroyDescriptorPool(g_Device, g_DescriptorPool, g_Allocator); + +#ifdef APP_USE_VULKAN_DEBUG_REPORT + // Remove the debug report callback + auto f_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); + f_vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); +#endif // APP_USE_VULKAN_DEBUG_REPORT + + vkDestroyDevice(g_Device, g_Allocator); + vkDestroyInstance(g_Instance, g_Allocator); +} + +static void CleanupVulkanWindow() +{ + ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); +} + +static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data) +{ + VkResult err; + + VkSemaphore image_acquired_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].ImageAcquiredSemaphore; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; + err = vkAcquireNextImageKHR(g_Device, wd->Swapchain, UINT64_MAX, image_acquired_semaphore, VK_NULL_HANDLE, &wd->FrameIndex); + if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) + { + g_SwapChainRebuild = true; + return; + } + check_vk_result(err); + + ImGui_ImplVulkanH_Frame* fd = &wd->Frames[wd->FrameIndex]; + { + err = vkWaitForFences(g_Device, 1, &fd->Fence, VK_TRUE, UINT64_MAX); // wait indefinitely instead of periodically checking + check_vk_result(err); + + err = vkResetFences(g_Device, 1, &fd->Fence); + check_vk_result(err); + } + { + err = vkResetCommandPool(g_Device, fd->CommandPool, 0); + check_vk_result(err); + VkCommandBufferBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + info.flags |= VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + err = vkBeginCommandBuffer(fd->CommandBuffer, &info); + check_vk_result(err); + } + { + VkRenderPassBeginInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; + info.renderPass = wd->RenderPass; + info.framebuffer = fd->Framebuffer; + info.renderArea.extent.width = wd->Width; + info.renderArea.extent.height = wd->Height; + info.clearValueCount = 1; + info.pClearValues = &wd->ClearValue; + vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); + } + + // Record dear imgui primitives into command buffer + ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer); + + // Submit command buffer + vkCmdEndRenderPass(fd->CommandBuffer); + { + VkPipelineStageFlags wait_stage = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; + VkSubmitInfo info = {}; + info.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &image_acquired_semaphore; + info.pWaitDstStageMask = &wait_stage; + info.commandBufferCount = 1; + info.pCommandBuffers = &fd->CommandBuffer; + info.signalSemaphoreCount = 1; + info.pSignalSemaphores = &render_complete_semaphore; + + err = vkEndCommandBuffer(fd->CommandBuffer); + check_vk_result(err); + err = vkQueueSubmit(g_Queue, 1, &info, fd->Fence); + check_vk_result(err); + } +} + +static void FramePresent(ImGui_ImplVulkanH_Window* wd) +{ + if (g_SwapChainRebuild) + return; + VkSemaphore render_complete_semaphore = wd->FrameSemaphores[wd->SemaphoreIndex].RenderCompleteSemaphore; + VkPresentInfoKHR info = {}; + info.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; + info.waitSemaphoreCount = 1; + info.pWaitSemaphores = &render_complete_semaphore; + info.swapchainCount = 1; + info.pSwapchains = &wd->Swapchain; + info.pImageIndices = &wd->FrameIndex; + VkResult err = vkQueuePresentKHR(g_Queue, &info); + if (err == VK_ERROR_OUT_OF_DATE_KHR || err == VK_SUBOPTIMAL_KHR) + { + g_SwapChainRebuild = true; + return; + } + check_vk_result(err); + wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores +} + +// Main code +int main(int, char**) +{ + // Setup SDL + if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD)) + { + printf("Error: %s\n", SDL_GetError()); + return -1; + } + + // From 2.0.18: Enable native IME. +#ifdef SDL_HINT_IME_SHOW_UI + SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1"); +#endif + + // Create window with Vulkan graphics context + SDL_WindowFlags window_flags = (SDL_WindowFlags)(SDL_WINDOW_VULKAN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY); + SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL2+Vulkan example", 1280, 720, window_flags); + SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); + if (window == nullptr) + { + printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError()); + return -1; + } + + + uint32_t extensions_count = 0; + const char* const* extensions = SDL_Vulkan_GetInstanceExtensions(&extensions_count); + ImVector extensions_vec; + extensions_vec.resize(extensions_count); + for (uint32_t i = 0; i < extensions_count; ++i) + { + extensions_vec[i] = extensions[i]; + } + // std::move + SetupVulkan(static_cast&&>(extensions_vec)); + + // Create Window Surface + VkSurfaceKHR surface; + VkResult err; + if (!SDL_Vulkan_CreateSurface(window, g_Instance, g_Allocator, &surface)) + { + printf("Failed to create Vulkan surface.\n"); + return 1; + } + + // Create Framebuffers + int w, h; + SDL_GetWindowSize(window, &w, &h); + ImGui_ImplVulkanH_Window* wd = &g_MainWindowData; + SetupVulkanWindow(wd, surface, w, h); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsLight(); + + // Setup Platform/Renderer backends + ImGui_ImplSDL3_InitForVulkan(window); + ImGui_ImplVulkan_InitInfo init_info = {}; + init_info.Instance = g_Instance; + init_info.PhysicalDevice = g_PhysicalDevice; + init_info.Device = g_Device; + init_info.QueueFamily = g_QueueFamily; + init_info.Queue = g_Queue; + init_info.PipelineCache = g_PipelineCache; + init_info.DescriptorPool = g_DescriptorPool; + init_info.RenderPass = wd->RenderPass; + init_info.Subpass = 0; + init_info.MinImageCount = g_MinImageCount; + init_info.ImageCount = wd->ImageCount; + init_info.MSAASamples = VK_SAMPLE_COUNT_1_BIT; + init_info.Allocator = g_Allocator; + init_info.CheckVkResultFn = check_vk_result; + ImGui_ImplVulkan_Init(&init_info); + + // 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. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - The fonts will be rasterized at a given size (w/ oversampling) and stored into a texture when calling ImFontAtlas::Build()/GetTexDataAsXXXX(), which ImGui_ImplXXXX_NewFrame below will call. + // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + //io.Fonts->AddFontDefault(); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf", 18.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf", 16.0f); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf", 15.0f); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf", 18.0f, nullptr, io.Fonts->GetGlyphRangesJapanese()); + //IM_ASSERT(font != nullptr); + + // Our state + bool show_demo_window = true; + bool show_another_window = false; + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle events (inputs, window resize, etc.) + // You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. + // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. + // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. + // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. + SDL_Event event; + while (SDL_PollEvent(&event)) + { + ImGui_ImplSDL3_ProcessEvent(&event); + if (event.type == SDL_QUIT) + done = true; + if (event.type == SDL_EVENT_WINDOW_CLOSE_REQUESTED && event.window.windowID == SDL_GetWindowID(window)) + done = true; + } + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) + { + SDL_Delay(10); + continue; + } + + // Resize swap chain? + int fb_width, fb_height; + SDL_GetWindowSize(window, &fb_width, &fb_height); + if (fb_width > 0 && fb_height > 0 && (g_SwapChainRebuild || g_MainWindowData.Width != fb_width || g_MainWindowData.Height != fb_height)) + { + ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, fb_width, fb_height, g_MinImageCount); + g_MainWindowData.FrameIndex = 0; + g_SwapChainRebuild = false; + } + + // Start the Dear ImGui frame + ImGui_ImplVulkan_NewFrame(); + ImGui_ImplSDL3_NewFrame(); + ImGui::NewFrame(); + + // 1. Show the big demo window (Most of the sample code is in ImGui::ShowDemoWindow()! You can browse its code to learn more about Dear ImGui!). + if (show_demo_window) + ImGui::ShowDemoWindow(&show_demo_window); + + // 2. Show a simple window that we create ourselves. We use a Begin/End pair to create a named window. + { + static float f = 0.0f; + static int counter = 0; + + ImGui::Begin("Hello, world!"); // Create a window called "Hello, world!" and append into it. + + ImGui::Text("This is some useful text."); // Display some text (you can use a format strings too) + ImGui::Checkbox("Demo Window", &show_demo_window); // Edit bools storing our window open/close state + ImGui::Checkbox("Another Window", &show_another_window); + + ImGui::SliderFloat("float", &f, 0.0f, 1.0f); // Edit 1 float using a slider from 0.0f to 1.0f + ImGui::ColorEdit3("clear color", (float*)&clear_color); // Edit 3 floats representing a color + + if (ImGui::Button("Button")) // Buttons return true when clicked (most widgets return true when edited/activated) + counter++; + ImGui::SameLine(); + ImGui::Text("counter = %d", counter); + + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / io.Framerate, io.Framerate); + ImGui::End(); + } + + // 3. Show another simple window. + if (show_another_window) + { + ImGui::Begin("Another Window", &show_another_window); // Pass a pointer to our bool variable (the window will have a closing button that will clear the bool when clicked) + ImGui::Text("Hello from another window!"); + if (ImGui::Button("Close Me")) + show_another_window = false; + ImGui::End(); + } + + // Rendering + ImGui::Render(); + ImDrawData* draw_data = ImGui::GetDrawData(); + const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); + if (!is_minimized) + { + wd->ClearValue.color.float32[0] = clear_color.x * clear_color.w; + wd->ClearValue.color.float32[1] = clear_color.y * clear_color.w; + wd->ClearValue.color.float32[2] = clear_color.z * clear_color.w; + wd->ClearValue.color.float32[3] = clear_color.w; + FrameRender(wd, draw_data); + FramePresent(wd); + } + } + + // Cleanup + err = vkDeviceWaitIdle(g_Device); + check_vk_result(err); + ImGui_ImplVulkan_Shutdown(); + ImGui_ImplSDL3_Shutdown(); + ImGui::DestroyContext(); + + CleanupVulkanWindow(); + CleanupVulkan(); + + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +}