]> git.tdb.fi Git - libs/gl.git/commitdiff
Reorder members of Renderer and PipelineState
authorMikko Rasa <tdb@tdb.fi>
Fri, 12 Nov 2021 16:55:36 +0000 (18:55 +0200)
committerMikko Rasa <tdb@tdb.fi>
Fri, 12 Nov 2021 18:58:50 +0000 (20:58 +0200)
source/backends/opengl/pipelinestate_backend.cpp
source/core/pipelinestate.cpp
source/core/pipelinestate.h
source/render/renderer.cpp
source/render/renderer.h

index 58e12e7ff2126040eed1b2d62580b8c0bf68cbc4..91789701705d31441a55864f80a4e337d84cfdae 100644 (file)
@@ -106,37 +106,28 @@ void OpenGLPipelineState::apply(unsigned mask) const
                }
        }
 
-       if(mask&PipelineState::VERTEX_SETUP)
+       if(mask&PipelineState::UNIFORMS)
        {
-               const VertexSetup *vertex_setup = self->vertex_setup;
-               glBindVertexArray(vertex_setup ? vertex_setup->id : 0);
-               if(vertex_setup)
-               {
-                       static Require _req(MSP_primitive_restart);
-
-                       vertex_setup->refresh();
-                       unsigned ri = (vertex_setup->get_index_type()==UNSIGNED_INT ? 0xFFFFFFFF : 0xFFFF);
-                       if(ri!=restart_index)
+               for(const PipelineState::BoundUniformBlock &u: self->uniform_blocks)
+                       if(u.changed || mask==~0U)
                        {
-                               if(!restart_index)
-                                       glEnable(GL_PRIMITIVE_RESTART);
-                               glPrimitiveRestartIndex(ri);
-                               restart_index = ri;
-                       }
-               }
-       }
-
-       if(mask&PipelineState::FACE_CULL)
-       {
-               glFrontFace(self->front_face==CLOCKWISE ? GL_CW : GL_CCW);
+                               if(u.block)
+                               {
+                                       if(u.binding>=0)
+                                       {
+                                               glBindBufferRange(GL_UNIFORM_BUFFER, u.binding, u.block->get_buffer()->id, u.block->get_offset(), u.block->get_data_size());
+                                               bound_uniform_blocks[u.binding] = 1;
+                                       }
+                                       else if(self->shprog)
+                                       {
+                                               const char *data = static_cast<const char *>(u.block->get_data_pointer());
+                                               for(const Program::UniformCall &call: self->shprog->uniform_calls)
+                                                       call.func(call.location, call.size, data+call.location*16);
+                                       }
+                               }
 
-               if(self->face_cull!=NO_CULL && self->front_face!=NON_MANIFOLD)
-               {
-                       glEnable(GL_CULL_FACE);
-                       glCullFace(self->face_cull==CULL_FRONT ? GL_FRONT : GL_BACK);
-               }
-               else
-                       glDisable(GL_CULL_FACE);
+                               u.changed = false;
+                       }
        }
 
        if(mask&PipelineState::TEXTURES)
@@ -166,28 +157,37 @@ void OpenGLPipelineState::apply(unsigned mask) const
                        }
        }
 
