From c93ed0fd777cd01fbbdc91208ab9620661f8ca23 Mon Sep 17 00:00:00 2001 From: daiqingshuang Date: Mon, 19 Feb 2024 18:02:58 +0800 Subject: [PATCH] vulkan pipeline --- core/application/application.cpp | 3 +- core/application/application.h | 10 +- core/rhi/opengl/opengl_def.h | 8 - .../rhi/opengl/pixel_shader_drawer_opengl.cpp | 135 ------------ core/rhi/opengl/pixel_shader_drawer_opengl.h | 33 --- core/rhi/opengl/render_target_opengl.cpp | 182 ---------------- core/rhi/opengl/render_target_opengl.h | 28 --- core/rhi/opengl/renderer_opengl.cpp | 132 ------------ core/rhi/opengl/renderer_opengl.h | 30 --- core/rhi/opengl/shader/shader_cs_opengl.cpp | 22 -- core/rhi/opengl/shader/shader_cs_opengl.h | 16 -- core/rhi/opengl/shader/shader_gs_opengl.cpp | 1 - core/rhi/opengl/shader/shader_gs_opengl.h | 11 - core/rhi/opengl/shader/shader_opengl.cpp | 63 ------ core/rhi/opengl/shader/shader_opengl.h | 59 ------ .../opengl/shader/shader_program_opengl.cpp | 196 ------------------ .../rhi/opengl/shader/shader_program_opengl.h | 82 -------- core/rhi/opengl/shader/shader_ps_opengl.cpp | 1 - core/rhi/opengl/shader/shader_ps_opengl.h | 13 -- core/rhi/opengl/shader/shader_vs_opengl.cpp | 1 - core/rhi/opengl/shader/shader_vs_opengl.h | 10 - core/rhi/opengl/texture_opengl.cpp | 34 --- core/rhi/opengl/texture_opengl.h | 18 -- core/rhi/pixel_shader_drawer.cpp | 1 - core/rhi/pixel_shader_drawer.h | 22 -- core/rhi/vulkan/compute_pipeline.cpp | 48 +++++ core/rhi/vulkan/compute_pipeline.h | 14 ++ core/rhi/vulkan/pipeline.cpp | 46 ++++ core/rhi/vulkan/pipeline.h | 43 ++++ core/rhi/vulkan/render_target_vk.cpp | 1 + core/rhi/vulkan/render_target_vk.h | 8 + core/rhi/vulkan/renderer_vk.cpp | 34 ++- core/rhi/vulkan/renderer_vk.h | 18 +- core/rhi/vulkan/texture_vk.cpp | 51 +++++ core/rhi/vulkan/texture_vk.h | 17 ++ 35 files changed, 263 insertions(+), 1128 deletions(-) delete mode 100644 core/rhi/opengl/opengl_def.h delete mode 100644 core/rhi/opengl/pixel_shader_drawer_opengl.cpp delete mode 100644 core/rhi/opengl/pixel_shader_drawer_opengl.h delete mode 100644 core/rhi/opengl/render_target_opengl.cpp delete mode 100644 core/rhi/opengl/render_target_opengl.h delete mode 100644 core/rhi/opengl/renderer_opengl.cpp delete mode 100644 core/rhi/opengl/renderer_opengl.h delete mode 100644 core/rhi/opengl/shader/shader_cs_opengl.cpp delete mode 100644 core/rhi/opengl/shader/shader_cs_opengl.h delete mode 100644 core/rhi/opengl/shader/shader_gs_opengl.cpp delete mode 100644 core/rhi/opengl/shader/shader_gs_opengl.h delete mode 100644 core/rhi/opengl/shader/shader_opengl.cpp delete mode 100644 core/rhi/opengl/shader/shader_opengl.h delete mode 100644 core/rhi/opengl/shader/shader_program_opengl.cpp delete mode 100644 core/rhi/opengl/shader/shader_program_opengl.h delete mode 100644 core/rhi/opengl/shader/shader_ps_opengl.cpp delete mode 100644 core/rhi/opengl/shader/shader_ps_opengl.h delete mode 100644 core/rhi/opengl/shader/shader_vs_opengl.cpp delete mode 100644 core/rhi/opengl/shader/shader_vs_opengl.h delete mode 100644 core/rhi/opengl/texture_opengl.cpp delete mode 100644 core/rhi/opengl/texture_opengl.h delete mode 100644 core/rhi/pixel_shader_drawer.cpp delete mode 100644 core/rhi/pixel_shader_drawer.h create mode 100644 core/rhi/vulkan/compute_pipeline.cpp create mode 100644 core/rhi/vulkan/compute_pipeline.h create mode 100644 core/rhi/vulkan/pipeline.cpp create mode 100644 core/rhi/vulkan/pipeline.h create mode 100644 core/rhi/vulkan/render_target_vk.cpp create mode 100644 core/rhi/vulkan/render_target_vk.h create mode 100644 core/rhi/vulkan/texture_vk.cpp create mode 100644 core/rhi/vulkan/texture_vk.h diff --git a/core/application/application.cpp b/core/application/application.cpp index 60f669f..c0ad385 100644 --- a/core/application/application.cpp +++ b/core/application/application.cpp @@ -7,7 +7,6 @@ #include "imgui_internal.h" #include "filesystem/stb_image.h" #include "rhi/texture.h" -#include "rhi/opengl/renderer_opengl.h" #include "rhi/vulkan/renderer_vk.h" #include "spdlog/async.h" #include "spdlog/spdlog.h" @@ -21,7 +20,7 @@ static void glfw_error_callback(int error, const char* description) { spdlog::error("Glfw Error {}: {}", error, description); } -void application::init(window_params in_window_params, int argc, char** argv) { +void application::init(const window_params& in_window_params, int argc, char** argv) { try { async_spdlog_ = spdlog::basic_logger_mt("async_file_logger", "logs/log.txt"); } catch (const spdlog::spdlog_ex& ex) { diff --git a/core/application/application.h b/core/application/application.h index 378b24e..1c193c7 100644 --- a/core/application/application.h +++ b/core/application/application.h @@ -3,9 +3,9 @@ #include "imgui.h" #include "GLFW/glfw3.h" +class renderer_vk; class pixel_shader_drawer; class render_target; -class renderer; class texture; class application; @@ -42,7 +42,7 @@ public: return g_app_instance; } - virtual void init(window_params in_window_params, int argc, char** argv); + virtual void init(const window_params& in_window_params, int argc, char** argv); virtual int run(); @@ -67,16 +67,16 @@ public: [[nodiscard]] virtual const char* get_draw_ps_vertex_shader_entry() const = 0; // Vertex Shader used for drawing ps - [[nodiscard]] renderer* get_renderer() const { return renderer_; } + [[nodiscard]] renderer_vk* get_renderer() const { return renderer_; } [[nodiscard]] GLFWwindow* get_window() const { return window_; } protected: - renderer* renderer_ = nullptr; + renderer_vk* renderer_ = nullptr; GLFWwindow* window_ = nullptr; std::shared_ptr async_spdlog_; private: - void init_glfw(); + static void init_glfw(); void init_imgui(); diff --git a/core/rhi/opengl/opengl_def.h b/core/rhi/opengl/opengl_def.h deleted file mode 100644 index 63a030e..0000000 --- a/core/rhi/opengl/opengl_def.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#define CHECK_GL_ERRORS \ -{\ - GLenum Error = glGetError();\ - if (Error != 0)\ - spdlog::critical("GL error: 0x{:x}", Error);\ -} diff --git a/core/rhi/opengl/pixel_shader_drawer_opengl.cpp b/core/rhi/opengl/pixel_shader_drawer_opengl.cpp deleted file mode 100644 index a1c203c..0000000 --- a/core/rhi/opengl/pixel_shader_drawer_opengl.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "pixel_shader_drawer_opengl.h" - -#include "application/application.h" -#include "rhi/renderer.h" -#include "shader/shader_ps_opengl.h" -#include "shader/shader_vs_opengl.h" - -void ps_opengl_compute_callback(const ImDrawList* parent_list, const ImDrawCmd* cmd) { - const auto data = static_cast(cmd->UserCallbackData); - const std::shared_ptr& rt = data->rt; - const auto program = data->program; - program->use_program(); - - // do on callback - float x = 0; - float width = rt->get_width(); - float y = 0; - float height = rt->get_height(); - - const float ortho_projection[4][4] = - { - {2.0f / (width - x), 0.0f, 0.0f, 0.0f}, - {0.0f, 2.0f / (y - height), 0.0f, 0.0f}, - {0.0f, 0.0f, -1.0f, 0.0f}, - {(width + x) / (x - width), (y + height) / (height - y), 0.0f, 1.0f}, - }; - // glUseProgram(bd->ShaderHandle); - // glUniform1i(bd->AttribLocationTex, 0); - // glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]); - program->set_uniform("viewMatrix", ortho_projection); - - // ImVec2 clip_min(x, y); - // ImVec2 clip_max(width, height); - glViewport(0, 0, width, height); - - // Apply scissor/clipping rectangle (Y is inverted in OpenGL) - glScissor(0, 0, width, height); - // glScissor((int)clip_min.x, (int)(0 - clip_max.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y)); - - ImDrawVert& vert1 = data->vtx_buffer[0]; - ImDrawVert& vert2 = data->vtx_buffer[1]; - ImDrawVert& vert3 = data->vtx_buffer[2]; - ImDrawVert& vert4 = data->vtx_buffer[3]; - vert1.pos = ImVec2(0, 0); - vert2.pos = ImVec2(width, 0); - vert3.pos = ImVec2(width, height); - vert4.pos = ImVec2(0, height); - vert1.uv = ImVec2(0, 0); - vert2.uv = ImVec2(1, 0); - vert3.uv = ImVec2(1, 1); - vert4.uv = ImVec2(0, 1); - vert1.col = 0xFFFFFFFF; - vert2.col = 0xFFFFFFFF; - vert3.col = 0xFFFFFFFF; - vert4.col = 0xFFFFFFFF; - - - const size_t vtx_size = data->vtx_buffer.size() * sizeof(ImDrawVert); - const size_t idx_size = data->idx_buffer.size() * sizeof(ImDrawIdx); - glBufferSubData(GL_ARRAY_BUFFER, 0, vtx_size, data->vtx_buffer.data()); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, idx_size, data->idx_buffer.data()); - - glBindBuffer(GL_ARRAY_BUFFER, data->vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data->ibo); - - glBindFramebuffer(GL_FRAMEBUFFER, rt->get_fbo()); - - glDrawElementsBaseVertex(GL_TRIANGLES, 6, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, 0, 0); - // glDrawElements(GL_TRIANGLES, 6, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, 0); - - program->unuse_program(); - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - - -pixel_shader_drawer_opengl::~pixel_shader_drawer_opengl() { - if (vbo) - glDeleteBuffers(1, &vbo); - if (ibo) - glDeleteBuffers(1, &ibo); -} - -void pixel_shader_drawer_opengl::init(int width, int height, std::shared_ptr in_pixel_shader, - std::shared_ptr in_vertex_shader) { - if (!in_vertex_shader) { - in_vertex_shader = application::get()->get_renderer()->get_pixel_shader_render_default_vs(); - } - - const auto gl_ps = std::static_pointer_cast(in_pixel_shader); - const auto gl_vs = std::static_pointer_cast(in_vertex_shader); - vertex_shader = gl_vs; - pixel_shader = gl_ps; - rt = std::static_pointer_cast( - application::get()->create_render_target(width, height, texture_format::RGBA32_FLOAT)); - program = std::make_shared(); - program->create_program(gl_ps, gl_vs); - - idx_buffer = {0, 1, 2, 0, 2, 3}; - vtx_buffer.resize(4); - - glGenBuffers(1, &vbo); - glGenBuffers(1, &ibo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - const size_t vtx_size = vtx_buffer.size() * sizeof(ImDrawVert); - glBufferData(GL_ARRAY_BUFFER, vtx_size, vtx_buffer.data(), GL_STREAM_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo); - const size_t idx_size = idx_buffer.size() * sizeof(ImDrawIdx); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, idx_size, idx_buffer.data(), GL_STREAM_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -void pixel_shader_drawer_opengl::resize(int width, int height) { - rt->resize(width, height); -} - -void pixel_shader_drawer_opengl::draw() { -#if _DEBUG - assert(!(pixel_shader.expired() || vertex_shader.expired())); -#endif - ImGui::GetWindowDrawList()->AddCallback(ps_opengl_compute_callback, this); - ImGui::GetWindowDrawList()->AddCallback(ImDrawCallback_ResetRenderState, nullptr); - rt->draw(); -} - -void pixel_shader_drawer_opengl::set_vertex_shader(std::shared_ptr in_vertex_shader) { -#if _DEBUG - assert(!(pixel_shader.expired() || vertex_shader.expired())); -#endif - program->create_program(pixel_shader.lock(), vertex_shader.lock()); -} diff --git a/core/rhi/opengl/pixel_shader_drawer_opengl.h b/core/rhi/opengl/pixel_shader_drawer_opengl.h deleted file mode 100644 index 76b6446..0000000 --- a/core/rhi/opengl/pixel_shader_drawer_opengl.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -#include "render_target_opengl.h" -#include "rhi/pixel_shader_drawer.h" -#include "shader/shader_program_opengl.h" - -class shader_ps_opengl; -class shader_vs_opengl; - -class pixel_shader_drawer_opengl : public pixel_shader_drawer { -public: - pixel_shader_drawer_opengl() = default; - - ~pixel_shader_drawer_opengl() override; - - void init(int width, int height, std::shared_ptr in_pixel_shader, - std::shared_ptr in_vertex_shader) override; - - void resize(int width, int height) override; - - void draw() override; - - void set_vertex_shader(std::shared_ptr in_vertex_shader) override; - - std::shared_ptr rt; - std::shared_ptr program; - std::vector vtx_buffer; - std::vector idx_buffer; - GLuint vbo = 0; - GLuint ibo = 0; - - std::weak_ptr vertex_shader; - std::weak_ptr pixel_shader; -}; diff --git a/core/rhi/opengl/render_target_opengl.cpp b/core/rhi/opengl/render_target_opengl.cpp deleted file mode 100644 index cc8c078..0000000 --- a/core/rhi/opengl/render_target_opengl.cpp +++ /dev/null @@ -1,182 +0,0 @@ -#include "render_target_opengl.h" - -#include "opengl_def.h" - -GLint to_internal_format(texture_format format) { - switch (format) { - case texture_format::RGBA8: - return GL_RGBA8; - case texture_format::RGBA16_FLOAT: - return GL_RGBA16F; - case texture_format::RGBA32_FLOAT: - return GL_RGBA32F; - case texture_format::R32_FLOAT: - return GL_R32F; - case texture_format::RG32_FLOAT: - return GL_RG32F; - case texture_format::R11F_G11F_B10F: - return GL_R11F_G11F_B10F; - case texture_format::R16_FLOAT: - return GL_R16F; - case texture_format::RGBA16: - return GL_RGBA16; - case texture_format::RGB10_A2: - return GL_RGB10_A2; - case texture_format::RG16: - return GL_RG16; - case texture_format::RG8: - return GL_RG8; - case texture_format::R16: - return GL_R16; - case texture_format::R8: - return GL_R8; - case texture_format::RG16_SNORM: - return GL_RG16_SNORM; - case texture_format::RG8_SNORM: - return GL_RG8_SNORM; - case texture_format::R16_SNORM: - return GL_R16_SNORM; - case texture_format::R8_SNORM: - return GL_R8_SNORM; - case texture_format::R32I: - return GL_R32I; - case texture_format::R32UI: - return GL_R32UI; - case texture_format::R8I: - return GL_R8I; - case texture_format::R16I: - return GL_R16I; - case texture_format::R32F: - return GL_R32F; - case texture_format::R8UI: - return GL_R8UI; - case texture_format::R16UI: - return GL_R16UI; - case texture_format::RG32I: - return GL_RG32I; - case texture_format::RG32UI: - return GL_RG32UI; - case texture_format::RG8I: - return GL_RG8I; - case texture_format::RG16I: - return GL_RG16I; - case texture_format::RGB10_A2UI: - return GL_RGB10_A2UI; - case texture_format::RG16UI: - return GL_RG16UI; - default: - return GL_RGBA8; - } - return 0; -} - -void render_target_opengl::on_init(int width, int height, texture_format format) { - glGenFramebuffers(1, &fbo_); - CHECK_GL_ERRORS - glBindFramebuffer(GL_FRAMEBUFFER, fbo_); - CHECK_GL_ERRORS - -#if defined(__APPLE__) -LockGLContext([NSOpenGLContext currentContext]); -#endif - - // Create a new OpenGL texture - glGenTextures(1, &texture_); - CHECK_GL_ERRORS - - glBindTexture(GL_TEXTURE_2D, texture_); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - internal_format_ = to_internal_format(format); - glTexImage2D(GL_TEXTURE_2D, 0, internal_format_, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - CHECK_GL_ERRORS - - glBindFramebuffer(GL_FRAMEBUFFER, fbo_); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0); - - CHECK_GL_ERRORS - - glBindFramebuffer(GL_FRAMEBUFFER, 0); - -#if defined(__APPLE__) - UnlockGLContext([NSOpenGLContext currentContext]); -#endif -} - -render_target_opengl::~render_target_opengl() { - glDeleteFramebuffers(1, &fbo_); - glDeleteTextures(1, &texture_); -} - -void* render_target_opengl::lock(lock_state state) { - locked_texture_ = malloc(width_ * height_ * 4); - switch (state) { - case lock_state::READ: - case lock_state::READ_WRITE: { - glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, locked_texture_); - } - break; - case lock_state::WRITE: - break; - case lock_state::NONE: - break; - } - return locked_texture_; -} - -void render_target_opengl::unlock() { -#if defined(__APPLE__) - LockGLContext([NSOpenGLContext currentContext]); -#endif - // Ensure texturing is enabled before setting texture properties - - glBindTexture(GL_TEXTURE_2D, texture_); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width_, height_, 0, GL_RGBA, GL_UNSIGNED_BYTE, locked_texture_); - -#if defined(__APPLE__) - UnlockGLContext([NSOpenGLContext currentContext]); -#endif - - free(locked_texture_); - locked_texture_ = nullptr; -} - -void render_target_opengl::on_resize(int width, int height) { - width_ = width; - height_ = height; - glDeleteTextures(1, &texture_); - glDeleteFramebuffers(1, &fbo_); - texture_ = 0; - fbo_ = 0; - -#if defined(__APPLE__) - LockGLContext([NSOpenGLContext currentContext]); -#endif - glGenTextures(1, &texture_); - CHECK_GL_ERRORS - - glBindTexture(GL_TEXTURE_2D, texture_); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); - CHECK_GL_ERRORS - - glGenFramebuffers(1, &fbo_); - glBindFramebuffer(GL_FRAMEBUFFER, fbo_); - glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture_, 0); - - CHECK_GL_ERRORS - - glBindTexture(GL_TEXTURE_2D, 0); - glBindFramebuffer(GL_FRAMEBUFFER, 0); - -#if defined(__APPLE__) - UnlockGLContext([NSOpenGLContext currentContext]); -#endif -} diff --git a/core/rhi/opengl/render_target_opengl.h b/core/rhi/opengl/render_target_opengl.h deleted file mode 100644 index debdfcb..0000000 --- a/core/rhi/opengl/render_target_opengl.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include "rhi/render_target.h" - -class render_target_opengl : public render_target { -public: - - ~render_target_opengl() override; - - ImTextureID get_texture_id() override { return (void*) static_cast(texture_); } - [[nodiscard]] GLuint get_fbo() const { return fbo_; } - [[nodiscard]] GLuint get_texture() const { return texture_; } - [[nodiscard]] GLint get_internal_format() const { return internal_format_; } - - void* lock(lock_state state) override; - - void unlock() override; - -protected: - void on_init(int width, int height, texture_format format) override; - void on_resize(int width, int height) override; - -private: - GLuint fbo_ = 0; - GLuint texture_ = 0; - GLint internal_format_ = 0; - void* locked_texture_ = nullptr; -}; diff --git a/core/rhi/opengl/renderer_opengl.cpp b/core/rhi/opengl/renderer_opengl.cpp deleted file mode 100644 index 2dfdcff..0000000 --- a/core/rhi/opengl/renderer_opengl.cpp +++ /dev/null @@ -1,132 +0,0 @@ -#include "renderer_opengl.h" - -#include "imgui_impl_glfw.h" -#include "imgui_impl_opengl3.h" -#include "imgui_impl_sdl3.h" -#include "pixel_shader_drawer_opengl.h" -#include "render_target_opengl.h" -#include "texture_opengl.h" -#include "application/application.h" -#include "rhi/shader.h" -#include "shader/shader_cs_opengl.h" -#include "shader/shader_gs_opengl.h" -#include "shader/shader_ps_opengl.h" -#include "shader/shader_vs_opengl.h" - -void renderer_opengl::pre_init() { - // Decide GL+GLSL versions -#if defined(IMGUI_IMPL_OPENGL_ES2) - // GL ES 2.0 + GLSL 100 - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); - glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_ES_API); -#elif defined(__APPLE__) - // GL 3.2 + GLSL 150 - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); - glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only - glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // Required on Mac -#else - // GL 3.0 + GLSL 130 - glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4); - glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6); - //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // 3.2+ only - //glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); // 3.0+ only -#endif -} - -bool renderer_opengl::init(GLFWwindow* window_handle) { - if (has_initialized_) - return true; - - glfwMakeContextCurrent(window_handle); - if (gladLoadGL() == 0) { - spdlog::error("Failed to initialize OpenGL loader!"); - return false; - } - - glfwSwapInterval(1); // Enable vsync - - const auto glsl_version = "#version 460"; - // Setup Platform/Renderer backends - ImGui_ImplGlfw_InitForOpenGL(window_handle, false); -#ifdef __EMSCRIPTEN__ - ImGui_ImplGlfw_InstallEmscriptenCanvasResizeCallback("#canvas"); -#endif - ImGui_ImplOpenGL3_Init(glsl_version); - - has_initialized_ = true; - return true; -} - -void renderer_opengl::shutdown() { - renderer::shutdown(); -#ifdef __EMSCRIPTEN__ - EMSCRIPTEN_MAINLOOP_END; -#endif - ImGui_ImplOpenGL3_Shutdown(); - ImGui_ImplGlfw_Shutdown(); -} - -void renderer_opengl::post_shutdown() { - renderer::post_shutdown(); -} - -std::shared_ptr renderer_opengl::load_shader(const std::string& entry_name) { - return nullptr; -} - -std::shared_ptr renderer_opengl::create_pixel_shader_drawer() { - return std::make_shared(); -} - -void renderer_opengl::new_frame(GLFWwindow* window_handle) { - // Start the Dear ImGui frame - ImGui_ImplOpenGL3_NewFrame(); - ImGui_ImplGlfw_NewFrame(); - ImGui::NewFrame(); -} - -void renderer_opengl::end_frame(GLFWwindow* window_handle) { - const ImGuiIO& io = ImGui::GetIO(); - - // Rendering - ImGui::Render(); - int display_w, display_h; - glfwGetFramebufferSize(window_handle, &display_w, &display_h); - glViewport(0, 0, display_w, display_h); - glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, - clear_color.w); - glClear(GL_COLOR_BUFFER_BIT); - ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData()); - - // Update and Render additional Platform Windows - // (Platform functions may change the current OpenGL context, so we save/restore it to make it easier to paste this code elsewhere. - // For this specific demo app we could also call glfwMakeContextCurrent(window) directly) - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - GLFWwindow* backup_current_context = glfwGetCurrentContext(); - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); - glfwMakeContextCurrent(backup_current_context); - } - - glfwSwapBuffers(window_handle); -} - -void renderer_opengl::resize(int width, int height) { -} - -std::shared_ptr renderer_opengl::create_texture(const unsigned char* data, int width, int height) { - auto out = std::make_shared(); - if (!out->init_data(data, width, height)) { - out = nullptr; - } - return out; -} - -std::shared_ptr renderer_opengl::create_render_target(int width, int height, texture_format format) { - const auto target_dx11 = std::make_shared(); - target_dx11->init(width, height, format); - return target_dx11; -} diff --git a/core/rhi/opengl/renderer_opengl.h b/core/rhi/opengl/renderer_opengl.h deleted file mode 100644 index 2216633..0000000 --- a/core/rhi/opengl/renderer_opengl.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include "rhi/renderer.h" - -class renderer_opengl : public renderer { -public: - void pre_init() override; - - bool init(GLFWwindow* window_handle) override; - - void shutdown() override; - - void post_shutdown() override; - - std::shared_ptr load_shader(const std::string& entry_name) override; - - std::shared_ptr create_pixel_shader_drawer() override; - - void new_frame(GLFWwindow* window_handle) override; - - void end_frame(GLFWwindow* window_handle) override; - - void resize(int width, int height) override; - - std::shared_ptr create_texture(const unsigned char* data, int width, int height) override; - - std::shared_ptr create_render_target(int width, int height, texture_format format) override; - -private: - bool has_initialized_ = false; -}; diff --git a/core/rhi/opengl/shader/shader_cs_opengl.cpp b/core/rhi/opengl/shader/shader_cs_opengl.cpp deleted file mode 100644 index df6c84b..0000000 --- a/core/rhi/opengl/shader/shader_cs_opengl.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "shader_cs_opengl.h" - -#include "shader_program_opengl.h" - - -shader_cs_opengl::shader_cs_opengl(): shader_opengl() { -} - -bool shader_cs_opengl::init() { - if (!shader_opengl::init()) - return false; - program_ = std::make_shared(); - std::shared_ptr in_compute_shader = std::static_pointer_cast(shared_from_this()); - program_->create_program(in_compute_shader); - return true; -} - -void shader_cs_opengl::compute(int x, int y, int z) { - program_->use_program(); - glDispatchCompute(x, y, z); - program_->unuse_program(); -} diff --git a/core/rhi/opengl/shader/shader_cs_opengl.h b/core/rhi/opengl/shader/shader_cs_opengl.h deleted file mode 100644 index e93d40b..0000000 --- a/core/rhi/opengl/shader/shader_cs_opengl.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include "shader_opengl.h" - -class shader_cs_opengl : public shader_opengl { -public: - explicit shader_cs_opengl(); - - bool init() override; - - [[nodiscard]] GLenum get_shader_type() const override { return GL_COMPUTE_SHADER; } - - void compute(int x, int y, int z) override; - -private: - std::shared_ptr program_; -}; diff --git a/core/rhi/opengl/shader/shader_gs_opengl.cpp b/core/rhi/opengl/shader/shader_gs_opengl.cpp deleted file mode 100644 index 127ab8d..0000000 --- a/core/rhi/opengl/shader/shader_gs_opengl.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "shader_gs_opengl.h" diff --git a/core/rhi/opengl/shader/shader_gs_opengl.h b/core/rhi/opengl/shader/shader_gs_opengl.h deleted file mode 100644 index 9448c16..0000000 --- a/core/rhi/opengl/shader/shader_gs_opengl.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include "shader_opengl.h" -#include "rhi/opengl/opengl_def.h" - -class shader_gs_opengl : public shader_opengl { -public: - shader_gs_opengl() : shader_opengl() { - } - - [[nodiscard]] GLenum get_shader_type() const override { return GL_GEOMETRY_SHADER; } -}; diff --git a/core/rhi/opengl/shader/shader_opengl.cpp b/core/rhi/opengl/shader/shader_opengl.cpp deleted file mode 100644 index cb35396..0000000 --- a/core/rhi/opengl/shader/shader_opengl.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "shader_opengl.h" - -#include "shader_program_opengl.h" - -#include - -bool shader_opengl::init() { - shader_id_ = glCreateShader(get_shader_type()); - if (shader_id_ == 0) { - spdlog::error("Failed to create shader"); - return false; - } - // const auto code_blob = handle_->get_entry_point_code(); - // const auto code_array = static_cast(code_blob->getBufferPointer()); - // const GLint code_size = static_cast(code_blob->getBufferSize()); - // glShaderSource(shader_id_, 1, &code_array, &code_size); - - // opengl_get_refletion_data(code_array, uniform_map_, texture_map_); // slow - - glCompileShader(shader_id_); - GLint compile_status = GL_FALSE; - glGetShaderiv(shader_id_, GL_COMPILE_STATUS, &compile_status); - if (compile_status == GL_FALSE) { - GLint log_length = 0; - glGetShaderiv(shader_id_, GL_INFO_LOG_LENGTH, &log_length); - std::vector log(log_length); - glGetShaderInfoLog(shader_id_, log_length, nullptr, log.data()); - spdlog::error("Failed to compile shader: {}", log.data()); - - glDeleteShader(shader_id_); - shader_id_ = 0; - return false; - } - return true; -} - -void shader_opengl::set_using_program(std::shared_ptr in_program) { - if (using_program_.lock()) { - spdlog::error("Shader is already used by another program"); - return; - } - using_program_ = in_program; -} - -void shader_opengl::set_cbuffer(const char* name, void* buffer, int size) { - if (const auto program = using_program_.lock()) - program->set_uniform(name, buffer, size); -} - -void shader_opengl::set_uav_buffer(const char* name, void* buffer, int size, int element_size) { - if (const auto program = using_program_.lock()) - program->set_ssbo(name, buffer, size, element_size); -} - -void shader_opengl::set_render_target(const char* name, std::shared_ptr in_render_target) { - if (const auto program = using_program_.lock()) - program->set_render_target(name, in_render_target); -} - -void shader_opengl::set_texture(const char* name, std::shared_ptr in_texture) { - if (const auto program = using_program_.lock()) - program->set_texture(name, in_texture); -} diff --git a/core/rhi/opengl/shader/shader_opengl.h b/core/rhi/opengl/shader/shader_opengl.h deleted file mode 100644 index 269b62f..0000000 --- a/core/rhi/opengl/shader/shader_opengl.h +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once -#include - -#include "rhi/shader.h" - -class shader_program_opengl; - -struct opengl_uniform_data { - std::string type_name; - std::string name; - GLuint location = 0; - GLuint binding = 0; - GLint format = 0; -}; - -struct opengl_texture_data { - std::string sampler_name; - GLuint binding = 0; - GLint format = 0; -}; - -class shader_opengl : public shader { -public: - explicit shader_opengl() : shader(), shader_id_(0) { - } - - bool init() override; - - [[nodiscard]] bool is_initialized() const override { return shader_id_ != 0; } - - void bind() override { - } - - void unbind() override { - } - - void set_using_program(std::shared_ptr in_program); - - void set_cbuffer(const char* name, void* buffer, int size) override; - - void set_uav_buffer(const char* name, void* buffer, int size, int element_size) override; - - void set_render_target(const char* name, std::shared_ptr in_render_target) override; - - void set_texture(const char* name, std::shared_ptr in_texture) override; - - [[nodiscard]] virtual GLenum get_shader_type() const = 0; - - [[nodiscard]] GLuint get_shader_id() const { return shader_id_; } - - [[nodiscard]] const std::map& get_uniform_map() const { return uniform_map_; } - [[nodiscard]] const std::map& get_texture_map() const { return texture_map_; } - -protected: - GLuint shader_id_; - std::weak_ptr using_program_; - std::map uniform_map_; - std::map texture_map_; -}; diff --git a/core/rhi/opengl/shader/shader_program_opengl.cpp b/core/rhi/opengl/shader/shader_program_opengl.cpp deleted file mode 100644 index 86ccbaa..0000000 --- a/core/rhi/opengl/shader/shader_program_opengl.cpp +++ /dev/null @@ -1,196 +0,0 @@ -#include "shader_program_opengl.h" - -#include - -#include "shader_opengl.h" -#include "rhi/opengl/render_target_opengl.h" -#include "rhi/opengl/texture_opengl.h" - -bool shader_program_opengl::create_program(std::shared_ptr in_pixel_shader, - std::shared_ptr in_vertex_shader) { - if (program_id_) { - destroy_program(); - } - if (!in_pixel_shader || !in_pixel_shader->is_initialized()) { - spdlog::error("Pixel shader is not initialized"); - return false; - } - if (!in_vertex_shader || !in_vertex_shader->is_initialized()) { - spdlog::error("Vertex shader is not initialized"); - return false; - } - const GLuint pixel_id = in_pixel_shader->get_shader_id(); - const GLuint vertex_id = in_vertex_shader->get_shader_id(); - - program_id_ = glCreateProgram(); - if (program_id_ == 0) { - spdlog::error("Failed to create program"); - return false; - } - - glAttachShader(program_id_, vertex_id); - glAttachShader(program_id_, pixel_id); - - glLinkProgram(program_id_); - GLint link_status = GL_FALSE; - glGetProgramiv(program_id_, GL_LINK_STATUS, &link_status); - if (link_status == GL_FALSE) { - GLint log_length = 0; - glGetProgramiv(program_id_, GL_INFO_LOG_LENGTH, &log_length); - std::vector log(log_length); - glGetProgramInfoLog(program_id_, log_length, nullptr, log.data()); - spdlog::error("Failed to link program: {}", log.data()); - - glDeleteProgram(program_id_); - program_id_ = 0; - return false; - } - - glDetachShader(program_id_, vertex_id); - glDetachShader(program_id_, pixel_id); - - pixel_shader_ = in_pixel_shader; - vertex_shader_ = in_vertex_shader; - in_pixel_shader->set_using_program(shared_from_this()); - in_vertex_shader->set_using_program(shared_from_this()); - - uniform_map_.clear(); - texture_map_.clear(); - update_param_map(in_pixel_shader); - update_param_map(in_vertex_shader); - return true; -} - -bool shader_program_opengl::create_program(std::shared_ptr in_compute_shader) { - if (program_id_) { - destroy_program(); - } - if (!in_compute_shader || !in_compute_shader->is_initialized()) { - spdlog::error("Compute shader is not initialized"); - return false; - } - const GLuint compute_id = in_compute_shader->get_shader_id(); - - program_id_ = glCreateProgram(); - if (program_id_ == 0) { - spdlog::error("Failed to create program"); - return false; - } - - glAttachShader(program_id_, compute_id); - - glLinkProgram(program_id_); - GLint link_status = GL_FALSE; - glGetProgramiv(program_id_, GL_LINK_STATUS, &link_status); - if (link_status == GL_FALSE) { - GLint log_length = 0; - glGetProgramiv(program_id_, GL_INFO_LOG_LENGTH, &log_length); - std::vector log(log_length); - glGetProgramInfoLog(program_id_, log_length, nullptr, log.data()); - spdlog::error("Failed to link program: {}", log.data()); - - glDeleteProgram(program_id_); - program_id_ = 0; - return false; - } - - glDetachShader(program_id_, compute_id); - compute_shader_ = in_compute_shader; - in_compute_shader->set_using_program(shared_from_this()); - - uniform_map_.clear(); - texture_map_.clear(); - update_param_map(in_compute_shader); - return true; -} - -void shader_program_opengl::destroy_program() { - for (const auto& val: ubo_map_ | std::views::values) - glDeleteBuffers(1, &val); - - if (const auto shader = pixel_shader_.lock()) - shader->set_using_program(nullptr); - if (const auto shader = vertex_shader_.lock()) - shader->set_using_program(nullptr); - if (const auto shader = compute_shader_.lock()) - shader->set_using_program(nullptr); - if (!program_id_) - return; - glDeleteProgram(program_id_); - program_id_ = 0; - ubo_map_.clear(); - uniform_map_.clear(); - texture_map_.clear(); -} - -void shader_program_opengl::set_uniform(const char* slang_name, void* buffer, int size) { - const auto& uniform_name = uniform_map_.find(slang_name); - if (uniform_name == uniform_map_.end()) - return; - - const auto& uniform_data = uniform_name->second; - GLuint using_bind_point = uniform_data.binding; - const auto find_ubo = ubo_map_.find(using_bind_point); - if (find_ubo != ubo_map_.end()) { - glBindBuffer(GL_UNIFORM_BUFFER, find_ubo->second); - glBufferSubData(GL_UNIFORM_BUFFER, 0, size, buffer); - return; - } - - const GLint block_index = glGetUniformBlockIndex(program_id_, uniform_data.type_name.c_str()); - glUniformBlockBinding(program_id_, block_index, uniform_data.binding); - - // Create a buffer and copy the projection matrix to it. - GLuint ubo = 0; - glGenBuffers(1, &ubo); - - glBindBuffer(GL_UNIFORM_BUFFER, ubo); - glBufferData(GL_UNIFORM_BUFFER, size, buffer, GL_STATIC_DRAW); - - glBindBufferBase(GL_UNIFORM_BUFFER, using_bind_point, ubo); - - ubo_map_.insert(std::pair(using_bind_point, ubo)); -} - -void shader_program_opengl::set_ssbo(const char* slang_name, void* buffer, int size, int element_size) { - const auto& uniform_name = uniform_map_.find(slang_name); - if (uniform_name == uniform_map_.end()) - return; - const auto& uniform_data = uniform_name->second; - const GLint location = glGetProgramResourceIndex(program_id_, GL_SHADER_STORAGE_BLOCK, uniform_data.name.c_str()); - if (location == -1) { - spdlog::error("Failed to find ssbo: {}", slang_name); - return; - } -} - -void shader_program_opengl::set_render_target(const char* name, std::shared_ptr in_render_target) { - const auto& texture_name = texture_map_.find(name); - if (texture_name == texture_map_.end()) - return; - - std::shared_ptr rt = std::static_pointer_cast(in_render_target); - const opengl_texture_data& texture_data = texture_name->second; - if (texture_data.format != rt->get_internal_format()) - spdlog::error("Mismatched texture format: {}, need{}, yours {}", name, texture_data.format, - rt->get_internal_format()); - glBindImageTexture(texture_data.binding, rt->get_texture(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); -} - -void shader_program_opengl::set_texture(const char* name, std::shared_ptr in_texture) { - const auto& texture_name = texture_map_.find(name); - if (texture_name == texture_map_.end()) - return; - - std::shared_ptr t = std::static_pointer_cast(in_texture); - const opengl_texture_data& texture_data = texture_name->second; - glBindImageTexture(texture_data.binding, t->get_texture(), 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32F); -} - -void shader_program_opengl::update_param_map(std::shared_ptr in_shader) { - const auto& uniform_pairs = in_shader->get_uniform_map(); - const auto& texture_pairs = in_shader->get_texture_map(); - - uniform_map_.insert(uniform_pairs.begin(), uniform_pairs.end()); - texture_map_.insert(texture_pairs.begin(), texture_pairs.end()); -} diff --git a/core/rhi/opengl/shader/shader_program_opengl.h b/core/rhi/opengl/shader/shader_program_opengl.h deleted file mode 100644 index c3f1196..0000000 --- a/core/rhi/opengl/shader/shader_program_opengl.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once -#include -#include - -#include "shader_opengl.h" - -class texture; -class render_target; -class shader; -class shader_opengl; - -class shader_program_opengl : public std::enable_shared_from_this { -public: - ~shader_program_opengl() { - destroy_program(); - } - - void use_program() { - GLint prev_program_id = 0; - glGetIntegerv(GL_CURRENT_PROGRAM, &prev_program_id); - prev_program_id_ = prev_program_id; - glUseProgram(program_id_); - } - - void unuse_program() const { - glUseProgram(prev_program_id_); - } - - [[nodiscard]] GLuint get_program_id() const { return program_id_; } - - bool create_program(std::shared_ptr in_pixel_shader, - std::shared_ptr in_vertex_shader); - - bool create_program(std::shared_ptr in_compute_shader); - - void destroy_program(); - - void set_uniform(const char* slang_name, void* buffer, int size); - - void set_ssbo(const char* slang_name, void* buffer, int size, int element_size); - - void set_render_target(const char* name, std::shared_ptr in_render_target); - - void set_texture(const char* name, std::shared_ptr in_texture); - - template - void set_uniform(const char* name, const T& buffer) { - set_uniform(name, (void*) &buffer, sizeof(T)); - } - - template - void set_uniform(const char* name, const std::vector& buffer) { - set_uniform(name, (void*) buffer.data(), sizeof(T) * buffer.size()); - } - - template - void set_ssbo(const char* name, const T& buffer) { - set_ssbo(name, (void*) &buffer, sizeof(T), sizeof(T)); - } - - template - void set_ssbo(const char* name, const std::vector& buffer) { - set_ssbo(name, (void*) buffer.data(), sizeof(T) * buffer.size(), sizeof(T)); - } - - [[nodiscard]] bool is_initialized() const { return program_id_ != 0; } - -private: - void update_param_map(std::shared_ptr in_shader); - - - std::map uniform_map_; // slang_name -> uniform_data - std::map texture_map_; // slang_name -> uniform_data - std::map ubo_map_; // binding -> ubo - - GLuint program_id_ = 0; - GLuint prev_program_id_ = 0; - - std::weak_ptr pixel_shader_; - std::weak_ptr vertex_shader_; - std::weak_ptr compute_shader_; -}; diff --git a/core/rhi/opengl/shader/shader_ps_opengl.cpp b/core/rhi/opengl/shader/shader_ps_opengl.cpp deleted file mode 100644 index 6b33561..0000000 --- a/core/rhi/opengl/shader/shader_ps_opengl.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "shader_ps_opengl.h" diff --git a/core/rhi/opengl/shader/shader_ps_opengl.h b/core/rhi/opengl/shader/shader_ps_opengl.h deleted file mode 100644 index 972c7d8..0000000 --- a/core/rhi/opengl/shader/shader_ps_opengl.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "shader_opengl.h" -#include "rhi/opengl/render_target_opengl.h" - -class shader_vs_opengl; - -class shader_ps_opengl : public shader_opengl { -public: - explicit shader_ps_opengl() : shader_opengl() { - } - - [[nodiscard]] GLenum get_shader_type() const override { return GL_FRAGMENT_SHADER; } -}; diff --git a/core/rhi/opengl/shader/shader_vs_opengl.cpp b/core/rhi/opengl/shader/shader_vs_opengl.cpp deleted file mode 100644 index 35008d8..0000000 --- a/core/rhi/opengl/shader/shader_vs_opengl.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "shader_vs_opengl.h" diff --git a/core/rhi/opengl/shader/shader_vs_opengl.h b/core/rhi/opengl/shader/shader_vs_opengl.h deleted file mode 100644 index bd2f2bf..0000000 --- a/core/rhi/opengl/shader/shader_vs_opengl.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once -#include "shader_opengl.h" - -class shader_vs_opengl : public shader_opengl { -public: - shader_vs_opengl() : shader_opengl() { - } - - [[nodiscard]] GLenum get_shader_type() const override { return GL_VERTEX_SHADER; } -}; diff --git a/core/rhi/opengl/texture_opengl.cpp b/core/rhi/opengl/texture_opengl.cpp deleted file mode 100644 index 22f3ece..0000000 --- a/core/rhi/opengl/texture_opengl.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "texture_opengl.h" - -#include "opengl_def.h" - -texture_opengl::~texture_opengl() { - if (texture_id_ != 0) { - glDeleteTextures(1, &texture_id_); - } -} - -bool texture_opengl::init_data(const unsigned char* data, int width, int height) { - width_ = width; - height_ = height; - -#if defined(__APPLE__) - LockGLContext([NSOpenGLContext currentContext]); -#endif - - // Create a new OpenGL texture - glGenTextures(1, &texture_id_); - CHECK_GL_ERRORS - - glBindTexture(GL_TEXTURE_2D, texture_id_); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - CHECK_GL_ERRORS -#if defined(__APPLE__) - UnlockGLContext([NSOpenGLContext currentContext]); -#endif - return true; -} diff --git a/core/rhi/opengl/texture_opengl.h b/core/rhi/opengl/texture_opengl.h deleted file mode 100644 index d69c98e..0000000 --- a/core/rhi/opengl/texture_opengl.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include "rhi/texture.h" - -class texture_opengl : public texture { -public: - ~texture_opengl() override; - - ImTextureID get_texture_id() override { return (void*) static_cast(texture_id_); } - GLuint get_texture() const { return texture_id_; } - - bool init_data(const unsigned char* data, int width, int height) override; - - [[nodiscard]] bool is_valid() const override { return texture_id_ != 0; } - -private: - GLuint texture_id_ = 0; -}; diff --git a/core/rhi/pixel_shader_drawer.cpp b/core/rhi/pixel_shader_drawer.cpp deleted file mode 100644 index 5a4fdc0..0000000 --- a/core/rhi/pixel_shader_drawer.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pixel_shader_drawer.h" diff --git a/core/rhi/pixel_shader_drawer.h b/core/rhi/pixel_shader_drawer.h deleted file mode 100644 index 12f673a..0000000 --- a/core/rhi/pixel_shader_drawer.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -class shader; -class render_target; - -class pixel_shader_drawer { -public: - virtual ~pixel_shader_drawer() = default; - - virtual void init(int width, int height, std::shared_ptr in_pixel_shader, - std::shared_ptr in_vertex_shader = nullptr) = 0; - - virtual void resize(int width, int height) = 0; - - virtual void draw() = 0; - - virtual void set_vertex_shader(std::shared_ptr in_vertex_shader) { - } - -protected: - std::shared_ptr rt_; -}; diff --git a/core/rhi/vulkan/compute_pipeline.cpp b/core/rhi/vulkan/compute_pipeline.cpp new file mode 100644 index 0000000..90cb902 --- /dev/null +++ b/core/rhi/vulkan/compute_pipeline.cpp @@ -0,0 +1,48 @@ +#include "compute_pipeline.h" + +#include "application/application.h" +#include + +#include "renderer_vk.h" + +void compute_pipeline::add_binding(uint32_t binding, vk::DescriptorType descriptor_type, uint32_t descriptor_count, const vk::Sampler* immutable_samplers) { + const vk::ShaderStageFlags flag = vk::ShaderStageFlagBits::eCompute; + + vk::DescriptorSetLayoutBinding descriptor_set_layout_binding; + descriptor_set_layout_binding.setBinding(binding); + descriptor_set_layout_binding.setDescriptorType(descriptor_type); + descriptor_set_layout_binding.setDescriptorCount(descriptor_count); + descriptor_set_layout_binding.setStageFlags(flag); + descriptor_set_layout_binding.setPImmutableSamplers(immutable_samplers); + descriptor_set_layout_bindings_.push_back(descriptor_set_layout_binding); +} + +void compute_pipeline::create() { + const auto renderer_vk = application::get()->get_renderer(); + auto device = renderer_vk->device; + + vk::PipelineCacheCreateInfo pipeline_cache_create_info; + pipeline_cache_create_info.setInitialDataSize(0); + pipeline_cache_ = device.createPipelineCache(pipeline_cache_create_info); + + create_pipeline_layout(); + + vk::ComputePipelineCreateInfo compute_pipeline_create_info; + compute_pipeline_create_info.setLayout(pipeline_layout_); + const auto pipeline_result = device.createComputePipeline(pipeline_cache_, compute_pipeline_create_info); + check_vk_result(pipeline_result.result); + pipeline_ = pipeline_result.value; +} + +void compute_pipeline::destroy() { + const auto renderer_vk = application::get()->get_renderer(); + auto device = renderer_vk->device; + + device.destroyPipeline(pipeline_); + device.destroyPipelineCache(pipeline_cache_); + device.destroyPipelineLayout(pipeline_layout_); +} + +void compute_pipeline::bind(vk::CommandBuffer command_buffer) const { + command_buffer.bindPipeline(vk::PipelineBindPoint::eCompute, pipeline_); +} diff --git a/core/rhi/vulkan/compute_pipeline.h b/core/rhi/vulkan/compute_pipeline.h new file mode 100644 index 0000000..d66dd08 --- /dev/null +++ b/core/rhi/vulkan/compute_pipeline.h @@ -0,0 +1,14 @@ +#pragma once +#include "pipeline.h" + +class compute_pipeline : pipeline { +public: + void add_binding(uint32_t binding, vk::DescriptorType descriptor_type, uint32_t descriptor_count, const vk::Sampler* immutable_samplers) override; + void create() override; + void destroy() override; + void bind(vk::CommandBuffer command_buffer) const override; + + void set_shader(const std::string& file_path) { + + } +}; diff --git a/core/rhi/vulkan/pipeline.cpp b/core/rhi/vulkan/pipeline.cpp new file mode 100644 index 0000000..f74f26f --- /dev/null +++ b/core/rhi/vulkan/pipeline.cpp @@ -0,0 +1,46 @@ +#include "pipeline.h" + +#include "renderer_vk.h" +#include "application/application.h" + +void pipeline::create_pipeline_layout() { + const auto renderer = application::get()->get_renderer(); + const auto device = renderer->device; + + vk::DescriptorSetLayoutCreateInfo descriptor_set_layout_create_info; + descriptor_set_layout_create_info.setBindings(descriptor_set_layout_bindings_); + vk::DescriptorSetLayout descriptor_set_layout = device.createDescriptorSetLayout(descriptor_set_layout_create_info); + + vk::PipelineLayoutCreateInfo pipeline_layout_create_info; + pipeline_layout_create_info.setSetLayouts(descriptor_set_layout); + pipeline_layout_ = device.createPipelineLayout(pipeline_layout_create_info); +} + +void pipeline::create_pipeline_command() const { + const auto renderer = application::get()->get_renderer(); + const auto device = renderer->device; + const auto command_pool = renderer->command_pool; + + vk::CommandBufferAllocateInfo command_buffer_allocate_info; + command_buffer_allocate_info.setCommandPool(command_pool); + command_buffer_allocate_info.setLevel(vk::CommandBufferLevel::ePrimary); + command_buffer_allocate_info.setCommandBufferCount(1); + const vk::CommandBuffer command_buffer = device.allocateCommandBuffers(command_buffer_allocate_info)[0]; + + vk::CommandBufferBeginInfo command_buffer_begin_info; + command_buffer_begin_info.setFlags(vk::CommandBufferUsageFlagBits::eOneTimeSubmit); + command_buffer.begin(command_buffer_begin_info); + + bind(command_buffer); + + command_buffer.end(); + + vk::SubmitInfo submit_info; + submit_info.setCommandBufferCount(1); + submit_info.setPCommandBuffers(&command_buffer); + renderer->queue.submit(submit_info, nullptr); + renderer->queue.waitIdle(); + + device.freeCommandBuffers(command_pool, command_buffer); + device.destroyCommandPool(command_pool); +} diff --git a/core/rhi/vulkan/pipeline.h b/core/rhi/vulkan/pipeline.h new file mode 100644 index 0000000..79cf3f6 --- /dev/null +++ b/core/rhi/vulkan/pipeline.h @@ -0,0 +1,43 @@ +#pragma once +#include + +class pipeline { +public: + virtual ~pipeline() = default; + + virtual void add_binding(uint32_t binding, vk::DescriptorType descriptor_type, uint32_t descriptor_count, const vk::Sampler* immutable_samplers) = 0; + + void add_uniform_buffer(uint32_t binding, uint32_t descriptor_count = 1) { + add_binding(binding, vk::DescriptorType::eUniformBuffer, descriptor_count, nullptr); + } + void add_storage_buffer(uint32_t binding, uint32_t descriptor_count = 1) { + add_binding(binding, vk::DescriptorType::eStorageBuffer, descriptor_count, nullptr); + } + void add_sampled_image(uint32_t binding, uint32_t descriptor_count = 1, const vk::Sampler* immutable_samplers = nullptr) { + add_binding(binding, vk::DescriptorType::eSampledImage, descriptor_count, immutable_samplers); + } + void add_storage_image(uint32_t binding, uint32_t descriptor_count = 1) { + add_binding(binding, vk::DescriptorType::eStorageImage, descriptor_count, nullptr); + } + void add_input_attachment(uint32_t binding, uint32_t descriptor_count = 1) { + add_binding(binding, vk::DescriptorType::eInputAttachment, descriptor_count, nullptr); + } + void add_sampler(uint32_t binding, uint32_t descriptor_count = 1, const vk::Sampler* immutable_samplers = nullptr) { + add_binding(binding, vk::DescriptorType::eSampler, descriptor_count, immutable_samplers); + } + void add_combined_image_sampler(uint32_t binding, uint32_t descriptor_count = 1, const vk::Sampler* immutable_samplers = nullptr) { + add_binding(binding, vk::DescriptorType::eCombinedImageSampler, descriptor_count, immutable_samplers); + } + + void create_pipeline_layout(); + + virtual void create() = 0; + virtual void destroy() = 0; + virtual void bind(vk::CommandBuffer command_buffer) const = 0; + void create_pipeline_command() const; + + vk::Pipeline pipeline_; + vk::PipelineCache pipeline_cache_; + vk::PipelineLayout pipeline_layout_; + std::vector descriptor_set_layout_bindings_; +}; diff --git a/core/rhi/vulkan/render_target_vk.cpp b/core/rhi/vulkan/render_target_vk.cpp new file mode 100644 index 0000000..8715998 --- /dev/null +++ b/core/rhi/vulkan/render_target_vk.cpp @@ -0,0 +1 @@ +#include "render_target_vk.h" diff --git a/core/rhi/vulkan/render_target_vk.h b/core/rhi/vulkan/render_target_vk.h new file mode 100644 index 0000000..75930ba --- /dev/null +++ b/core/rhi/vulkan/render_target_vk.h @@ -0,0 +1,8 @@ +#pragma once + +#include "rhi/render_target.h" + + +class render_target_vk : public render_target { + +}; diff --git a/core/rhi/vulkan/renderer_vk.cpp b/core/rhi/vulkan/renderer_vk.cpp index b8534e0..06e04a7 100644 --- a/core/rhi/vulkan/renderer_vk.cpp +++ b/core/rhi/vulkan/renderer_vk.cpp @@ -2,23 +2,7 @@ #include "imgui_impl_glfw.h" #include "utils/utils.hpp" - -static void check_vk_result(vk::Result err) { - if (err == vk::Result::eSuccess) - return; - - spdlog::error("[vulkan] Error: VkResult = {}", vk::to_string(err)); - abort(); -} - -static void check_vk_result(VkResult err) { - if (err == VK_SUCCESS) - return; - if (err < 0) { - spdlog::error("[vulkan] Error: VkResult = {}", err); - abort(); - } -} +#include "GLFW/glfw3.h" static bool is_extension_available(const std::vector& properties, const char* extension) { return std::ranges::any_of(properties, [extension](const vk::ExtensionProperties& p) { @@ -34,9 +18,7 @@ vk::PhysicalDevice renderer_vk::setup_vulkan_select_physical_device() const { // most common cases (multi-gpu/integrated+dedicated graphics). Handling more complicated setups (multiple // dedicated GPUs) is out of scope of this sample. for (auto& device: gpus) { - auto properties = device.getProperties(); - - if (properties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) + if (const auto properties = device.getProperties(); properties.deviceType == vk::PhysicalDeviceType::eDiscreteGpu) return device; } @@ -76,7 +58,7 @@ void renderer_vk::setup_vulkan(ImVector instance_extensions) { // Select graphics queue family { - auto queues = physical_device.getQueueFamilyProperties(); + const auto queues = physical_device.getQueueFamilyProperties(); for (uint32_t i = 0; i < queues.size(); i++) { if (queues[i].queueFlags & vk::QueueFlagBits::eGraphics) { queue_family = i; @@ -117,6 +99,14 @@ void renderer_vk::setup_vulkan(ImVector instance_extensions) { descriptor_pool = device.createDescriptorPool(descriptor_pool_create_info); } + + // Create Command Pool + { + vk::CommandPoolCreateInfo cmd_pool_info; + cmd_pool_info.setQueueFamilyIndex(queue_family); + cmd_pool_info.setFlags(vk::CommandPoolCreateFlagBits::eResetCommandBuffer); + command_pool = device.createCommandPool(cmd_pool_info); + } } // All the ImGui_ImplVulkanH_XXX structures/functions are optional helpers used by the demo. @@ -377,7 +367,7 @@ void renderer_vk::init_vulkan(GLFWwindow* window_handle) { init_info.Device = device; init_info.QueueFamily = queue_family; init_info.Queue = queue; - init_info.PipelineCache = pipeline_cache; + init_info.PipelineCache = VK_NULL_HANDLE; init_info.DescriptorPool = descriptor_pool; init_info.RenderPass = main_window_data.RenderPass; init_info.Subpass = 0; diff --git a/core/rhi/vulkan/renderer_vk.h b/core/rhi/vulkan/renderer_vk.h index 5027af7..febfda9 100644 --- a/core/rhi/vulkan/renderer_vk.h +++ b/core/rhi/vulkan/renderer_vk.h @@ -8,6 +8,22 @@ #include "imgui_impl_vulkan.h" #include "rhi/renderer.h" +static void check_vk_result(vk::Result err) { + if (err == vk::Result::eSuccess) + return; + + spdlog::error("[vulkan] Error: VkResult = {}", vk::to_string(err)); + abort(); +} + +static void check_vk_result(VkResult err) { + if (err == VK_SUCCESS) + return; + if (err < 0) { + spdlog::error("[vulkan] Error: VkResult = {}", err); + abort(); + } +} class renderer_vk : public renderer { public: @@ -38,8 +54,8 @@ public: vk::Device device = VK_NULL_HANDLE; uint32_t queue_family = (uint32_t)-1; vk::Queue queue = VK_NULL_HANDLE; - vk::PipelineCache pipeline_cache = VK_NULL_HANDLE; vk::DescriptorPool descriptor_pool = VK_NULL_HANDLE; + vk::CommandPool command_pool = VK_NULL_HANDLE; ImGui_ImplVulkanH_Window main_window_data; int min_image_count = 2; diff --git a/core/rhi/vulkan/texture_vk.cpp b/core/rhi/vulkan/texture_vk.cpp new file mode 100644 index 0000000..ab4bfb0 --- /dev/null +++ b/core/rhi/vulkan/texture_vk.cpp @@ -0,0 +1,51 @@ +#include "texture_vk.h" + +#include "renderer_vk.h" +#include "application/application.h" +#include "GLFW/glfw3.h" + +bool texture_vk::init_data(const unsigned char* data, int width, int height) { + auto vk_rder = static_cast(application::get()->get_renderer()); + auto& device = vk_rder->device; + + vk::ImageCreateInfo image_info; + image_info.setFormat(vk::Format::eR8G8B8A8Srgb); + image_info.setImageType(vk::ImageType::e2D); + image_info.setExtent({static_cast(width), static_cast(height), 1}); + image_info.setMipLevels(1); + image_info.setArrayLayers(1); + image_info.setSamples(vk::SampleCountFlagBits::e1); + image_ = device.createImage(image_info); + + vk::ImageViewCreateInfo view_info; + view_info.setImage(image_); + view_info.setViewType(vk::ImageViewType::e2D); + view_info.setFormat(vk::Format::eR8G8B8A8Srgb); + view_info.setSubresourceRange({vk::ImageAspectFlagBits::eColor, 0, 1, 0, 1}); + image_view_ = device.createImageView(view_info); + + vk::SamplerCreateInfo sampler_info; + sampler_info.setMagFilter(vk::Filter::eLinear); + sampler_info.setMinFilter(vk::Filter::eLinear); + sampler_info.setAddressModeU(vk::SamplerAddressMode::eClampToEdge); + sampler_info.setAddressModeV(vk::SamplerAddressMode::eClampToEdge); + sampler_info.setAddressModeW(vk::SamplerAddressMode::eClampToEdge); + sampler_info.setAnisotropyEnable(VK_FALSE); + sampler_info.setMaxAnisotropy(1); + sampler_info.setBorderColor(vk::BorderColor::eFloatOpaqueWhite); + sampler_info.setUnnormalizedCoordinates(VK_FALSE); + sampler_info.setCompareEnable(VK_FALSE); + sampler_info.setCompareOp(vk::CompareOp::eAlways); + sampler_info.setMipmapMode(vk::SamplerMipmapMode::eLinear); + sampler_ = device.createSampler(sampler_info); + + vk::BufferCreateInfo buffer_info; + buffer_info.setSize(width * height * 4); + buffer_info.setUsage(vk::BufferUsageFlagBits::eTransferSrc); + buffer_info.setSharingMode(vk::SharingMode::eExclusive); + buffer_ = device.createBuffer(buffer_info); + + + + return true; +} diff --git a/core/rhi/vulkan/texture_vk.h b/core/rhi/vulkan/texture_vk.h new file mode 100644 index 0000000..8b7b76a --- /dev/null +++ b/core/rhi/vulkan/texture_vk.h @@ -0,0 +1,17 @@ +#pragma once +#include + +#include "rhi/texture.h" + + +class texture_vk : public texture { +public: + bool init_data(const unsigned char* data, int width, int height) override; + bool is_valid() const override { return image_view_; } + ImTextureID get_texture_id() override { return static_cast(image_view_); } +private: + vk::Image image_; + vk::ImageView image_view_; + vk::Sampler sampler_; + vk::Buffer buffer_; +};