]> git.tdb.fi Git - libs/gl.git/commitdiff
Remove generic clipping state
authorMikko Rasa <tdb@tdb.fi>
Sun, 10 Oct 2021 14:08:42 +0000 (17:08 +0300)
committerMikko Rasa <tdb@tdb.fi>
Sun, 10 Oct 2021 15:35:28 +0000 (18:35 +0300)
Instead do things the Vulkan way and set the enabled clip planes based on
the declared size of the gl_ClipDistance array in the shader.

22 files changed:
shaderlib/common.glsl
shaderlib/msp_interface.glsl
source/backends/opengl/pipelinestate_backend.cpp
source/backends/opengl/pipelinestate_backend.h
source/backends/opengl/program_backend.cpp
source/core/clipping.cpp [deleted file]
source/core/clipping.h [deleted file]
source/core/clipplane.cpp [deleted file]
source/core/clipplane.h [deleted file]
source/core/pipelinestate.cpp
source/core/pipelinestate.h
source/core/program.cpp
source/core/program.h
source/core/reflectdata.h
source/glsl/compiler.cpp
source/glsl/compiler.h
source/glsl/finalize.cpp
source/glsl/syntax.h
source/render/renderer.cpp
source/render/renderer.h
source/render/sequence.cpp
source/render/sequence.h

index 03cfd5af7c62a610a815a031c64abf5f7a4f6772..b83ff3804200fef4acfa270d378cc681c64d280d 100644 (file)
@@ -51,12 +51,6 @@ void standard_transform()
        out vec3 world_look_dir = normalize(world_vertex.xyz-eye_pos);
 
        out float fog_coord = eye_vertex.z;
-
-       if(use_clipping)
-       {
-               for(int i=0; i<max_clip_planes; ++i)
-                       gl_ClipDistance[i] = dot(world_vertex, clip_planes[i].equation);
-       }
 }
 
 virtual void custom_transform()
index 3fdd606b1b51f70585fc9fd619133b13e63a46b3..13cd9ccf9665a92d6603164639e1edc6099e6847 100644 (file)
@@ -6,11 +6,6 @@ struct LightSourceParameters
        vec3 attenuation;
 };
 
-struct ClipPlane
-{
-       vec4 equation;
-};
-
 uniform mat4 world_obj_matrix;
 uniform mat3 world_obj_normal_matrix;
 uniform CameraTransform
@@ -30,13 +25,6 @@ uniform Lighting
        float fog_density;
 };
 
-layout(constant_id=auto) const bool use_clipping = false;
-layout(constant_id=auto) const int max_clip_planes = 8;
-uniform Clipping
-{
-       ClipPlane clip_planes[max_clip_planes];
-};
-
 #pragma MSP stage(vertex)
 layout(location=0) in vec4 vertex;
 layout(location=1) in vec4 color;
index 738de3ac5fea34250f29659a09752e2208d497e7..cda3439cbb6750b0a66ba8eaa0374371c019f859 100644 (file)
@@ -30,6 +30,7 @@ const OpenGLPipelineState *OpenGLPipelineState::last_applied = 0;
 vector<int> OpenGLPipelineState::bound_tex_targets;
 vector<char> OpenGLPipelineState::bound_uniform_blocks;
 unsigned OpenGLPipelineState::restart_index = 0;
+unsigned OpenGLPipelineState::n_clip_distances = 0;
 
 OpenGLPipelineState::OpenGLPipelineState()
 {
@@ -88,8 +89,23 @@ void OpenGLPipelineState::apply(unsigned mask) const
        }
 
        if(mask&PipelineState::SHPROG)
+       {
                glUseProgram(self->shprog ? self->shprog->id : 0);
 
+               unsigned ncd = (self->shprog ? self->shprog->get_n_clip_distances() : 0);
+               if(ncd!=n_clip_distances)
+               {
+                       for(unsigned i=0; (i<ncd || i<n_clip_distances); ++i)
+                       {
+                               if(i<ncd)
+                                       glEnable(GL_CLIP_PLANE0+i);
+                               else
+                                       glDisable(GL_CLIP_PLANE0+i);
+                       }
+                       n_clip_distances = ncd;
+               }
+       }
+
        if(mask&PipelineState::VERTEX_SETUP)
        {
                const VertexSetup *vertex_setup = self->vertex_setup;
@@ -123,18 +139,6 @@ void OpenGLPipelineState::apply(unsigned mask) const
                        glDisable(GL_CULL_FACE);
        }
 