-       if(mask&PipelineState::UNIFORMS)
+       if(mask&PipelineState::VERTEX_SETUP)
        {
-               for(const PipelineState::BoundUniformBlock &u: self->uniform_blocks)
-                       if(u.changed || mask==~0U)
-                       {
-                               if(u.block)
-                               {
-                                       if(u.binding>=0)
-                                       {
-                                               glBindBufferRange(GL_UNIFORM_BUFFER, u.binding, u.block->get_buffer()->id, u.block->get_offset(), u.block->get_data_size());
-                                               bound_uniform_blocks[u.binding] = 1;
-                                       }
-                                       else if(self->shprog)
-                                       {
-                                               const char *data = static_cast<const char *>(u.block->get_data_pointer());
-                                               for(const Program::UniformCall &call: self->shprog->uniform_calls)
-                                                       call.func(call.location, call.size, data+call.location*16);
-                                       }
-                               }
+               const VertexSetup *vertex_setup = self->vertex_setup;
+               glBindVertexArray(vertex_setup ? vertex_setup->id : 0);
+               if(vertex_setup)
+               {
+                       static Require _req(MSP_primitive_restart);
 
-                               u.changed = false;
+                       vertex_setup->refresh();
+                       unsigned ri = (vertex_setup->get_index_type()==UNSIGNED_INT ? 0xFFFFFFFF : 0xFFFF);
+                       if(ri!=restart_index)
+                       {
+                               if(!restart_index)
+                                       glEnable(GL_PRIMITIVE_RESTART);
+                               glPrimitiveRestartIndex(ri);
+                               restart_index = ri;
                        }
+               }
+       }
+
+       if(mask&PipelineState::FACE_CULL)
+       {
+               glFrontFace(self->front_face==CLOCKWISE ? GL_CW : GL_CCW);
+
+               if(self->face_cull!=NO_CULL && self->front_face!=NON_MANIFOLD)
+               {
+                       glEnable(GL_CULL_FACE);
+                       glCullFace(self->face_cull==CULL_FRONT ? GL_FRONT : GL_BACK);
+               }
+               else
+                       glDisable(GL_CULL_FACE);
        }
 
        if(mask&PipelineState::DEPTH_TEST)
index 933109e6e09e492ae65b38f3780e395db01063d6..0306a2626c9c4cbde629e6fc236fb2648431ebc5 100644 (file)
@@ -37,19 +37,17 @@ void PipelineState::set_shader_program(const Program *p)
        set(shprog, p, SHPROG);
 }
 
-void PipelineState::set_vertex_setup(const VertexSetup *s)
-{
-       set(vertex_setup, s, VERTEX_SETUP);
-}
-
-void PipelineState::set_front_face(FaceWinding w)
-{
-       set(front_face, w, FACE_CULL);
-}
-
-void PipelineState::set_face_cull(CullMode c)
+void PipelineState::set_uniform_block(int binding, const UniformBlock *block)
 {
-       set(face_cull, c, FACE_CULL);
+       auto i = lower_bound_member(uniform_blocks, binding, &BoundUniformBlock::binding);
+       if(i==uniform_blocks.end() || i->binding!=binding)
+               i = uniform_blocks.insert(i, BoundUniformBlock(binding));
+       if(block!=i->block || binding<0)
+       {
+               i->block = block;
+               i->changed = true;
+               changes |= UNIFORMS;
+       }
 }
 
 void PipelineState::set_texture(unsigned binding, const Texture *tex, const Sampler *samp)
@@ -69,17 +67,19 @@ void PipelineState::set_texture(unsigned binding, const Texture *tex, const Samp
        }
 }
 
-void PipelineState::set_uniform_block(int binding, const UniformBlock *block)
+void PipelineState::set_vertex_setup(const VertexSetup *s)
 {
-       auto i = lower_bound_member(uniform_blocks, binding, &BoundUniformBlock::binding);
-       if(i==uniform_blocks.end() || i->binding!=binding)
-               i = uniform_blocks.insert(i, BoundUniformBlock(binding));
-       if(block!=i->block || binding<0)
-       {
-               i->block = block;
-               i->changed = true;
-               changes |= UNIFORMS;
-       }
+       set(vertex_setup, s, VERTEX_SETUP);
+}
+
+void PipelineState::set_front_face(FaceWinding w)
+{
+       set(front_face, w, FACE_CULL);
+}
+
+void PipelineState::set_face_cull(CullMode c)
+{
+       set(face_cull, c, FACE_CULL);
 }
 
 void PipelineState::set_depth_test(const DepthTest *dt)
