From e3f4233cefff611e03a2031c6194a118d946a5d9 Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 25 Jul 2015 20:13:11 -0500 Subject: Initial implementation of fragment shader generation with caching. --- src/video_core/renderer_opengl/gl_rasterizer.h | 110 ++++++++++++++++++------- 1 file changed, 79 insertions(+), 31 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 1fe307846..19e8db69a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -5,6 +5,7 @@ #pragma once #include +#include #include "common/common_types.h" @@ -13,6 +14,60 @@ #include "video_core/renderer_opengl/gl_state.h" #include "video_core/shader/shader_interpreter.h" +template +inline size_t hash(const T& o) { + return std::hash()(o); +} + +template +inline size_t combine_hash(const T& o) { + return hash(o); +} + +template +inline size_t combine_hash(const T& o, const Args&... args) { + return hash(o) * 3 + combine_hash(args...); +} + +struct ShaderCacheKey { + using Regs = Pica::Regs; + + bool operator ==(const ShaderCacheKey& o) const { + return hash(*this) == hash(o); + }; + + Regs::CompareFunc alpha_test_func; + std::array tev_stages; + u8 combiner_buffer_input; + + bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { + return (stage_index < 4) && (combiner_buffer_input & (1 << stage_index)); + } + + bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { + return (stage_index < 4) && ((combiner_buffer_input >> 4) & (1 << stage_index)); + } +}; + +namespace std { + +template<> struct hash<::Pica::Regs::TevStageConfig> { + size_t operator()(const ::Pica::Regs::TevStageConfig& o) { + return ::combine_hash( + ::hash(o.source_raw), ::hash(o.modifier_raw), + ::hash(o.op_raw), ::hash(o.scale_raw)); + } +}; + +template<> struct hash<::ShaderCacheKey> { + size_t operator()(const ::ShaderCacheKey& o) const { + return ::combine_hash(o.alpha_test_func, o.combiner_buffer_input, + o.tev_stages[0], o.tev_stages[1], o.tev_stages[2], + o.tev_stages[3], o.tev_stages[4], o.tev_stages[5]); + } +}; +} + class RasterizerOpenGL : public HWRasterizer { public: @@ -33,6 +88,8 @@ public: /// Draw the current batch of triangles void DrawTriangles() override; + void RegenerateShaders(); + /// Commit the rasterizer's framebuffer contents immediately to the current 3DS memory framebuffer void CommitFramebuffer() override; @@ -59,6 +116,22 @@ private: GLuint updates_combiner_buffer_color_alpha; }; + struct TEVShader { + OGLShader shader; + + // Hardware fragment shader + GLuint uniform_alphatest_ref; + GLuint uniform_tex; + GLuint uniform_tev_combiner_buffer_color; + GLuint uniform_tev_const_colors; + + TEVShader() = default; + TEVShader(TEVShader&& o) : shader(std::move(o.shader)), + uniform_alphatest_ref(o.uniform_alphatest_ref), uniform_tex(o.uniform_tex), + uniform_tev_combiner_buffer_color(o.uniform_tev_combiner_buffer_color), + uniform_tev_const_colors(o.uniform_tev_const_colors) {} + }; + /// Structure used for storing information about color textures struct TextureInfo { OGLTexture texture; @@ -156,27 +229,12 @@ private: /// Syncs the depth test states to match the PICA register void SyncDepthTest(); - /// Syncs the specified TEV stage's color and alpha sources to match the PICA register - void SyncTevSources(unsigned stage_index, const Pica::Regs::TevStageConfig& config); - - /// Syncs the specified TEV stage's color and alpha modifiers to match the PICA register - void SyncTevModifiers(unsigned stage_index, const Pica::Regs::TevStageConfig& config); - - /// Syncs the specified TEV stage's color and alpha combiner operations to match the PICA register - void SyncTevOps(unsigned stage_index, const Pica::Regs::TevStageConfig& config); - - /// Syncs the specified TEV stage's constant color to match the PICA register - void SyncTevColor(unsigned stage_index, const Pica::Regs::TevStageConfig& config); - - /// Syncs the specified TEV stage's color and alpha multipliers to match the PICA register - void SyncTevMultipliers(unsigned stage_index, const Pica::Regs::TevStageConfig& config); + /// Syncs the TEV constant color to match the PICA register + void SyncTevConstColor(int tev_index, const Pica::Regs::TevStageConfig& tev_stage); /// Syncs the TEV combiner color buffer to match the PICA register void SyncCombinerColor(); - /// Syncs the TEV combiner write flags to match the PICA register - void SyncCombinerWriteFlags(); - /// Syncs the remaining OpenGL drawing state to match the current PICA state void SyncDrawState(); @@ -213,21 +271,11 @@ private: std::array texture_samplers; TextureInfo fb_color_texture; DepthTextureInfo fb_depth_texture; - OGLShader shader; + + std::unordered_map shader_cache; + TEVShader* current_shader = nullptr; + OGLVertexArray vertex_array; OGLBuffer vertex_buffer; OGLFramebuffer framebuffer; - - // Hardware vertex shader - GLuint attrib_position; - GLuint attrib_color; - GLuint attrib_texcoords; - - // Hardware fragment shader - GLuint uniform_alphatest_enabled; - GLuint uniform_alphatest_func; - GLuint uniform_alphatest_ref; - GLuint uniform_tex; - GLuint uniform_tev_combiner_buffer_color; - TEVConfigUniforms uniform_tev_cfgs[6]; }; -- cgit v1.2.3 From 3c057bd3d80b049720b11d0b44391c18870c28e8 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 5 Oct 2015 20:52:04 -0400 Subject: gl_rasterizer: Move logic for creating ShaderCacheKey to a static function. --- src/video_core/renderer_opengl/gl_rasterizer.h | 45 +++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 19e8db69a..5bc4a319f 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -9,6 +9,7 @@ #include "common/common_types.h" +#include "video_core/pica.h" #include "video_core/hwrasterizer_base.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" #include "video_core/renderer_opengl/gl_state.h" @@ -37,7 +38,7 @@ struct ShaderCacheKey { }; Regs::CompareFunc alpha_test_func; - std::array tev_stages; + std::array tev_stages = {}; u8 combiner_buffer_input; bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { @@ -47,6 +48,48 @@ struct ShaderCacheKey { bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { return (stage_index < 4) && ((combiner_buffer_input >> 4) & (1 << stage_index)); } + + static ShaderCacheKey CurrentShaderConfig() { + const auto& regs = Pica::g_state.regs; + ShaderCacheKey config; + + config.alpha_test_func = regs.output_merger.alpha_test.enable ? + regs.output_merger.alpha_test.func.Value() : Pica::Regs::CompareFunc::Always; + + config.tev_stages[0].source_raw = regs.tev_stage0.source_raw; + config.tev_stages[1].source_raw = regs.tev_stage1.source_raw; + config.tev_stages[2].source_raw = regs.tev_stage2.source_raw; + config.tev_stages[3].source_raw = regs.tev_stage3.source_raw; + config.tev_stages[4].source_raw = regs.tev_stage4.source_raw; + config.tev_stages[5].source_raw = regs.tev_stage5.source_raw; + + config.tev_stages[0].modifier_raw = regs.tev_stage0.modifier_raw; + config.tev_stages[1].modifier_raw = regs.tev_stage1.modifier_raw; + config.tev_stages[2].modifier_raw = regs.tev_stage2.modifier_raw; + config.tev_stages[3].modifier_raw = regs.tev_stage3.modifier_raw; + config.tev_stages[4].modifier_raw = regs.tev_stage4.modifier_raw; + config.tev_stages[5].modifier_raw = regs.tev_stage5.modifier_raw; + + config.tev_stages[0].op_raw = regs.tev_stage0.op_raw; + config.tev_stages[1].op_raw = regs.tev_stage1.op_raw; + config.tev_stages[2].op_raw = regs.tev_stage2.op_raw; + config.tev_stages[3].op_raw = regs.tev_stage3.op_raw; + config.tev_stages[4].op_raw = regs.tev_stage4.op_raw; + config.tev_stages[5].op_raw = regs.tev_stage5.op_raw; + + config.tev_stages[0].scale_raw = regs.tev_stage0.scale_raw; + config.tev_stages[1].scale_raw = regs.tev_stage1.scale_raw; + config.tev_stages[2].scale_raw = regs.tev_stage2.scale_raw; + config.tev_stages[3].scale_raw = regs.tev_stage3.scale_raw; + config.tev_stages[4].scale_raw = regs.tev_stage4.scale_raw; + config.tev_stages[5].scale_raw = regs.tev_stage5.scale_raw; + + config.combiner_buffer_input = + regs.tev_combiner_buffer_input.update_mask_rgb.Value() | + regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; + + return config; + } }; namespace std { -- cgit v1.2.3 From c86b9d42423b5a83ccba40f828b7ad9dafe3e317 Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 5 Oct 2015 22:33:47 -0400 Subject: renderer_opengl: Refactor shader generation/caching to be more organized + various cleanups. --- src/video_core/renderer_opengl/gl_rasterizer.h | 41 +++++++++++--------------- 1 file changed, 18 insertions(+), 23 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 5bc4a319f..de9e4d22e 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -4,6 +4,8 @@ #pragma once +#include +#include #include #include @@ -15,21 +17,6 @@ #include "video_core/renderer_opengl/gl_state.h" #include "video_core/shader/shader_interpreter.h" -template -inline size_t hash(const T& o) { - return std::hash()(o); -} - -template -inline size_t combine_hash(const T& o) { - return hash(o); -} - -template -inline size_t combine_hash(const T& o, const Args&... args) { - return hash(o) * 3 + combine_hash(args...); -} - struct ShaderCacheKey { using Regs = Pica::Regs; @@ -49,7 +36,7 @@ struct ShaderCacheKey { return (stage_index < 4) && ((combiner_buffer_input >> 4) & (1 << stage_index)); } - static ShaderCacheKey CurrentShaderConfig() { + static ShaderCacheKey CurrentConfig() { const auto& regs = Pica::g_state.regs; ShaderCacheKey config; @@ -94,8 +81,14 @@ struct ShaderCacheKey { namespace std { +template<> struct hash<::Pica::Regs::CompareFunc> { + std::size_t operator()(const ::Pica::Regs::CompareFunc& o) { + return ::hash((unsigned)o); + } +}; + template<> struct hash<::Pica::Regs::TevStageConfig> { - size_t operator()(const ::Pica::Regs::TevStageConfig& o) { + std::size_t operator()(const ::Pica::Regs::TevStageConfig& o) { return ::combine_hash( ::hash(o.source_raw), ::hash(o.modifier_raw), ::hash(o.op_raw), ::hash(o.scale_raw)); @@ -103,13 +96,14 @@ template<> struct hash<::Pica::Regs::TevStageConfig> { }; template<> struct hash<::ShaderCacheKey> { - size_t operator()(const ::ShaderCacheKey& o) const { + std::size_t operator()(const ::ShaderCacheKey& o) const { return ::combine_hash(o.alpha_test_func, o.combiner_buffer_input, o.tev_stages[0], o.tev_stages[1], o.tev_stages[2], o.tev_stages[3], o.tev_stages[4], o.tev_stages[5]); } }; -} + +} // namespace std class RasterizerOpenGL : public HWRasterizer { public: @@ -131,8 +125,6 @@ public: /// Draw the current batch of triangles void DrawTriangles() override; - void RegenerateShaders(); - /// Commit the rasterizer's framebuffer contents immediately to the current 3DS memory framebuffer void CommitFramebuffer() override; @@ -245,6 +237,9 @@ private: /// Reconfigure the OpenGL depth texture to use the given format and dimensions void ReconfigureDepthTexture(DepthTextureInfo& texture, Pica::Regs::DepthFormat format, u32 width, u32 height); + /// Sets the OpenGL shader in accordance with the current PICA register state + void SetShader(); + /// Syncs the state and contents of the OpenGL framebuffer to match the current PICA framebuffer void SyncFramebuffer(); @@ -315,8 +310,8 @@ private: TextureInfo fb_color_texture; DepthTextureInfo fb_depth_texture; - std::unordered_map shader_cache; - TEVShader* current_shader = nullptr; + std::unordered_map> shader_cache; + const TEVShader* current_shader = nullptr; OGLVertexArray vertex_array; OGLBuffer vertex_buffer; -- cgit v1.2.3 From f2e7f7e1019eeffc0aee438f788449fc4e0c118f Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 6 Oct 2015 18:34:50 -0400 Subject: gl_rasterizer: Add documentation to ShaderCacheKey. --- src/video_core/renderer_opengl/gl_rasterizer.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index de9e4d22e..484579d82 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -17,6 +17,14 @@ #include "video_core/renderer_opengl/gl_state.h" #include "video_core/shader/shader_interpreter.h" +/** + * This struct contains all state used to generate the GLSL shader program that emulates the current + * Pica register configuration. This struct is used as a cache key for generated GLSL shader + * programs. The functions in gl_shader_gen.cpp should retrieve state from this struct only, not by + * directly accessing Pica registers. This should reduce the risk of bugs in shader generation where + * Pica state is not being captured in the shader cache key, thereby resulting in (what should be) + * two separate shaders sharing the same key. + */ struct ShaderCacheKey { using Regs = Pica::Regs; @@ -36,6 +44,11 @@ struct ShaderCacheKey { return (stage_index < 4) && ((combiner_buffer_input >> 4) & (1 << stage_index)); } + /** + * This function is used to construct a ShaderCacheKey with the current Pica register + * configuration. Don't construct a ShaderCacheKey manually, instead call this function (and + * extend it as additional state needs to be captured to generate shaders). + */ static ShaderCacheKey CurrentConfig() { const auto& regs = Pica::g_state.regs; ShaderCacheKey config; @@ -43,6 +56,9 @@ struct ShaderCacheKey { config.alpha_test_func = regs.output_merger.alpha_test.enable ? regs.output_merger.alpha_test.func.Value() : Pica::Regs::CompareFunc::Always; + // Copy relevant TevStageConfig fields only. We're doing this manually (instead of calling + // the GetTevStages() function) because BitField explicitly disables copies. + config.tev_stages[0].source_raw = regs.tev_stage0.source_raw; config.tev_stages[1].source_raw = regs.tev_stage1.source_raw; config.tev_stages[2].source_raw = regs.tev_stage2.source_raw; -- cgit v1.2.3 From 71edb55114af129d6f580e271ad5196043342abe Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 9 Oct 2015 19:32:38 -0400 Subject: gl_shader_gen: Require explicit uniform locations. - Fixes uniform issue on AMD. --- src/video_core/renderer_opengl/gl_rasterizer.h | 40 +++++++++----------------- 1 file changed, 14 insertions(+), 26 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 484579d82..79c34944a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -153,36 +153,24 @@ public: /// Notify rasterizer that a 3DS memory region has been changed void NotifyFlush(PAddr addr, u32 size) override; -private: - /// Structure used for managing texture environment states - struct TEVConfigUniforms { - GLuint enabled; - GLuint color_sources; - GLuint alpha_sources; - GLuint color_modifiers; - GLuint alpha_modifiers; - GLuint color_alpha_op; - GLuint color_alpha_multiplier; - GLuint const_color; - GLuint updates_combiner_buffer_color_alpha; - }; - - struct TEVShader { + /// OpenGL shader generated for a given Pica register state + struct PicaShader { + /// OpenGL shader resource OGLShader shader; - // Hardware fragment shader - GLuint uniform_alphatest_ref; - GLuint uniform_tex; - GLuint uniform_tev_combiner_buffer_color; - GLuint uniform_tev_const_colors; - - TEVShader() = default; - TEVShader(TEVShader&& o) : shader(std::move(o.shader)), - uniform_alphatest_ref(o.uniform_alphatest_ref), uniform_tex(o.uniform_tex), - uniform_tev_combiner_buffer_color(o.uniform_tev_combiner_buffer_color), - uniform_tev_const_colors(o.uniform_tev_const_colors) {} + /// Fragment shader uniforms + enum Uniform : GLuint { + AlphaTestRef = 0, + TevConstColors = 1, + Texture0 = 7, + Texture1 = 8, + Texture2 = 9, + TevCombinerBufferColor = 10, + }; }; +private: + /// Structure used for storing information about color textures struct TextureInfo { OGLTexture texture; -- cgit v1.2.3 From 240a3b80d970b56b4ed3671536489eb0e32532ae Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 9 Oct 2015 22:46:47 -0400 Subject: gl_rasterizer: Use MMH3 hash for shader cache hey. - Includes a check to confirm no hash collisions. --- src/video_core/renderer_opengl/gl_rasterizer.h | 133 +++++++++++-------------- 1 file changed, 57 insertions(+), 76 deletions(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index 79c34944a..cf8df8d9c 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -5,11 +5,13 @@ #pragma once #include +#include #include #include #include #include "common/common_types.h" +#include "common/hash.h" #include "video_core/pica.h" #include "video_core/hwrasterizer_base.h" @@ -25,97 +27,76 @@ * Pica state is not being captured in the shader cache key, thereby resulting in (what should be) * two separate shaders sharing the same key. */ -struct ShaderCacheKey { - using Regs = Pica::Regs; - - bool operator ==(const ShaderCacheKey& o) const { - return hash(*this) == hash(o); - }; - - Regs::CompareFunc alpha_test_func; - std::array tev_stages = {}; - u8 combiner_buffer_input; - - bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { - return (stage_index < 4) && (combiner_buffer_input & (1 << stage_index)); - } - - bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { - return (stage_index < 4) && ((combiner_buffer_input >> 4) & (1 << stage_index)); - } - - /** - * This function is used to construct a ShaderCacheKey with the current Pica register - * configuration. Don't construct a ShaderCacheKey manually, instead call this function (and - * extend it as additional state needs to be captured to generate shaders). - */ - static ShaderCacheKey CurrentConfig() { +struct PicaShaderConfig { + /// Construct a PicaShaderConfig with the current Pica register configuration. + static PicaShaderConfig CurrentConfig() { + PicaShaderConfig res; const auto& regs = Pica::g_state.regs; - ShaderCacheKey config; - config.alpha_test_func = regs.output_merger.alpha_test.enable ? + res.alpha_test_func = regs.output_merger.alpha_test.enable ? regs.output_merger.alpha_test.func.Value() : Pica::Regs::CompareFunc::Always; // Copy relevant TevStageConfig fields only. We're doing this manually (instead of calling // the GetTevStages() function) because BitField explicitly disables copies. - config.tev_stages[0].source_raw = regs.tev_stage0.source_raw; - config.tev_stages[1].source_raw = regs.tev_stage1.source_raw; - config.tev_stages[2].source_raw = regs.tev_stage2.source_raw; - config.tev_stages[3].source_raw = regs.tev_stage3.source_raw; - config.tev_stages[4].source_raw = regs.tev_stage4.source_raw; - config.tev_stages[5].source_raw = regs.tev_stage5.source_raw; - - config.tev_stages[0].modifier_raw = regs.tev_stage0.modifier_raw; - config.tev_stages[1].modifier_raw = regs.tev_stage1.modifier_raw; - config.tev_stages[2].modifier_raw = regs.tev_stage2.modifier_raw; - config.tev_stages[3].modifier_raw = regs.tev_stage3.modifier_raw; - config.tev_stages[4].modifier_raw = regs.tev_stage4.modifier_raw; - config.tev_stages[5].modifier_raw = regs.tev_stage5.modifier_raw; - - config.tev_stages[0].op_raw = regs.tev_stage0.op_raw; - config.tev_stages[1].op_raw = regs.tev_stage1.op_raw; - config.tev_stages[2].op_raw = regs.tev_stage2.op_raw; - config.tev_stages[3].op_raw = regs.tev_stage3.op_raw; - config.tev_stages[4].op_raw = regs.tev_stage4.op_raw; - config.tev_stages[5].op_raw = regs.tev_stage5.op_raw; - - config.tev_stages[0].scale_raw = regs.tev_stage0.scale_raw; - config.tev_stages[1].scale_raw = regs.tev_stage1.scale_raw; - config.tev_stages[2].scale_raw = regs.tev_stage2.scale_raw; - config.tev_stages[3].scale_raw = regs.tev_stage3.scale_raw; - config.tev_stages[4].scale_raw = regs.tev_stage4.scale_raw; - config.tev_stages[5].scale_raw = regs.tev_stage5.scale_raw; - - config.combiner_buffer_input = + res.tev_stages[0].sources_raw = regs.tev_stage0.sources_raw; + res.tev_stages[1].sources_raw = regs.tev_stage1.sources_raw; + res.tev_stages[2].sources_raw = regs.tev_stage2.sources_raw; + res.tev_stages[3].sources_raw = regs.tev_stage3.sources_raw; + res.tev_stages[4].sources_raw = regs.tev_stage4.sources_raw; + res.tev_stages[5].sources_raw = regs.tev_stage5.sources_raw; + + res.tev_stages[0].modifiers_raw = regs.tev_stage0.modifiers_raw; + res.tev_stages[1].modifiers_raw = regs.tev_stage1.modifiers_raw; + res.tev_stages[2].modifiers_raw = regs.tev_stage2.modifiers_raw; + res.tev_stages[3].modifiers_raw = regs.tev_stage3.modifiers_raw; + res.tev_stages[4].modifiers_raw = regs.tev_stage4.modifiers_raw; + res.tev_stages[5].modifiers_raw = regs.tev_stage5.modifiers_raw; + + res.tev_stages[0].ops_raw = regs.tev_stage0.ops_raw; + res.tev_stages[1].ops_raw = regs.tev_stage1.ops_raw; + res.tev_stages[2].ops_raw = regs.tev_stage2.ops_raw; + res.tev_stages[3].ops_raw = regs.tev_stage3.ops_raw; + res.tev_stages[4].ops_raw = regs.tev_stage4.ops_raw; + res.tev_stages[5].ops_raw = regs.tev_stage5.ops_raw; + + res.tev_stages[0].scales_raw = regs.tev_stage0.scales_raw; + res.tev_stages[1].scales_raw = regs.tev_stage1.scales_raw; + res.tev_stages[2].scales_raw = regs.tev_stage2.scales_raw; + res.tev_stages[3].scales_raw = regs.tev_stage3.scales_raw; + res.tev_stages[4].scales_raw = regs.tev_stage4.scales_raw; + res.tev_stages[5].scales_raw = regs.tev_stage5.scales_raw; + + res.combiner_buffer_input = regs.tev_combiner_buffer_input.update_mask_rgb.Value() | regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; - return config; + return res; } -}; - -namespace std { -template<> struct hash<::Pica::Regs::CompareFunc> { - std::size_t operator()(const ::Pica::Regs::CompareFunc& o) { - return ::hash((unsigned)o); + bool TevStageUpdatesCombinerBufferColor(unsigned stage_index) const { + return (stage_index < 4) && (combiner_buffer_input & (1 << stage_index)); } -}; -template<> struct hash<::Pica::Regs::TevStageConfig> { - std::size_t operator()(const ::Pica::Regs::TevStageConfig& o) { - return ::combine_hash( - ::hash(o.source_raw), ::hash(o.modifier_raw), - ::hash(o.op_raw), ::hash(o.scale_raw)); + bool TevStageUpdatesCombinerBufferAlpha(unsigned stage_index) const { + return (stage_index < 4) && ((combiner_buffer_input >> 4) & (1 << stage_index)); } + + bool operator ==(const PicaShaderConfig& o) const { + return std::memcmp(this, &o, sizeof(PicaShaderConfig)) == 0; + }; + + Pica::Regs::CompareFunc alpha_test_func; + std::array tev_stages = {}; + u8 combiner_buffer_input; }; -template<> struct hash<::ShaderCacheKey> { - std::size_t operator()(const ::ShaderCacheKey& o) const { - return ::combine_hash(o.alpha_test_func, o.combiner_buffer_input, - o.tev_stages[0], o.tev_stages[1], o.tev_stages[2], - o.tev_stages[3], o.tev_stages[4], o.tev_stages[5]); +namespace std { + +template <> +struct hash { + std::size_t operator()(const PicaShaderConfig& k) const { + return Common::ComputeHash64(&k, sizeof(PicaShaderConfig)); } }; @@ -314,8 +295,8 @@ private: TextureInfo fb_color_texture; DepthTextureInfo fb_depth_texture; - std::unordered_map> shader_cache; - const TEVShader* current_shader = nullptr; + std::unordered_map> shader_cache; + const PicaShader* current_shader = nullptr; OGLVertexArray vertex_array; OGLBuffer vertex_buffer; -- cgit v1.2.3 From 0ebcff710e6b5d266158ec364cf08bd8f22ae74a Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 12 Oct 2015 22:23:26 -0400 Subject: gl_shader_gen: Various cleanups to shader generation. --- src/video_core/renderer_opengl/gl_rasterizer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/video_core/renderer_opengl/gl_rasterizer.h') diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index cf8df8d9c..872cae7da 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -95,7 +95,7 @@ namespace std { template <> struct hash { - std::size_t operator()(const PicaShaderConfig& k) const { + size_t operator()(const PicaShaderConfig& k) const { return Common::ComputeHash64(&k, sizeof(PicaShaderConfig)); } }; -- cgit v1.2.3