-       if(mask&PipelineState::CLIP_PLANES)
-       {
-               unsigned max_clip_planes = DeviceInfo::get_global().limits.max_clip_planes;
-               for(unsigned i=0; i<max_clip_planes; ++i)
-               {
-                       if((self->enabled_clip_planes>>i)&1)
-                               glEnable(GL_CLIP_PLANE0+i);
-                       else
-                               glDisable(GL_CLIP_PLANE0+i);
-               }
-       }
-
        if(mask&PipelineState::TEXTURES)
        {
                for(const PipelineState::BoundTexture &t: self->textures)
@@ -243,11 +247,9 @@ void OpenGLPipelineState::clear()
                glUseProgram(0);
                glBindVertexArray(0);
 
-               unsigned max_clip_planes = DeviceInfo::get_global().limits.max_clip_planes;
-               unsigned enabled_clip_planes = static_cast<const PipelineState *>(last_applied)->enabled_clip_planes;
-               for(unsigned i=0; i<max_clip_planes; ++i)
-                       if((enabled_clip_planes>>i)&1)
-                               glDisable(GL_CLIP_PLANE0+i);
+               for(unsigned i=0; i<n_clip_distances; ++i)
+                       glDisable(GL_CLIP_PLANE0+i);
+               n_clip_distances = 0;
 
                for(unsigned i=0; i<bound_tex_targets.size(); ++i)
                        if(bound_tex_targets[i])
index 24ef6989fb6de1a2968a27660315f0221fad53ab..0b1c4a877d056d16cfde9946de07dc9fdc0fde1b 100644 (file)
@@ -16,6 +16,7 @@ protected:
        static std::vector<int> bound_tex_targets;
        static std::vector<char> bound_uniform_blocks;
        static unsigned restart_index;
+       static unsigned n_clip_distances;
 
        OpenGLPipelineState();
        ~OpenGLPipelineState();
index 86235ebe45c6d769b4367c0328f56dd26b43a418..b902db5f6a99043df53af71632230ff9eed263e1 100644 (file)
@@ -136,6 +136,9 @@ void OpenGLProgram::add_glsl_stages(const GlslModule &mod, const map<string, int
 
        transient.textures = compiler.get_texture_bindings();
        transient.blocks = compiler.get_uniform_block_bindings();
+
+       ReflectData &rd = static_cast<Program *>(this)->reflect_data;
+       rd.n_clip_distances = compiler.get_n_clip_distances();
 }
 
 void OpenGLProgram::compile_glsl_stage(const GlslModule &mod, unsigned stage_id)
diff --git a/source/core/clipping.cpp b/source/core/clipping.cpp
deleted file mode 100644 (file)
index 30d1f7c..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-#include <msp/core/algorithm.h>
-#include "clipping.h"
-#include "clipplane.h"
-#include "deviceinfo.h"
-#include "error.h"
-
-using namespace std;
-
-namespace Msp {
-namespace GL {
-
-void Clipping::attach(const ClipPlane &p)
-{
-       if(find_member(planes, &p, &AttachedPlane::plane)!=planes.end())
-               return;
-       if(planes.size()>=DeviceInfo::get_global().limits.max_clip_planes)
-               throw invalid_operation("Clipping::attach");
-
-       planes.push_back(&p);
-}
-
-void Clipping::detach(const ClipPlane &p)
-{
-       auto i = find_member(planes, &p, &AttachedPlane::plane);
-       if(i!=planes.end())
-               planes.erase(i);
-}
-
-const ProgramData &Clipping::get_shader_data() const
-{
-       for(unsigned i=0; i<planes.size(); ++i)
-               if(planes[i].plane->get_generation()!=planes[i].generation)
-               {
-                       planes[i].plane->update_shader_data(shdata, i);
-                       planes[i].generation = planes[i].plane->get_generation();
-               }
-
-       return shdata;
-}
-
-} // namespace GL
-} // namespace Msp
diff --git a/source/core/clipping.h b/source/core/clipping.h
deleted file mode 100644 (file)
index f682dc6..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-#ifndef MSP_GL_CLIPPING_H_
-#define MSP_GL_CLIPPING_H_
-
-#include <vector>
-#include "programdata.h"
-
-namespace Msp {
-namespace GL {
-
-class ClipPlane;
-
-class Clipping
-{
-private:
-       struct AttachedPlane
-       {
-               const ClipPlane *plane;
-               mutable unsigned generation;
-
-               AttachedPlane(const ClipPlane *p): plane(p), generation(0) { }
-       };
-
-       std::vector<AttachedPlane> planes;
-       mutable ProgramData shdata;
-
-public:
-       void attach(const ClipPlane &);
-       void detach(const ClipPlane &);
-
-       unsigned get_n_planes() const { return planes.size(); }
-
-       const ProgramData &get_shader_data() const;
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
diff --git a/source/core/clipplane.cpp b/source/core/clipplane.cpp
deleted file mode 100644 (file)
index 256f2be..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <msp/strings/format.h>
-#include "clipplane.h"
-#include "programdata.h"
-
-namespace Msp {
-namespace GL {
-
-ClipPlane::ClipPlane(const Vector4 &e):
-       eq(e)
-{ }
-
-ClipPlane::ClipPlane(const Vector3 &p, const Vector3 &d):
-       eq(compose(d, -dot(p, d)))
-{ }
-
-void ClipPlane::set_equation(const Vector4 &e)
-{
-       eq = e;
-       ++generation;
-}
-
-void ClipPlane::set_plane(const Vector3 &p, const Vector3 &d)
-{
-       Vector3 nd = normalize(d);
-       set_equation(compose(nd, -dot(p, nd)));
-}
-
-void ClipPlane::update_shader_data(ProgramData &shdata, unsigned i) const
-{
-       shdata.uniform(format("clip_planes[%d].equation", i), eq);
-}
-
-} // namespace GL
-} // namespace Msp
diff --git a/source/core/clipplane.h b/source/core/clipplane.h
deleted file mode 100644 (file)
index a2b5625..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#ifndef MSP_GL_CLIPPLANE_H_
-#define MSP_GL_CLIPPLANE_H_
-
-#include "vector.h"
-
-namespace Msp {
-namespace GL {
-
-class ProgramData;
-
-class ClipPlane
-{
-private:
-       Vector4 eq = { 0.0f, 0.0f, 0.0f, 1.0f };
-       unsigned generation = 0;
-
-public:
-       ClipPlane() = default;
-       ClipPlane(const Vector4 &);
-       ClipPlane(const Vector3 &, const Vector3 &);
-
-       void set_equation(const Vector4 &);
-       void set_plane(const Vector3 &, const Vector3 &);
-       void update_shader_data(ProgramData &, unsigned) const;
-
-       unsigned get_generation() const { return generation; }
-};
-
-} // namespace GL
-} // namespace Msp
-
-#endif
index 23a2ed6a96b9b61dfcabe7e044324da797773572..933109e6e09e492ae65b38f3780e395db01063d6 100644 (file)
@@ -52,11 +52,6 @@ void PipelineState::set_face_cull(CullMode c)
        set(face_cull, c, FACE_CULL);
 }
 
-void PipelineState::set_enabled_clip_planes(unsigned p)
-{
-       set(enabled_clip_planes, p, CLIP_PLANES);
-}
-
 void PipelineState::set_texture(unsigned binding, const Texture *tex, const Sampler *samp)
 {
        if((tex!=0)!=(samp!=0))
index 0d0520a0262565a1c56a9b78ab9bece536677e95..6d4d2f6441099a2565fc2d245e57f475bacd49f6 100644 (file)
@@ -49,7 +49,6 @@ private:
                SHPROG = 1,
                VERTEX_SETUP = 2,
                FACE_CULL = 4,
-               CLIP_PLANES = 8,
                TEXTURES = 16,
                UNIFORMS = 32,
                DEPTH_TEST = 64,
@@ -67,7 +66,6 @@ private:
        const VertexSetup *vertex_setup = 0;
        FaceWinding front_face = COUNTERCLOCKWISE;
        CullMode face_cull = NO_CULL;
-       unsigned enabled_clip_planes = 0;
        std::vector<BoundTexture> textures;
        std::vector<BoundUniformBlock> uniform_blocks;
        const DepthTest *depth_test = 0;
@@ -85,7 +83,6 @@ public:
        void set_vertex_setup(const VertexSetup *);
        void set_front_face(FaceWinding);
        void set_face_cull(CullMode);
-       void set_enabled_clip_planes(unsigned);
        void set_texture(unsigned, const Texture *, const Sampler *);
        void set_uniform_block(int, const UniformBlock *);
        void set_depth_test(const DepthTest *);
index 5c8257b2fc60de50bf0e767beb90a5f8da5784e2..4707f4c0416e2be185441efebe847e65ed49fd7a 100644 (file)
@@ -173,6 +173,20 @@ void Program::collect_attributes(const SpirVModule &mod)
                }
 }
 
+void Program::collect_builtins(const SpirVModule &mod)
+{
+       for(const SpirVModule::Variable &v: mod.get_variables())
+               if(v.storage==SpirVModule::OUTPUT && v.struct_type)
+                       collect_builtins(*v.struct_type);
+}
+
+void Program::collect_builtins(const SpirVModule::Structure &strct)
+{
+       for(const SpirVModule::StructMember &m: strct.members)
+               if(m.builtin==SpirVModule::CLIP_DISTANCE)
+                       reflect_data.n_clip_distances = m.array_size;
+}
+
 const ReflectData::UniformBlockInfo &Program::get_uniform_block_info(const string &name) const
 {
        auto i = find_member(reflect_data.uniform_blocks, name, &ReflectData::UniformBlockInfo::name);
index fd1c1ae09d10e12943ca13140339b96d59cd5ecf..770c6badc1cbe31a69945a805e1dd1346d8b91ff 100644 (file)
@@ -62,6 +62,8 @@ private:
        void collect_uniforms(const SpirVModule &, const std::map<unsigned, int> &);
        void collect_block_uniforms(const SpirVModule::Structure &, const std::string &, unsigned, const std::map<unsigned, int> &, std::vector<std::string> &);
        void collect_attributes(const SpirVModule &);
+       void collect_builtins(const SpirVModule &);
+       void collect_builtins(const SpirVModule::Structure &);
 
 public:
        ReflectData::LayoutHash get_uniform_layout_hash() const { return reflect_data.layout_hash; }
@@ -76,6 +78,7 @@ public:
        const std::vector<ReflectData::AttributeInfo> &get_attributes() const { return reflect_data.attributes; }
        const ReflectData::AttributeInfo &get_attribute_info(const std::string &) const;
        int get_attribute_location(const std::string &) const;
+       unsigned get_n_clip_distances() const { return reflect_data.n_clip_distances; }
 
        using ProgramBackend::set_debug_name;
 };
index fff190a52dcbde157e98f042e7ead8534d42713b..5041b5796284e2c419f143678f372ac725ac4981 100644 (file)
@@ -58,6 +58,7 @@ struct ReflectData
        std::vector<UniformInfo> uniforms;
        LayoutHash layout_hash;
        std::vector<AttributeInfo> attributes;
+       unsigned n_clip_distances = 0;
 
        void update_layout_hash();
 };
index 4b1d4edf11d0e6e29c8410ab123521b440826128..e658a79ea98c2adc7c469b092f43ca84da9db161 100644 (file)
@@ -195,6 +195,14 @@ const map<string, unsigned> &Compiler::get_uniform_block_bindings() const
        return module->shared.uniform_block_bindings;
 }
 
