From 99c6b7501afa7a712fdd61c8f1f1ecd6937a9783 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 9 Apr 2022 09:33:21 +0300 Subject: [PATCH] Refactor Renderer's texture management to make it more extensible The same code can now be used for other kinds of resources as well. --- source/render/renderer.cpp | 55 ++++++++++++++++++++------------------ source/render/renderer.h | 26 ++++++++++++++---- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/source/render/renderer.cpp b/source/render/renderer.cpp index 98246da7..f2fb002e 100644 --- a/source/render/renderer.cpp +++ b/source/render/renderer.cpp @@ -178,32 +178,36 @@ void Renderer::set_texture(Tag tag, const Texture *tex, int level, const Sampler else samp = 0; - if(texture_stack.size()>state.texture_count) + set_resource(texture_stack, state.texture_count, tag, { tex, samp, level }); +} + +template +void Renderer::set_resource(vector> &stack, unsigned &count, Tag tag, const T &res) +{ + if(stack.size()>count) { - BoundTexture &bt = texture_stack[state.texture_count]; - if(bt.tag==tag && bt.texture==tex && bt.sampler==samp) + BoundResource &top = stack[count]; + if(top.tag==tag && top.resource==res) { - ++state.texture_count; + ++count; return; } else - flush_textures(); + flush_resources(stack, count); } - for(auto i=texture_stack.end(); i!=texture_stack.begin(); ) + for(auto i=stack.end(); i!=stack.begin(); ) if((--i)->tag==tag) { - i->replaced = texture_stack.size(); + i->replaced = stack.size(); break; } - texture_stack.emplace_back(); - BoundTexture &bound_tex = texture_stack.back(); - bound_tex.tag = tag; - bound_tex.texture = tex; - bound_tex.sampler = samp; - bound_tex.level = level; - state.texture_count = texture_stack.size(); + stack.emplace_back(); + BoundResource &bound_res = stack.back(); + bound_res.tag = tag; + bound_res.resource = res; + count = stack.size(); } void Renderer::flush_shader_data() @@ -214,15 +218,14 @@ void Renderer::flush_shader_data() shdata_stack.erase(shdata_stack.begin()+state.shdata_count, shdata_stack.end()); } -void Renderer::flush_textures() +template +void Renderer::flush_resources(vector> &stack, unsigned &count) { - const State &state = get_state(); + for(unsigned i=0; i=static_cast(count)) + stack[i].replaced = -1; - for(unsigned i=0; i=static_cast(state.texture_count)) - texture_stack[i].replaced = -1; - - texture_stack.erase(texture_stack.begin()+state.texture_count, texture_stack.end()); + stack.erase(stack.begin()+count, stack.end()); } void Renderer::set_vertex_setup(const VertexSetup *vs) @@ -339,7 +342,7 @@ void Renderer::apply_framebuffer() void Renderer::apply_state() { - const State &state = get_state(); + State &state = get_state(); if(!state.shprog) throw invalid_operation("Renderer::apply_state"); @@ -402,15 +405,15 @@ void Renderer::apply_state() ps.set_face_cull(state.face_cull); if(state.texture_count &t: texture_stack) + if(t.resource.texture && t.replaced<0) { if(t.binding<0 || shprog_changed) t.binding = state.shprog->get_uniform_binding(t.tag); if(t.binding>=0) - ps.set_texture(t.binding, t.texture, t.level, t.sampler); + ps.set_texture(t.binding, t.resource.texture, t.resource.level, t.resource.sampler); } static const DepthTest default_depth_test; diff --git a/source/render/renderer.h b/source/render/renderer.h index 4e702042..9335164b 100644 --- a/source/render/renderer.h +++ b/source/render/renderer.h @@ -63,14 +63,25 @@ public: }; private: - struct BoundTexture + struct SampledTexture { - Tag tag; - mutable int binding = -1; const Texture *texture = 0; const Sampler *sampler = 0; int level = -1; + + SampledTexture() = default; + SampledTexture(const Texture *t, const Sampler *s, int l): texture(t), sampler(s), level(l) { } + + bool operator==(const SampledTexture &o) const { return texture==o.texture && sampler==o.sampler && level==o.level; } + }; + + template + struct BoundResource + { + Tag tag; + mutable int binding = -1; int replaced = -1; + T resource; }; struct BoundProgramData @@ -115,7 +126,7 @@ private: State *current_state = 0; ProgramData standard_shdata; std::vector shdata_stack; - std::vector texture_stack; + std::vector> texture_stack; const Texture &placeholder_texture; const Sampler &default_sampler; PipelineState *last_pipeline = 0; @@ -188,8 +199,13 @@ public: void set_texture(Tag, const Texture *, int, const Sampler * = 0); private: + template + static void set_resource(std::vector> &, unsigned &, Tag, const T &); + void flush_shader_data(); - void flush_textures(); + + template + static void flush_resources(std::vector> &, unsigned &); public: void set_vertex_setup(const VertexSetup *); -- 2.43.0