index 478705367a1b67a67b125f85f752a8f46d6014ee..31938829ec61186e0cc6863fe7870640e898ebf1 100644 (file)
@@ -51,28 +51,28 @@ private:
 
        enum ChangeMask
        {
-               SHPROG = 1,
-               VERTEX_SETUP = 2,
-               FACE_CULL = 4,
-               TEXTURES = 16,
-               UNIFORMS = 32,
-               DEPTH_TEST = 64,
-               STENCIL_TEST = 128,
-               BLEND = 256,
-               FRAMEBUFFER = 512,
-               VIEWPORT = 1024,
-               SCISSOR = 2048
+               FRAMEBUFFER = 1,
+               VIEWPORT = 2,
+               SCISSOR = 4,
+               SHPROG = 8,
+               UNIFORMS = 16,
+               TEXTURES = 32,
+               VERTEX_SETUP = 64,
+               FACE_CULL = 128,
+               DEPTH_TEST = 256,
+               STENCIL_TEST = 512,
+               BLEND = 1024
        };
 
        const Framebuffer *framebuffer = 0;
        const Rect *viewport = 0;
        const Rect *scissor = 0;
        const Program *shprog = 0;
+       std::vector<BoundUniformBlock> uniform_blocks;
+       std::vector<BoundTexture> textures;
        const VertexSetup *vertex_setup = 0;
        FaceWinding front_face = COUNTERCLOCKWISE;
        CullMode face_cull = NO_CULL;
-       std::vector<BoundTexture> textures;
-       std::vector<BoundUniformBlock> uniform_blocks;
        const DepthTest *depth_test = 0;
        const StencilTest *stencil_test = 0;
        const Blend *blend = 0;
@@ -85,11 +85,11 @@ public:
        void set_viewport(const Rect *);
        void set_scissor(const Rect *);
        void set_shader_program(const Program *);
+       void set_uniform_block(int, const UniformBlock *);
+       void set_texture(unsigned, const Texture *, const Sampler *);
        void set_vertex_setup(const VertexSetup *);
        void set_front_face(FaceWinding);
        void set_face_cull(CullMode);
-       void set_texture(unsigned, const Texture *, const Sampler *);
-       void set_uniform_block(int, const UniformBlock *);
        void set_depth_test(const DepthTest *);
        void set_stencil_test(const StencilTest *);
        void set_blend(const Blend *);
index 044ab55db7d3404d0f7ac9db3181d1e3eb3e5281..3b28d8545b668b75fe2b0d580232dfe96a22e06b 100644 (file)
@@ -34,6 +34,34 @@ Renderer::~Renderer()
        end();
 }
 
+void Renderer::end()
+{
+       if(state_stack.size()>1)
+               throw invalid_operation("Renderer::end");
+
+       *state = State();
+       shdata_stack.clear();
+       add_shader_data(standard_shdata);
+
+       commands.use_pipeline(0);
+}
+
+void Renderer::push_state()
+{
+       state_stack.push_back(state_stack.back());
+       state = &state_stack.back();
+}
+
+void Renderer::pop_state()
+{
+       if(state_stack.size()==1)
+               throw stack_underflow("Renderer::pop_state");
+
+       state_stack.pop_back();
+       state = &state_stack.back();
+       changed |= MATRIX;
+}
+
 void Renderer::set_camera(const Camera &c)
 {
        state->camera = &c;
@@ -68,6 +96,31 @@ void Renderer::set_scissor(const Rect *s)
        state->scissor = s;
 }
 
+void Renderer::set_shader_program(const Program *p, const ProgramData *d)
+{
+       state->shprog = p;
+       if(p && d)
+               add_shader_data(*d);
+}
+
+void Renderer::add_shader_data(const ProgramData &d)
+{
+       if(state->shdata_count<shdata_stack.size())
+       {
+               const BoundProgramData &top = shdata_stack.back();
+               if(top.shdata==&d && top.generation==d.get_generation())
+               {
+                       ++state->shdata_count;
+                       return;
+               }
+       }
+
+       flush_shader_data();
+       shdata_stack.push_back(&d);
+       state->shdata_count = shdata_stack.size();
+       changed |= SHADER_DATA;
+}
+
 void Renderer::set_texture(Tag tag, const Texture *tex, const Sampler *samp)
 {
        if(tex)
@@ -101,6 +154,12 @@ void Renderer::set_texture(Tag tag, const Texture *tex, const Sampler *samp)
        state->texture_count = texture_stack.size();
 }
 