+unsigned Compiler::get_n_clip_distances() const
+{
+       if(!compiled)
+               throw invalid_operation("Compiler::get_n_clip_distances");
+       auto i = find_member(module->stages, Stage::VERTEX, &Stage::type);
+       return (i!=module->stages.end() ? i->n_clip_distances : 0);
+}
+
 const SourceMap &Compiler::get_source_map() const
 {
        return module->source_map;
index 1c07f3250d9bc4d964168a7fd868a16346e5cd06..9d839745aa752e365b81057a3f46b917c52c9401 100644 (file)
@@ -112,6 +112,8 @@ public:
        source). */
        const std::map<std::string, unsigned> &get_uniform_block_bindings() const;
 
+       unsigned get_n_clip_distances() const;
+
        /** Returns the mapping of source indices to filenames.  Can be used to
        translate error messages. */
        const SourceMap &get_source_map() const;
index 4068037e919e81b5cc514d12584bec7df8088360..27c352098e0c0b0206616336f431e2c84de1942d 100644 (file)
@@ -574,6 +574,10 @@ void LegacyConverter::visit(VariableDeclaration &var)
                }
        }
 
+       if(var.name=="gl_ClipDistance")
+               if(const Literal *literal_size = dynamic_cast<const Literal *>(var.array_size.get()))
+                       stage->n_clip_distances = literal_size->value.value<int>();
+
        TraversingVisitor::visit(var);
 }
 
