Skip to content

Commit

Permalink
Backends: SDLGPU3: Added sdl_gpu backend (amends). (#8163, #7998, #7988)
Browse files Browse the repository at this point in the history
  • Loading branch information
ocornut committed Jan 9, 2025
1 parent 8bbccf7 commit e799849
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 201 deletions.
301 changes: 144 additions & 157 deletions backends/imgui_impl_sdlgpu3.cpp

Large diffs are not rendered by default.

18 changes: 9 additions & 9 deletions backends/imgui_impl_sdlgpu3.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// dear imgui: Renderer Backend for SDL_Gpu
// dear imgui: Renderer Backend for SDL_GPU
// This needs to be used along with the SDL3 Platform Backend

// Implemented features:
Expand Down Expand Up @@ -27,20 +27,20 @@

// Initialization data, for ImGui_ImplSDLGPU_Init()
// - Remember to set ColorTargetFormat to the correct format. If you're rendering to the swapchain, call SDL_GetGPUSwapchainTextureFormat to query the right value
struct ImGui_ImplSDLGPU_InitInfo
struct ImGui_ImplSDLGPU3_InitInfo
{
SDL_GPUDevice* GpuDevice = nullptr;
SDL_GPUTextureFormat ColorTargetFormat = SDL_GPU_TEXTUREFORMAT_INVALID;
SDL_GPUSampleCount MSAASamples = SDL_GPU_SAMPLECOUNT_1;
};

// Follow "Getting Started" link and check examples/ folder to learn about using backends!
IMGUI_IMPL_API bool ImGui_ImplSDLGPU_Init(ImGui_ImplSDLGPU_InitInfo* info);
IMGUI_IMPL_API void ImGui_ImplSDLGPU_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDLGPU_NewFrame();
IMGUI_IMPL_API void Imgui_ImplSDLGPU_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer);
IMGUI_IMPL_API void ImGui_ImplSDLGPU_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline = nullptr);
IMGUI_IMPL_API bool ImGui_ImplSDLGPU_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplSDLGPU_DestroyFontsTexture();
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_Init(ImGui_ImplSDLGPU3_InitInfo* info);
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_Shutdown();
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_NewFrame();
IMGUI_IMPL_API void Imgui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer);
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline = nullptr);
IMGUI_IMPL_API bool ImGui_ImplSDLGPU3_CreateFontsTexture();
IMGUI_IMPL_API void ImGui_ImplSDLGPU3_DestroyFontsTexture();

#endif // #ifndef IMGUI_DISABLE
6 changes: 5 additions & 1 deletion backends/sdlgpu3/build_instructions.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@

Instructions to rebuild imgui_impl_sdlgpu3_shaders.h
(You don't need to copy this folder if you are using the backend as-is)

1) Compile the raw shader files to SPIRV:

glslc -o vertex.spv -c shader.vert
Expand Down Expand Up @@ -33,4 +37,4 @@
Proceed to step 4


4) Either find a way to load the shader bytecode from file, or use a tool like https://notisrac.github.io/FileToCArray/ to convert the file to a uint8_t array
4) Use a tool like https://notisrac.github.io/FileToCArray/ or misc/fonts/binary_to_compressed_c.cpp in imgui repository to convert the file to a uint8_t array.
5 changes: 3 additions & 2 deletions backends/sdlgpu3/shader.frag
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ layout(location = 0) out vec4 fColor;

layout(set=2, binding=0) uniform sampler2D sTexture;

layout(location = 0) in struct {
layout(location = 0) in struct
{
vec4 Color;
vec2 UV;
} In;

void main()
{
fColor = In.Color * texture(sTexture, In.UV.st);
}
}
8 changes: 5 additions & 3 deletions backends/sdlgpu3/shader.vert
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ layout(location = 0) in vec2 aPos;
layout(location = 1) in vec2 aUV;
layout(location = 2) in vec4 aColor;

layout(set=1,binding=0) uniform UBO {
layout(set=1,binding=0) uniform UBO
{
vec2 uScale;
vec2 uTranslate;
} ubo;

layout(location = 0) out struct {
layout(location = 0) out struct
{
vec4 Color;
vec2 UV;
} Out;
Expand All @@ -19,4 +21,4 @@ void main()
Out.UV = aUV;
gl_Position = vec4(aPos * ubo.uScale + ubo.uTranslate, 0, 1);
gl_Position.y *= -1.0f;
}
}
4 changes: 4 additions & 0 deletions backends/vulkan/build_instructions.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