+void Renderer::flush_shader_data()
+{
+       if(shdata_stack.size()>state->shdata_count)
+               shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
+}
+
 void Renderer::flush_textures()
 {
        for(unsigned i=0; i<state->texture_count; ++i)
@@ -110,37 +169,6 @@ void Renderer::flush_textures()
        texture_stack.erase(texture_stack.begin()+state->texture_count, texture_stack.end());
 }
 
-void Renderer::set_shader_program(const Program *p, const ProgramData *d)
-{
-       state->shprog = p;
-       if(p && d)
-               add_shader_data(*d);
-}
-
-void Renderer::add_shader_data(const ProgramData &d)
-{
-       if(state->shdata_count<shdata_stack.size())
-       {
-               const BoundProgramData &top = shdata_stack.back();
-               if(top.shdata==&d && top.generation==d.get_generation())
-               {
-                       ++state->shdata_count;
-                       return;
-               }
-       }
-
-       flush_shader_data();
-       shdata_stack.push_back(&d);
-       state->shdata_count = shdata_stack.size();
-       changed |= SHADER_DATA;
-}
-
-void Renderer::flush_shader_data()
-{
-       if(shdata_stack.size()>state->shdata_count)
-               shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
-}
-
 void Renderer::set_vertex_setup(const VertexSetup *vs)
 {
        state->vertex_setup = vs;
@@ -176,34 +204,6 @@ void Renderer::set_object_lod_bias(unsigned b)
        state->object_lod_bias = b;
 }
 
