diff --git a/src/video_core/rasterizer_accelerated.cpp b/src/video_core/rasterizer_accelerated.cpp index 3384b973e..fd99abe6a 100644 --- a/src/video_core/rasterizer_accelerated.cpp +++ b/src/video_core/rasterizer_accelerated.cpp @@ -5,10 +5,25 @@ #include #include "core/memory.h" #include "video_core/rasterizer_accelerated.h" +#include "video_core/pica_state.h" #include "video_core/video_core.h" namespace VideoCore { +static Common::Vec4f ColorRGBA8(const u32 color) { + const auto rgba = + Common::Vec4u{color >> 0 & 0xFF, color >> 8 & 0xFF, color >> 16 & 0xFF, color >> 24 & 0xFF}; + return rgba / 255.0f; +} + +static Common::Vec3f LightColor(const Pica::LightingRegs::LightColor& color) { + return Common::Vec3u{color.r, color.g, color.b} / 255.0f; +} + +RasterizerAccelerated::RasterizerAccelerated() { + uniform_block_data.lighting_lut_dirty.fill(true); +} + void RasterizerAccelerated::UpdatePagesCachedCount(PAddr addr, u32 size, int delta) { const u32 page_start = addr >> Memory::CITRA_PAGE_BITS; const u32 page_end = ((addr + size - 1) >> Memory::CITRA_PAGE_BITS) + 1; @@ -101,4 +116,195 @@ void RasterizerAccelerated::ClearAll(bool flush) { cached_pages = {}; } +void RasterizerAccelerated::SyncDepthScale() { + float depth_scale = + Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32(); + + if (depth_scale != uniform_block_data.data.depth_scale) { + uniform_block_data.data.depth_scale = depth_scale; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncDepthOffset() { + float depth_offset = + Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32(); + + if (depth_offset != uniform_block_data.data.depth_offset) { + uniform_block_data.data.depth_offset = depth_offset; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncFogColor() { + const auto& regs = Pica::g_state.regs; + uniform_block_data.data.fog_color = { + regs.texturing.fog_color.r.Value() / 255.0f, + regs.texturing.fog_color.g.Value() / 255.0f, + regs.texturing.fog_color.b.Value() / 255.0f, + }; + uniform_block_data.dirty = true; +} + +void RasterizerAccelerated::SyncProcTexNoise() { + const auto& regs = Pica::g_state.regs.texturing; + uniform_block_data.data.proctex_noise_f = { + Pica::float16::FromRaw(regs.proctex_noise_frequency.u).ToFloat32(), + Pica::float16::FromRaw(regs.proctex_noise_frequency.v).ToFloat32(), + }; + uniform_block_data.data.proctex_noise_a = { + regs.proctex_noise_u.amplitude / 4095.0f, + regs.proctex_noise_v.amplitude / 4095.0f, + }; + uniform_block_data.data.proctex_noise_p = { + Pica::float16::FromRaw(regs.proctex_noise_u.phase).ToFloat32(), + Pica::float16::FromRaw(regs.proctex_noise_v.phase).ToFloat32(), + }; + + uniform_block_data.dirty = true; +} + +void RasterizerAccelerated::SyncProcTexBias() { + const auto& regs = Pica::g_state.regs.texturing; + uniform_block_data.data.proctex_bias = + Pica::float16::FromRaw(regs.proctex.bias_low | (regs.proctex_lut.bias_high << 8)) + .ToFloat32(); + + uniform_block_data.dirty = true; +} + +void RasterizerAccelerated::SyncAlphaTest() { + const auto& regs = Pica::g_state.regs; + if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { + uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncCombinerColor() { + auto combiner_color = + ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw); + if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { + uniform_block_data.data.tev_combiner_buffer_color = combiner_color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncTevConstColor(std::size_t stage_index, + const Pica::TexturingRegs::TevStageConfig& tev_stage) { + const auto const_color = ColorRGBA8(tev_stage.const_color); + + if (const_color == uniform_block_data.data.const_color[stage_index]) { + return; + } + + uniform_block_data.data.const_color[stage_index] = const_color; + uniform_block_data.dirty = true; +} + +void RasterizerAccelerated::SyncGlobalAmbient() { + auto color = LightColor(Pica::g_state.regs.lighting.global_ambient); + if (color != uniform_block_data.data.lighting_global_ambient) { + uniform_block_data.data.lighting_global_ambient = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightSpecular0(int light_index) { + auto color = LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0); + if (color != uniform_block_data.data.light_src[light_index].specular_0) { + uniform_block_data.data.light_src[light_index].specular_0 = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightSpecular1(int light_index) { + auto color = LightColor(Pica::g_state.regs.lighting.light[light_index].specular_1); + if (color != uniform_block_data.data.light_src[light_index].specular_1) { + uniform_block_data.data.light_src[light_index].specular_1 = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightDiffuse(int light_index) { + auto color = LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse); + if (color != uniform_block_data.data.light_src[light_index].diffuse) { + uniform_block_data.data.light_src[light_index].diffuse = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightAmbient(int light_index) { + auto color = LightColor(Pica::g_state.regs.lighting.light[light_index].ambient); + if (color != uniform_block_data.data.light_src[light_index].ambient) { + uniform_block_data.data.light_src[light_index].ambient = color; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightPosition(int light_index) { + const Common::Vec3f position = { + Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(), + Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(), + Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32()}; + + if (position != uniform_block_data.data.light_src[light_index].position) { + uniform_block_data.data.light_src[light_index].position = position; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightSpotDirection(int light_index) { + const auto& light = Pica::g_state.regs.lighting.light[light_index]; + const auto spot_direction = Common::Vec3f{light.spot_x / 2047.0f, light.spot_y / 2047.0f, light.spot_z / 2047.0f}; + + if (spot_direction != uniform_block_data.data.light_src[light_index].spot_direction) { + uniform_block_data.data.light_src[light_index].spot_direction = spot_direction; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightDistanceAttenuationBias(int light_index) { + float dist_atten_bias = + Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias) + .ToFloat32(); + + if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) { + uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncLightDistanceAttenuationScale(int light_index) { + float dist_atten_scale = + Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale) + .ToFloat32(); + + if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) { + uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncShadowBias() { + const auto& shadow = Pica::g_state.regs.framebuffer.shadow; + float constant = Pica::float16::FromRaw(shadow.constant).ToFloat32(); + float linear = Pica::float16::FromRaw(shadow.linear).ToFloat32(); + + if (constant != uniform_block_data.data.shadow_bias_constant || + linear != uniform_block_data.data.shadow_bias_linear) { + uniform_block_data.data.shadow_bias_constant = constant; + uniform_block_data.data.shadow_bias_linear = linear; + uniform_block_data.dirty = true; + } +} + +void RasterizerAccelerated::SyncShadowTextureBias() { + int bias = Pica::g_state.regs.texturing.shadow.bias << 1; + if (bias != uniform_block_data.data.shadow_texture_bias) { + uniform_block_data.data.shadow_texture_bias = bias; + uniform_block_data.dirty = true; + } +} + } // namespace VideoCore diff --git a/src/video_core/rasterizer_accelerated.h b/src/video_core/rasterizer_accelerated.h index ff238b623..184b74e00 100644 --- a/src/video_core/rasterizer_accelerated.h +++ b/src/video_core/rasterizer_accelerated.h @@ -3,19 +3,107 @@ // Refer to the license.txt file included. #pragma once + +#include "common/vector_math.h" #include "video_core/rasterizer_interface.h" +#include "video_core/regs_texturing.h" +#include "video_core/shader/shader_uniforms.h" namespace VideoCore { class RasterizerAccelerated : public RasterizerInterface { public: + RasterizerAccelerated(); virtual ~RasterizerAccelerated() = default; void UpdatePagesCachedCount(PAddr addr, u32 size, int delta) override; void ClearAll(bool flush) override; +protected: + /// Syncs the depth scale to match the PICA register + void SyncDepthScale(); + + /// Syncs the depth offset to match the PICA register + void SyncDepthOffset(); + + /// Syncs the fog states to match the PICA register + void SyncFogColor(); + + /// Sync the procedural texture noise configuration to match the PICA register + void SyncProcTexNoise(); + + /// Sync the procedural texture bias configuration to match the PICA register + void SyncProcTexBias(); + + /// Syncs the alpha test states to match the PICA register + void SyncAlphaTest(); + + /// Syncs the TEV combiner color buffer to match the PICA register + void SyncCombinerColor(); + + /// Syncs the TEV constant color to match the PICA register + void SyncTevConstColor(std::size_t tev_index, + const Pica::TexturingRegs::TevStageConfig& tev_stage); + + /// Syncs the lighting global ambient color to match the PICA register + void SyncGlobalAmbient(); + + /// Syncs the specified light's specular 0 color to match the PICA register + void SyncLightSpecular0(int light_index); + + /// Syncs the specified light's specular 1 color to match the PICA register + void SyncLightSpecular1(int light_index); + + /// Syncs the specified light's diffuse color to match the PICA register + void SyncLightDiffuse(int light_index); + + /// Syncs the specified light's ambient color to match the PICA register + void SyncLightAmbient(int light_index); + + /// Syncs the specified light's position to match the PICA register + void SyncLightPosition(int light_index); + + /// Syncs the specified spot light direcition to match the PICA register + void SyncLightSpotDirection(int light_index); + + /// Syncs the specified light's distance attenuation bias to match the PICA register + void SyncLightDistanceAttenuationBias(int light_index); + + /// Syncs the specified light's distance attenuation scale to match the PICA register + void SyncLightDistanceAttenuationScale(int light_index); + + /// Syncs the shadow rendering bias to match the PICA register + void SyncShadowBias(); + + /// Syncs the shadow texture bias to match the PICA register + void SyncShadowTextureBias(); + private: + struct UniformBlockData { + Pica::Shader::UniformData data{}; + std::array lighting_lut_dirty{}; + bool lighting_lut_dirty_any = true; + bool fog_lut_dirty = true; + bool proctex_noise_lut_dirty = true; + bool proctex_color_map_dirty = true; + bool proctex_alpha_map_dirty = true; + bool proctex_lut_dirty = true; + bool proctex_diff_lut_dirty = true; + bool dirty = true; + }; + +protected: std::array cached_pages{}; + + UniformBlockData uniform_block_data{}; + std::array, Pica::LightingRegs::NumLightingSampler> + lighting_lut_data{}; + std::array fog_lut_data{}; + std::array proctex_noise_lut_data{}; + std::array proctex_color_map_data{}; + std::array proctex_alpha_map_data{}; + std::array proctex_lut_data{}; + std::array proctex_diff_lut_data{}; }; } // namespace VideoCore diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 5d16d185f..cc9b6b543 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -71,19 +71,6 @@ RasterizerOpenGL::RasterizerOpenGL(Frontend::EmuWindow& emu_window, Driver& driv sw_vao.Create(); hw_vao.Create(); - uniform_block_data.dirty = true; - - uniform_block_data.lighting_lut_dirty.fill(true); - uniform_block_data.lighting_lut_dirty_any = true; - - uniform_block_data.fog_lut_dirty = true; - - uniform_block_data.proctex_noise_lut_dirty = true; - uniform_block_data.proctex_color_map_dirty = true; - uniform_block_data.proctex_alpha_map_dirty = true; - uniform_block_data.proctex_lut_dirty = true; - uniform_block_data.proctex_diff_lut_dirty = true; - glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &uniform_buffer_alignment); uniform_size_aligned_vs = Common::AlignUp(sizeof(VSUniformData), uniform_buffer_alignment); @@ -1653,24 +1640,6 @@ void RasterizerOpenGL::SyncCullMode() { } } -void RasterizerOpenGL::SyncDepthScale() { - float depth_scale = - Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32(); - if (depth_scale != uniform_block_data.data.depth_scale) { - uniform_block_data.data.depth_scale = depth_scale; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncDepthOffset() { - float depth_offset = - Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32(); - if (depth_offset != uniform_block_data.data.depth_offset) { - uniform_block_data.data.depth_offset = depth_offset; - uniform_block_data.dirty = true; - } -} - void RasterizerOpenGL::SyncBlendEnabled() { state.blend.enabled = (Pica::g_state.regs.framebuffer.output_merger.alphablend_enable == 1); } @@ -1700,51 +1669,6 @@ void RasterizerOpenGL::SyncBlendColor() { state.blend.color.alpha = blend_color[3]; } -void RasterizerOpenGL::SyncFogColor() { - const auto& regs = Pica::g_state.regs; - uniform_block_data.data.fog_color = { - regs.texturing.fog_color.r.Value() / 255.0f, - regs.texturing.fog_color.g.Value() / 255.0f, - regs.texturing.fog_color.b.Value() / 255.0f, - }; - uniform_block_data.dirty = true; -} - -void RasterizerOpenGL::SyncProcTexNoise() { - const auto& regs = Pica::g_state.regs.texturing; - uniform_block_data.data.proctex_noise_f = { - Pica::float16::FromRaw(regs.proctex_noise_frequency.u).ToFloat32(), - Pica::float16::FromRaw(regs.proctex_noise_frequency.v).ToFloat32(), - }; - uniform_block_data.data.proctex_noise_a = { - regs.proctex_noise_u.amplitude / 4095.0f, - regs.proctex_noise_v.amplitude / 4095.0f, - }; - uniform_block_data.data.proctex_noise_p = { - Pica::float16::FromRaw(regs.proctex_noise_u.phase).ToFloat32(), - Pica::float16::FromRaw(regs.proctex_noise_v.phase).ToFloat32(), - }; - - uniform_block_data.dirty = true; -} - -void RasterizerOpenGL::SyncProcTexBias() { - const auto& regs = Pica::g_state.regs.texturing; - uniform_block_data.data.proctex_bias = - Pica::float16::FromRaw(regs.proctex.bias_low | (regs.proctex_lut.bias_high << 8)) - .ToFloat32(); - - uniform_block_data.dirty = true; -} - -void RasterizerOpenGL::SyncAlphaTest() { - const auto& regs = Pica::g_state.regs; - if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { - uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref; - uniform_block_data.dirty = true; - } -} - void RasterizerOpenGL::SyncLogicOp() { const auto& regs = Pica::g_state.regs; state.logic_op = PicaToGL::LogicOp(regs.framebuffer.output_merger.logic_op); @@ -1828,131 +1752,6 @@ void RasterizerOpenGL::SyncDepthTest() { : GL_ALWAYS; } -void RasterizerOpenGL::SyncCombinerColor() { - auto combiner_color = - PicaToGL::ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw); - if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { - uniform_block_data.data.tev_combiner_buffer_color = combiner_color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncTevConstColor(std::size_t stage_index, - const Pica::TexturingRegs::TevStageConfig& tev_stage) { - const auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); - - if (const_color == uniform_block_data.data.const_color[stage_index]) { - return; - } - - uniform_block_data.data.const_color[stage_index] = const_color; - uniform_block_data.dirty = true; -} - -void RasterizerOpenGL::SyncGlobalAmbient() { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.global_ambient); - if (color != uniform_block_data.data.lighting_global_ambient) { - uniform_block_data.data.lighting_global_ambient = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightSpecular0(int light_index) { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0); - if (color != uniform_block_data.data.light_src[light_index].specular_0) { - uniform_block_data.data.light_src[light_index].specular_0 = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightSpecular1(int light_index) { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_1); - if (color != uniform_block_data.data.light_src[light_index].specular_1) { - uniform_block_data.data.light_src[light_index].specular_1 = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightDiffuse(int light_index) { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse); - if (color != uniform_block_data.data.light_src[light_index].diffuse) { - uniform_block_data.data.light_src[light_index].diffuse = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightAmbient(int light_index) { - auto color = PicaToGL::LightColor(Pica::g_state.regs.lighting.light[light_index].ambient); - if (color != uniform_block_data.data.light_src[light_index].ambient) { - uniform_block_data.data.light_src[light_index].ambient = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightPosition(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - const Common::Vec3f position = {Pica::float16::FromRaw(light.x).ToFloat32(), - Pica::float16::FromRaw(light.y).ToFloat32(), - Pica::float16::FromRaw(light.z).ToFloat32()}; - - if (position != uniform_block_data.data.light_src[light_index].position) { - uniform_block_data.data.light_src[light_index].position = position; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightSpotDirection(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - const auto spot_direction = - Common::Vec3f{light.spot_x / 2047.0f, light.spot_y / 2047.0f, light.spot_z / 2047.0f}; - - if (spot_direction != uniform_block_data.data.light_src[light_index].spot_direction) { - uniform_block_data.data.light_src[light_index].spot_direction = spot_direction; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightDistanceAttenuationBias(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - float dist_atten_bias = Pica::float20::FromRaw(light.dist_atten_bias).ToFloat32(); - - if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) { - uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncLightDistanceAttenuationScale(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - float dist_atten_scale = Pica::float20::FromRaw(light.dist_atten_scale).ToFloat32(); - - if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) { - uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncShadowBias() { - const auto& shadow = Pica::g_state.regs.framebuffer.shadow; - GLfloat constant = Pica::float16::FromRaw(shadow.constant).ToFloat32(); - GLfloat linear = Pica::float16::FromRaw(shadow.linear).ToFloat32(); - - if (constant != uniform_block_data.data.shadow_bias_constant || - linear != uniform_block_data.data.shadow_bias_linear) { - uniform_block_data.data.shadow_bias_constant = constant; - uniform_block_data.data.shadow_bias_linear = linear; - uniform_block_data.dirty = true; - } -} - -void RasterizerOpenGL::SyncShadowTextureBias() { - GLint bias = Pica::g_state.regs.texturing.shadow.bias << 1; - if (bias != uniform_block_data.data.shadow_texture_bias) { - uniform_block_data.data.shadow_texture_bias = bias; - uniform_block_data.dirty = true; - } -} - void RasterizerOpenGL::SyncAndUploadLUTsLF() { constexpr std::size_t max_size = sizeof(Common::Vec2f) * 256 * Pica::LightingRegs::NumLightingSampler + diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index ca6ac95eb..b5d08a23a 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -3,12 +3,10 @@ // Refer to the license.txt file included. #pragma once -#include "common/vector_math.h" + #include "core/hw/gpu.h" #include "video_core/pica_types.h" #include "video_core/rasterizer_accelerated.h" -#include "video_core/regs_lighting.h" -#include "video_core/regs_texturing.h" #include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_state.h" #include "video_core/renderer_opengl/gl_stream_buffer.h" @@ -133,12 +131,6 @@ private: /// Syncs the cull mode to match the PICA register void SyncCullMode(); - /// Syncs the depth scale to match the PICA register - void SyncDepthScale(); - - /// Syncs the depth offset to match the PICA register - void SyncDepthOffset(); - /// Syncs the blend enabled status to match the PICA register void SyncBlendEnabled(); @@ -148,18 +140,6 @@ private: /// Syncs the blend color to match the PICA register void SyncBlendColor(); - /// Syncs the fog states to match the PICA register - void SyncFogColor(); - - /// Sync the procedural texture noise configuration to match the PICA register - void SyncProcTexNoise(); - - /// Sync the procedural texture bias configuration to match the PICA register - void SyncProcTexBias(); - - /// Syncs the alpha test states to match the PICA register - void SyncAlphaTest(); - /// Syncs the logic op states to match the PICA register void SyncLogicOp(); @@ -178,46 +158,6 @@ private: /// Syncs the depth test states to match the PICA register void SyncDepthTest(); - /// Syncs the TEV combiner color buffer to match the PICA register - void SyncCombinerColor(); - - /// Syncs the TEV constant color to match the PICA register - void SyncTevConstColor(std::size_t tev_index, - const Pica::TexturingRegs::TevStageConfig& tev_stage); - - /// Syncs the lighting global ambient color to match the PICA register - void SyncGlobalAmbient(); - - /// Syncs the specified light's specular 0 color to match the PICA register - void SyncLightSpecular0(int light_index); - - /// Syncs the specified light's specular 1 color to match the PICA register - void SyncLightSpecular1(int light_index); - - /// Syncs the specified light's diffuse color to match the PICA register - void SyncLightDiffuse(int light_index); - - /// Syncs the specified light's ambient color to match the PICA register - void SyncLightAmbient(int light_index); - - /// Syncs the specified light's position to match the PICA register - void SyncLightPosition(int light_index); - - /// Syncs the specified spot light direcition to match the PICA register - void SyncLightSpotDirection(int light_index); - - /// Syncs the specified light's distance attenuation bias to match the PICA register - void SyncLightDistanceAttenuationBias(int light_index); - - /// Syncs the specified light's distance attenuation scale to match the PICA register - void SyncLightDistanceAttenuationScale(int light_index); - - /// Syncs the shadow rendering bias to match the PICA register - void SyncShadowBias(); - - /// Syncs the shadow texture bias to match the PICA register - void SyncShadowTextureBias(); - /// Syncs and uploads the lighting, fog and proctex LUTs void SyncAndUploadLUTs(); void SyncAndUploadLUTsLF(); @@ -263,19 +203,6 @@ private: bool is_amd; bool shader_dirty = true; - struct { - UniformData data; - std::array lighting_lut_dirty; - bool lighting_lut_dirty_any; - bool fog_lut_dirty; - bool proctex_noise_lut_dirty; - bool proctex_color_map_dirty; - bool proctex_alpha_map_dirty; - bool proctex_lut_dirty; - bool proctex_diff_lut_dirty; - bool dirty; - } uniform_block_data = {}; - std::unique_ptr shader_program_manager; // They shall be big enough for about one frame. @@ -304,15 +231,6 @@ private: OGLTexture texture_buffer_lut_lf; OGLTexture texture_buffer_lut_rg; OGLTexture texture_buffer_lut_rgba; - - std::array, Pica::LightingRegs::NumLightingSampler> - lighting_lut_data{}; - std::array fog_lut_data{}; - std::array proctex_noise_lut_data{}; - std::array proctex_color_map_data{}; - std::array proctex_alpha_map_data{}; - std::array proctex_lut_data{}; - std::array proctex_diff_lut_data{}; }; } // namespace OpenGL diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 954d60ac7..da839999d 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -132,8 +132,6 @@ RasterizerVulkan::RasterizerVulkan(Frontend::EmuWindow& emu_window, const Instan null_surface.Transition(vk::ImageLayout::eShaderReadOnlyOptimal, 0, 1); null_storage_surface.Transition(vk::ImageLayout::eGeneral, 0, 1); - uniform_block_data.lighting_lut_dirty.fill(true); - uniform_buffer_alignment = instance.UniformMinAlignment(); uniform_size_aligned_vs = Common::AlignUp(sizeof(Pica::Shader::VSUniformData), uniform_buffer_alignment); @@ -1694,26 +1692,6 @@ void RasterizerVulkan::SyncCullMode() { pipeline_info.rasterization.cull_mode.Assign(regs.rasterizer.cull_mode); } -void RasterizerVulkan::SyncDepthScale() { - float depth_scale = - Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_range).ToFloat32(); - - if (depth_scale != uniform_block_data.data.depth_scale) { - uniform_block_data.data.depth_scale = depth_scale; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncDepthOffset() { - float depth_offset = - Pica::float24::FromRaw(Pica::g_state.regs.rasterizer.viewport_depth_near_plane).ToFloat32(); - - if (depth_offset != uniform_block_data.data.depth_offset) { - uniform_block_data.data.depth_offset = depth_offset; - uniform_block_data.dirty = true; - } -} - void RasterizerVulkan::SyncBlendEnabled() { pipeline_info.blending.blend_enable.Assign( Pica::g_state.regs.framebuffer.output_merger.alphablend_enable); @@ -1745,51 +1723,6 @@ void RasterizerVulkan::SyncBlendColor() { }); } -void RasterizerVulkan::SyncFogColor() { - const auto& regs = Pica::g_state.regs; - uniform_block_data.data.fog_color = { - regs.texturing.fog_color.r.Value() / 255.0f, - regs.texturing.fog_color.g.Value() / 255.0f, - regs.texturing.fog_color.b.Value() / 255.0f, - }; - uniform_block_data.dirty = true; -} - -void RasterizerVulkan::SyncProcTexNoise() { - const auto& regs = Pica::g_state.regs.texturing; - uniform_block_data.data.proctex_noise_f = { - Pica::float16::FromRaw(regs.proctex_noise_frequency.u).ToFloat32(), - Pica::float16::FromRaw(regs.proctex_noise_frequency.v).ToFloat32(), - }; - uniform_block_data.data.proctex_noise_a = { - regs.proctex_noise_u.amplitude / 4095.0f, - regs.proctex_noise_v.amplitude / 4095.0f, - }; - uniform_block_data.data.proctex_noise_p = { - Pica::float16::FromRaw(regs.proctex_noise_u.phase).ToFloat32(), - Pica::float16::FromRaw(regs.proctex_noise_v.phase).ToFloat32(), - }; - - uniform_block_data.dirty = true; -} - -void RasterizerVulkan::SyncProcTexBias() { - const auto& regs = Pica::g_state.regs.texturing; - uniform_block_data.data.proctex_bias = - Pica::float16::FromRaw(regs.proctex.bias_low | (regs.proctex_lut.bias_high << 8)) - .ToFloat32(); - - uniform_block_data.dirty = true; -} - -void RasterizerVulkan::SyncAlphaTest() { - const auto& regs = Pica::g_state.regs; - if (regs.framebuffer.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { - uniform_block_data.data.alphatest_ref = regs.framebuffer.output_merger.alpha_test.ref; - uniform_block_data.dirty = true; - } -} - void RasterizerVulkan::SyncLogicOp() { const auto& regs = Pica::g_state.regs; pipeline_info.blending.logic_op.Assign(regs.framebuffer.output_merger.logic_op); @@ -1846,132 +1779,6 @@ void RasterizerVulkan::SyncDepthTest() { pipeline_info.depth_stencil.depth_compare_op.Assign(compare_op); } -void RasterizerVulkan::SyncCombinerColor() { - auto combiner_color = - PicaToVK::ColorRGBA8(Pica::g_state.regs.texturing.tev_combiner_buffer_color.raw); - if (combiner_color != uniform_block_data.data.tev_combiner_buffer_color) { - uniform_block_data.data.tev_combiner_buffer_color = combiner_color; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncTevConstColor(std::size_t stage_index, - const Pica::TexturingRegs::TevStageConfig& tev_stage) { - const auto const_color = PicaToVK::ColorRGBA8(tev_stage.const_color); - - if (const_color == uniform_block_data.data.const_color[stage_index]) { - return; - } - - uniform_block_data.data.const_color[stage_index] = const_color; - uniform_block_data.dirty = true; -} - -void RasterizerVulkan::SyncGlobalAmbient() { - auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.global_ambient); - if (color != uniform_block_data.data.lighting_global_ambient) { - uniform_block_data.data.lighting_global_ambient = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncLightSpecular0(int light_index) { - auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_0); - if (color != uniform_block_data.data.light_src[light_index].specular_0) { - uniform_block_data.data.light_src[light_index].specular_0 = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncLightSpecular1(int light_index) { - auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.light[light_index].specular_1); - if (color != uniform_block_data.data.light_src[light_index].specular_1) { - uniform_block_data.data.light_src[light_index].specular_1 = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncLightDiffuse(int light_index) { - auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.light[light_index].diffuse); - if (color != uniform_block_data.data.light_src[light_index].diffuse) { - uniform_block_data.data.light_src[light_index].diffuse = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncLightAmbient(int light_index) { - auto color = PicaToVK::LightColor(Pica::g_state.regs.lighting.light[light_index].ambient); - if (color != uniform_block_data.data.light_src[light_index].ambient) { - uniform_block_data.data.light_src[light_index].ambient = color; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncLightPosition(int light_index) { - const Common::Vec3f position = { - Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].x).ToFloat32(), - Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].y).ToFloat32(), - Pica::float16::FromRaw(Pica::g_state.regs.lighting.light[light_index].z).ToFloat32()}; - - if (position != uniform_block_data.data.light_src[light_index].position) { - uniform_block_data.data.light_src[light_index].position = position; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncLightSpotDirection(int light_index) { - const auto& light = Pica::g_state.regs.lighting.light[light_index]; - const auto spot_direction = Common::Vec3i{light.spot_x, light.spot_y, light.spot_z} / 2047.0f; - - if (spot_direction != uniform_block_data.data.light_src[light_index].spot_direction) { - uniform_block_data.data.light_src[light_index].spot_direction = spot_direction; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncLightDistanceAttenuationBias(int light_index) { - float dist_atten_bias = - Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_bias) - .ToFloat32(); - - if (dist_atten_bias != uniform_block_data.data.light_src[light_index].dist_atten_bias) { - uniform_block_data.data.light_src[light_index].dist_atten_bias = dist_atten_bias; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncLightDistanceAttenuationScale(int light_index) { - float dist_atten_scale = - Pica::float20::FromRaw(Pica::g_state.regs.lighting.light[light_index].dist_atten_scale) - .ToFloat32(); - - if (dist_atten_scale != uniform_block_data.data.light_src[light_index].dist_atten_scale) { - uniform_block_data.data.light_src[light_index].dist_atten_scale = dist_atten_scale; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncShadowBias() { - const auto& shadow = Pica::g_state.regs.framebuffer.shadow; - float constant = Pica::float16::FromRaw(shadow.constant).ToFloat32(); - float linear = Pica::float16::FromRaw(shadow.linear).ToFloat32(); - - if (constant != uniform_block_data.data.shadow_bias_constant || - linear != uniform_block_data.data.shadow_bias_linear) { - uniform_block_data.data.shadow_bias_constant = constant; - uniform_block_data.data.shadow_bias_linear = linear; - uniform_block_data.dirty = true; - } -} - -void RasterizerVulkan::SyncShadowTextureBias() { - int bias = Pica::g_state.regs.texturing.shadow.bias << 1; - if (bias != uniform_block_data.data.shadow_texture_bias) { - uniform_block_data.data.shadow_texture_bias = bias; - uniform_block_data.dirty = true; - } -} - void RasterizerVulkan::SyncAndUploadLUTsLF() { constexpr std::size_t max_size = sizeof(Common::Vec2f) * 256 * Pica::LightingRegs::NumLightingSampler + diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h index 65787b13c..4df96fa03 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.h +++ b/src/video_core/renderer_vulkan/vk_rasterizer.h @@ -4,16 +4,12 @@ #pragma once -#include "common/vector_math.h" #include "core/hw/gpu.h" #include "video_core/rasterizer_accelerated.h" -#include "video_core/regs_lighting.h" -#include "video_core/regs_texturing.h" #include "video_core/renderer_vulkan/vk_pipeline_cache.h" #include "video_core/renderer_vulkan/vk_stream_buffer.h" #include "video_core/renderer_vulkan/vk_texture_runtime.h" #include "video_core/shader/shader.h" -#include "video_core/shader/shader_uniforms.h" namespace Frontend { class EmuWindow; @@ -125,12 +121,6 @@ private: /// Syncs the cull mode to match the PICA register void SyncCullMode(); - /// Syncs the depth scale to match the PICA register - void SyncDepthScale(); - - /// Syncs the depth offset to match the PICA register - void SyncDepthOffset(); - /// Syncs the blend enabled status to match the PICA register void SyncBlendEnabled(); @@ -140,18 +130,6 @@ private: /// Syncs the blend color to match the PICA register void SyncBlendColor(); - /// Syncs the fog states to match the PICA register - void SyncFogColor(); - - /// Sync the procedural texture noise configuration to match the PICA register - void SyncProcTexNoise(); - - /// Sync the procedural texture bias configuration to match the PICA register - void SyncProcTexBias(); - - /// Syncs the alpha test states to match the PICA register - void SyncAlphaTest(); - /// Syncs the logic op states to match the PICA register void SyncLogicOp(); @@ -170,46 +148,6 @@ private: /// Syncs the depth test states to match the PICA register void SyncDepthTest(); - /// Syncs the TEV combiner color buffer to match the PICA register - void SyncCombinerColor(); - - /// Syncs the TEV constant color to match the PICA register - void SyncTevConstColor(std::size_t tev_index, - const Pica::TexturingRegs::TevStageConfig& tev_stage); - - /// Syncs the lighting global ambient color to match the PICA register - void SyncGlobalAmbient(); - - /// Syncs the specified light's specular 0 color to match the PICA register - void SyncLightSpecular0(int light_index); - - /// Syncs the specified light's specular 1 color to match the PICA register - void SyncLightSpecular1(int light_index); - - /// Syncs the specified light's diffuse color to match the PICA register - void SyncLightDiffuse(int light_index); - - /// Syncs the specified light's ambient color to match the PICA register - void SyncLightAmbient(int light_index); - - /// Syncs the specified light's position to match the PICA register - void SyncLightPosition(int light_index); - - /// Syncs the specified spot light direcition to match the PICA register - void SyncLightSpotDirection(int light_index); - - /// Syncs the specified light's distance attenuation bias to match the PICA register - void SyncLightDistanceAttenuationBias(int light_index); - - /// Syncs the specified light's distance attenuation scale to match the PICA register - void SyncLightDistanceAttenuationScale(int light_index); - - /// Syncs the shadow rendering bias to match the PICA register - void SyncShadowBias(); - - /// Syncs the shadow texture bias to match the PICA register - void SyncShadowTextureBias(); - /// Syncs and uploads the lighting, fog and proctex LUTs void SyncAndUploadLUTs(); void SyncAndUploadLUTsLF(); @@ -283,19 +221,6 @@ private: Surface null_surface; Surface null_storage_surface; - struct { - Pica::Shader::UniformData data{}; - std::array lighting_lut_dirty{}; - bool lighting_lut_dirty_any = true; - bool fog_lut_dirty = true; - bool proctex_noise_lut_dirty = true; - bool proctex_color_map_dirty = true; - bool proctex_alpha_map_dirty = true; - bool proctex_lut_dirty = true; - bool proctex_diff_lut_dirty = true; - bool dirty = true; - } uniform_block_data = {}; - std::array texture_samplers; SamplerInfo texture_cube_sampler; std::unordered_map samplers; @@ -310,15 +235,6 @@ private: std::size_t uniform_buffer_alignment; std::size_t uniform_size_aligned_vs; std::size_t uniform_size_aligned_fs; - - std::array, Pica::LightingRegs::NumLightingSampler> - lighting_lut_data{}; - std::array fog_lut_data{}; - std::array proctex_noise_lut_data{}; - std::array proctex_color_map_data{}; - std::array proctex_alpha_map_data{}; - std::array proctex_lut_data{}; - std::array proctex_diff_lut_data{}; }; } // namespace Vulkan