index a3b217d40895f2d6e4ae790abec56082094b6e95..d3797ac415ecb73c222220c1596a82c7fb2b9fed 100644 (file)
@@ -533,6 +533,7 @@ struct Stage
        std::map<std::string, unsigned> locations;
        std::map<std::string, unsigned> texture_bindings;
        std::map<std::string, unsigned> uniform_block_bindings;
+       unsigned n_clip_distances = 0;
        Features required_features;
        std::vector<Diagnostic> diagnostics;
 
index ad5f87d5a4fd6fd8add9613b7562cb4415de0156..5e155f2e970ac75f4ba85b59d857e66aa3c30f0b 100644 (file)
@@ -1,7 +1,6 @@
 #include "batch.h"
 #include "buffer.h"
 #include "camera.h"
-#include "clipping.h"
 #include "error.h"
 #include "framebuffer.h"
 #include "lighting.h"
@@ -124,13 +123,6 @@ void Renderer::set_lighting(const Lighting *l)
                add_shader_data(l->get_shader_data());
 }
 
-void Renderer::set_clipping(const Clipping *c)
-{
-       state->clipping = c;
-       if(c)
-               add_shader_data(c->get_shader_data());
-}
-
 void Renderer::set_shader_program(const Program *p, const ProgramData *d)
 {
        state->shprog = p;
@@ -324,7 +316,6 @@ void Renderer::apply_state()
 
        pipeline_state.set_front_face(state->front_face);
        pipeline_state.set_face_cull(state->face_cull);
-       pipeline_state.set_enabled_clip_planes(state->clipping ? (1<<state->clipping->get_n_planes())-1 : 0);
 
        if(state->texture_count<texture_stack.size())
                flush_textures();
index fa7de736d1ff868b0be1874acb04c997b48254da..42515e822993b622a163d5eb454359bf0a86f145 100644 (file)
@@ -16,7 +16,6 @@ class Batch;
 class Buffer;
 class Camera;
 union ClearValue;
-class Clipping;
 class Material;
 class Mesh;
 class Lighting;
@@ -91,7 +90,6 @@ private:
                const Rect *viewport = 0;
                const Rect *scissor = 0;
                unsigned texture_count = 0;
-               const Clipping *clipping = 0;
                const Program *shprog = 0;
                unsigned shdata_count = 0;
                const VertexSetup *vertex_setup = 0;
@@ -150,7 +148,6 @@ public:
        DEPRECATED void set_material(const Material *);
 
        DEPRECATED void set_lighting(const Lighting *);
-       void set_clipping(const Clipping *);
 
        /** Sets the shader program to use.  An initial set of data can be set as
        well, with the same semantics as add_shader_data. */
index f2a88a51f760ab6ccc6fc9e5c17062ab460824ae..e0fb408fad95aa274d63171c5b8f5b012c56d50a 100644 (file)
@@ -150,7 +150,6 @@ void Sequence::render(Renderer &renderer, Tag tag) const
 
                if (const Lighting *lighting = s.get_lighting())
                        renderer.add_shader_data(lighting->get_shader_data());
-               renderer.set_clipping(s.get_clipping());
 
                if(const Renderable *renderable = s.get_renderable())
                        renderer.render(*renderable, s.get_tag());
@@ -193,7 +192,6 @@ void Sequence::set_debug_name(const string &name)
 Sequence::Step::Step(Tag t, Renderable *r):
        tag(t),
        lighting(0),
-       clipping(0),
        renderable(r)
 { }
 
@@ -217,10 +215,5 @@ void Sequence::Step::set_blend(const Blend &b)
        blend = b;
 }
 
