From 4bf4154cad127560ffe831e7b2cd1a0b960d0f03 Mon Sep 17 00:00:00 2001 From: ShadowNinja Date: Tue, 22 Nov 2016 09:05:39 -0500 Subject: Fix superflous shader setting updates (#4800) This improves rendering performance by ~40% --- src/shader.h | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 54 insertions(+), 9 deletions(-) (limited to 'src/shader.h') diff --git a/src/shader.h b/src/shader.h index b8aa88bce..766871f02 100644 --- a/src/shader.h +++ b/src/shader.h @@ -21,6 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #ifndef SHADER_HEADER #define SHADER_HEADER +#include #include "irrlichttypes_extrabloated.h" #include "threads.h" #include @@ -43,8 +44,7 @@ class IGameDef; std::string getShaderPath(const std::string &name_of_shader, const std::string &filename); -struct ShaderInfo -{ +struct ShaderInfo { std::string name; video::E_MATERIAL_TYPE base_material; video::E_MATERIAL_TYPE material; @@ -66,20 +66,66 @@ namespace irr { namespace video { class IMaterialRendererServices; } } -class IShaderConstantSetter -{ + +class IShaderConstantSetter { public: virtual ~IShaderConstantSetter(){}; virtual void onSetConstants(video::IMaterialRendererServices *services, bool is_highlevel) = 0; }; + +class IShaderConstantSetterFactory { +public: + virtual ~IShaderConstantSetterFactory() {}; + virtual IShaderConstantSetter* create() = 0; +}; + + +template +class CachedShaderSetting { + const char *m_name; + T m_sent[count]; + bool has_been_set; + bool is_pixel; +protected: + CachedShaderSetting(const char *name, bool is_pixel) : + m_name(name), has_been_set(false), is_pixel(is_pixel) + {} +public: + void set(const T value[count], video::IMaterialRendererServices *services) + { + if (has_been_set && std::equal(m_sent, m_sent + count, value)) + return; + if (is_pixel) + services->setPixelShaderConstant(m_name, value, count); + else + services->setVertexShaderConstant(m_name, value, count); + std::copy(value, value + count, m_sent); + has_been_set = true; + } +}; + +template +class CachedPixelShaderSetting : public CachedShaderSetting { +public: + CachedPixelShaderSetting(const char *name) : + CachedShaderSetting(name, true){} +}; + +template +class CachedVertexShaderSetting : public CachedShaderSetting { +public: + CachedVertexShaderSetting(const char *name) : + CachedShaderSetting(name, false){} +}; + + /* ShaderSource creates and caches shaders. */ -class IShaderSource -{ +class IShaderSource { public: IShaderSource(){} virtual ~IShaderSource(){} @@ -90,8 +136,7 @@ public: const u8 material_type, const u8 drawtype){return 0;} }; -class IWritableShaderSource : public IShaderSource -{ +class IWritableShaderSource : public IShaderSource { public: IWritableShaderSource(){} virtual ~IWritableShaderSource(){} @@ -105,7 +150,7 @@ public: virtual void insertSourceShader(const std::string &name_of_shader, const std::string &filename, const std::string &program)=0; virtual void rebuildShaders()=0; - virtual void addGlobalConstantSetter(IShaderConstantSetter *setter)=0; + virtual void addShaderConstantSetterFactory(IShaderConstantSetterFactory *setter) = 0; }; IWritableShaderSource* createShaderSource(IrrlichtDevice *device); -- cgit v1.2.3