Script to rebuild shaders stored inside imgui_impl_vulkan.h
(You don't need to copy this folder if you are using the backend as-is)

1 change: 1 addition & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ Other changes:
- Demo: Added label edition to Property Editor demo + fix an ID issue. (#8266) [@moritz-h]
- Misc: Fixed misc/cpp/imgui_stdlib.h/.cpp not supporting IMGUI_DISABLE. (#8294) [@juur]
- Misc: Fixed MinGW builds uses UTF-8 friendly _wfopen(). (#8300)
- Backends: SDL_GPU for SDL3: Added backend for SDL_GPU! (#8163, #7998, #7988) [@DeltaW0x].
- Backends: Allegro5: Avoid calling al_set_mouse_cursor() repeatedly since it appears
to leak on on X11 (#8256). [@Helodity]
- Backends: Metal: Fixed leaks when using metal-cpp. (#8276, #8166) [@selimsandal]
Expand Down
24 changes: 22 additions & 2 deletions docs/EXAMPLES.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,8 @@ This support building with Emscripten and targeting WebGL.<BR>
Prefer using that if you are using modern GL or WebGL in your application.

[example_sdl2_sdlrenderer2/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_sdlrenderer2/) <BR>
SDL2 (Win32, Mac, Linux, etc.) + SDL_Renderer for SDL2 (most graphics backends are supported underneath) <BR>
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer.cpp <BR>
SDL2 (Win32, Mac, Linux, etc.) + SDL_Renderer for SDL2 example.<BR>
= main.cpp + imgui_impl_sdl2.cpp + imgui_impl_sdlrenderer2.cpp <BR>
This requires SDL 2.0.18+ (released November 2021) <BR>

[example_sdl2_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl2_vulkan/) <BR>
Expand All @@ -149,6 +149,26 @@ SDL2 (Win32, Mac, Linux, etc.) + Vulkan example. <BR>
This is quite long and tedious, because: Vulkan. <BR>
For this example, the main.cpp file exceptionally use helpers function from imgui_impl_vulkan.h/cpp.

[example_sdl3_opengl3/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_opengl3/) <BR>
SDL3 (Win32, Mac, Linux, etc.) + OpenGL3+/ES2/ES3 example. <BR>
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_opengl3.cpp <BR>
This uses more modern GL calls and custom shaders. <BR>
This support building with Emscripten and targeting WebGL.<BR>

[example_sdl3_sdlgpu3/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_sdlgpu3/) <BR>
SDL3 (Win32, Mac, Linux, etc.) + SDL_GPU for SDL3 example.<BR>
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_sdlrenderer3.cpp <BR>

[example_sdl3_sdlrenderer3/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_sdlrenderer3/) <BR>
SDL3 (Win32, Mac, Linux, etc.) + SDL_Renderer for SDL3 example.<BR>
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_sdlrenderer3.cpp <BR>

[example_sdl3_vulkan/](https://github.com/ocornut/imgui/blob/master/examples/example_sdl3_vulkan/) <BR>
SDL3 (Win32, Mac, Linux, etc.) + Vulkan example. <BR>
= main.cpp + imgui_impl_sdl3.cpp + imgui_impl_vulkan.cpp <BR>
This is quite long and tedious, because: Vulkan. <BR>
For this example, the main.cpp file exceptionally use helpers function from imgui_impl_vulkan.h/cpp.

[example_win32_directx9/](https://github.com/ocornut/imgui/blob/master/examples/example_win32_directx9/) <BR>
DirectX9 example, Windows only. <BR>
= main.cpp + imgui_impl_win32.cpp + imgui_impl_dx9.cpp
Expand Down
2 changes: 1 addition & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ On most platforms and when using C++, **you should be able to use a combination
Integrating Dear ImGui within your custom engine is a matter of 1) wiring mouse/keyboard/gamepad inputs 2) uploading a texture to your GPU/render engine 3) providing a render function that can bind textures and render textured triangles, which is essentially what Backends are doing. The [examples/](https://github.com/ocornut/imgui/tree/master/examples) folder is populated with applications doing just that: setting up a window and using backends. If you follow the [Getting Started](https://github.com/ocornut/imgui/wiki/Getting-Started) guide it should in theory takes you less than an hour to integrate Dear ImGui. **Make sure to spend time reading the [FAQ](https://www.dearimgui.com/faq), comments, and the examples applications!**

Officially maintained backends/bindings (in repository):
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_Renderer, Vulkan, WebGPU.
- Renderers: DirectX9, DirectX10, DirectX11, DirectX12, Metal, OpenGL/ES/ES2, SDL_GPU, SDL_Renderer2/3, Vulkan, WebGPU.
- Platforms: GLFW, SDL2/SDL3, Win32, Glut, OSX, Android.
- Frameworks: Allegro5, Emscripten.

Expand Down
53 changes: 27 additions & 26 deletions examples/example_sdl3_sdlgpu3/main.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Dear ImGui: standalone example application for SDL_Gpu
// Dear ImGui: standalone example application for SDL3 + SDL_GPU

// Learn about Dear ImGui:
// - FAQ https://dearimgui.com/faq
Expand All @@ -17,7 +17,6 @@
#include <stdlib.h> // abort
#include <SDL3/SDL.h>


// This example doesn't compile with Emscripten yet! Awaiting SDL3 support.
#ifdef __EMSCRIPTEN__
#include "../libs/emscripten/emscripten_mainloop_stub.h"
Expand All @@ -34,23 +33,23 @@ int main(int, char**)
}

// Create SDL window graphics context
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDLGpu example", 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY);
SDL_Window* window = SDL_CreateWindow("Dear ImGui SDL3+SDL_GPU example", 1280, 720, SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY);
if (window == nullptr)
{
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
return -1;
}

// Create SDL Gpu Device
SDL_GPUDevice* gpuDevice = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV | SDL_GPU_SHADERFORMAT_DXIL | SDL_GPU_SHADERFORMAT_METALLIB,true,nullptr);
if (gpuDevice == nullptr)
// Create GPU Device
SDL_GPUDevice* gpu_device = SDL_CreateGPUDevice(SDL_GPU_SHADERFORMAT_SPIRV | SDL_GPU_SHADERFORMAT_DXIL | SDL_GPU_SHADERFORMAT_METALLIB,true,nullptr);
if (gpu_device == nullptr)
{
printf("Error: SDL_CreateGPUDevice(): %s\n", SDL_GetError());
return -1;
}

// Claim window for GPU Device
if (!SDL_ClaimWindowForGPUDevice(gpuDevice, window))
if (!SDL_ClaimWindowForGPUDevice(gpu_device, window))
{
printf("Error: SDL_ClaimWindowForGPUDevice(): %s\n", SDL_GetError());
return -1;
Expand All @@ -69,11 +68,11 @@ int main(int, char**)

// Setup Platform/Renderer backends
ImGui_ImplSDL3_InitForOther(window);
ImGui_ImplSDLGPU_InitInfo init_info = {};
init_info.GpuDevice = gpuDevice;
init_info.ColorTargetFormat = SDL_GetGPUSwapchainTextureFormat(gpuDevice, window);
ImGui_ImplSDLGPU3_InitInfo init_info = {};
init_info.GpuDevice = gpu_device;
init_info.ColorTargetFormat = SDL_GetGPUSwapchainTextureFormat(gpu_device, window);
init_info.MSAASamples = SDL_GPU_SAMPLECOUNT_1;
ImGui_ImplSDLGPU_Init(&init_info);
ImGui_ImplSDLGPU3_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.
Expand Down Expand Up @@ -119,9 +118,9 @@ int main(int, char**)
SDL_Delay(10);
continue;
}

// Start the Dear ImGui frame
ImGui_ImplSDLGPU_NewFrame();
ImGui_ImplSDLGPU3_NewFrame();
ImGui_ImplSDL3_NewFrame();
ImGui::NewFrame();

Expand Down Expand Up @@ -167,18 +166,15 @@ int main(int, char**)
ImDrawData* draw_data = ImGui::GetDrawData();
const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f);

// Acquire a GPU command buffer
SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(gpuDevice);
SDL_GPUCommandBuffer* command_buffer = SDL_AcquireGPUCommandBuffer(gpu_device); // Acquire a GPU command buffer

//Acquire a swapchain texture
SDL_GPUTexture* swapchain_texture;
SDL_AcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr);
SDL_AcquireGPUSwapchainTexture(command_buffer, window, &swapchain_texture, nullptr, nullptr); // Acquire a swapchain texture

if (swapchain_texture != nullptr && !is_minimized)
{
// !!! THIS IS MANDATORY !!!
// Call Imgui_ImplSDLGPU_PrepareDrawData to upload the vertex/index buffer
Imgui_ImplSDLGPU_PrepareDrawData(draw_data, command_buffer);
// This is mandatory: call Imgui_ImplSDLGPU3_PrepareDrawData() to upload the vertex/index buffer!
Imgui_ImplSDLGPU3_PrepareDrawData(draw_data, command_buffer);

// Setup and start a render pass
SDL_GPUColorTargetInfo target_info = {};
Expand All @@ -190,21 +186,26 @@ int main(int, char**)
target_info.layer_or_depth_plane = 0;
target_info.cycle = false;
SDL_GPURenderPass* render_pass = SDL_BeginGPURenderPass(command_buffer, &target_info, 1, nullptr);
/// Render ImGui
ImGui_ImplSDLGPU_RenderDrawData(draw_data, command_buffer, render_pass);

// Render ImGui
ImGui_ImplSDLGPU3_RenderDrawData(draw_data, command_buffer, render_pass);

SDL_EndGPURenderPass(render_pass);
}

// Submit the command buffer
SDL_SubmitGPUCommandBuffer(command_buffer);
}
// Cleanup
SDL_WaitForGPUIdle(gpuDevice);
SDL_WaitForGPUIdle(gpu_device);
ImGui_ImplSDL3_Shutdown();
ImGui_ImplSDLGPU_Shutdown();
ImGui_ImplSDLGPU3_Shutdown();
ImGui::DestroyContext();
SDL_ReleaseWindowFromGPUDevice(gpuDevice, window);
SDL_DestroyGPUDevice(gpuDevice);

SDL_ReleaseWindowFromGPUDevice(gpu_device, window);
SDL_DestroyGPUDevice(gpu_device);
SDL_DestroyWindow(window);
SDL_Quit();

return 0;
}

0 comments on commit e799849

Please sign in to comment.