-void Renderer::push_state()
-{
-       state_stack.push_back(state_stack.back());
-       state = &state_stack.back();
-}
-
-void Renderer::pop_state()
-{
-       if(state_stack.size()==1)
-               throw stack_underflow("Renderer::pop_state");
-
-       state_stack.pop_back();
-       state = &state_stack.back();
-       changed |= MATRIX;
-}
-
-void Renderer::end()
-{
-       if(state_stack.size()>1)
-               throw invalid_operation("Renderer::end");
-
-       *state = State();
-       shdata_stack.clear();
-       add_shader_data(standard_shdata);
-
-       commands.use_pipeline(0);
-}
-
 void Renderer::clear(const ClearValue *values)
 {
        pipeline_state.set_framebuffer(state->framebuffer);
@@ -259,6 +259,13 @@ void Renderer::apply_state()
        if(!state->shprog)
                throw invalid_operation("Renderer::apply_state");
 
+       pipeline_state.set_framebuffer(state->framebuffer);
+       pipeline_state.set_viewport(state->viewport);
+       pipeline_state.set_scissor(state->scissor);
+
+       bool shprog_changed = (state->shprog!=pipeline_state.get_shader_program());
+       pipeline_state.set_shader_program(state->shprog);
+
        if(changed&MATRIX)
        {
                standard_shdata.uniform("world_obj_matrix", state->model_matrix);
@@ -268,12 +275,22 @@ void Renderer::apply_state()
                changed &= ~MATRIX;
        }
 
-       pipeline_state.set_framebuffer(state->framebuffer);
-       pipeline_state.set_viewport(state->viewport);
-       pipeline_state.set_scissor(state->scissor);
+       bool shdata_changed = changed&SHADER_DATA;
+       for(auto i=shdata_stack.begin(); (!shdata_changed && i!=shdata_stack.end()); ++i)
+               shdata_changed = (i->shdata->get_generation()!=i->generation);
+       bool extra_shdata = (shdata_stack.size()>state->shdata_count);
 
-       bool shprog_changed = (state->shprog!=pipeline_state.get_shader_program());
-       pipeline_state.set_shader_program(state->shprog);
+       if(shdata_changed || shprog_changed || extra_shdata)
+       {
+               if(extra_shdata)
+                       shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
+               for(const BoundProgramData &d: shdata_stack)
+               {
+                       d.shdata->apply(*state->shprog, pipeline_state);
+                       d.generation = d.shdata->get_generation();
+               }
+               changed &= ~SHADER_DATA;
+       }
 
        if(state->vertex_setup)
        {
@@ -299,23 +316,6 @@ void Renderer::apply_state()
                                pipeline_state.set_texture(t.binding, t.texture, t.sampler);
                }
 
-       bool shdata_changed = changed&SHADER_DATA;
-       for(auto i=shdata_stack.begin(); (!shdata_changed && i!=shdata_stack.end()); ++i)
-               shdata_changed = (i->shdata->get_generation()!=i->generation);
-       bool extra_shdata = (shdata_stack.size()>state->shdata_count);
-
-       if(shdata_changed || shprog_changed || extra_shdata)
-       {
-               if(extra_shdata)
-                       shdata_stack.erase(shdata_stack.begin()+state->shdata_count, shdata_stack.end());
-               for(const BoundProgramData &d: shdata_stack)
-               {
-                       d.shdata->apply(*state->shprog, pipeline_state);
-                       d.generation = d.shdata->get_generation();
-               }
-               changed &= ~SHADER_DATA;
-       }
-
        pipeline_state.set_depth_test(state->depth_test);
        pipeline_state.set_stencil_test(state->stencil_test);
        pipeline_state.set_blend(state->blend);
index 36fe6c919a5e063de7b5fa0e74353fe0643b700d..0371e8374a6a9207faf913f13c16f653cf75fac1 100644 (file)
@@ -101,9 +101,9 @@ private:
        unsigned char changed = 0;
        std::vector<State> state_stack;
        State *state;
-       std::vector<BoundTexture> texture_stack;
        ProgramData standard_shdata;
        std::vector<BoundProgramData> shdata_stack;
+       std::vector<BoundTexture> texture_stack;
        PipelineState pipeline_state;
        Commands commands;
 
@@ -111,6 +111,19 @@ public:
        Renderer();
        ~Renderer();
 
+
+       /** Unbinds all objects and resets related state.  There must be no unpopped
+       state in the stack.  The Renderer remains valid and may be reused for
+       further rendering. */
+       void end();
+
+       /** Saves the current state so it can be restored later. */
+       void push_state();
+
+       /** Restores a previously saved state.  Must be matched with an earlier
+       push_state call. */
+       void pop_state();
+
        /** Sets the camera to render from.  The model matrix is reset to identity. */
        void set_camera(const Camera &);
 
@@ -131,11 +144,6 @@ public:
 
        const Framebuffer *get_framebuffer() const { return state->framebuffer; }
 
-       void set_texture(Tag, const Texture *, const Sampler * = 0);
-private:
-       void flush_textures();
-
-public:
        /** Sets the shader program to use.  As a convenience, uniform values may be
        specified at the same time. */
        void set_shader_program(const Program *prog, const ProgramData *data = 0);
@@ -145,8 +153,11 @@ public:
        last will be used. */
        void add_shader_data(const ProgramData &data);
 
+       void set_texture(Tag, const Texture *, const Sampler * = 0);
+
 private:
        void flush_shader_data();
+       void flush_textures();
 
 public:
        void set_vertex_setup(const VertexSetup *);
@@ -160,18 +171,6 @@ public:
        void set_object_lod_bias(unsigned);
        unsigned get_object_lod_bias() const { return state->object_lod_bias; }
 
-       /** Saves the current state so it can be restored later. */
-       void push_state();
-
-       /** Restores a previously saved state.  Must be matched with an earlier
-       push_state call. */
-       void pop_state();
-
-       /** Unbinds all objects and resets related state.  There must be no unpopped
-       state in the stack.  The Renderer remains valid and may be reused for
-       further rendering. */
-       void end();
-
        void clear(const ClearValue *);
 
        /** Draws a batch of primitives.  A shader must be active. */