diff --git a/demo/gl/tz_triangle_demo.cpp b/demo/gl/tz_triangle_demo.cpp index d79aaacd10..8220583ca9 100644 --- a/demo/gl/tz_triangle_demo.cpp +++ b/demo/gl/tz_triangle_demo.cpp @@ -21,12 +21,12 @@ int main() rinfo.shader().set_shader(tz::gl::ShaderStage::Fragment, ImportedShaderSource(tz_triangle_demo, fragment)); rinfo.set_options({tz::gl::RendererOption::NoDepthTesting}); - tz::gl::Renderer renderer = tz::gl::device().create_renderer(rinfo); + tz::gl::RendererHandle renh = tz::gl::device().create_renderer(rinfo); while(!tz::window().is_close_requested()) { tz::window().begin_frame(); - renderer.render(1); + tz::gl::device().get_renderer(renh).render(1); tz::dbgui::run([]() { ImGui::ShowDemoWindow(); diff --git a/src/tz/dbgui/dbgui.cpp b/src/tz/dbgui/dbgui.cpp index 01369f7760..7ca638abf6 100644 --- a/src/tz/dbgui/dbgui.cpp +++ b/src/tz/dbgui/dbgui.cpp @@ -35,8 +35,8 @@ namespace tz::dbgui struct TopazRenderData { - std::unique_ptr renderer = nullptr; - std::unique_ptr final_renderer = nullptr; + tz::gl::RendererHandle renderer = tz::nullhand; + tz::gl::RendererHandle final_renderer = tz::nullhand; tz::gl::ResourceHandle vertex_buffer = tz::nullhand; tz::gl::ResourceHandle index_buffer = tz::nullhand; tz::gl::ResourceHandle shader_data_buffer = tz::nullhand; @@ -348,14 +348,14 @@ namespace tz::dbgui rinfo.set_output(wout); rinfo.debug_name("ImGui Intermediate Renderer"); - global_render_data->renderer = std::make_unique(tz::gl::device().create_renderer(rinfo)); + global_render_data->renderer = tz::gl::device().create_renderer(rinfo); tz::gl::RendererInfo empty; empty.shader().set_shader(tz::gl::ShaderStage::Vertex, ImportedShaderSource(empty, vertex)); empty.shader().set_shader(tz::gl::ShaderStage::Fragment, ImportedShaderSource(empty, fragment)); empty.set_options({tz::gl::RendererOption::NoClearOutput, tz::gl::RendererOption::NoDepthTesting, tz::gl::RendererOption::Internal_FinalDebugUIRenderer}); empty.debug_name("ImGui Final Renderer"); - global_render_data->final_renderer = std::make_unique(tz::gl::device().create_renderer(empty)); + global_render_data->final_renderer = tz::gl::device().create_renderer(empty); io.Fonts->SetTexID(0); @@ -382,9 +382,9 @@ namespace tz::dbgui tz_assert(draw != nullptr, "Null imgui draw data!"); tz_assert(draw->Valid, "Invalid draw data!"); - tz_assert(global_render_data->renderer != nullptr, "Null imgui renderer when trying to render!"); + tz_assert(global_render_data->renderer != tz::nullhand, "Null imgui renderer when trying to render!"); // We have a font texture already. - tz::gl::Renderer& renderer = *(global_render_data->renderer); + tz::gl::Renderer& renderer = tz::gl::device().get_renderer(global_render_data->renderer); // We have no idea how big our vertex/index buffers need to be. Let's copy over the data now. const auto req_idx_size = static_cast(draw->TotalIdxCount) * sizeof(ImDrawIdx); const auto req_vtx_size = static_cast(draw->TotalVtxCount) * sizeof(ImDrawVert); @@ -466,7 +466,7 @@ namespace tz::dbgui } { TZ_PROFZONE("Dbgui Render - Final Pass", TZ_PROFCOL_PURPLE); - global_render_data->final_renderer->render(); + tz::gl::device().get_renderer(global_render_data->final_renderer).render(); } } @@ -474,6 +474,7 @@ namespace tz::dbgui { bool show_info = false; bool show_window_info = false; + bool show_device_info = false; }; ImGuiTabTZ tab_tz; @@ -644,6 +645,15 @@ namespace tz::dbgui } + void draw_tz_device_info() + { + if(ImGui::Begin("Device", &tab_tz.show_device_info)) + { + ImGui::Text("well met"); + ImGui::End(); + } + } + void imgui_impl_begin_commands() { if(ImGui::BeginMainMenuBar()) @@ -652,6 +662,7 @@ namespace tz::dbgui { ImGui::MenuItem("Info", nullptr, &tab_tz.show_info); ImGui::MenuItem("Window", nullptr, &tab_tz.show_window_info); + ImGui::MenuItem("Device", nullptr, &tab_tz.show_device_info); if(ImGui::MenuItem("Debug Breakpoint")) { tz_error("Manual debug breakpoint occurred."); @@ -673,6 +684,10 @@ namespace tz::dbgui { draw_tz_window_info(); } + if(tab_tz.show_device_info) + { + draw_tz_device_info(); + } } } diff --git a/src/tz/gl/api/device.hpp b/src/tz/gl/api/device.hpp index bd44e6c415..0f7ec8f8fe 100644 --- a/src/tz/gl/api/device.hpp +++ b/src/tz/gl/api/device.hpp @@ -16,12 +16,13 @@ namespace tz::gl * - Have direct access to the window surface, and exposes relevant information about said surface. */ template - concept DeviceType = requires(T t, RendererInfo& rinfo) + concept DeviceType = requires(T t, RendererInfo& rinfo, RendererHandle h) { requires std::is_default_constructible_v>; requires RendererInfoType; - {t.create_renderer(rinfo)} -> RendererType; + {t.create_renderer(rinfo)} -> std::same_as; + {t.get_renderer(h)} -> RendererType; {t.get_window_format()} -> std::same_as; }; } diff --git a/src/tz/gl/api/renderer.hpp b/src/tz/gl/api/renderer.hpp index 070ea8128c..c913ee9d49 100644 --- a/src/tz/gl/api/renderer.hpp +++ b/src/tz/gl/api/renderer.hpp @@ -14,6 +14,10 @@ namespace tz::gl { + namespace detail + { + struct RendererTag{}; + } /** * @ingroup tz_gl2_renderer * Specifies options to enable extra functionality within Renderers. @@ -133,6 +137,12 @@ namespace tz::gl */ using RendererEditRequest = std::vector; + /** + * @ingroup tz_gl2_renderer + * Represents a handle for a renderer owned by an existing device. + */ + using RendererHandle = tz::Handle; + /** * @ingroup tz_gl2_renderer * Named requirement for a Renderer. diff --git a/src/tz/gl/impl/frontend/ogl2/device.cpp b/src/tz/gl/impl/frontend/ogl2/device.cpp index 04ffc268dc..18377d74ac 100644 --- a/src/tz/gl/impl/frontend/ogl2/device.cpp +++ b/src/tz/gl/impl/frontend/ogl2/device.cpp @@ -11,10 +11,21 @@ namespace tz::gl glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); } - RendererOGL DeviceOGL::create_renderer(const RendererInfoOGL& info) + tz::gl::RendererHandle DeviceOGL::create_renderer(const RendererInfoOGL& info) { TZ_PROFZONE("OpenGL Frontend - Renderer Create (via Device)", TZ_PROFCOL_RED); - return {info}; + this->renderers.push_back({info}); + return static_cast(this->renderers.size() - 1); + } + + const RendererOGL& DeviceOGL::get_renderer(tz::gl::RendererHandle handle) const + { + return this->renderers[static_cast(static_cast(handle))]; + } + + RendererOGL& DeviceOGL::get_renderer(tz::gl::RendererHandle handle) + { + return this->renderers[static_cast(static_cast(handle))]; } ImageFormat DeviceOGL::get_window_format() const diff --git a/src/tz/gl/impl/frontend/ogl2/device.hpp b/src/tz/gl/impl/frontend/ogl2/device.hpp index 231bf7893c..a2819762b8 100644 --- a/src/tz/gl/impl/frontend/ogl2/device.hpp +++ b/src/tz/gl/impl/frontend/ogl2/device.hpp @@ -13,8 +13,12 @@ namespace tz::gl DeviceOGL(); // Satisfies DeviceType. - RendererOGL create_renderer(const RendererInfoOGL& info); + tz::gl::RendererHandle create_renderer(const RendererInfoOGL& info); + const RendererOGL& get_renderer(tz::gl::RendererHandle handle) const; + RendererOGL& get_renderer(tz::gl::RendererHandle handle); ImageFormat get_window_format() const; + private: + std::vector renderers; }; static_assert(DeviceType); } diff --git a/src/tz/gl/impl/frontend/vk2/device.cpp b/src/tz/gl/impl/frontend/vk2/device.cpp index 71095d25e1..e75ed3b660 100644 --- a/src/tz/gl/impl/frontend/vk2/device.cpp +++ b/src/tz/gl/impl/frontend/vk2/device.cpp @@ -342,17 +342,28 @@ namespace tz::gl TZ_PROFZONE("Vulkan Frontend - DeviceVulkan Create", TZ_PROFCOL_YELLOW); } - RendererVulkan DeviceVulkan::create_renderer(const RendererInfoVulkan& info) + tz::gl::RendererHandle DeviceVulkan::create_renderer(const RendererInfoVulkan& info) { TZ_PROFZONE("Vulkan Frontend - Renderer Create (via DeviceVulkan)", TZ_PROFCOL_YELLOW); - return {info, + this->renderers.push_back({info, { .device = &this->device, .output_images = this->window_storage.get_output_images(), .device_window = &this->window_storage, .device_scheduler = &this->scheduler, .resize_callback = &this->window_storage.resize_callback() - }}; + }}); + return static_cast(this->renderers.size() - 1); + } + + const tz::gl::RendererVulkan& DeviceVulkan::get_renderer(tz::gl::RendererHandle handle) const + { + return this->renderers[static_cast(static_cast(handle))]; + } + + tz::gl::RendererVulkan& DeviceVulkan::get_renderer(tz::gl::RendererHandle handle) + { + return this->renderers[static_cast(static_cast(handle))]; } ImageFormat DeviceVulkan::get_window_format() const diff --git a/src/tz/gl/impl/frontend/vk2/device.hpp b/src/tz/gl/impl/frontend/vk2/device.hpp index ba8ad90819..6e0a93b716 100644 --- a/src/tz/gl/impl/frontend/vk2/device.hpp +++ b/src/tz/gl/impl/frontend/vk2/device.hpp @@ -76,7 +76,9 @@ namespace tz::gl DeviceVulkan(const DeviceVulkan& copy) = delete; // Satisfies DeviceType. - RendererVulkan create_renderer(const RendererInfoVulkan& info); + tz::gl::RendererHandle create_renderer(const RendererInfoVulkan& info); + const tz::gl::RendererVulkan& get_renderer(tz::gl::RendererHandle handle) const; + tz::gl::RendererVulkan& get_renderer(tz::gl::RendererHandle handle); ImageFormat get_window_format() const; const vk2::LogicalDevice& vk_get_logical_device() const; private: @@ -85,6 +87,7 @@ namespace tz::gl vk2::LogicalDevice device; DeviceWindowVulkan window_storage; DeviceRenderSchedulerVulkan scheduler; + std::vector renderers; }; static_assert(DeviceType);