-void Sequence::Step::set_clipping(const Clipping *c)
-{
-       clipping = c;
-}
-
 } // namespace GL
 } // namespace Msp
index cc4b6963b017ce98b2250597d2f02c8c55f67988..9a3d0207191bb79e5ca9f6e9614440aeee75d4c9 100644 (file)
@@ -11,7 +11,6 @@
 namespace Msp {
 namespace GL {
 
-class Clipping;
 class Lighting;
 class PostProcessor;
 class RenderTarget;
@@ -21,9 +20,9 @@ Top-level content class.  Typically a Sequence is used as the content
 Renderable for a View or effects such as ShadowMap or EnvironmentMap.
 
 A Sequence consists of a number of steps.  Each step is defined with a
-Renderable and a tag to render it with and may also have Lighting, Clipping,
-DepthTest and Blend states.  Scenes can be used to further organize Renderables
-within a step.
+Renderable and a tag to render it with and may also have Lighting, DepthTest
+and Blend states.  Scenes can be used to further organize Renderables within a
+step.
 
 PostProcessors can be applied after all of the steps in the Sequence have been
 processed.  Framebuffer objects are automatically used to pass render results
@@ -41,7 +40,6 @@ public:
                DepthTest depth_test;
                StencilTest stencil_test;
                Blend blend;
-               const Clipping *clipping;
                Renderable *renderable;
 
        public:
@@ -53,12 +51,10 @@ public:
                void set_depth_test(const DepthTest &);
                void set_stencil_test(const StencilTest &);
                void set_blend(const Blend &);
-               void set_clipping(const Clipping *);
                const Lighting *get_lighting() const { return lighting; }
                const DepthTest &get_depth_test() const { return depth_test; }
                const StencilTest &get_stencil_test() const { return stencil_test; }
                const Blend &get_blend() const { return blend; }
-               const Clipping *get_clipping() const { return clipping; }
                Renderable *get_renderable() const { return renderable; }
        };