From 042bffaff3cda8b1fe124139208e227186ae93d8 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Mon, 25 Oct 2021 22:54:57 +0200 Subject: [PATCH] Renderer code refactoring. --- build/android/app/CMakeLists.txt | 1 - build/linux/Makefile | 1 - src/engine/BUILD.gn | 6 +- src/engine/engine.cc | 9 +- src/engine/engine.h | 9 +- src/engine/renderer/geometry.cc | 18 +- src/engine/renderer/geometry.h | 8 +- src/engine/renderer/opengl/render_command.cc | 2 + src/engine/renderer/opengl/render_command.h | 37 +- src/engine/renderer/opengl/renderer_opengl.cc | 408 +++++++++--------- src/engine/renderer/opengl/renderer_opengl.h | 57 ++- src/engine/renderer/render_resource.cc | 16 - src/engine/renderer/render_resource.h | 55 +-- src/engine/renderer/renderer.h | 45 +- src/engine/renderer/shader.cc | 48 +-- src/engine/renderer/shader.h | 8 +- src/engine/renderer/texture.cc | 20 +- src/engine/renderer/texture.h | 9 +- src/engine/renderer/vulkan/renderer_vulkan.cc | 347 ++++++++------- src/engine/renderer/vulkan/renderer_vulkan.h | 59 ++- 20 files changed, 569 insertions(+), 594 deletions(-) delete mode 100644 src/engine/renderer/render_resource.cc diff --git a/build/android/app/CMakeLists.txt b/build/android/app/CMakeLists.txt index f19b8e3..4f36d26 100644 --- a/build/android/app/CMakeLists.txt +++ b/build/android/app/CMakeLists.txt @@ -81,7 +81,6 @@ add_library(kaliber SHARED ../../../src/engine/renderer/opengl/render_command.cc ../../../src/engine/renderer/opengl/renderer_opengl_android.cc ../../../src/engine/renderer/opengl/renderer_opengl.cc - ../../../src/engine/renderer/render_resource.cc ../../../src/engine/renderer/renderer_types.cc ../../../src/engine/renderer/shader.cc ../../../src/engine/renderer/texture.cc diff --git a/build/linux/Makefile b/build/linux/Makefile index 4702bd2..94c5811 100644 --- a/build/linux/Makefile +++ b/build/linux/Makefile @@ -106,7 +106,6 @@ GLTEST_SRC := \ $(SRC_ROOT)/engine/renderer/opengl/render_command.cc \ $(SRC_ROOT)/engine/renderer/opengl/renderer_opengl_linux.cc \ $(SRC_ROOT)/engine/renderer/opengl/renderer_opengl.cc \ - $(SRC_ROOT)/engine/renderer/render_resource.cc \ $(SRC_ROOT)/engine/renderer/renderer_types.cc \ $(SRC_ROOT)/engine/renderer/shader.cc \ $(SRC_ROOT)/engine/renderer/texture.cc \ diff --git a/src/engine/BUILD.gn b/src/engine/BUILD.gn index a7dca6c..503a559 100644 --- a/src/engine/BUILD.gn +++ b/src/engine/BUILD.gn @@ -8,7 +8,6 @@ source_set("engine") { "audio/audio_base.cc", "audio/audio_base.h", "audio/audio_forward.h", - "audio/audio_sample.h", "audio/audio.h", "drawable.cc", "drawable.h", @@ -29,9 +28,7 @@ source_set("engine") { "persistent_data.h", "platform/asset_file.cc", "platform/asset_file.h", - "platform/platform_base.cc", - "platform/platform_base.h", - "platform/platform_forward.h", + "platform/platform.cc", "platform/platform.h", "renderer/geometry.cc", "renderer/geometry.h", @@ -40,7 +37,6 @@ source_set("engine") { "renderer/opengl/render_command.h", "renderer/opengl/renderer_opengl.cc", "renderer/opengl/renderer_opengl.h", - "renderer/render_resource.cc", "renderer/render_resource.h", "renderer/renderer_types.cc", "renderer/renderer_types.h", diff --git a/src/engine/engine.cc b/src/engine/engine.cc index f71adee..72f41d7 100644 --- a/src/engine/engine.cc +++ b/src/engine/engine.cc @@ -440,16 +440,13 @@ bool Engine::IsMobile() const { return platform_->mobile_device(); } -std::unique_ptr Engine::CreateRenderResourceInternal( - RenderResourceFactoryBase& factory) { - return renderer_->CreateResource(factory); -} - void Engine::ContextLost() { CreateRenderResources(); - for (auto& t : textures_) + for (auto& t : textures_) { + t.second.texture->Destroy(); RefreshImage(t.first); + } game_->ContextLost(); } diff --git a/src/engine/engine.h b/src/engine/engine.h index 12879ac..a45b3e1 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -11,7 +11,6 @@ #include "../base/vecmath.h" #include "audio/audio_forward.h" #include "persistent_data.h" -#include "renderer/render_resource.h" class TextureCompressor; @@ -65,10 +64,7 @@ class Engine { template std::unique_ptr CreateRenderResource() { - RenderResourceFactory factory; - std::unique_ptr resource = - CreateRenderResourceInternal(factory); - return std::unique_ptr(static_cast(resource.release())); + return std::unique_ptr(static_cast(new T(renderer_))); } void SetImageSource(const std::string& asset_name, @@ -212,9 +208,6 @@ class Engine { base::Random random_; - std::unique_ptr CreateRenderResourceInternal( - RenderResourceFactoryBase& factory); - void ContextLost(); bool CreateRenderResources(); diff --git a/src/engine/renderer/geometry.cc b/src/engine/renderer/geometry.cc index 9ff312f..6a61eff 100644 --- a/src/engine/renderer/geometry.cc +++ b/src/engine/renderer/geometry.cc @@ -5,10 +5,7 @@ namespace eng { -Geometry::Geometry(unsigned resource_id, - std::shared_ptr impl_data, - Renderer* renderer) - : RenderResource(resource_id, impl_data, renderer) {} +Geometry::Geometry(Renderer* renderer) : RenderResource(renderer) {} Geometry::~Geometry() { Destroy(); @@ -16,22 +13,21 @@ Geometry::~Geometry() { void Geometry::Create(std::unique_ptr mesh) { Destroy(); - valid_ = true; vertex_description_ = mesh->vertex_description(); primitive_ = mesh->primitive(); - renderer_->CreateGeometry(impl_data_, std::move(mesh)); + resource_id_ = renderer_->CreateGeometry(std::move(mesh)); } void Geometry::Destroy() { - if (valid_) { - renderer_->DestroyGeometry(impl_data_); - valid_ = false; + if (IsValid()) { + renderer_->DestroyGeometry(resource_id_); + resource_id_ = 0; } } void Geometry::Draw() { - if (valid_) - renderer_->Draw(impl_data_); + if (IsValid()) + renderer_->Draw(resource_id_); } } // namespace eng diff --git a/src/engine/renderer/geometry.h b/src/engine/renderer/geometry.h index 78c9f79..f87fa65 100644 --- a/src/engine/renderer/geometry.h +++ b/src/engine/renderer/geometry.h @@ -14,14 +14,12 @@ class Mesh; class Geometry : public RenderResource { public: - Geometry(unsigned resource_id, - std::shared_ptr impl_data, - Renderer* renderer); - ~Geometry() override; + Geometry(Renderer* renderer); + ~Geometry(); void Create(std::unique_ptr mesh); - void Destroy() override; + void Destroy(); void Draw(); diff --git a/src/engine/renderer/opengl/render_command.cc b/src/engine/renderer/opengl/render_command.cc index deed111..02baf8c 100644 --- a/src/engine/renderer/opengl/render_command.cc +++ b/src/engine/renderer/opengl/render_command.cc @@ -15,6 +15,8 @@ namespace eng { RENDER_COMMAND_IMPL(CmdPresent, false); +RENDER_COMMAND_IMPL(CmdInvalidateAllResources, true); +RENDER_COMMAND_IMPL(CmdCreateTexture, true); RENDER_COMMAND_IMPL(CmdUpdateTexture, true); RENDER_COMMAND_IMPL(CmdDestoryTexture, true); RENDER_COMMAND_IMPL(CmdActivateTexture, false); diff --git a/src/engine/renderer/opengl/render_command.h b/src/engine/renderer/opengl/render_command.h index e6fff3e..a697618 100644 --- a/src/engine/renderer/opengl/render_command.h +++ b/src/engine/renderer/opengl/render_command.h @@ -50,81 +50,88 @@ struct RenderCommand { RENDER_COMMAND_BEGIN(CmdPresent) RENDER_COMMAND_END +RENDER_COMMAND_BEGIN(CmdInvalidateAllResources) +RENDER_COMMAND_END + +RENDER_COMMAND_BEGIN(CmdCreateTexture) + uint64_t resource_id; +RENDER_COMMAND_END + RENDER_COMMAND_BEGIN(CmdUpdateTexture) std::unique_ptr image; - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdDestoryTexture) - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdActivateTexture) - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdCreateGeometry) std::unique_ptr mesh; - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdDestroyGeometry) - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdDrawGeometry) - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdCreateShader) std::unique_ptr source; VertexDescripton vertex_description; - std::shared_ptr impl_data; + uint64_t resource_id; bool enable_depth_test; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdDestroyShader) - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdActivateShader) - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdSetUniformVec2) std::string name; base::Vector2f v; - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdSetUniformVec3) std::string name; base::Vector3f v; - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdSetUniformVec4) std::string name; base::Vector4f v; - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdSetUniformMat4) std::string name; base::Matrix4f m; - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdSetUniformInt) std::string name; int i; - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END RENDER_COMMAND_BEGIN(CmdSetUniformFloat) std::string name; float f; - std::shared_ptr impl_data; + uint64_t resource_id; RENDER_COMMAND_END } // namespace eng diff --git a/src/engine/renderer/opengl/renderer_opengl.cc b/src/engine/renderer/opengl/renderer_opengl.cc index a03c061..dd21143 100644 --- a/src/engine/renderer/opengl/renderer_opengl.cc +++ b/src/engine/renderer/opengl/renderer_opengl.cc @@ -45,128 +45,136 @@ RendererOpenGL::RendererOpenGL() = default; RendererOpenGL::~RendererOpenGL() = default; -void RendererOpenGL::CreateGeometry(std::shared_ptr impl_data, - std::unique_ptr mesh) { +uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr mesh) { auto cmd = std::make_unique(); cmd->mesh = std::move(mesh); - cmd->impl_data = impl_data; + cmd->resource_id = ++last_resource_id_; EnqueueCommand(std::move(cmd)); + return last_resource_id_; } -void RendererOpenGL::DestroyGeometry(std::shared_ptr impl_data) { +void RendererOpenGL::DestroyGeometry(uint64_t resource_id) { auto cmd = std::make_unique(); - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::Draw(std::shared_ptr impl_data) { +void RendererOpenGL::Draw(uint64_t resource_id) { auto cmd = std::make_unique(); - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::UpdateTexture(std::shared_ptr impl_data, +uint64_t RendererOpenGL::CreateTexture() { + auto cmd = std::make_unique(); + cmd->resource_id = ++last_resource_id_; + EnqueueCommand(std::move(cmd)); + return last_resource_id_; +} + +void RendererOpenGL::UpdateTexture(uint64_t resource_id, std::unique_ptr image) { auto cmd = std::make_unique(); cmd->image = std::move(image); - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::DestroyTexture(std::shared_ptr impl_data) { +void RendererOpenGL::DestroyTexture(uint64_t resource_id) { auto cmd = std::make_unique(); - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::ActivateTexture(std::shared_ptr impl_data) { +void RendererOpenGL::ActivateTexture(uint64_t resource_id) { auto cmd = std::make_unique(); - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::CreateShader(std::shared_ptr impl_data, - std::unique_ptr source, - const VertexDescripton& vertex_description, - Primitive primitive, - bool enable_depth_test) { +uint64_t RendererOpenGL::CreateShader( + std::unique_ptr source, + const VertexDescripton& vertex_description, + Primitive primitive, + bool enable_depth_test) { auto cmd = std::make_unique(); cmd->source = std::move(source); cmd->vertex_description = vertex_description; - cmd->impl_data = impl_data; + cmd->resource_id = ++last_resource_id_; cmd->enable_depth_test = enable_depth_test; EnqueueCommand(std::move(cmd)); + return last_resource_id_; } -void RendererOpenGL::DestroyShader(std::shared_ptr impl_data) { +void RendererOpenGL::DestroyShader(uint64_t resource_id) { auto cmd = std::make_unique(); - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::ActivateShader(std::shared_ptr impl_data) { +void RendererOpenGL::ActivateShader(uint64_t resource_id) { auto cmd = std::make_unique(); - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::SetUniform(std::shared_ptr impl_data, +void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector2f& val) { auto cmd = std::make_unique(); cmd->name = name; cmd->v = val; - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::SetUniform(std::shared_ptr impl_data, +void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector3f& val) { auto cmd = std::make_unique(); cmd->name = name; cmd->v = val; - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::SetUniform(std::shared_ptr impl_data, +void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector4f& val) { auto cmd = std::make_unique(); cmd->name = name; cmd->v = val; - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::SetUniform(std::shared_ptr impl_data, +void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, const base::Matrix4f& val) { auto cmd = std::make_unique(); cmd->name = name; cmd->m = val; - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::SetUniform(std::shared_ptr impl_data, +void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, float val) { auto cmd = std::make_unique(); cmd->name = name; cmd->f = val; - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } -void RendererOpenGL::SetUniform(std::shared_ptr impl_data, +void RendererOpenGL::SetUniform(uint64_t resource_id, const std::string& name, int val) { auto cmd = std::make_unique(); cmd->name = name; cmd->i = val; - cmd->impl_data = impl_data; + cmd->resource_id = resource_id; EnqueueCommand(std::move(cmd)); } @@ -182,47 +190,21 @@ void RendererOpenGL::ContextLost() { LOG << "Context lost."; #ifdef THREADED_RENDERING - global_commands_.clear(); - draw_commands_[0].clear(); - draw_commands_[1].clear(); + { + std::unique_lock scoped_lock(mutex_); + global_commands_.clear(); + draw_commands_[0].clear(); + draw_commands_[1].clear(); + } - main_thread_task_runner_->PostTask( - HERE, std::bind(&RendererOpenGL::InvalidateAllResources, this)); + DestroyAllResources(); main_thread_task_runner_->PostTask(HERE, context_lost_cb_); #else - InvalidateAllResources(); + DestroyAllResources(); context_lost_cb_(); #endif // THREADED_RENDERING } -std::unique_ptr RendererOpenGL::CreateResource( - RenderResourceFactoryBase& factory) { - static unsigned last_id = 0; - - // Set implementation specific data. This data will be sent with render - // commands to the render thread and sould not be used in any other thread. - std::shared_ptr impl_data; - if (factory.IsTypeOf()) - impl_data = std::make_shared(); - else if (factory.IsTypeOf()) - impl_data = std::make_shared(); - else if (factory.IsTypeOf()) - impl_data = std::make_shared(); - else - NOTREACHED << "- Unknown resource type."; - - unsigned resource_id = ++last_id; - auto resource = factory.Create(resource_id, impl_data, this); - resources_[resource_id] = resource.get(); - return resource; -} - -void RendererOpenGL::ReleaseResource(unsigned resource_id) { - auto it = resources_.find(resource_id); - if (it != resources_.end()) - resources_.erase(it); -} - size_t RendererOpenGL::GetAndResetFPS() { int ret = fps_; fps_ = 0; @@ -309,9 +291,37 @@ bool RendererOpenGL::InitCommon() { return true; } -void RendererOpenGL::InvalidateAllResources() { - for (auto& r : resources_) - r.second->Destroy(); +void RendererOpenGL::DestroyAllResources() { + std::vector resource_ids; + for (auto& r : geometries_) + resource_ids.push_back(r.first); + for (auto& r : resource_ids) { + auto cmd = std::make_unique(); + cmd->resource_id = r; + ProcessCommand(cmd.get()); + } + + resource_ids.clear(); + for (auto& r : shaders_) + resource_ids.push_back(r.first); + for (auto& r : resource_ids) { + auto cmd = std::make_unique(); + cmd->resource_id = r; + ProcessCommand(cmd.get()); + } + + resource_ids.clear(); + for (auto& r : textures_) + resource_ids.push_back(r.first); + for (auto& r : resource_ids) { + auto cmd = std::make_unique(); + cmd->resource_id = r; + ProcessCommand(cmd.get()); + } + + DCHECK(geometries_.size() == 0); + DCHECK(shaders_.size() == 0); + DCHECK(textures_.size() == 0); } bool RendererOpenGL::StartRenderThread() { @@ -425,6 +435,9 @@ void RendererOpenGL::ProcessCommand(RenderCommand* cmd) { case CmdPresent::CMD_ID: HandleCmdPresent(cmd); break; + case CmdCreateTexture::CMD_ID: + HandleCmdCreateTexture(cmd); + break; case CmdUpdateTexture::CMD_ID: HandleCmdUpdateTexture(cmd); break; @@ -475,18 +488,29 @@ void RendererOpenGL::ProcessCommand(RenderCommand* cmd) { } } -void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) { - auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - bool new_texture = impl_data->id == 0; +void RendererOpenGL::HandleCmdCreateTexture(RenderCommand* cmd) { + auto* c = static_cast(cmd); GLuint gl_id = 0; - if (new_texture) - glGenTextures(1, &gl_id); - else - gl_id = impl_data->id; + glGenTextures(1, &gl_id); - glBindTexture(GL_TEXTURE_2D, gl_id); + BindTexture(gl_id); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + textures_.insert({c->resource_id, {gl_id}}); +} + +void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) { + auto* c = static_cast(cmd); + auto it = textures_.find(c->resource_id); + if (it == textures_.end()) + return; + + BindTexture(it->second.id); if (c->image->IsCompressed()) { GLenum format = 0; switch (c->image->GetFormat()) { @@ -515,8 +539,8 @@ void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) { c->image->GetHeight(), 0, c->image->GetSize(), c->image->GetBuffer()); - // Sometimes the first glCompressedTexImage2D call after context-lost - // generates GL_INVALID_VALUE. + // On some devices the first glCompressedTexImage2D call after context-lost + // returns GL_INVALID_VALUE for some reason. GLenum err = glGetError(); if (err == GL_INVALID_VALUE) { glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, c->image->GetWidth(), @@ -532,40 +556,30 @@ void RendererOpenGL::HandleCmdUpdateTexture(RenderCommand* cmd) { c->image->GetHeight(), 0, GL_RGBA, GL_UNSIGNED_BYTE, c->image->GetBuffer()); } - - if (new_texture) { - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - *impl_data = {gl_id}; - } } void RendererOpenGL::HandleCmdDestoryTexture(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) { - glDeleteTextures(1, &(impl_data->id)); - *impl_data = {}; - } + auto it = textures_.find(c->resource_id); + if (it == textures_.end()) + return; + + glDeleteTextures(1, &(it->second.id)); + textures_.erase(it); } void RendererOpenGL::HandleCmdActivateTexture(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0 && impl_data->id != active_texture_id_) { - glBindTexture(GL_TEXTURE_2D, impl_data->id); - active_texture_id_ = impl_data->id; + auto it = textures_.find(c->resource_id); + if (it == textures_.end()) { + return; } + + BindTexture(it->second.id); } void RendererOpenGL::HandleCmdCreateGeometry(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->vertex_buffer_id > 0) - return; // Verify that we have a valid layout and get the total byte size per vertex. GLuint vertex_size = c->mesh->GetVertexSize(); @@ -613,71 +627,71 @@ void RendererOpenGL::HandleCmdCreateGeometry(RenderCommand* cmd) { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - *impl_data = {(GLsizei)c->mesh->num_vertices(), - (GLsizei)c->mesh->num_indices(), - kGlPrimitive[c->mesh->primitive()], - kGlDataType[c->mesh->index_description()], - vertex_layout, - vertex_size, - vertex_array_id, - vertex_buffer_id, - index_buffer_id}; + geometries_[c->resource_id] = {(GLsizei)c->mesh->num_vertices(), + (GLsizei)c->mesh->num_indices(), + kGlPrimitive[c->mesh->primitive()], + kGlDataType[c->mesh->index_description()], + vertex_layout, + vertex_size, + vertex_array_id, + vertex_buffer_id, + index_buffer_id}; } void RendererOpenGL::HandleCmdDestroyGeometry(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->vertex_buffer_id == 0) + auto it = geometries_.find(c->resource_id); + if (it == geometries_.end()) return; - if (impl_data->index_buffer_id) - glDeleteBuffers(1, &(impl_data->index_buffer_id)); - if (impl_data->vertex_buffer_id) - glDeleteBuffers(1, &(impl_data->vertex_buffer_id)); - if (impl_data->vertex_array_id) - glDeleteVertexArrays(1, &(impl_data->vertex_array_id)); + if (it->second.index_buffer_id) + glDeleteBuffers(1, &(it->second.index_buffer_id)); + if (it->second.vertex_buffer_id) + glDeleteBuffers(1, &(it->second.vertex_buffer_id)); + if (it->second.vertex_array_id) + glDeleteVertexArrays(1, &(it->second.vertex_array_id)); - *impl_data = {}; + geometries_.erase(it); } void RendererOpenGL::HandleCmdDrawGeometry(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->vertex_buffer_id == 0) + auto it = geometries_.find(c->resource_id); + if (it == geometries_.end()) return; // Set up the vertex data. - if (impl_data->vertex_array_id) - glBindVertexArray(impl_data->vertex_array_id); + if (it->second.vertex_array_id) + glBindVertexArray(it->second.vertex_array_id); else { - glBindBuffer(GL_ARRAY_BUFFER, impl_data->vertex_buffer_id); + glBindBuffer(GL_ARRAY_BUFFER, it->second.vertex_buffer_id); for (GLuint attribute_index = 0; - attribute_index < (GLuint)impl_data->vertex_layout.size(); + attribute_index < (GLuint)it->second.vertex_layout.size(); ++attribute_index) { - GeometryOpenGL::Element& e = impl_data->vertex_layout[attribute_index]; + GeometryOpenGL::Element& e = it->second.vertex_layout[attribute_index]; glEnableVertexAttribArray(attribute_index); glVertexAttribPointer(attribute_index, e.num_elements, e.type, GL_FALSE, - impl_data->vertex_size, + it->second.vertex_size, (const GLvoid*)e.vertex_offset); } - if (impl_data->num_indices > 0) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, impl_data->index_buffer_id); + if (it->second.num_indices > 0) + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id); } // Draw the primitive. - if (impl_data->num_indices > 0) - glDrawElements(impl_data->primitive, impl_data->num_indices, - impl_data->index_type, NULL); + if (it->second.num_indices > 0) + glDrawElements(it->second.primitive, it->second.num_indices, + it->second.index_type, NULL); else - glDrawArrays(impl_data->primitive, 0, impl_data->num_vertices); + glDrawArrays(it->second.primitive, 0, it->second.num_vertices); // Clean up states. - if (impl_data->vertex_array_id) + if (it->second.vertex_array_id) glBindVertexArray(0); else { for (GLuint attribute_index = 0; - attribute_index < (GLuint)impl_data->vertex_layout.size(); + attribute_index < (GLuint)it->second.vertex_layout.size(); ++attribute_index) glDisableVertexAttribArray(attribute_index); @@ -688,9 +702,6 @@ void RendererOpenGL::HandleCmdDrawGeometry(RenderCommand* cmd) { void RendererOpenGL::HandleCmdCreateShader(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) - return; GLuint vertex_shader = CreateShader(c->source->GetVertexSource(), GL_VERTEX_SHADER); @@ -728,25 +739,29 @@ void RendererOpenGL::HandleCmdCreateShader(RenderCommand* cmd) { } } - *impl_data = {id, {}, c->enable_depth_test}; + shaders_[c->resource_id] = {id, {}, c->enable_depth_test}; } void RendererOpenGL::HandleCmdDestroyShader(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) { - glDeleteProgram(impl_data->id); - *impl_data = {}; - } + auto it = shaders_.find(c->resource_id); + if (it == shaders_.end()) + return; + + glDeleteProgram(it->second.id); + shaders_.erase(it); } void RendererOpenGL::HandleCmdActivateShader(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0 && impl_data->id != active_shader_id_) { - glUseProgram(impl_data->id); - active_shader_id_ = impl_data->id; - if (impl_data->enable_depth_test) + auto it = shaders_.find(c->resource_id); + if (it == shaders_.end()) + return; + + if (it->second.id != active_shader_id_) { + glUseProgram(it->second.id); + active_shader_id_ = it->second.id; + if (it->second.enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); @@ -755,67 +770,74 @@ void RendererOpenGL::HandleCmdActivateShader(RenderCommand* cmd) { void RendererOpenGL::HandleCmdSetUniformVec2(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) { - GLint index = - GetUniformLocation(impl_data->id, c->name, impl_data->uniforms); - if (index >= 0) - glUniform2fv(index, 1, c->v.GetData()); - } + auto it = shaders_.find(c->resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); + if (index >= 0) + glUniform2fv(index, 1, c->v.GetData()); } void RendererOpenGL::HandleCmdSetUniformVec3(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) { - GLint index = - GetUniformLocation(impl_data->id, c->name, impl_data->uniforms); - if (index >= 0) - glUniform3fv(index, 1, c->v.GetData()); - } + auto it = shaders_.find(c->resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); + if (index >= 0) + glUniform3fv(index, 1, c->v.GetData()); } void RendererOpenGL::HandleCmdSetUniformVec4(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) { - GLint index = - GetUniformLocation(impl_data->id, c->name, impl_data->uniforms); - if (index >= 0) - glUniform4fv(index, 1, c->v.GetData()); - } + auto it = shaders_.find(c->resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); + if (index >= 0) + glUniform4fv(index, 1, c->v.GetData()); } void RendererOpenGL::HandleCmdSetUniformMat4(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) { - GLint index = - GetUniformLocation(impl_data->id, c->name, impl_data->uniforms); - if (index >= 0) - glUniformMatrix4fv(index, 1, GL_FALSE, c->m.GetData()); - } + auto it = shaders_.find(c->resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); + if (index >= 0) + glUniformMatrix4fv(index, 1, GL_FALSE, c->m.GetData()); } void RendererOpenGL::HandleCmdSetUniformFloat(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) { - GLint index = - GetUniformLocation(impl_data->id, c->name, impl_data->uniforms); - if (index >= 0) - glUniform1f(index, c->f); - } + auto it = shaders_.find(c->resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); + if (index >= 0) + glUniform1f(index, c->f); } void RendererOpenGL::HandleCmdSetUniformInt(RenderCommand* cmd) { auto* c = static_cast(cmd); - auto impl_data = reinterpret_cast(c->impl_data.get()); - if (impl_data->id > 0) { - GLint index = - GetUniformLocation(impl_data->id, c->name, impl_data->uniforms); - if (index >= 0) - glUniform1i(index, c->i); + auto it = shaders_.find(c->resource_id); + if (it == shaders_.end()) + return; + + GLint index = GetUniformLocation(it->second.id, c->name, it->second.uniforms); + if (index >= 0) + glUniform1i(index, c->i); +} + +void RendererOpenGL::BindTexture(GLuint id) { + if (id != active_texture_id_) { + glBindTexture(GL_TEXTURE_2D, id); + active_texture_id_ = id; } } diff --git a/src/engine/renderer/opengl/renderer_opengl.h b/src/engine/renderer/opengl/renderer_opengl.h index 4a0e0dd..4525fcd 100644 --- a/src/engine/renderer/opengl/renderer_opengl.h +++ b/src/engine/renderer/opengl/renderer_opengl.h @@ -20,7 +20,6 @@ #include "opengl.h" -#include "../render_resource.h" #include "../renderer.h" #if defined(__ANDROID__) @@ -50,51 +49,46 @@ class RendererOpenGL : public Renderer { void Shutdown() override; - void CreateGeometry(std::shared_ptr impl_data, - std::unique_ptr mesh) override; - void DestroyGeometry(std::shared_ptr impl_data) override; - void Draw(std::shared_ptr impl_data) override; + uint64_t CreateGeometry(std::unique_ptr mesh) override; + void DestroyGeometry(uint64_t resource_id) override; + void Draw(uint64_t resource_id) override; - void UpdateTexture(std::shared_ptr impl_data, + uint64_t CreateTexture() override; + void UpdateTexture(uint64_t resource_id, std::unique_ptr image) override; - void DestroyTexture(std::shared_ptr impl_data) override; - void ActivateTexture(std::shared_ptr impl_data) override; + void DestroyTexture(uint64_t resource_id) override; + void ActivateTexture(uint64_t resource_id) override; - void CreateShader(std::shared_ptr impl_data, - std::unique_ptr source, - const VertexDescripton& vertex_description, - Primitive primitive, - bool enable_depth_test) override; - void DestroyShader(std::shared_ptr impl_data) override; - void ActivateShader(std::shared_ptr impl_data) override; + uint64_t CreateShader(std::unique_ptr source, + const VertexDescripton& vertex_description, + Primitive primitive, + bool enable_depth_test) override; + void DestroyShader(uint64_t resource_id) override; + void ActivateShader(uint64_t resource_id) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector2f& val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector3f& val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector4f& val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, const base::Matrix4f& val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, float val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, int val) override; - void UploadUniforms(std::shared_ptr impl_data) override {} + void UploadUniforms(uint64_t resource_id) override {} void PrepareForDrawing() override {} void Present() override; - std::unique_ptr CreateResource( - RenderResourceFactoryBase& factory) override; - void ReleaseResource(unsigned resource_id) override; - size_t GetAndResetFPS() override; #if defined(__linux__) && !defined(__ANDROID__) @@ -130,14 +124,17 @@ class RendererOpenGL : public Renderer { GLuint id = 0; }; + std::unordered_map geometries_; + std::unordered_map shaders_; + std::unordered_map textures_; + uint64_t last_resource_id_ = 0; + GLuint active_shader_id_ = 0; GLuint active_texture_id_ = 0; bool vertex_array_objects_ = false; bool npot_ = false; - std::unordered_map resources_; - #ifdef THREADED_RENDERING // Global commands are independent from frames and guaranteed to be processed. std::deque> global_commands_; @@ -172,7 +169,7 @@ class RendererOpenGL : public Renderer { void ContextLost(); - void InvalidateAllResources(); + void DestroyAllResources(); bool StartRenderThread(); void TerminateRenderThread(); @@ -185,6 +182,7 @@ class RendererOpenGL : public Renderer { void ProcessCommand(RenderCommand* cmd); void HandleCmdPresent(RenderCommand* cmd); + void HandleCmdCreateTexture(RenderCommand* cmd); void HandleCmdUpdateTexture(RenderCommand* cmd); void HandleCmdDestoryTexture(RenderCommand* cmd); void HandleCmdActivateTexture(RenderCommand* cmd); @@ -201,6 +199,7 @@ class RendererOpenGL : public Renderer { void HandleCmdSetUniformFloat(RenderCommand* cmd); void HandleCmdSetUniformInt(RenderCommand* cmd); + void BindTexture(GLuint id); bool SetupVertexLayout(const VertexDescripton& vd, GLuint vertex_size, bool use_vao, diff --git a/src/engine/renderer/render_resource.cc b/src/engine/renderer/render_resource.cc deleted file mode 100644 index 711e283..0000000 --- a/src/engine/renderer/render_resource.cc +++ /dev/null @@ -1,16 +0,0 @@ -#include "render_resource.h" - -#include "renderer.h" - -namespace eng { - -RenderResource::RenderResource(unsigned resource_id, - std::shared_ptr impl_data, - Renderer* renderer) - : resource_id_(resource_id), impl_data_(impl_data), renderer_(renderer) {} - -RenderResource::~RenderResource() { - renderer_->ReleaseResource(resource_id_); -} - -} // namespace eng diff --git a/src/engine/renderer/render_resource.h b/src/engine/renderer/render_resource.h index 5a4920f..ea61462 100644 --- a/src/engine/renderer/render_resource.h +++ b/src/engine/renderer/render_resource.h @@ -1,10 +1,7 @@ #ifndef RENDER_RESOURCE_H #define RENDER_RESOURCE_H -#include -#include -#include -#include +#include namespace eng { @@ -12,60 +9,22 @@ class Renderer; class RenderResource { public: - RenderResource(unsigned resource_id, - std::shared_ptr impl_data, - Renderer* renderer); - virtual ~RenderResource(); + RenderResource(Renderer* renderer) : renderer_(renderer){}; - virtual void Destroy() = 0; + bool IsValid() const { return resource_id_ != 0; } - bool IsValid() const { return valid_; } - - std::shared_ptr impl_data() { return impl_data_; } + uint64_t resource_id() { return resource_id_; } protected: - unsigned resource_id_ = 0; - std::shared_ptr impl_data_; // For use in render thread only. - bool valid_ = false; - + uint64_t resource_id_ = 0; Renderer* renderer_ = nullptr; + ~RenderResource() = default; + RenderResource(const RenderResource&) = delete; RenderResource& operator=(const RenderResource&) = delete; }; -class RenderResourceFactoryBase { - public: - RenderResourceFactoryBase(std::type_index resource_type) - : resource_type_(resource_type) {} - virtual ~RenderResourceFactoryBase() = default; - - virtual std::unique_ptr - Create(unsigned id, std::shared_ptr impl_data, Renderer* renderer) = 0; - - template - bool IsTypeOf() const { - return resource_type_ == std::type_index(typeid(T)); - } - - private: - std::type_index resource_type_; -}; - -template -class RenderResourceFactory : public RenderResourceFactoryBase { - public: - RenderResourceFactory() - : RenderResourceFactoryBase(std::type_index(typeid(T))) {} - ~RenderResourceFactory() override = default; - - std::unique_ptr Create(unsigned id, - std::shared_ptr impl_data, - Renderer* renderer) override { - return std::make_unique(id, impl_data, renderer); - } -}; - } // namespace eng #endif // RENDER_RESOURCE_H diff --git a/src/engine/renderer/renderer.h b/src/engine/renderer/renderer.h index 59e735e..482ac1b 100644 --- a/src/engine/renderer/renderer.h +++ b/src/engine/renderer/renderer.h @@ -40,51 +40,46 @@ class Renderer { virtual void Shutdown() = 0; - virtual void CreateGeometry(std::shared_ptr impl_data, - std::unique_ptr mesh) = 0; - virtual void DestroyGeometry(std::shared_ptr impl_data) = 0; - virtual void Draw(std::shared_ptr impl_data) = 0; + virtual uint64_t CreateGeometry(std::unique_ptr mesh) = 0; + virtual void DestroyGeometry(uint64_t resource_id) = 0; + virtual void Draw(uint64_t resource_id) = 0; - virtual void UpdateTexture(std::shared_ptr impl_data, + virtual uint64_t CreateTexture() = 0; + virtual void UpdateTexture(uint64_t resource_id, std::unique_ptr image) = 0; - virtual void DestroyTexture(std::shared_ptr impl_data) = 0; - virtual void ActivateTexture(std::shared_ptr impl_data) = 0; + virtual void DestroyTexture(uint64_t resource_id) = 0; + virtual void ActivateTexture(uint64_t resource_id) = 0; - virtual void CreateShader(std::shared_ptr impl_data, - std::unique_ptr source, - const VertexDescripton& vertex_description, - Primitive primitive, - bool enable_depth_test) = 0; - virtual void DestroyShader(std::shared_ptr impl_data) = 0; - virtual void ActivateShader(std::shared_ptr impl_data) = 0; + virtual uint64_t CreateShader(std::unique_ptr source, + const VertexDescripton& vertex_description, + Primitive primitive, + bool enable_depth_test) = 0; + virtual void DestroyShader(uint64_t resource_id) = 0; + virtual void ActivateShader(uint64_t resource_id) = 0; - virtual void SetUniform(std::shared_ptr impl_data, + virtual void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector2f& val) = 0; - virtual void SetUniform(std::shared_ptr impl_data, + virtual void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector3f& val) = 0; - virtual void SetUniform(std::shared_ptr impl_data, + virtual void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector4f& val) = 0; - virtual void SetUniform(std::shared_ptr impl_data, + virtual void SetUniform(uint64_t resource_id, const std::string& name, const base::Matrix4f& val) = 0; - virtual void SetUniform(std::shared_ptr impl_data, + virtual void SetUniform(uint64_t resource_id, const std::string& name, float val) = 0; - virtual void SetUniform(std::shared_ptr impl_data, + virtual void SetUniform(uint64_t resource_id, const std::string& name, int val) = 0; - virtual void UploadUniforms(std::shared_ptr impl_data) = 0; + virtual void UploadUniforms(uint64_t resource_id) = 0; virtual void PrepareForDrawing() = 0; virtual void Present() = 0; - virtual std::unique_ptr CreateResource( - RenderResourceFactoryBase& factory) = 0; - virtual void ReleaseResource(unsigned resource_id) = 0; - bool SupportsETC1() const { return texture_compression_.etc1; } bool SupportsDXT1() const { return texture_compression_.dxt1 || texture_compression_.s3tc; diff --git a/src/engine/renderer/shader.cc b/src/engine/renderer/shader.cc index 25e4c8e..88e25bb 100644 --- a/src/engine/renderer/shader.cc +++ b/src/engine/renderer/shader.cc @@ -7,10 +7,7 @@ using namespace base; namespace eng { -Shader::Shader(unsigned resource_id, - std::shared_ptr impl_data, - Renderer* renderer) - : RenderResource(resource_id, impl_data, renderer) {} +Shader::Shader(Renderer* renderer) : RenderResource(renderer) {} Shader::~Shader() { Destroy(); @@ -21,56 +18,55 @@ void Shader::Create(std::unique_ptr source, Primitive primitive, bool enable_depth_test) { Destroy(); - valid_ = true; - renderer_->CreateShader(impl_data_, std::move(source), vd, primitive, - enable_depth_test); + resource_id_ = renderer_->CreateShader(std::move(source), vd, primitive, + enable_depth_test); } void Shader::Destroy() { - if (valid_) { - renderer_->DestroyShader(impl_data_); - valid_ = false; + if (IsValid()) { + renderer_->DestroyShader(resource_id_); + resource_id_ = 0; } } void Shader::Activate() { - if (valid_) - renderer_->ActivateShader(impl_data_); + if (IsValid()) + renderer_->ActivateShader(resource_id_); } void Shader::SetUniform(const std::string& name, const Vector2f& v) { - if (valid_) - renderer_->SetUniform(impl_data_, name, v); + if (IsValid()) + renderer_->SetUniform(resource_id_, name, v); } void Shader::SetUniform(const std::string& name, const Vector3f& v) { - if (valid_) - renderer_->SetUniform(impl_data_, name, v); + if (IsValid()) + renderer_->SetUniform(resource_id_, name, v); } void Shader::SetUniform(const std::string& name, const Vector4f& v) { - if (valid_) - renderer_->SetUniform(impl_data_, name, v); + if (IsValid()) + renderer_->SetUniform(resource_id_, name, v); } void Shader::SetUniform(const std::string& name, const Matrix4f& m) { - if (valid_) - renderer_->SetUniform(impl_data_, name, m); + if (IsValid()) + renderer_->SetUniform(resource_id_, name, m); } void Shader::SetUniform(const std::string& name, float f) { - if (valid_) - renderer_->SetUniform(impl_data_, name, f); + if (IsValid()) + renderer_->SetUniform(resource_id_, name, f); } void Shader::SetUniform(const std::string& name, int i) { - if (valid_) - renderer_->SetUniform(impl_data_, name, i); + if (IsValid()) + renderer_->SetUniform(resource_id_, name, i); } void Shader::UploadUniforms() { - if (valid_) - renderer_->UploadUniforms(impl_data_); + if (IsValid()) + renderer_->UploadUniforms(resource_id_); } } // namespace eng diff --git a/src/engine/renderer/shader.h b/src/engine/renderer/shader.h index 8d2b620..febcc24 100644 --- a/src/engine/renderer/shader.h +++ b/src/engine/renderer/shader.h @@ -15,17 +15,15 @@ class ShaderSource; class Shader : public RenderResource { public: - Shader(unsigned resource_id, - std::shared_ptr impl_data, - Renderer* renderer); - ~Shader() override; + Shader(Renderer* renderer); + ~Shader(); void Create(std::unique_ptr source, const VertexDescripton& vd, Primitive primitive, bool enable_depth_test); - void Destroy() override; + void Destroy(); void Activate(); diff --git a/src/engine/renderer/texture.cc b/src/engine/renderer/texture.cc index d659f35..faaba70 100644 --- a/src/engine/renderer/texture.cc +++ b/src/engine/renderer/texture.cc @@ -6,33 +6,31 @@ namespace eng { -Texture::Texture(unsigned resource_id, - std::shared_ptr impl_data, - Renderer* renderer) - : RenderResource(resource_id, impl_data, renderer) {} +Texture::Texture(Renderer* renderer) : RenderResource(renderer) {} Texture::~Texture() { Destroy(); } void Texture::Update(std::unique_ptr image) { - valid_ = true; + if (!IsValid()) + resource_id_ = renderer_->CreateTexture(); width_ = image->GetWidth(); height_ = image->GetHeight(); - renderer_->UpdateTexture(impl_data_, std::move(image)); + renderer_->UpdateTexture(resource_id_, std::move(image)); } void Texture::Destroy() { - if (valid_) { - renderer_->DestroyTexture(impl_data_); - valid_ = false; + if (IsValid()) { + renderer_->DestroyTexture(resource_id_); + resource_id_ = 0; DLOG << "Texture destroyed. resource_id: " << resource_id_; } } void Texture::Activate() { - if (valid_) - renderer_->ActivateTexture(impl_data_); + if (IsValid()) + renderer_->ActivateTexture(resource_id_); } } // namespace eng diff --git a/src/engine/renderer/texture.h b/src/engine/renderer/texture.h index a59bc6d..e2c74a9 100644 --- a/src/engine/renderer/texture.h +++ b/src/engine/renderer/texture.h @@ -13,15 +13,12 @@ class Renderer; class Texture : public RenderResource { public: - Texture(unsigned resource_id, - std::shared_ptr impl_data, - Renderer* renderer); - ~Texture() override; + Texture(Renderer* renderer); + ~Texture(); - // Uploads image. void Update(std::unique_ptr image); - void Destroy() override; + void Destroy(); void Activate(); diff --git a/src/engine/renderer/vulkan/renderer_vulkan.cc b/src/engine/renderer/vulkan/renderer_vulkan.cc index fe1a179..0d1fa70 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan.cc @@ -259,39 +259,39 @@ RendererVulkan::RendererVulkan() = default; RendererVulkan::~RendererVulkan() = default; -void RendererVulkan::CreateGeometry(std::shared_ptr impl_data, - std::unique_ptr mesh) { - auto geometry = reinterpret_cast(impl_data.get()); - geometry->num_vertices = mesh->num_vertices(); - size_t vertex_data_size = mesh->GetVertexSize() * geometry->num_vertices; +uint64_t RendererVulkan::CreateGeometry(std::unique_ptr mesh) { + auto& geometry = geometries_[++last_resource_id_] = {}; + + geometry.num_vertices = mesh->num_vertices(); + size_t vertex_data_size = mesh->GetVertexSize() * geometry.num_vertices; size_t index_data_size = 0; if (mesh->GetIndices()) { - geometry->num_indices = mesh->num_indices(); - geometry->index_type = GetIndexType(mesh->index_description()); - index_data_size = mesh->GetIndexSize() * geometry->num_indices; + geometry.num_indices = mesh->num_indices(); + geometry.index_type = GetIndexType(mesh->index_description()); + index_data_size = mesh->GetIndexSize() * geometry.num_indices; } size_t data_size = vertex_data_size + index_data_size; - AllocateBuffer(geometry->buffer, data_size, + AllocateBuffer(geometry.buffer, data_size, VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, VMA_MEMORY_USAGE_GPU_ONLY); task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this, - std::get<0>(geometry->buffer), 0, + std::get<0>(geometry.buffer), 0, mesh->GetVertices(), vertex_data_size)); - if (geometry->num_indices > 0) { - geometry->indices_offset = vertex_data_size; + if (geometry.num_indices > 0) { + geometry.indices_offset = vertex_data_size; task_runner_.PostTask( HERE, std::bind(&RendererVulkan::UpdateBuffer, this, - std::get<0>(geometry->buffer), geometry->indices_offset, + std::get<0>(geometry.buffer), geometry.indices_offset, mesh->GetIndices(), index_data_size)); } task_runner_.PostTask(HERE, std::bind(&RendererVulkan::BufferMemoryBarrier, this, - std::get<0>(geometry->buffer), 0, data_size, + std::get<0>(geometry.buffer), 0, data_size, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_VERTEX_INPUT_BIT, VK_ACCESS_TRANSFER_WRITE_BIT, @@ -301,76 +301,93 @@ void RendererVulkan::CreateGeometry(std::shared_ptr impl_data, std::unique_ptr own(mesh); }); semaphore_.Release(); + + return last_resource_id_; } -void RendererVulkan::DestroyGeometry(std::shared_ptr impl_data) { - auto geometry = reinterpret_cast(impl_data.get()); - FreeBuffer(std::move(geometry->buffer)); - geometry = {}; +void RendererVulkan::DestroyGeometry(uint64_t resource_id) { + auto it = geometries_.find(resource_id); + if (it == geometries_.end()) + return; + + FreeBuffer(std::move(it->second.buffer)); + geometries_.erase(it); } -void RendererVulkan::Draw(std::shared_ptr impl_data) { - auto geometry = reinterpret_cast(impl_data.get()); +void RendererVulkan::Draw(uint64_t resource_id) { + auto it = geometries_.find(resource_id); + if (it == geometries_.end()) + return; + VkDeviceSize offset = 0; vkCmdBindVertexBuffers(frames_[current_frame_].draw_command_buffer, 0, 1, - &std::get<0>(geometry->buffer), &offset); - if (geometry->num_indices > 0) { + &std::get<0>(it->second.buffer), &offset); + if (it->second.num_indices > 0) { vkCmdBindIndexBuffer(frames_[current_frame_].draw_command_buffer, - std::get<0>(geometry->buffer), - geometry->indices_offset, geometry->index_type); + std::get<0>(it->second.buffer), + it->second.indices_offset, it->second.index_type); vkCmdDrawIndexed(frames_[current_frame_].draw_command_buffer, - geometry->num_indices, 1, 0, 0, 0); + it->second.num_indices, 1, 0, 0, 0); } else { vkCmdDraw(frames_[current_frame_].draw_command_buffer, - geometry->num_vertices, 1, 0, 0); + it->second.num_vertices, 1, 0, 0); } } -void RendererVulkan::UpdateTexture(std::shared_ptr impl_data, +uint64_t RendererVulkan::CreateTexture() { + textures_.insert({++last_resource_id_, {}}); + return last_resource_id_; +} + +void RendererVulkan::UpdateTexture(uint64_t resource_id, std::unique_ptr image) { - auto texture = reinterpret_cast(impl_data.get()); + auto it = textures_.find(resource_id); + if (it == textures_.end()) + return; + VkImageLayout old_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkFormat format = GetImageFormat(image->GetFormat()); - if (texture->view != VK_NULL_HANDLE && - (texture->width != image->GetWidth() || - texture->height != image->GetHeight())) { + if (it->second.view != VK_NULL_HANDLE && + (it->second.width != image->GetWidth() || + it->second.height != image->GetHeight())) { // Size mismatch. Recreate the texture. - FreeTexture(std::move(texture->image), texture->view, - std::move(texture->desc_set)); - *texture = {}; + FreeTexture(std::move(it->second.image), it->second.view, + std::move(it->second.desc_set)); + it->second = {}; } - if (texture->view == VK_NULL_HANDLE) { - CreateTexture(texture->image, texture->view, texture->desc_set, format, - image->GetWidth(), image->GetHeight(), + if (it->second.view == VK_NULL_HANDLE) { + CreateTexture(it->second.image, it->second.view, it->second.desc_set, + format, image->GetWidth(), image->GetHeight(), VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VMA_MEMORY_USAGE_GPU_ONLY); old_layout = VK_IMAGE_LAYOUT_UNDEFINED; - texture->width = image->GetWidth(); - texture->height = image->GetHeight(); + it->second.width = image->GetWidth(); + it->second.height = image->GetHeight(); } task_runner_.PostTask( HERE, std::bind(&RendererVulkan::ImageMemoryBarrier, this, - std::get<0>(texture->image), + std::get<0>(it->second.image), VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, 0, VK_ACCESS_TRANSFER_WRITE_BIT, old_layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL)); task_runner_.PostTask( HERE, std::bind(&RendererVulkan::UpdateImage, this, - std::get<0>(texture->image), format, image->GetBuffer(), + std::get<0>(it->second.image), format, image->GetBuffer(), image->GetWidth(), image->GetHeight())); task_runner_.PostTask( - HERE, std::bind(&RendererVulkan::ImageMemoryBarrier, this, - std::get<0>(texture->image), VK_ACCESS_TRANSFER_WRITE_BIT, - VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | - VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, - 0, VK_ACCESS_SHADER_READ_BIT, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); + HERE, + std::bind(&RendererVulkan::ImageMemoryBarrier, this, + std::get<0>(it->second.image), VK_ACCESS_TRANSFER_WRITE_BIT, + VK_PIPELINE_STAGE_VERTEX_SHADER_BIT | + VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT | + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, + 0, VK_ACCESS_SHADER_READ_BIT, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL)); task_runner_.PostTask(HERE, [&, image = image.release()]() { // Transfer image ownership to the background thread. std::unique_ptr own(image); @@ -378,26 +395,30 @@ void RendererVulkan::UpdateTexture(std::shared_ptr impl_data, semaphore_.Release(); } -void RendererVulkan::DestroyTexture(std::shared_ptr impl_data) { - auto texture = reinterpret_cast(impl_data.get()); - FreeTexture(std::move(texture->image), texture->view, - std::move(texture->desc_set)); - *texture = {}; +void RendererVulkan::DestroyTexture(uint64_t resource_id) { + auto it = textures_.find(resource_id); + if (it == textures_.end()) + return; + + FreeTexture(std::move(it->second.image), it->second.view, + std::move(it->second.desc_set)); + textures_.erase(it); } -void RendererVulkan::ActivateTexture(std::shared_ptr impl_data) { - auto texture = reinterpret_cast(impl_data.get()); +void RendererVulkan::ActivateTexture(uint64_t resource_id) { + auto it = textures_.find(resource_id); + if (it == textures_.end()) + return; + // Keep as pengind and bind later in ActivateShader. - penging_descriptor_sets_[/*TODO*/ 0] = std::get<0>(texture->desc_set); + penging_descriptor_sets_[/*TODO*/ 0] = std::get<0>(it->second.desc_set); } -void RendererVulkan::CreateShader(std::shared_ptr impl_data, - std::unique_ptr source, - const VertexDescripton& vertex_description, - Primitive primitive, - bool enable_depth_test) { - auto shader = reinterpret_cast(impl_data.get()); - +uint64_t RendererVulkan::CreateShader( + std::unique_ptr source, + const VertexDescripton& vertex_description, + Primitive primitive, + bool enable_depth_test) { auto it = spirv_cache_.find(source->name()); if (it == spirv_cache_.end()) { std::array, 2> spirv; @@ -426,7 +447,7 @@ void RendererVulkan::CreateShader(std::shared_ptr impl_data, if (vkCreateShaderModule(device_, &shader_module_info, nullptr, &vert_shader_module) != VK_SUCCESS) { DLOG << "vkCreateShaderModule failed!"; - return; + return 0; } } @@ -441,12 +462,14 @@ void RendererVulkan::CreateShader(std::shared_ptr impl_data, if (vkCreateShaderModule(device_, &shader_module_info, nullptr, &frag_shader_module) != VK_SUCCESS) { DLOG << "vkCreateShaderModule failed!"; - return; + return 0; } } + auto& shader = shaders_[++last_resource_id_] = {}; + if (!CreatePipelineLayout(shader, spirv_vertex, spirv_fragment)) - return; + DLOG << "Failed to create pipeline layout!"; VkPipelineShaderStageCreateInfo vert_shader_stage_info{}; vert_shader_stage_info.sType = @@ -567,97 +590,125 @@ void RendererVulkan::CreateShader(std::shared_ptr impl_data, pipeline_info.pColorBlendState = &color_blending; pipeline_info.pDepthStencilState = &depth_stencil; pipeline_info.pDynamicState = &dynamic_state_create_info; - pipeline_info.layout = shader->pipeline_layout; + pipeline_info.layout = shader.pipeline_layout; pipeline_info.renderPass = context_.GetRenderPass(); pipeline_info.subpass = 0; pipeline_info.basePipelineHandle = VK_NULL_HANDLE; if (vkCreateGraphicsPipelines(device_, VK_NULL_HANDLE, 1, &pipeline_info, - nullptr, &shader->pipeline) != VK_SUCCESS) + nullptr, &shader.pipeline) != VK_SUCCESS) DLOG << "failed to create graphics pipeline."; vkDestroyShaderModule(device_, frag_shader_module, nullptr); vkDestroyShaderModule(device_, vert_shader_module, nullptr); + return last_resource_id_; } -void RendererVulkan::DestroyShader(std::shared_ptr impl_data) { - auto shader = reinterpret_cast(impl_data.get()); +void RendererVulkan::DestroyShader(uint64_t resource_id) { + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + frames_[current_frame_].pipelines_to_destroy.push_back( - std::make_tuple(shader->pipeline, shader->pipeline_layout)); - *shader = {}; + std::make_tuple(it->second.pipeline, it->second.pipeline_layout)); + shaders_.erase(it); } -void RendererVulkan::ActivateShader(std::shared_ptr impl_data) { - auto shader = reinterpret_cast(impl_data.get()); - if (active_pipeline_ != shader->pipeline) { - active_pipeline_ = shader->pipeline; +void RendererVulkan::ActivateShader(uint64_t resource_id) { + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + if (active_pipeline_ != it->second.pipeline) { + active_pipeline_ = it->second.pipeline; vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, shader->pipeline); + VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline); } - for (int i = 0; i < shader->desc_set_count; ++i) { + for (int i = 0; i < it->second.desc_set_count; ++i) { if (active_descriptor_sets_[i] != penging_descriptor_sets_[i]) { active_descriptor_sets_[i] = penging_descriptor_sets_[i]; vkCmdBindDescriptorSets(frames_[current_frame_].draw_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, - shader->pipeline_layout, 0, 1, + it->second.pipeline_layout, 0, 1, &active_descriptor_sets_[i], 0, nullptr); break; } } } -void RendererVulkan::SetUniform(std::shared_ptr impl_data, +void RendererVulkan::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector2f& val) { - auto shader = reinterpret_cast(impl_data.get()); - SetUniformInternal(shader, name, val); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + SetUniformInternal(it->second, name, val); } -void RendererVulkan::SetUniform(std::shared_ptr impl_data, +void RendererVulkan::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector3f& val) { - auto shader = reinterpret_cast(impl_data.get()); - SetUniformInternal(shader, name, val); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + SetUniformInternal(it->second, name, val); } -void RendererVulkan::SetUniform(std::shared_ptr impl_data, +void RendererVulkan::SetUniform(uint64_t resource_id, const std::string& name, const base::Vector4f& val) { - auto shader = reinterpret_cast(impl_data.get()); - SetUniformInternal(shader, name, val); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + SetUniformInternal(it->second, name, val); } -void RendererVulkan::SetUniform(std::shared_ptr impl_data, +void RendererVulkan::SetUniform(uint64_t resource_id, const std::string& name, const base::Matrix4f& val) { - auto shader = reinterpret_cast(impl_data.get()); - SetUniformInternal(shader, name, val); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + SetUniformInternal(it->second, name, val); } -void RendererVulkan::SetUniform(std::shared_ptr impl_data, +void RendererVulkan::SetUniform(uint64_t resource_id, const std::string& name, float val) { - auto shader = reinterpret_cast(impl_data.get()); - SetUniformInternal(shader, name, val); + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + SetUniformInternal(it->second, name, val); } -void RendererVulkan::SetUniform(std::shared_ptr impl_data, +void RendererVulkan::SetUniform(uint64_t resource_id, const std::string& name, int val) { - auto shader = reinterpret_cast(impl_data.get()); - for (auto& sampler_name : shader->sampler_uniform_names) { + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + + for (auto& sampler_name : it->second.sampler_uniform_names) { if (name == sampler_name) return; } - SetUniformInternal(shader, name, val); + SetUniformInternal(it->second, name, val); } -void RendererVulkan::UploadUniforms(std::shared_ptr impl_data) { - auto shader = reinterpret_cast(impl_data.get()); +void RendererVulkan::UploadUniforms(uint64_t resource_id) { + auto it = shaders_.find(resource_id); + if (it == shaders_.end()) + return; + vkCmdPushConstants( - frames_[current_frame_].draw_command_buffer, shader->pipeline_layout, + frames_[current_frame_].draw_command_buffer, it->second.pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, - shader->push_constants_size, shader->push_constants.get()); + it->second.push_constants_size, it->second.push_constants.get()); } void RendererVulkan::PrepareForDrawing() { @@ -818,7 +869,7 @@ void RendererVulkan::Shutdown() { return; LOG << "Shutting down renderer."; - InvalidateAllResources(); + DestroyAllResources(); quit_.store(true, std::memory_order_relaxed); semaphore_.Release(); @@ -1520,7 +1571,7 @@ void RendererVulkan::ImageMemoryBarrier(VkImage image, } bool RendererVulkan::CreatePipelineLayout( - ShaderVulkan* shader, + ShaderVulkan& shader, const std::vector& spirv_vertex, const std::vector& spirv_fragment) { SpvReflectShaderModule module_vertex; @@ -1608,14 +1659,14 @@ bool RendererVulkan::CreatePipelineLayout( break; } - shader->sampler_uniform_names.push_back(binding.name); - shader->desc_set_count++; + shader.sampler_uniform_names.push_back(binding.name); + shader.desc_set_count++; } } - if (active_descriptor_sets_.size() < shader->desc_set_count) { - active_descriptor_sets_.resize(shader->desc_set_count); - penging_descriptor_sets_.resize(shader->desc_set_count); + if (active_descriptor_sets_.size() < shader.desc_set_count) { + active_descriptor_sets_.resize(shader.desc_set_count); + penging_descriptor_sets_.resize(shader.desc_set_count); } // Parse push constants. @@ -1679,10 +1730,10 @@ bool RendererVulkan::CreatePipelineLayout( break; } - shader->push_constants_size = pconstants_vertex[0]->size; - shader->push_constants = - std::make_unique(shader->push_constants_size); - memset(shader->push_constants.get(), 0, shader->push_constants_size); + shader.push_constants_size = pconstants_vertex[0]->size; + shader.push_constants = + std::make_unique(shader.push_constants_size); + memset(shader.push_constants.get(), 0, shader.push_constants_size); size_t offset = 0; for (uint32_t j = 0; j < pconstants_vertex[0]->member_count; j++) { @@ -1691,7 +1742,7 @@ bool RendererVulkan::CreatePipelineLayout( << " padded_size: " << pconstants_vertex[0]->members[j].padded_size; - shader->variables[pconstants_vertex[0]->members[j].name] = { + shader.variables[pconstants_vertex[0]->members[j].name] = { pconstants_vertex[0]->members[j].size, offset}; offset += pconstants_vertex[0]->members[j].padded_size; } @@ -1716,11 +1767,11 @@ bool RendererVulkan::CreatePipelineLayout( } VkPushConstantRange push_constant_range; - if (shader->push_constants_size) { + if (shader.push_constants_size) { push_constant_range.stageFlags = VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT; push_constant_range.offset = 0; - push_constant_range.size = shader->push_constants_size; + push_constant_range.size = shader.push_constants_size; pipeline_layout_create_info.pushConstantRangeCount = 1; pipeline_layout_create_info.pPushConstantRanges = &push_constant_range; @@ -1730,7 +1781,7 @@ bool RendererVulkan::CreatePipelineLayout( } if (vkCreatePipelineLayout(device_, &pipeline_layout_create_info, nullptr, - &shader->pipeline_layout) != VK_SUCCESS) { + &shader.pipeline_layout) != VK_SUCCESS) { DLOG << "Failed to create pipeline layout!"; break; } @@ -1855,11 +1906,11 @@ void RendererVulkan::SetupThreadMain(int preallocate) { } template -bool RendererVulkan::SetUniformInternal(ShaderVulkan* shader, +bool RendererVulkan::SetUniformInternal(ShaderVulkan& shader, const std::string& name, T val) { - auto it = shader->variables.find(name); - if (it == shader->variables.end()) { + auto it = shader.variables.find(name); + if (it == shader.variables.end()) { DLOG << "No variable found with name " << name; return false; } @@ -1868,8 +1919,7 @@ bool RendererVulkan::SetUniformInternal(ShaderVulkan* shader, return false; } - auto* dst = - reinterpret_cast(shader->push_constants.get() + it->second[1]); + auto* dst = reinterpret_cast(shader.push_constants.get() + it->second[1]); *dst = val; return true; } @@ -1881,39 +1931,32 @@ bool RendererVulkan::IsFormatSupported(VkFormat format) { return properties.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT; } -std::unique_ptr RendererVulkan::CreateResource( - RenderResourceFactoryBase& factory) { - static unsigned last_id = 0; - - std::shared_ptr impl_data; - if (factory.IsTypeOf()) - impl_data = std::make_shared(); - else if (factory.IsTypeOf()) - impl_data = std::make_shared(); - else if (factory.IsTypeOf()) - impl_data = std::make_shared(); - else - NOTREACHED << "- Unknown resource type."; - - unsigned resource_id = ++last_id; - auto resource = factory.Create(resource_id, impl_data, this); - resources_[resource_id] = resource.get(); - return resource; -} - -void RendererVulkan::ReleaseResource(unsigned resource_id) { - auto it = resources_.find(resource_id); - if (it != resources_.end()) - resources_.erase(it); -} - size_t RendererVulkan::GetAndResetFPS() { return context_.GetAndResetFPS(); } -void RendererVulkan::InvalidateAllResources() { - for (auto& r : resources_) - r.second->Destroy(); +void RendererVulkan::DestroyAllResources() { + std::vector resource_ids; + for (auto& r : geometries_) + resource_ids.push_back(r.first); + for (auto& r : resource_ids) + DestroyGeometry(r); + + resource_ids.clear(); + for (auto& r : shaders_) + resource_ids.push_back(r.first); + for (auto& r : resource_ids) + DestroyShader(r); + + resource_ids.clear(); + for (auto& r : textures_) + resource_ids.push_back(r.first); + for (auto& r : resource_ids) + DestroyTexture(r); + + DCHECK(geometries_.size() == 0); + DCHECK(shaders_.size() == 0); + DCHECK(textures_.size() == 0); } } // namespace eng diff --git a/src/engine/renderer/vulkan/renderer_vulkan.h b/src/engine/renderer/vulkan/renderer_vulkan.h index 91e46f2..0aff1df 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.h +++ b/src/engine/renderer/vulkan/renderer_vulkan.h @@ -13,7 +13,6 @@ #include "../../../base/semaphore.h" #include "../../../base/task_runner.h" #include "../../../third_party/vma/vk_mem_alloc.h" -#include "../render_resource.h" #include "../renderer.h" namespace eng { @@ -33,51 +32,46 @@ class RendererVulkan : public Renderer { void Shutdown() override; - void CreateGeometry(std::shared_ptr impl_data, - std::unique_ptr mesh) override; - void DestroyGeometry(std::shared_ptr impl_data) override; - void Draw(std::shared_ptr impl_data) override; + uint64_t CreateGeometry(std::unique_ptr mesh) override; + void DestroyGeometry(uint64_t resource_id) override; + void Draw(uint64_t resource_id) override; - void UpdateTexture(std::shared_ptr impl_data, + uint64_t CreateTexture() override; + void UpdateTexture(uint64_t resource_id, std::unique_ptr image) override; - void DestroyTexture(std::shared_ptr impl_data) override; - void ActivateTexture(std::shared_ptr impl_data) override; + void DestroyTexture(uint64_t resource_id) override; + void ActivateTexture(uint64_t resource_id) override; - void CreateShader(std::shared_ptr impl_data, - std::unique_ptr source, - const VertexDescripton& vertex_description, - Primitive primitive, - bool enable_depth_test) override; - void DestroyShader(std::shared_ptr impl_data) override; - void ActivateShader(std::shared_ptr impl_data) override; + uint64_t CreateShader(std::unique_ptr source, + const VertexDescripton& vertex_description, + Primitive primitive, + bool enable_depth_test) override; + void DestroyShader(uint64_t resource_id) override; + void ActivateShader(uint64_t resource_id) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector2f& val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector3f& val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, const base::Vector4f& val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, const base::Matrix4f& val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, float val) override; - void SetUniform(std::shared_ptr impl_data, + void SetUniform(uint64_t resource_id, const std::string& name, int val) override; - void UploadUniforms(std::shared_ptr impl_data) override; + void UploadUniforms(uint64_t resource_id) override; void PrepareForDrawing() override; void Present() override; - std::unique_ptr CreateResource( - RenderResourceFactoryBase& factory) override; - void ReleaseResource(unsigned resource_id) override; - size_t GetAndResetFPS() override; #if defined(__linux__) && !defined(__ANDROID__) @@ -155,6 +149,11 @@ class RendererVulkan : public Renderer { VmaAllocationInfo alloc_info; }; + std::unordered_map geometries_; + std::unordered_map shaders_; + std::unordered_map textures_; + uint64_t last_resource_id_ = 0; + VulkanContext context_; VmaAllocator allocator_ = nullptr; @@ -179,8 +178,6 @@ class RendererVulkan : public Renderer { VkSampler sampler_ = VK_NULL_HANDLE; - std::unordered_map resources_; - std::thread setup_thread_; base::TaskRunner task_runner_; base::Semaphore semaphore_; @@ -250,7 +247,7 @@ class RendererVulkan : public Renderer { VkImageLayout old_layout, VkImageLayout new_layout); - bool CreatePipelineLayout(ShaderVulkan* shader, + bool CreatePipelineLayout(ShaderVulkan& shader, const std::vector& spirv_vertex, const std::vector& spirv_fragment); @@ -262,11 +259,11 @@ class RendererVulkan : public Renderer { void SetupThreadMain(int preallocate); template - bool SetUniformInternal(ShaderVulkan* shader, const std::string& name, T val); + bool SetUniformInternal(ShaderVulkan& shader, const std::string& name, T val); bool IsFormatSupported(VkFormat format); - void InvalidateAllResources(); + void DestroyAllResources(); }; } // namespace eng