From 010c6b097c2f099d046cb86e6b5d04dc278052d5 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Mon, 23 Oct 2023 23:07:32 +0200 Subject: [PATCH] Add support for texture units --- src/engine/image_quad.cc | 2 +- src/engine/imgui_backend.cc | 2 +- src/engine/platform/platform_observer.h | 3 -- src/engine/renderer/opengl/renderer_opengl.cc | 26 +++++++------ src/engine/renderer/opengl/renderer_opengl.h | 6 +-- .../opengl/renderer_opengl_android.cc | 2 +- .../renderer/opengl/renderer_opengl_linux.cc | 2 +- .../renderer/opengl/renderer_opengl_win.cc | 2 +- src/engine/renderer/renderer.h | 5 ++- src/engine/renderer/texture.cc | 4 +- src/engine/renderer/texture.h | 2 +- src/engine/renderer/vulkan/renderer_vulkan.cc | 37 +++++++++++-------- src/engine/renderer/vulkan/renderer_vulkan.h | 2 +- 13 files changed, 50 insertions(+), 45 deletions(-) diff --git a/src/engine/image_quad.cc b/src/engine/image_quad.cc index 2b597d0..4d76023 100644 --- a/src/engine/image_quad.cc +++ b/src/engine/image_quad.cc @@ -56,7 +56,7 @@ void ImageQuad::Draw(float frame_frac) { if (!texture_ || !texture_->IsValid()) return; - texture_->Activate(); + texture_->Activate(0); Vector2f tex_scale = {GetFrameWidth() / texture_->GetWidth(), GetFrameHeight() / texture_->GetHeight()}; diff --git a/src/engine/imgui_backend.cc b/src/engine/imgui_backend.cc index 74e4093..5cff8dc 100644 --- a/src/engine/imgui_backend.cc +++ b/src/engine/imgui_backend.cc @@ -131,7 +131,7 @@ void ImguiBackend::Render() { for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i]; - reinterpret_cast(pcmd->GetTexID())->Activate(); + reinterpret_cast(pcmd->GetTexID())->Activate(0); if (pcmd->ClipRect.z > pcmd->ClipRect.x && pcmd->ClipRect.w > pcmd->ClipRect.y) { diff --git a/src/engine/platform/platform_observer.h b/src/engine/platform/platform_observer.h index d6c11a8..9c4ad5a 100644 --- a/src/engine/platform/platform_observer.h +++ b/src/engine/platform/platform_observer.h @@ -7,9 +7,6 @@ class InputEvent; class PlatformObserver { public: - PlatformObserver() = default; - virtual ~PlatformObserver() = default; - virtual void OnWindowCreated() = 0; virtual void OnWindowDestroyed() = 0; virtual void OnWindowResized(int width, int height) = 0; diff --git a/src/engine/renderer/opengl/renderer_opengl.cc b/src/engine/renderer/opengl/renderer_opengl.cc index cb1e40a..010e1ef 100644 --- a/src/engine/renderer/opengl/renderer_opengl.cc +++ b/src/engine/renderer/opengl/renderer_opengl.cc @@ -199,8 +199,7 @@ void RendererOpenGL::Draw(uint64_t resource_id, uint64_t RendererOpenGL::CreateTexture() { GLuint gl_id = 0; glGenTextures(1, &gl_id); - - BindTexture(gl_id); + glBindTexture(GL_TEXTURE_2D, gl_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -218,7 +217,7 @@ void RendererOpenGL::UpdateTexture(uint64_t resource_id, if (it == textures_.end()) return; - BindTexture(it->second); + glBindTexture(GL_TEXTURE_2D, it->second); if (image->IsCompressed()) { GLenum format = 0; switch (image->GetFormat()) { @@ -275,13 +274,23 @@ void RendererOpenGL::DestroyTexture(uint64_t resource_id) { textures_.erase(it); } -void RendererOpenGL::ActivateTexture(uint64_t resource_id) { +void RendererOpenGL::ActivateTexture(uint64_t resource_id, + uint64_t texture_unit) { + if (texture_unit >= kMaxTextureUnits) { + DLOG(0) << "Invalid texture unit " << texture_unit; + return; + } + auto it = textures_.find(resource_id); if (it == textures_.end()) { return; } - BindTexture(it->second); + if (it->second != active_texture_id_[texture_unit]) { + glActiveTexture(GL_TEXTURE0 + texture_unit); + glBindTexture(GL_TEXTURE_2D, it->second); + active_texture_id_[texture_unit] = it->second; + } } uint64_t RendererOpenGL::CreateShader( @@ -550,13 +559,6 @@ void RendererOpenGL::DestroyAllResources() { DCHECK(textures_.size() == 0); } -void RendererOpenGL::BindTexture(GLuint id) { - if (id != active_texture_id_) { - glBindTexture(GL_TEXTURE_2D, id); - active_texture_id_ = id; - } -} - bool RendererOpenGL::SetupVertexLayout( const VertexDescription& vd, GLuint vertex_size, diff --git a/src/engine/renderer/opengl/renderer_opengl.h b/src/engine/renderer/opengl/renderer_opengl.h index 6fde45a..9d035f1 100644 --- a/src/engine/renderer/opengl/renderer_opengl.h +++ b/src/engine/renderer/opengl/renderer_opengl.h @@ -1,6 +1,7 @@ #ifndef ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H #define ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H +#include #include #include #include @@ -43,7 +44,7 @@ class RendererOpenGL final : public Renderer { uint64_t CreateTexture() final; void UpdateTexture(uint64_t resource_id, std::unique_ptr image) final; void DestroyTexture(uint64_t resource_id) final; - void ActivateTexture(uint64_t resource_id) final; + void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final; uint64_t CreateShader(std::unique_ptr source, const VertexDescription& vertex_description, @@ -113,7 +114,7 @@ class RendererOpenGL final : public Renderer { uint64_t last_resource_id_ = 0; GLuint active_shader_id_ = 0; - GLuint active_texture_id_ = 0; + std::array active_texture_id_ = {}; bool vertex_array_objects_ = false; bool npot_ = false; @@ -144,7 +145,6 @@ class RendererOpenGL final : public Renderer { void ContextLost(); void DestroyAllResources(); - void BindTexture(GLuint id); bool SetupVertexLayout(const VertexDescription& vd, GLuint vertex_size, bool use_vao, diff --git a/src/engine/renderer/opengl/renderer_opengl_android.cc b/src/engine/renderer/opengl/renderer_opengl_android.cc index 7428630..8e0ab41 100644 --- a/src/engine/renderer/opengl/renderer_opengl_android.cc +++ b/src/engine/renderer/opengl/renderer_opengl_android.cc @@ -57,7 +57,7 @@ void RendererOpenGL::Present() { } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); active_shader_id_ = 0; - active_texture_id_ = 0; + active_texture_id_ = {}; fps_++; } diff --git a/src/engine/renderer/opengl/renderer_opengl_linux.cc b/src/engine/renderer/opengl/renderer_opengl_linux.cc index 9ab2229..d5c7a2a 100644 --- a/src/engine/renderer/opengl/renderer_opengl_linux.cc +++ b/src/engine/renderer/opengl/renderer_opengl_linux.cc @@ -50,7 +50,7 @@ void RendererOpenGL::Present() { glXSwapBuffers(display_, window_); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); active_shader_id_ = 0; - active_texture_id_ = 0; + active_texture_id_ = {}; fps_++; } diff --git a/src/engine/renderer/opengl/renderer_opengl_win.cc b/src/engine/renderer/opengl/renderer_opengl_win.cc index a7eed2c..83b1a29 100644 --- a/src/engine/renderer/opengl/renderer_opengl_win.cc +++ b/src/engine/renderer/opengl/renderer_opengl_win.cc @@ -72,7 +72,7 @@ void RendererOpenGL::Present() { SwapBuffers(dc_); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); active_shader_id_ = 0; - active_texture_id_ = 0; + active_texture_id_ = {}; fps_++; } diff --git a/src/engine/renderer/renderer.h b/src/engine/renderer/renderer.h index f9a5e4f..37708de 100644 --- a/src/engine/renderer/renderer.h +++ b/src/engine/renderer/renderer.h @@ -19,7 +19,8 @@ enum class RendererType { kUnknown, kVulkan, kOpenGL }; class Renderer { public: - const unsigned kInvalidId = 0; + static const unsigned kInvalidId = 0; + static const unsigned kMaxTextureUnits = 8; static std::unique_ptr Create(RendererType type, base::Closure context_lost_cb); @@ -51,7 +52,7 @@ class Renderer { virtual void UpdateTexture(uint64_t resource_id, std::unique_ptr image) = 0; virtual void DestroyTexture(uint64_t resource_id) = 0; - virtual void ActivateTexture(uint64_t resource_id) = 0; + virtual void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) = 0; virtual uint64_t CreateShader(std::unique_ptr source, const VertexDescription& vertex_description, diff --git a/src/engine/renderer/texture.cc b/src/engine/renderer/texture.cc index 99bac94..865af01 100644 --- a/src/engine/renderer/texture.cc +++ b/src/engine/renderer/texture.cc @@ -28,9 +28,9 @@ void Texture::Destroy() { } } -void Texture::Activate() { +void Texture::Activate(uint64_t texture_unit) { if (IsValid()) - renderer_->ActivateTexture(resource_id_); + renderer_->ActivateTexture(resource_id_, texture_unit); } } // namespace eng diff --git a/src/engine/renderer/texture.h b/src/engine/renderer/texture.h index 51d6b8a..8b7b1ad 100644 --- a/src/engine/renderer/texture.h +++ b/src/engine/renderer/texture.h @@ -20,7 +20,7 @@ class Texture : public RenderResource { void Destroy(); - void Activate(); + void Activate(uint64_t texture_unit); int GetWidth() const { return width_; } int GetHeight() const { return height_; } diff --git a/src/engine/renderer/vulkan/renderer_vulkan.cc b/src/engine/renderer/vulkan/renderer_vulkan.cc index ad6b760..f487e50 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan.cc @@ -559,21 +559,24 @@ void RendererVulkan::DestroyTexture(uint64_t resource_id) { textures_.erase(it); } -void RendererVulkan::ActivateTexture(uint64_t resource_id) { +void RendererVulkan::ActivateTexture(uint64_t resource_id, + uint64_t texture_unit) { auto it = textures_.find(resource_id); if (it == textures_.end()) return; - if (active_descriptor_sets_[/*TODO*/ 0] != std::get<0>(it->second.desc_set)) { - active_descriptor_sets_[/*TODO*/ 0] = std::get<0>(it->second.desc_set); - if (active_shader_id_ != 0) { + if (active_descriptor_sets_[texture_unit] != + std::get<0>(it->second.desc_set)) { + active_descriptor_sets_[texture_unit] = std::get<0>(it->second.desc_set); + if (active_shader_id_ != kInvalidId) { auto active_shader = shaders_.find(active_shader_id_); if (active_shader != shaders_.end() && - active_shader->second.desc_set_count > 0) { - vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - active_shader->second.pipeline_layout, 0, 1, - &active_descriptor_sets_[0], 0, nullptr); + active_shader->second.desc_set_count > texture_unit) { + vkCmdBindDescriptorSets( + frames_[current_frame_].draw_command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + active_shader->second.pipeline_layout, texture_unit, 1, + &active_descriptor_sets_[texture_unit], 0, nullptr); } } } @@ -788,12 +791,14 @@ void RendererVulkan::ActivateShader(uint64_t resource_id) { active_shader_id_ = resource_id; vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline); - if (it->second.desc_set_count > 0 && - active_descriptor_sets_[/*TODO*/ 0] != VK_NULL_HANDLE) { - vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, - it->second.pipeline_layout, 0, 1, - &active_descriptor_sets_[0], 0, nullptr); + + for (size_t i = 0; i < it->second.desc_set_count; ++i) { + if (active_descriptor_sets_[i] != VK_NULL_HANDLE) { + vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, + it->second.pipeline_layout, i, 1, + &active_descriptor_sets_[i], 0, nullptr); + } } } } @@ -2053,7 +2058,7 @@ void RendererVulkan::SwapBuffers() { context_.SwapBuffers(); current_frame_ = (current_frame_ + 1) % frames_.size(); - active_shader_id_ = 0; + active_shader_id_ = kInvalidId; for (auto& ds : active_descriptor_sets_) ds = VK_NULL_HANDLE; diff --git a/src/engine/renderer/vulkan/renderer_vulkan.h b/src/engine/renderer/vulkan/renderer_vulkan.h index 2cfba22..86d296f 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.h +++ b/src/engine/renderer/vulkan/renderer_vulkan.h @@ -45,7 +45,7 @@ class RendererVulkan final : public Renderer { uint64_t CreateTexture() final; void UpdateTexture(uint64_t resource_id, std::unique_ptr image) final; void DestroyTexture(uint64_t resource_id) final; - void ActivateTexture(uint64_t resource_id) final; + void ActivateTexture(uint64_t resource_id, uint64_t texture_unit) final; uint64_t CreateShader(std::unique_ptr source, const VertexDescription& vertex_description,