From 8144057bff2709385669ca20e55043ba6bf47ab4 Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Tue, 7 Nov 2023 12:18:07 +0100 Subject: [PATCH] std::shared_ptr resource --- src/engine/renderer/opengl/renderer_opengl.cc | 248 +++++++------- src/engine/renderer/opengl/renderer_opengl.h | 72 +++-- src/engine/renderer/renderer.h | 48 +-- src/engine/renderer/vulkan/renderer_vulkan.cc | 302 ++++++++---------- src/engine/renderer/vulkan/renderer_vulkan.h | 69 ++-- 5 files changed, 342 insertions(+), 397 deletions(-) diff --git a/src/engine/renderer/opengl/renderer_opengl.cc b/src/engine/renderer/opengl/renderer_opengl.cc index 0d0801e..a97bb4a 100644 --- a/src/engine/renderer/opengl/renderer_opengl.cc +++ b/src/engine/renderer/opengl/renderer_opengl.cc @@ -71,23 +71,25 @@ void RendererOpenGL::ResetScissor() { glDisable(GL_SCISSOR_TEST); } -uint64_t RendererOpenGL::CreateGeometry(std::unique_ptr mesh) { +std::shared_ptr RendererOpenGL::CreateGeometry( + std::unique_ptr mesh) { auto id = CreateGeometry(mesh->primitive(), mesh->vertex_description(), mesh->index_description()); - if (id != kInvalidId) + if (id) UpdateGeometry(id, mesh->num_vertices(), mesh->GetVertices(), mesh->num_indices(), mesh->GetIndices()); return id; } -uint64_t RendererOpenGL::CreateGeometry(Primitive primitive, - VertexDescription vertex_description, - DataType index_description) { +std::shared_ptr RendererOpenGL::CreateGeometry( + Primitive primitive, + VertexDescription vertex_description, + DataType index_description) { // Verify that we have a valid layout and get the total byte size per vertex. GLuint vertex_size = GetVertexSize(vertex_description); if (!vertex_size) { LOG(0) << "Invalid vertex layout"; - return kInvalidId; + return nullptr; } GLuint vertex_array_id = 0; @@ -107,7 +109,7 @@ uint64_t RendererOpenGL::CreateGeometry(Primitive primitive, if (!SetupVertexLayout(vertex_description, vertex_size, vertex_array_objects_, vertex_layout)) { LOG(0) << "Invalid vertex layout"; - return kInvalidId; + return nullptr; } // Create the index buffer. @@ -126,106 +128,102 @@ uint64_t RendererOpenGL::CreateGeometry(Primitive primitive, glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - uint64_t resource_id = ++last_resource_id_; - geometries_[resource_id] = {0, - 0, - kGlPrimitive[primitive], - kGlDataType[index_description], - vertex_layout, - vertex_size, - vertex_array_id, - vertex_buffer_id, - (GLuint)GetIndexSize(index_description), - index_buffer_id}; - return resource_id; + auto it = + geometries_.insert(geometries_.end(), std::make_shared()); + **it = {it, + 0, + 0, + kGlPrimitive[primitive], + kGlDataType[index_description], + vertex_layout, + vertex_size, + vertex_array_id, + vertex_buffer_id, + (GLuint)GetIndexSize(index_description), + index_buffer_id}; + return *it; } -void RendererOpenGL::UpdateGeometry(uint64_t resource_id, +void RendererOpenGL::UpdateGeometry(std::shared_ptr resource, size_t num_vertices, const void* vertices, size_t num_indices, const void* indices) { - auto it = geometries_.find(resource_id); - if (it == geometries_.end()) - return; + auto geometry = std::static_pointer_cast(resource); // Go with GL_STATIC_DRAW for the first update. - GLenum usage = it->second.num_vertices > 0 ? GL_STREAM_DRAW : GL_STATIC_DRAW; + GLenum usage = geometry->num_vertices > 0 ? GL_STREAM_DRAW : GL_STATIC_DRAW; // Upload the vertex data. - glBindBuffer(GL_ARRAY_BUFFER, it->second.vertex_buffer_id); - glBufferData(GL_ARRAY_BUFFER, num_vertices * it->second.vertex_size, vertices, + glBindBuffer(GL_ARRAY_BUFFER, geometry->vertex_buffer_id); + glBufferData(GL_ARRAY_BUFFER, num_vertices * geometry->vertex_size, vertices, usage); glBindBuffer(GL_ARRAY_BUFFER, 0); - it->second.num_vertices = (GLsizei)num_vertices; + geometry->num_vertices = (GLsizei)num_vertices; // Upload the index data. - if (it->second.index_buffer_id) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_indices * it->second.index_size, + if (geometry->index_buffer_id) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->index_buffer_id); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_indices * geometry->index_size, indices, usage); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - it->second.num_indices = (GLsizei)num_indices; + geometry->num_indices = (GLsizei)num_indices; } } -void RendererOpenGL::DestroyGeometry(uint64_t resource_id) { - auto it = geometries_.find(resource_id); - if (it == geometries_.end()) - return; +void RendererOpenGL::DestroyGeometry(std::shared_ptr resource) { + auto geometry = std::static_pointer_cast(resource); - 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)); + if (geometry->index_buffer_id) + glDeleteBuffers(1, &(geometry->index_buffer_id)); + if (geometry->vertex_buffer_id) + glDeleteBuffers(1, &(geometry->vertex_buffer_id)); + if (geometry->vertex_array_id) + glDeleteVertexArrays(1, &(geometry->vertex_array_id)); - geometries_.erase(it); + geometries_.erase(geometry->it); } -void RendererOpenGL::Draw(uint64_t resource_id, +void RendererOpenGL::Draw(std::shared_ptr resource, size_t num_indices, size_t start_offset) { - auto it = geometries_.find(resource_id); - if (it == geometries_.end()) - return; + auto geometry = std::static_pointer_cast(resource); if (num_indices == 0) - num_indices = it->second.num_indices; + num_indices = geometry->num_indices; // Set up the vertex data. - if (it->second.vertex_array_id) { - glBindVertexArray(it->second.vertex_array_id); + if (geometry->vertex_array_id) { + glBindVertexArray(geometry->vertex_array_id); } else { - glBindBuffer(GL_ARRAY_BUFFER, it->second.vertex_buffer_id); + glBindBuffer(GL_ARRAY_BUFFER, geometry->vertex_buffer_id); for (GLuint attribute_index = 0; - attribute_index < (GLuint)it->second.vertex_layout.size(); + attribute_index < (GLuint)geometry->vertex_layout.size(); ++attribute_index) { - GeometryOpenGL::Element& e = it->second.vertex_layout[attribute_index]; + GeometryOpenGL::Element& e = geometry->vertex_layout[attribute_index]; glEnableVertexAttribArray(attribute_index); glVertexAttribPointer(attribute_index, e.num_elements, e.type, GL_TRUE, - it->second.vertex_size, + geometry->vertex_size, (const GLvoid*)e.vertex_offset); } if (num_indices > 0) - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, it->second.index_buffer_id); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->index_buffer_id); } // Draw the primitive. if (num_indices > 0) - glDrawElements(it->second.primitive, num_indices, it->second.index_type, + glDrawElements(geometry->primitive, num_indices, geometry->index_type, (void*)(intptr_t)(start_offset * sizeof(unsigned short))); else - glDrawArrays(it->second.primitive, 0, it->second.num_vertices); + glDrawArrays(geometry->primitive, 0, geometry->num_vertices); // Clean up states. - if (it->second.vertex_array_id) + if (geometry->vertex_array_id) glBindVertexArray(0); else { for (GLuint attribute_index = 0; - attribute_index < (GLuint)it->second.vertex_layout.size(); + attribute_index < (GLuint)geometry->vertex_layout.size(); ++attribute_index) glDisableVertexAttribArray(attribute_index); @@ -234,7 +232,7 @@ void RendererOpenGL::Draw(uint64_t resource_id, } } -uint64_t RendererOpenGL::CreateTexture() { +std::shared_ptr RendererOpenGL::CreateTexture() { GLuint gl_id = 0; glGenTextures(1, &gl_id); glBindTexture(GL_TEXTURE_2D, gl_id); @@ -244,28 +242,27 @@ uint64_t RendererOpenGL::CreateTexture() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - uint64_t resource_id = ++last_resource_id_; - textures_[resource_id] = gl_id; - return resource_id; + auto it = + textures_.insert(textures_.end(), std::make_shared()); + **it = {it, gl_id}; + return *it; } -void RendererOpenGL::UpdateTexture(uint64_t resource_id, +void RendererOpenGL::UpdateTexture(std::shared_ptr resource, std::unique_ptr image) { - UpdateTexture(resource_id, image->GetWidth(), image->GetHeight(), + UpdateTexture(resource, image->GetWidth(), image->GetHeight(), image->GetFormat(), image->GetSize(), image->GetBuffer()); } -void RendererOpenGL::UpdateTexture(uint64_t resource_id, +void RendererOpenGL::UpdateTexture(std::shared_ptr resource, int width, int height, ImageFormat format, size_t data_size, uint8_t* image_data) { - auto it = textures_.find(resource_id); - if (it == textures_.end()) - return; + auto texture = std::static_pointer_cast(resource); - glBindTexture(GL_TEXTURE_2D, it->second); + glBindTexture(GL_TEXTURE_2D, texture->id); if (IsCompressedFormat(format)) { GLenum gl_format = 0; switch (format) { @@ -311,35 +308,28 @@ void RendererOpenGL::UpdateTexture(uint64_t resource_id, } } -void RendererOpenGL::DestroyTexture(uint64_t resource_id) { - auto it = textures_.find(resource_id); - if (it == textures_.end()) - return; - - glDeleteTextures(1, &(it->second)); - textures_.erase(it); +void RendererOpenGL::DestroyTexture(std::shared_ptr resource) { + auto texture = std::static_pointer_cast(resource); + glDeleteTextures(1, &(texture->id)); + textures_.erase(texture->it); } -void RendererOpenGL::ActivateTexture(uint64_t resource_id, +void RendererOpenGL::ActivateTexture(std::shared_ptr resource, size_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; - } - - if (it->second != active_texture_id_[texture_unit]) { + auto texture = std::static_pointer_cast(resource); + if (texture->id != active_texture_id_[texture_unit]) { glActiveTexture(GL_TEXTURE0 + texture_unit); - glBindTexture(GL_TEXTURE_2D, it->second); - active_texture_id_[texture_unit] = it->second; + glBindTexture(GL_TEXTURE_2D, texture->id); + active_texture_id_[texture_unit] = texture->id; } } -uint64_t RendererOpenGL::CreateShader( +std::shared_ptr RendererOpenGL::CreateShader( std::unique_ptr source, const VertexDescription& vertex_description, Primitive primitive, @@ -382,103 +372,79 @@ uint64_t RendererOpenGL::CreateShader( } } - uint64_t resource_id = ++last_resource_id_; - shaders_[resource_id] = {id, {}, enable_depth_test}; - return resource_id; + auto it = shaders_.insert(shaders_.end(), std::make_shared()); + **it = {it, id, {}, enable_depth_test}; + return *it; } -void RendererOpenGL::DestroyShader(uint64_t resource_id) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - glDeleteProgram(it->second.id); - shaders_.erase(it); +void RendererOpenGL::DestroyShader(std::shared_ptr resource) { + auto shader = std::static_pointer_cast(resource); + glDeleteProgram(shader->id); + shaders_.erase(shader->it); } -void RendererOpenGL::ActivateShader(uint64_t resource_id) { - auto it = shaders_.find(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) +void RendererOpenGL::ActivateShader(std::shared_ptr resource) { + auto shader = std::static_pointer_cast(resource); + if (shader->id != active_shader_id_) { + glUseProgram(shader->id); + active_shader_id_ = shader->id; + if (shader->enable_depth_test) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST); } } -void RendererOpenGL::SetUniform(uint64_t resource_id, +void RendererOpenGL::SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector2f& val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + auto shader = std::static_pointer_cast(resource); + GLint index = GetUniformLocation(shader->id, name, shader->uniforms); if (index >= 0) glUniform2fv(index, 1, val.GetData()); } -void RendererOpenGL::SetUniform(uint64_t resource_id, +void RendererOpenGL::SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector3f& val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + auto shader = std::static_pointer_cast(resource); + GLint index = GetUniformLocation(shader->id, name, shader->uniforms); if (index >= 0) glUniform3fv(index, 1, val.GetData()); } -void RendererOpenGL::SetUniform(uint64_t resource_id, +void RendererOpenGL::SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector4f& val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + auto shader = std::static_pointer_cast(resource); + GLint index = GetUniformLocation(shader->id, name, shader->uniforms); if (index >= 0) glUniform4fv(index, 1, val.GetData()); } -void RendererOpenGL::SetUniform(uint64_t resource_id, +void RendererOpenGL::SetUniform(std::shared_ptr resource, const std::string& name, const base::Matrix4f& val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + auto shader = std::static_pointer_cast(resource); + GLint index = GetUniformLocation(shader->id, name, shader->uniforms); if (index >= 0) glUniformMatrix4fv(index, 1, GL_FALSE, val.GetData()); } -void RendererOpenGL::SetUniform(uint64_t resource_id, +void RendererOpenGL::SetUniform(std::shared_ptr resource, const std::string& name, float val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + auto shader = std::static_pointer_cast(resource); + GLint index = GetUniformLocation(shader->id, name, shader->uniforms); if (index >= 0) glUniform1f(index, val); } -void RendererOpenGL::SetUniform(uint64_t resource_id, +void RendererOpenGL::SetUniform(std::shared_ptr resource, const std::string& name, int val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - GLint index = GetUniformLocation(it->second.id, name, it->second.uniforms); + auto shader = std::static_pointer_cast(resource); + GLint index = GetUniformLocation(shader->id, name, shader->uniforms); if (index >= 0) glUniform1i(index, val); } diff --git a/src/engine/renderer/opengl/renderer_opengl.h b/src/engine/renderer/opengl/renderer_opengl.h index e4658cb..51767dc 100644 --- a/src/engine/renderer/opengl/renderer_opengl.h +++ b/src/engine/renderer/opengl/renderer_opengl.h @@ -2,9 +2,9 @@ #define ENGINE_RENDERER_OPENGL_RENDERER_OPENGL_H #include +#include #include #include -#include #include #include @@ -38,56 +38,62 @@ class RendererOpenGL final : public Renderer { void SetScissor(int x, int y, int width, int height) final; void ResetScissor() final; - uint64_t CreateGeometry(std::unique_ptr mesh) final; - uint64_t CreateGeometry(Primitive primitive, - VertexDescription vertex_description, - DataType index_description = kDataType_Invalid) final; - void UpdateGeometry(uint64_t resource_id, + std::shared_ptr CreateGeometry(std::unique_ptr mesh) final; + std::shared_ptr CreateGeometry( + Primitive primitive, + VertexDescription vertex_description, + DataType index_description = kDataType_Invalid) final; + void UpdateGeometry(std::shared_ptr resource, size_t num_vertices, const void* vertices, size_t num_indices, const void* indices) final; - void DestroyGeometry(uint64_t resource_id) final; - void Draw(uint64_t resource_id, + void DestroyGeometry(std::shared_ptr resource) final; + void Draw(std::shared_ptr resource, size_t num_indices = 0, size_t start_offset = 0) final; - uint64_t CreateTexture() final; - void UpdateTexture(uint64_t resource_id, std::unique_ptr image) final; - void UpdateTexture(uint64_t resource_id, + std::shared_ptr CreateTexture() final; + void UpdateTexture(std::shared_ptr resource, + std::unique_ptr image) final; + void UpdateTexture(std::shared_ptr resource, int width, int height, ImageFormat format, size_t data_size, uint8_t* image_data) final; - void DestroyTexture(uint64_t resource_id) final; - void ActivateTexture(uint64_t resource_id, size_t texture_unit) final; + void DestroyTexture(std::shared_ptr resource) final; + void ActivateTexture(std::shared_ptr resource, + size_t texture_unit) final; - uint64_t CreateShader(std::unique_ptr source, - const VertexDescription& vertex_description, - Primitive primitive, - bool enable_depth_test) final; - void DestroyShader(uint64_t resource_id) final; - void ActivateShader(uint64_t resource_id) final; + std::shared_ptr CreateShader( + std::unique_ptr source, + const VertexDescription& vertex_description, + Primitive primitive, + bool enable_depth_test) final; + void DestroyShader(std::shared_ptr resource) final; + void ActivateShader(std::shared_ptr resource) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector2f& val) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector3f& val) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector4f& val) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, const base::Matrix4f& val) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, float val) final; - void SetUniform(uint64_t resource_id, const std::string& name, int val) final; - void UploadUniforms(uint64_t resource_id) final {} + void SetUniform(std::shared_ptr resource, + const std::string& name, + int val) final; + void UploadUniforms(std::shared_ptr resource) final {} void PrepareForDrawing() final; void Present() final; @@ -106,6 +112,7 @@ class RendererOpenGL final : public Renderer { size_t vertex_offset; }; + std::list>::iterator it; GLsizei num_vertices = 0; GLsizei num_indices = 0; GLenum primitive = 0; @@ -119,6 +126,7 @@ class RendererOpenGL final : public Renderer { }; struct ShaderOpenGL { + std::list>::iterator it; GLuint id = 0; std::vector geometries_; - std::unordered_map shaders_; - std::unordered_map textures_; - uint64_t last_resource_id_ = 0; + struct TextureOpenGL { + std::list>::iterator it; + GLuint id = 0; + }; + + std::list> geometries_; + std::list> shaders_; + std::list> textures_; GLuint active_shader_id_ = 0; std::array active_texture_id_ = {}; diff --git a/src/engine/renderer/renderer.h b/src/engine/renderer/renderer.h index 010c572..cadd443 100644 --- a/src/engine/renderer/renderer.h +++ b/src/engine/renderer/renderer.h @@ -45,59 +45,61 @@ class Renderer { virtual void SetScissor(int x, int y, int width, int height) = 0; virtual void ResetScissor() = 0; - virtual uint64_t CreateGeometry(std::unique_ptr mesh) = 0; - virtual uint64_t CreateGeometry( + virtual std::shared_ptr CreateGeometry(std::unique_ptr mesh) = 0; + virtual std::shared_ptr CreateGeometry( Primitive primitive, VertexDescription vertex_description, DataType index_description = kDataType_Invalid) = 0; - virtual void UpdateGeometry(uint64_t resource_id, + virtual void UpdateGeometry(std::shared_ptr resource, size_t num_vertices, const void* vertices, size_t num_indices, const void* indices) = 0; - virtual void DestroyGeometry(uint64_t resource_id) = 0; - virtual void Draw(uint64_t resource_id, + virtual void DestroyGeometry(std::shared_ptr resource) = 0; + virtual void Draw(std::shared_ptr resource, size_t num_indices = 0, size_t start_offset = 0) = 0; - virtual uint64_t CreateTexture() = 0; - virtual void UpdateTexture(uint64_t resource_id, + virtual std::shared_ptr CreateTexture() = 0; + virtual void UpdateTexture(std::shared_ptr resource, std::unique_ptr image) = 0; - virtual void UpdateTexture(uint64_t resource_id, + virtual void UpdateTexture(std::shared_ptr resource, int width, int height, ImageFormat format, size_t data_size, uint8_t* image_data) = 0; - virtual void DestroyTexture(uint64_t resource_id) = 0; - virtual void ActivateTexture(uint64_t resource_id, size_t texture_unit) = 0; + virtual void DestroyTexture(std::shared_ptr resource) = 0; + virtual void ActivateTexture(std::shared_ptr resource, + size_t texture_unit) = 0; - virtual uint64_t CreateShader(std::unique_ptr source, - const VertexDescription& 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 std::shared_ptr CreateShader( + std::unique_ptr source, + const VertexDescription& vertex_description, + Primitive primitive, + bool enable_depth_test) = 0; + virtual void DestroyShader(std::shared_ptr resource) = 0; + virtual void ActivateShader(std::shared_ptr resource) = 0; - virtual void SetUniform(uint64_t resource_id, + virtual void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector2f& val) = 0; - virtual void SetUniform(uint64_t resource_id, + virtual void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector3f& val) = 0; - virtual void SetUniform(uint64_t resource_id, + virtual void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector4f& val) = 0; - virtual void SetUniform(uint64_t resource_id, + virtual void SetUniform(std::shared_ptr resource, const std::string& name, const base::Matrix4f& val) = 0; - virtual void SetUniform(uint64_t resource_id, + virtual void SetUniform(std::shared_ptr resource, const std::string& name, float val) = 0; - virtual void SetUniform(uint64_t resource_id, + virtual void SetUniform(std::shared_ptr resource, const std::string& name, int val) = 0; - virtual void UploadUniforms(uint64_t resource_id) = 0; + virtual void UploadUniforms(std::shared_ptr resource) = 0; virtual void PrepareForDrawing() = 0; virtual void Present() = 0; diff --git a/src/engine/renderer/vulkan/renderer_vulkan.cc b/src/engine/renderer/vulkan/renderer_vulkan.cc index adda543..97a763b 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.cc +++ b/src/engine/renderer/vulkan/renderer_vulkan.cc @@ -442,10 +442,11 @@ void RendererVulkan::ResetScissor() { vkCmdSetScissor(frames_[current_frame_].draw_command_buffer, 0, 1, &scissor); } -uint64_t RendererVulkan::CreateGeometry(std::unique_ptr mesh) { +std::shared_ptr RendererVulkan::CreateGeometry( + std::unique_ptr mesh) { auto id = CreateGeometry(mesh->primitive(), mesh->vertex_description(), mesh->index_description()); - if (id != kInvalidId) + if (id) UpdateGeometry(id, mesh->num_vertices(), mesh->GetVertices(), mesh->num_indices(), mesh->GetIndices()); task_runner_.Delete(HERE, std::move(mesh)); @@ -453,61 +454,61 @@ uint64_t RendererVulkan::CreateGeometry(std::unique_ptr mesh) { return id; } -uint64_t RendererVulkan::CreateGeometry(Primitive primitive, - VertexDescription vertex_description, - DataType index_description) { - auto& geometry = geometries_[++last_resource_id_] = {}; - geometry.vertex_size = GetVertexSize(vertex_description); - geometry.index_type = GetIndexType(index_description); - geometry.index_type_size = GetIndexSize(index_description); - return last_resource_id_; +std::shared_ptr RendererVulkan::CreateGeometry( + Primitive primitive, + VertexDescription vertex_description, + DataType index_description) { + auto it = + geometries_.insert(geometries_.end(), std::make_shared()); + (*it)->vertex_size = GetVertexSize(vertex_description); + (*it)->index_type = GetIndexType(index_description); + (*it)->index_type_size = GetIndexSize(index_description); + return *it; } -void RendererVulkan::UpdateGeometry(uint64_t resource_id, +void RendererVulkan::UpdateGeometry(std::shared_ptr resource, size_t num_vertices, const void* vertices, size_t num_indices, const void* indices) { - auto it = geometries_.find(resource_id); - if (it == geometries_.end()) - return; + auto geometry = std::static_pointer_cast(resource); - it->second.num_vertices = num_vertices; - size_t vertex_data_size = it->second.vertex_size * it->second.num_vertices; + geometry->num_vertices = num_vertices; + size_t vertex_data_size = geometry->vertex_size * geometry->num_vertices; size_t index_data_size = 0; if (indices) { - DCHECK(it->second.index_type != VK_INDEX_TYPE_NONE_KHR); - it->second.num_indices = num_indices; - index_data_size = it->second.index_type_size * it->second.num_indices; + DCHECK(geometry->index_type != VK_INDEX_TYPE_NONE_KHR); + geometry->num_indices = num_indices; + index_data_size = geometry->index_type_size * geometry->num_indices; } size_t data_size = vertex_data_size + index_data_size; - if (it->second.buffer_size < data_size) { + if (geometry->buffer_size < data_size) { DLOG(1) << __func__ << "Reallocate buffer " << data_size; - if (it->second.buffer_size > 0) - FreeBuffer(std::move(it->second.buffer)); - AllocateBuffer(it->second.buffer, data_size, + if (geometry->buffer_size > 0) + FreeBuffer(std::move(geometry->buffer)); + 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); - it->second.buffer_size = data_size; + geometry->buffer_size = data_size; } task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this, - std::get<0>(it->second.buffer), 0, + std::get<0>(geometry->buffer), 0, vertices, vertex_data_size)); - if (it->second.num_indices > 0) { - it->second.index_data_offset = vertex_data_size; - task_runner_.PostTask(HERE, std::bind(&RendererVulkan::UpdateBuffer, this, - std::get<0>(it->second.buffer), - it->second.index_data_offset, indices, - index_data_size)); + if (geometry->num_indices > 0) { + geometry->index_data_offset = vertex_data_size; + task_runner_.PostTask( + HERE, std::bind(&RendererVulkan::UpdateBuffer, this, + std::get<0>(geometry->buffer), + geometry->index_data_offset, indices, index_data_size)); } task_runner_.PostTask(HERE, std::bind(&RendererVulkan::BufferMemoryBarrier, this, - std::get<0>(it->second.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, @@ -515,143 +516,125 @@ void RendererVulkan::UpdateGeometry(uint64_t resource_id, semaphore_.release(); } -void RendererVulkan::DestroyGeometry(uint64_t resource_id) { - auto it = geometries_.find(resource_id); - if (it == geometries_.end()) - return; - - FreeBuffer(std::move(it->second.buffer)); +void RendererVulkan::DestroyGeometry(std::shared_ptr resource) { + auto geometry = std::static_pointer_cast(resource); + FreeBuffer(std::move(geometry->buffer)); geometries_.erase(it); } -void RendererVulkan::Draw(uint64_t resource_id, +void RendererVulkan::Draw(std::shared_ptr resource, size_t num_indices, size_t start_offset) { - auto it = geometries_.find(resource_id); - if (it == geometries_.end()) - return; + auto geometry = std::static_pointer_cast(resource); - uint64_t data_offset = start_offset * it->second.index_type_size; + uint64_t data_offset = start_offset * geometry->index_type_size; if (num_indices == 0) - num_indices = it->second.num_indices; + num_indices = geometry->num_indices; VkDeviceSize offset = 0; vkCmdBindVertexBuffers(frames_[current_frame_].draw_command_buffer, 0, 1, - &std::get<0>(it->second.buffer), &offset); + &std::get<0>(geometry->buffer), &offset); if (num_indices > 0) { vkCmdBindIndexBuffer(frames_[current_frame_].draw_command_buffer, - std::get<0>(it->second.buffer), - it->second.index_data_offset + data_offset, - it->second.index_type); + std::get<0>(geometry->buffer), + geometry->index_data_offset + data_offset, + geometry->index_type); vkCmdDrawIndexed(frames_[current_frame_].draw_command_buffer, num_indices, 1, 0, 0, 0); } else { vkCmdDraw(frames_[current_frame_].draw_command_buffer, - it->second.num_vertices, 1, 0, 0); + geometry->num_vertices, 1, 0, 0); } } -uint64_t RendererVulkan::CreateTexture() { - textures_.insert({++last_resource_id_, {}}); - return last_resource_id_; +std::shared_ptr RendererVulkan::CreateTexture() { + auto it = + textures_.insert(textures_.end(), std::make_shared()); + (*it)->it = it; + return *it; } -void RendererVulkan::UpdateTexture(uint64_t resource_id, +void RendererVulkan::UpdateTexture(std::shared_ptr resource, std::unique_ptr image) { - UpdateTexture(resource_id, image->GetWidth(), image->GetHeight(), + UpdateTexture(resource, image->GetWidth(), image->GetHeight(), image->GetFormat(), image->GetSize(), image->GetBuffer()); task_runner_.Delete(HERE, std::move(image)); semaphore_.release(); } -void RendererVulkan::UpdateTexture(uint64_t resource_id, +void RendererVulkan::UpdateTexture(std::shared_ptr resource, int width, int height, ImageFormat format, size_t data_size, uint8_t* image_data) { - auto it = textures_.find(resource_id); - if (it == textures_.end()) - return; + auto texture = std::static_pointer_cast(resource); VkImageLayout old_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; VkFormat vk_format = GetImageFormat(format); - if (it->second.view != VK_NULL_HANDLE && - (it->second.width != width || it->second.height != height)) { + if (texture->view != VK_NULL_HANDLE && + (texture->width != width || texture->height != height)) { // Size mismatch. Recreate the texture. - FreeImage(std::move(it->second.image), it->second.view, - std::move(it->second.desc_set)); + FreeImage(std::move(texture->image), texture->view, + std::move(texture->desc_set)); it->second = {}; } - if (it->second.view == VK_NULL_HANDLE) { - AllocateImage(it->second.image, it->second.view, it->second.desc_set, - vk_format, width, height, + if (texture->view == VK_NULL_HANDLE) { + AllocateImage(texture->image, texture->view, texture->desc_set, vk_format, + width, height, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VMA_MEMORY_USAGE_GPU_ONLY); old_layout = VK_IMAGE_LAYOUT_UNDEFINED; - it->second.width = width; - it->second.height = height; + texture->width = width; + texture->height = height; } task_runner_.PostTask( HERE, std::bind(&RendererVulkan::ImageMemoryBarrier, this, - std::get<0>(it->second.image), + std::get<0>(texture->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>(it->second.image), - vk_format, image_data, width, height)); + std::get<0>(texture->image), vk_format, + image_data, width, height)); task_runner_.PostTask( - 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)); + 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)); semaphore_.release(); } -void RendererVulkan::DestroyTexture(uint64_t resource_id) { - auto it = textures_.find(resource_id); - if (it == textures_.end()) - return; - - FreeImage(std::move(it->second.image), it->second.view, - std::move(it->second.desc_set)); - textures_.erase(it); +void RendererVulkan::DestroyTexture(std::shared_ptr resource) { + auto texture = std::static_pointer_cast(resource); + FreeImage(std::move(texture->image), texture->view, + std::move(texture->desc_set)); + textures_.erase(texture->it); } -void RendererVulkan::ActivateTexture(uint64_t resource_id, +void RendererVulkan::ActivateTexture(std::shared_ptr resource, size_t texture_unit) { - auto it = textures_.find(resource_id); - if (it == textures_.end()) - return; - - 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 > 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); - } + auto texture = std::static_pointer_cast(resource); + if (active_descriptor_sets_[texture_unit] != std::get<0>(texture->desc_set)) { + active_descriptor_sets_[texture_unit] = std::get<0>(texture->desc_set); + if (active_shader_ && active_shader_->desc_set_count > texture_unit) { + vkCmdBindDescriptorSets( + frames_[current_frame_].draw_command_buffer, + VK_PIPELINE_BIND_POINT_GRAPHICS, active_shader_->pipeline_layout, + texture_unit, 1, &active_descriptor_sets_[texture_unit], 0, nullptr); } } } -uint64_t RendererVulkan::CreateShader( +std::shared_ptr RendererVulkan::CreateShader( std::unique_ptr source, const VertexDescription& vertex_description, Primitive primitive, @@ -703,9 +686,9 @@ uint64_t RendererVulkan::CreateShader( } } - auto& shader = shaders_[++last_resource_id_] = {}; + auto it = shaders_.insert(shaders_.end(), std::make_shared()); - if (!CreatePipelineLayout(shader, spirv_vertex, spirv_fragment)) + if (!CreatePipelineLayout(**it, spirv_vertex, spirv_fragment)) DLOG(0) << "Failed to create pipeline layout!"; VkPipelineShaderStageCreateInfo vert_shader_stage_info{}; @@ -827,124 +810,97 @@ uint64_t RendererVulkan::CreateShader( 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 = (*it)->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, &(*it)->pipeline) != VK_SUCCESS) DLOG(0) << "failed to create graphics pipeline."; vkDestroyShaderModule(device_, frag_shader_module, nullptr); vkDestroyShaderModule(device_, vert_shader_module, nullptr); - return last_resource_id_; + return *it; } -void RendererVulkan::DestroyShader(uint64_t resource_id) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - +void RendererVulkan::DestroyShader(std::shared_ptr resource) { + auto shader = std::static_pointer_cast(resource); frames_[current_frame_].pipelines_to_destroy.push_back( - std::make_tuple(it->second.pipeline, it->second.pipeline_layout)); - shaders_.erase(it); + std::make_tuple(shader->pipeline, shader->pipeline_layout)); + shaders_.erase(shader->it); } -void RendererVulkan::ActivateShader(uint64_t resource_id) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - if (active_shader_id_ != resource_id) { - active_shader_id_ = resource_id; +void RendererVulkan::ActivateShader(std::shared_ptr resource) { + auto shader = std::static_pointer_cast(resource); + if (active_shader_ != resource) { + active_shader_ = std::static_pointer_cast(resource); vkCmdBindPipeline(frames_[current_frame_].draw_command_buffer, - VK_PIPELINE_BIND_POINT_GRAPHICS, it->second.pipeline); + VK_PIPELINE_BIND_POINT_GRAPHICS, shader->pipeline); - for (size_t i = 0; i < it->second.desc_set_count; ++i) { + for (size_t i = 0; i < shader->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, + shader->pipeline_layout, i, 1, &active_descriptor_sets_[i], 0, nullptr); } } } } -void RendererVulkan::SetUniform(uint64_t resource_id, +void RendererVulkan::SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector2f& val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - SetUniformInternal(it->second, name, val); + auto shader = std::static_pointer_cast(resource); + SetUniformInternal(*shader, name, val); } -void RendererVulkan::SetUniform(uint64_t resource_id, +void RendererVulkan::SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector3f& val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - SetUniformInternal(it->second, name, val); + auto shader = std::static_pointer_cast(resource); + SetUniformInternal(*shader, name, val); } -void RendererVulkan::SetUniform(uint64_t resource_id, +void RendererVulkan::SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector4f& val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - SetUniformInternal(it->second, name, val); + auto shader = std::static_pointer_cast(resource); + SetUniformInternal(*shader, name, val); } -void RendererVulkan::SetUniform(uint64_t resource_id, +void RendererVulkan::SetUniform(std::shared_ptr resource, const std::string& name, const base::Matrix4f& val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - SetUniformInternal(it->second, name, val); + auto shader = std::static_pointer_cast(resource); + SetUniformInternal(*shader, name, val); } -void RendererVulkan::SetUniform(uint64_t resource_id, +void RendererVulkan::SetUniform(std::shared_ptr resource, const std::string& name, float val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - SetUniformInternal(it->second, name, val); + auto shader = std::static_pointer_cast(resource); + SetUniformInternal(*shader, name, val); } -void RendererVulkan::SetUniform(uint64_t resource_id, +void RendererVulkan::SetUniform(std::shared_ptr resource, const std::string& name, int val) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - - for (auto& sampler_name : it->second.sampler_uniform_names) { + auto shader = std::static_pointer_cast(resource); + for (auto& sampler_name : shader->sampler_uniform_names) { if (name == sampler_name) return; } - SetUniformInternal(it->second, name, val); + SetUniformInternal(*shader, name, val); } -void RendererVulkan::UploadUniforms(uint64_t resource_id) { - auto it = shaders_.find(resource_id); - if (it == shaders_.end()) - return; - +void RendererVulkan::UploadUniforms(std::shared_ptr resource) { + auto shader = std::static_pointer_cast(resource); vkCmdPushConstants( - frames_[current_frame_].draw_command_buffer, it->second.pipeline_layout, + frames_[current_frame_].draw_command_buffer, shader->pipeline_layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, - it->second.push_constants_size, it->second.push_constants.get()); + shader->push_constants_size, shader->push_constants.get()); } void RendererVulkan::PrepareForDrawing() { @@ -2112,7 +2068,7 @@ void RendererVulkan::SwapBuffers() { context_.SwapBuffers(); current_frame_ = (current_frame_ + 1) % frames_.size(); - active_shader_id_ = kInvalidId; + active_shader_ = nullptr; 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 1eb7475..6323dac 100644 --- a/src/engine/renderer/vulkan/renderer_vulkan.h +++ b/src/engine/renderer/vulkan/renderer_vulkan.h @@ -2,6 +2,7 @@ #define ENGINE_RENDERER_VULKAN_RENDERER_VULKAN_H #include +#include #include #include #include @@ -39,55 +40,61 @@ class RendererVulkan final : public Renderer { void SetScissor(int x, int y, int width, int height) final; void ResetScissor() final; - uint64_t CreateGeometry(std::unique_ptr mesh) final; - uint64_t CreateGeometry(Primitive primitive, - VertexDescription vertex_description, - DataType index_description = kDataType_Invalid) final; - void UpdateGeometry(uint64_t resource_id, + std::shared_ptr CreateGeometry(std::unique_ptr mesh) final; + std::shared_ptr CreateGeometry( + Primitive primitive, + VertexDescription vertex_description, + DataType index_description = kDataType_Invalid) final; + void UpdateGeometry(std::shared_ptr resource, size_t num_vertices, const void* vertices, size_t num_indices, const void* indices) final; - void DestroyGeometry(uint64_t resource_id) final; - void Draw(uint64_t resource_id, + void DestroyGeometry(std::shared_ptr resource) final; + void Draw(std::shared_ptr resource, size_t num_indices = 0, size_t start_offset = 0) final; - uint64_t CreateTexture() final; - void UpdateTexture(uint64_t resource_id, std::unique_ptr image) final; - void UpdateTexture(uint64_t resource_id, + std::shared_ptr CreateTexture() final; + void UpdateTexture(std::shared_ptr resource, + std::unique_ptr image) final; + void UpdateTexture(std::shared_ptr resource, int width, int height, ImageFormat format, size_t data_size, uint8_t* image_data) final; - void DestroyTexture(uint64_t resource_id) final; - void ActivateTexture(uint64_t resource_id, size_t texture_unit) final; + void DestroyTexture(std::shared_ptr resource) final; + void ActivateTexture(std::shared_ptr resource, + size_t texture_unit) final; - uint64_t CreateShader(std::unique_ptr source, - const VertexDescription& vertex_description, - Primitive primitive, - bool enable_depth_test) final; - void DestroyShader(uint64_t resource_id) final; - void ActivateShader(uint64_t resource_id) final; + std::shared_ptr CreateShader( + std::unique_ptr source, + const VertexDescription& vertex_description, + Primitive primitive, + bool enable_depth_test) final; + void DestroyShader(std::shared_ptr resource) final; + void ActivateShader(std::shared_ptr resource) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector2f& val) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector3f& val) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, const base::Vector4f& val) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, const base::Matrix4f& val) final; - void SetUniform(uint64_t resource_id, + void SetUniform(std::shared_ptr resource, const std::string& name, float val) final; - void SetUniform(uint64_t resource_id, const std::string& name, int val) final; - void UploadUniforms(uint64_t resource_id) final; + void SetUniform(std::shared_ptr resource, + const std::string& name, + int val) final; + void UploadUniforms(std::shared_ptr resource) final; void PrepareForDrawing() final; void Present() final; @@ -120,6 +127,7 @@ class RendererVulkan final : public Renderer { spirv_cache_; struct GeometryVulkan { + std::list>::iterator it; Buffer buffer; size_t buffer_size = 0; uint32_t num_vertices = 0; @@ -131,6 +139,7 @@ class RendererVulkan final : public Renderer { }; struct ShaderVulkan { + std::list>::iterator it; std::vector>::iterator it; Buffer image; VkImageView view = VK_NULL_HANDLE; DescSet desc_set = {}; @@ -176,10 +186,9 @@ class RendererVulkan final : public Renderer { VmaAllocationInfo alloc_info; }; - std::unordered_map geometries_; - std::unordered_map shaders_; - std::unordered_map textures_; - uint64_t last_resource_id_ = 0; + std::list> geometries_; + std::list> shaders_; + std::list> textures_; bool context_lost_ = false; @@ -198,7 +207,7 @@ class RendererVulkan final : public Renderer { uint64_t max_staging_buffer_size_ = 16 * 1024 * 1024; bool staging_buffer_used_ = false; - uint64_t active_shader_id_ = 0; + std::shared_ptr active_shader_ = 0; std::vector> desc_pools_; VkDescriptorSetLayout descriptor_set_layout_ = VK_NULL_HANDLE;