diff options
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 351 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.h | 56 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 33 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 20 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_gen.cpp | 105 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/pica_to_gl.h | 20 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 17 |
7 files changed, 318 insertions, 284 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 2d2f4edc1..de1d5eba7 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -14,8 +14,10 @@ #include "common/microprofile.h" #include "common/vector_math.h" #include "core/hw/gpu.h" -#include "video_core/pica.h" #include "video_core/pica_state.h" +#include "video_core/regs_framebuffer.h" +#include "video_core/regs_rasterizer.h" +#include "video_core/regs_texturing.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_shader_gen.h" #include "video_core/renderer_opengl/gl_shader_util.h" @@ -26,16 +28,6 @@ MICROPROFILE_DEFINE(OpenGL_Drawing, "OpenGL", "Drawing", MP_RGB(128, 128, 192)); MICROPROFILE_DEFINE(OpenGL_Blits, "OpenGL", "Blits", MP_RGB(100, 100, 255)); MICROPROFILE_DEFINE(OpenGL_CacheManagement, "OpenGL", "Cache Mgmt", MP_RGB(100, 255, 100)); -static bool IsPassThroughTevStage(const Pica::Regs::TevStageConfig& stage) { - return (stage.color_op == Pica::Regs::TevStageConfig::Operation::Replace && - stage.alpha_op == Pica::Regs::TevStageConfig::Operation::Replace && - stage.color_source1 == Pica::Regs::TevStageConfig::Source::Previous && - stage.alpha_source1 == Pica::Regs::TevStageConfig::Source::Previous && - stage.color_modifier1 == Pica::Regs::TevStageConfig::ColorModifier::SourceColor && - stage.alpha_modifier1 == Pica::Regs::TevStageConfig::AlphaModifier::SourceAlpha && - stage.GetColorMultiplier() == 1 && stage.GetAlphaMultiplier() == 1); -} - RasterizerOpenGL::RasterizerOpenGL() : shader_dirty(true) { // Create sampler objects for (size_t i = 0; i < texture_samplers.size(); ++i) { @@ -181,7 +173,7 @@ void RasterizerOpenGL::DrawTriangles() { CachedSurface* depth_surface; MathUtil::Rectangle<int> rect; std::tie(color_surface, depth_surface, rect) = - res_cache.GetFramebufferSurfaces(regs.framebuffer); + res_cache.GetFramebufferSurfaces(regs.framebuffer.framebuffer); state.draw.draw_framebuffer = framebuffer.handle; state.Apply(); @@ -190,20 +182,24 @@ void RasterizerOpenGL::DrawTriangles() { color_surface != nullptr ? color_surface->texture.handle : 0, 0); glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, depth_surface != nullptr ? depth_surface->texture.handle : 0, 0); - bool has_stencil = regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8; + bool has_stencil = + regs.framebuffer.framebuffer.depth_format == Pica::FramebufferRegs::DepthFormat::D24S8; glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, (has_stencil && depth_surface != nullptr) ? depth_surface->texture.handle : 0, 0); // Sync the viewport // These registers hold half-width and half-height, so must be multiplied by 2 - GLsizei viewport_width = (GLsizei)Pica::float24::FromRaw(regs.viewport_size_x).ToFloat32() * 2; - GLsizei viewport_height = (GLsizei)Pica::float24::FromRaw(regs.viewport_size_y).ToFloat32() * 2; + GLsizei viewport_width = + (GLsizei)Pica::float24::FromRaw(regs.rasterizer.viewport_size_x).ToFloat32() * 2; + GLsizei viewport_height = + (GLsizei)Pica::float24::FromRaw(regs.rasterizer.viewport_size_y).ToFloat32() * 2; - glViewport((GLint)(rect.left + regs.viewport_corner.x * color_surface->res_scale_width), - (GLint)(rect.bottom + regs.viewport_corner.y * color_surface->res_scale_height), - (GLsizei)(viewport_width * color_surface->res_scale_width), - (GLsizei)(viewport_height * color_surface->res_scale_height)); + glViewport( + (GLint)(rect.left + regs.rasterizer.viewport_corner.x * color_surface->res_scale_width), + (GLint)(rect.bottom + regs.rasterizer.viewport_corner.y * color_surface->res_scale_height), + (GLsizei)(viewport_width * color_surface->res_scale_width), + (GLsizei)(viewport_height * color_surface->res_scale_height)); if (uniform_block_data.data.framebuffer_scale[0] != color_surface->res_scale_width || uniform_block_data.data.framebuffer_scale[1] != color_surface->res_scale_height) { @@ -215,16 +211,16 @@ void RasterizerOpenGL::DrawTriangles() { // Scissor checks are window-, not viewport-relative, which means that if the cached texture // sub-rect changes, the scissor bounds also need to be updated. - GLint scissor_x1 = - static_cast<GLint>(rect.left + regs.scissor_test.x1 * color_surface->res_scale_width); - GLint scissor_y1 = - static_cast<GLint>(rect.bottom + regs.scissor_test.y1 * color_surface->res_scale_height); + GLint scissor_x1 = static_cast<GLint>( + rect.left + regs.rasterizer.scissor_test.x1 * color_surface->res_scale_width); + GLint scissor_y1 = static_cast<GLint>( + rect.bottom + regs.rasterizer.scissor_test.y1 * color_surface->res_scale_height); // x2, y2 have +1 added to cover the entire pixel area, otherwise you might get cracks when // scaling or doing multisampling. - GLint scissor_x2 = - static_cast<GLint>(rect.left + (regs.scissor_test.x2 + 1) * color_surface->res_scale_width); + GLint scissor_x2 = static_cast<GLint>( + rect.left + (regs.rasterizer.scissor_test.x2 + 1) * color_surface->res_scale_width); GLint scissor_y2 = static_cast<GLint>( - rect.bottom + (regs.scissor_test.y2 + 1) * color_surface->res_scale_height); + rect.bottom + (regs.rasterizer.scissor_test.y2 + 1) * color_surface->res_scale_height); if (uniform_block_data.data.scissor_x1 != scissor_x1 || uniform_block_data.data.scissor_x2 != scissor_x2 || @@ -239,7 +235,7 @@ void RasterizerOpenGL::DrawTriangles() { } // Sync and bind the texture surfaces - const auto pica_textures = regs.GetTextures(); + const auto pica_textures = regs.texturing.GetTextures(); for (unsigned texture_index = 0; texture_index < pica_textures.size(); ++texture_index) { const auto& texture = pica_textures[texture_index]; @@ -316,69 +312,69 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { switch (id) { // Culling - case PICA_REG_INDEX(cull_mode): + case PICA_REG_INDEX(rasterizer.cull_mode): SyncCullMode(); break; // Depth modifiers - case PICA_REG_INDEX(viewport_depth_range): + case PICA_REG_INDEX(rasterizer.viewport_depth_range): SyncDepthScale(); break; - case PICA_REG_INDEX(viewport_depth_near_plane): + case PICA_REG_INDEX(rasterizer.viewport_depth_near_plane): SyncDepthOffset(); break; // Depth buffering - case PICA_REG_INDEX(depthmap_enable): + case PICA_REG_INDEX(rasterizer.depthmap_enable): shader_dirty = true; break; // Blending - case PICA_REG_INDEX(output_merger.alphablend_enable): + case PICA_REG_INDEX(framebuffer.output_merger.alphablend_enable): SyncBlendEnabled(); break; - case PICA_REG_INDEX(output_merger.alpha_blending): + case PICA_REG_INDEX(framebuffer.output_merger.alpha_blending): SyncBlendFuncs(); break; - case PICA_REG_INDEX(output_merger.blend_const): + case PICA_REG_INDEX(framebuffer.output_merger.blend_const): SyncBlendColor(); break; // Fog state - case PICA_REG_INDEX(fog_color): + case PICA_REG_INDEX(texturing.fog_color): SyncFogColor(); break; - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[0], 0xe8): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[1], 0xe9): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[2], 0xea): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[3], 0xeb): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[4], 0xec): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[5], 0xed): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[6], 0xee): - case PICA_REG_INDEX_WORKAROUND(fog_lut_data[7], 0xef): + case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[0], 0xe8): + case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[1], 0xe9): + case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[2], 0xea): + case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[3], 0xeb): + case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[4], 0xec): + case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[5], 0xed): + case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[6], 0xee): + case PICA_REG_INDEX_WORKAROUND(texturing.fog_lut_data[7], 0xef): uniform_block_data.fog_lut_dirty = true; break; // Alpha test - case PICA_REG_INDEX(output_merger.alpha_test): + case PICA_REG_INDEX(framebuffer.output_merger.alpha_test): SyncAlphaTest(); shader_dirty = true; break; // Sync GL stencil test + stencil write mask // (Pica stencil test function register also contains a stencil write mask) - case PICA_REG_INDEX(output_merger.stencil_test.raw_func): + case PICA_REG_INDEX(framebuffer.output_merger.stencil_test.raw_func): SyncStencilTest(); SyncStencilWriteMask(); break; - case PICA_REG_INDEX(output_merger.stencil_test.raw_op): - case PICA_REG_INDEX(framebuffer.depth_format): + case PICA_REG_INDEX(framebuffer.output_merger.stencil_test.raw_op): + case PICA_REG_INDEX(framebuffer.framebuffer.depth_format): SyncStencilTest(); break; // Sync GL depth test + depth and color write mask // (Pica depth test function register also contains a depth and color write mask) - case PICA_REG_INDEX(output_merger.depth_test_enable): + case PICA_REG_INDEX(framebuffer.output_merger.depth_test_enable): SyncDepthTest(); SyncDepthWriteMask(); SyncColorWriteMask(); @@ -386,88 +382,88 @@ void RasterizerOpenGL::NotifyPicaRegisterChanged(u32 id) { // Sync GL depth and stencil write mask // (This is a dedicated combined depth / stencil write-enable register) - case PICA_REG_INDEX(framebuffer.allow_depth_stencil_write): + case PICA_REG_INDEX(framebuffer.framebuffer.allow_depth_stencil_write): SyncDepthWriteMask(); SyncStencilWriteMask(); break; // Sync GL color write mask // (This is a dedicated color write-enable register) - case PICA_REG_INDEX(framebuffer.allow_color_write): + case PICA_REG_INDEX(framebuffer.framebuffer.allow_color_write): SyncColorWriteMask(); break; // Scissor test - case PICA_REG_INDEX(scissor_test.mode): + case PICA_REG_INDEX(rasterizer.scissor_test.mode): shader_dirty = true; break; // Logic op - case PICA_REG_INDEX(output_merger.logic_op): + case PICA_REG_INDEX(framebuffer.output_merger.logic_op): SyncLogicOp(); break; // Texture 0 type - case PICA_REG_INDEX(texture0.type): + case PICA_REG_INDEX(texturing.texture0.type): shader_dirty = true; break; // TEV stages // (This also syncs fog_mode and fog_flip which are part of tev_combiner_buffer_input) - case PICA_REG_INDEX(tev_stage0.color_source1): - case PICA_REG_INDEX(tev_stage0.color_modifier1): - case PICA_REG_INDEX(tev_stage0.color_op): - case PICA_REG_INDEX(tev_stage0.color_scale): - case PICA_REG_INDEX(tev_stage1.color_source1): - case PICA_REG_INDEX(tev_stage1.color_modifier1): - case PICA_REG_INDEX(tev_stage1.color_op): - case PICA_REG_INDEX(tev_stage1.color_scale): - case PICA_REG_INDEX(tev_stage2.color_source1): - case PICA_REG_INDEX(tev_stage2.color_modifier1): - case PICA_REG_INDEX(tev_stage2.color_op): - case PICA_REG_INDEX(tev_stage2.color_scale): - case PICA_REG_INDEX(tev_stage3.color_source1): - case PICA_REG_INDEX(tev_stage3.color_modifier1): - case PICA_REG_INDEX(tev_stage3.color_op): - case PICA_REG_INDEX(tev_stage3.color_scale): - case PICA_REG_INDEX(tev_stage4.color_source1): - case PICA_REG_INDEX(tev_stage4.color_modifier1): - case PICA_REG_INDEX(tev_stage4.color_op): - case PICA_REG_INDEX(tev_stage4.color_scale): - case PICA_REG_INDEX(tev_stage5.color_source1): - case PICA_REG_INDEX(tev_stage5.color_modifier1): - case PICA_REG_INDEX(tev_stage5.color_op): - case PICA_REG_INDEX(tev_stage5.color_scale): - case PICA_REG_INDEX(tev_combiner_buffer_input): + case PICA_REG_INDEX(texturing.tev_stage0.color_source1): + case PICA_REG_INDEX(texturing.tev_stage0.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage0.color_op): + case PICA_REG_INDEX(texturing.tev_stage0.color_scale): + case PICA_REG_INDEX(texturing.tev_stage1.color_source1): + case PICA_REG_INDEX(texturing.tev_stage1.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage1.color_op): + case PICA_REG_INDEX(texturing.tev_stage1.color_scale): + case PICA_REG_INDEX(texturing.tev_stage2.color_source1): + case PICA_REG_INDEX(texturing.tev_stage2.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage2.color_op): + case PICA_REG_INDEX(texturing.tev_stage2.color_scale): + case PICA_REG_INDEX(texturing.tev_stage3.color_source1): + case PICA_REG_INDEX(texturing.tev_stage3.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage3.color_op): + case PICA_REG_INDEX(texturing.tev_stage3.color_scale): + case PICA_REG_INDEX(texturing.tev_stage4.color_source1): + case PICA_REG_INDEX(texturing.tev_stage4.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage4.color_op): + case PICA_REG_INDEX(texturing.tev_stage4.color_scale): + case PICA_REG_INDEX(texturing.tev_stage5.color_source1): + case PICA_REG_INDEX(texturing.tev_stage5.color_modifier1): + case PICA_REG_INDEX(texturing.tev_stage5.color_op): + case PICA_REG_INDEX(texturing.tev_stage5.color_scale): + case PICA_REG_INDEX(texturing.tev_combiner_buffer_input): shader_dirty = true; break; - case PICA_REG_INDEX(tev_stage0.const_r): - SyncTevConstColor(0, regs.tev_stage0); + case PICA_REG_INDEX(texturing.tev_stage0.const_r): + SyncTevConstColor(0, regs.texturing.tev_stage0); break; - case PICA_REG_INDEX(tev_stage1.const_r): - SyncTevConstColor(1, regs.tev_stage1); + case PICA_REG_INDEX(texturing.tev_stage1.const_r): + SyncTevConstColor(1, regs.texturing.tev_stage1); break; - case PICA_REG_INDEX(tev_stage2.const_r): - SyncTevConstColor(2, regs.tev_stage2); + case PICA_REG_INDEX(texturing.tev_stage2.const_r): + SyncTevConstColor(2, regs.texturing.tev_stage2); break; - case PICA_REG_INDEX(tev_stage3.const_r): - SyncTevConstColor(3, regs.tev_stage3); + case PICA_REG_INDEX(texturing.tev_stage3.const_r): + SyncTevConstColor(3, regs.texturing.tev_stage3); break; - case PICA_REG_INDEX(tev_stage4.const_r): - SyncTevConstColor(4, regs.tev_stage4); + case PICA_REG_INDEX(texturing.tev_stage4.const_r): + SyncTevConstColor(4, regs.texturing.tev_stage4); break; - case PICA_REG_INDEX(tev_stage5.const_r): - SyncTevConstColor(5, regs.tev_stage5); + case PICA_REG_INDEX(texturing.tev_stage5.const_r): + SyncTevConstColor(5, regs.texturing.tev_stage5); break; // TEV combiner buffer color - case PICA_REG_INDEX(tev_combiner_buffer_color): + case PICA_REG_INDEX(texturing.tev_combiner_buffer_color): SyncCombinerColor(); break; // Fragment lighting switches case PICA_REG_INDEX(lighting.disable): - case PICA_REG_INDEX(lighting.num_lights): + case PICA_REG_INDEX(lighting.max_light_index): case PICA_REG_INDEX(lighting.config0): case PICA_REG_INDEX(lighting.config1): case PICA_REG_INDEX(lighting.abs_lut_input): @@ -716,8 +712,6 @@ void RasterizerOpenGL::FlushAndInvalidateRegion(PAddr addr, u32 size) { bool RasterizerOpenGL::AccelerateDisplayTransfer(const GPU::Regs::DisplayTransferConfig& config) { MICROPROFILE_SCOPE(OpenGL_Blits); - using PixelFormat = CachedSurface::PixelFormat; - using SurfaceType = CachedSurface::SurfaceType; CachedSurface src_params; src_params.addr = config.GetPhysicalInputAddress(); @@ -978,7 +972,9 @@ void RasterizerOpenGL::SamplerInfo::Create() { // Other attributes have correct defaults } -void RasterizerOpenGL::SamplerInfo::SyncWithConfig(const Pica::Regs::TextureConfig& config) { +void RasterizerOpenGL::SamplerInfo::SyncWithConfig( + const Pica::TexturingRegs::TextureConfig& config) { + GLuint s = sampler.handle; if (mag_filter != config.mag_filter) { @@ -1075,67 +1071,69 @@ void RasterizerOpenGL::SetShader() { current_shader = shader_cache.emplace(config, std::move(shader)).first->second.get(); - unsigned int block_index = - glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); - GLint block_size; - glGetActiveUniformBlockiv(current_shader->shader.handle, block_index, - GL_UNIFORM_BLOCK_DATA_SIZE, &block_size); - ASSERT_MSG(block_size == sizeof(UniformData), - "Uniform block size did not match! Got %d, expected %zu", - static_cast<int>(block_size), sizeof(UniformData)); - glUniformBlockBinding(current_shader->shader.handle, block_index, 0); - - // Update uniforms - SyncDepthScale(); - SyncDepthOffset(); - SyncAlphaTest(); - SyncCombinerColor(); - auto& tev_stages = Pica::g_state.regs.GetTevStages(); - for (int index = 0; index < tev_stages.size(); ++index) - SyncTevConstColor(index, tev_stages[index]); + GLuint block_index = glGetUniformBlockIndex(current_shader->shader.handle, "shader_data"); + if (block_index != GL_INVALID_INDEX) { + GLint block_size; + glGetActiveUniformBlockiv(current_shader->shader.handle, block_index, + GL_UNIFORM_BLOCK_DATA_SIZE, &block_size); + ASSERT_MSG(block_size == sizeof(UniformData), + "Uniform block size did not match! Got %d, expected %zu", + static_cast<int>(block_size), sizeof(UniformData)); + glUniformBlockBinding(current_shader->shader.handle, block_index, 0); + + // Update uniforms + SyncDepthScale(); + SyncDepthOffset(); + SyncAlphaTest(); + SyncCombinerColor(); + auto& tev_stages = Pica::g_state.regs.texturing.GetTevStages(); + for (int index = 0; index < tev_stages.size(); ++index) + SyncTevConstColor(index, tev_stages[index]); + + SyncGlobalAmbient(); + for (int light_index = 0; light_index < 8; light_index++) { + SyncLightSpecular0(light_index); + SyncLightSpecular1(light_index); + SyncLightDiffuse(light_index); + SyncLightAmbient(light_index); + SyncLightPosition(light_index); + SyncLightDistanceAttenuationBias(light_index); + SyncLightDistanceAttenuationScale(light_index); + } - SyncGlobalAmbient(); - for (int light_index = 0; light_index < 8; light_index++) { - SyncLightSpecular0(light_index); - SyncLightSpecular1(light_index); - SyncLightDiffuse(light_index); - SyncLightAmbient(light_index); - SyncLightPosition(light_index); - SyncLightDistanceAttenuationBias(light_index); - SyncLightDistanceAttenuationScale(light_index); + SyncFogColor(); } - - SyncFogColor(); } } void RasterizerOpenGL::SyncCullMode() { const auto& regs = Pica::g_state.regs; - switch (regs.cull_mode) { - case Pica::Regs::CullMode::KeepAll: + switch (regs.rasterizer.cull_mode) { + case Pica::RasterizerRegs::CullMode::KeepAll: state.cull.enabled = false; break; - case Pica::Regs::CullMode::KeepClockWise: + case Pica::RasterizerRegs::CullMode::KeepClockWise: state.cull.enabled = true; state.cull.front_face = GL_CW; break; - case Pica::Regs::CullMode::KeepCounterClockWise: + case Pica::RasterizerRegs::CullMode::KeepCounterClockWise: state.cull.enabled = true; state.cull.front_face = GL_CCW; break; default: - LOG_CRITICAL(Render_OpenGL, "Unknown cull mode %d", regs.cull_mode.Value()); + LOG_CRITICAL(Render_OpenGL, "Unknown cull mode %d", regs.rasterizer.cull_mode.Value()); UNIMPLEMENTED(); break; } } void RasterizerOpenGL::SyncDepthScale() { - float depth_scale = Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_range).ToFloat32(); + 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; @@ -1144,7 +1142,7 @@ void RasterizerOpenGL::SyncDepthScale() { void RasterizerOpenGL::SyncDepthOffset() { float depth_offset = - Pica::float24::FromRaw(Pica::g_state.regs.viewport_depth_near_plane).ToFloat32(); + 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; @@ -1152,25 +1150,28 @@ void RasterizerOpenGL::SyncDepthOffset() { } void RasterizerOpenGL::SyncBlendEnabled() { - state.blend.enabled = (Pica::g_state.regs.output_merger.alphablend_enable == 1); + state.blend.enabled = (Pica::g_state.regs.framebuffer.output_merger.alphablend_enable == 1); } void RasterizerOpenGL::SyncBlendFuncs() { const auto& regs = Pica::g_state.regs; state.blend.rgb_equation = - PicaToGL::BlendEquation(regs.output_merger.alpha_blending.blend_equation_rgb); + PicaToGL::BlendEquation(regs.framebuffer.output_merger.alpha_blending.blend_equation_rgb); state.blend.a_equation = - PicaToGL::BlendEquation(regs.output_merger.alpha_blending.blend_equation_a); + PicaToGL::BlendEquation(regs.framebuffer.output_merger.alpha_blending.blend_equation_a); state.blend.src_rgb_func = - PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_rgb); + PicaToGL::BlendFunc(regs.framebuffer.output_merger.alpha_blending.factor_source_rgb); state.blend.dst_rgb_func = - PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_rgb); - state.blend.src_a_func = PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_source_a); - state.blend.dst_a_func = PicaToGL::BlendFunc(regs.output_merger.alpha_blending.factor_dest_a); + PicaToGL::BlendFunc(regs.framebuffer.output_merger.alpha_blending.factor_dest_rgb); + state.blend.src_a_func = + PicaToGL::BlendFunc(regs.framebuffer.output_merger.alpha_blending.factor_source_a); + state.blend.dst_a_func = + PicaToGL::BlendFunc(regs.framebuffer.output_merger.alpha_blending.factor_dest_a); } void RasterizerOpenGL::SyncBlendColor() { - auto blend_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.output_merger.blend_const.raw); + auto blend_color = + PicaToGL::ColorRGBA8(Pica::g_state.regs.framebuffer.output_merger.blend_const.raw); state.blend.color.red = blend_color[0]; state.blend.color.green = blend_color[1]; state.blend.color.blue = blend_color[2]; @@ -1180,8 +1181,8 @@ void RasterizerOpenGL::SyncBlendColor() { void RasterizerOpenGL::SyncFogColor() { const auto& regs = Pica::g_state.regs; uniform_block_data.data.fog_color = { - regs.fog_color.r.Value() / 255.0f, regs.fog_color.g.Value() / 255.0f, - regs.fog_color.b.Value() / 255.0f, + 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; } @@ -1202,70 +1203,78 @@ void RasterizerOpenGL::SyncFogLUT() { void RasterizerOpenGL::SyncAlphaTest() { const auto& regs = Pica::g_state.regs; - if (regs.output_merger.alpha_test.ref != uniform_block_data.data.alphatest_ref) { - uniform_block_data.data.alphatest_ref = regs.output_merger.alpha_test.ref; + 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() { - state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.output_merger.logic_op); + state.logic_op = PicaToGL::LogicOp(Pica::g_state.regs.framebuffer.output_merger.logic_op); } void RasterizerOpenGL::SyncColorWriteMask() { const auto& regs = Pica::g_state.regs; auto IsColorWriteEnabled = [&](u32 value) { - return (regs.framebuffer.allow_color_write != 0 && value != 0) ? GL_TRUE : GL_FALSE; + return (regs.framebuffer.framebuffer.allow_color_write != 0 && value != 0) ? GL_TRUE + : GL_FALSE; }; - state.color_mask.red_enabled = IsColorWriteEnabled(regs.output_merger.red_enable); - state.color_mask.green_enabled = IsColorWriteEnabled(regs.output_merger.green_enable); - state.color_mask.blue_enabled = IsColorWriteEnabled(regs.output_merger.blue_enable); - state.color_mask.alpha_enabled = IsColorWriteEnabled(regs.output_merger.alpha_enable); + state.color_mask.red_enabled = IsColorWriteEnabled(regs.framebuffer.output_merger.red_enable); + state.color_mask.green_enabled = + IsColorWriteEnabled(regs.framebuffer.output_merger.green_enable); + state.color_mask.blue_enabled = IsColorWriteEnabled(regs.framebuffer.output_merger.blue_enable); + state.color_mask.alpha_enabled = + IsColorWriteEnabled(regs.framebuffer.output_merger.alpha_enable); } void RasterizerOpenGL::SyncStencilWriteMask() { const auto& regs = Pica::g_state.regs; - state.stencil.write_mask = (regs.framebuffer.allow_depth_stencil_write != 0) - ? static_cast<GLuint>(regs.output_merger.stencil_test.write_mask) - : 0; + state.stencil.write_mask = + (regs.framebuffer.framebuffer.allow_depth_stencil_write != 0) + ? static_cast<GLuint>(regs.framebuffer.output_merger.stencil_test.write_mask) + : 0; } void RasterizerOpenGL::SyncDepthWriteMask() { const auto& regs = Pica::g_state.regs; - state.depth.write_mask = - (regs.framebuffer.allow_depth_stencil_write != 0 && regs.output_merger.depth_write_enable) - ? GL_TRUE - : GL_FALSE; + state.depth.write_mask = (regs.framebuffer.framebuffer.allow_depth_stencil_write != 0 && + regs.framebuffer.output_merger.depth_write_enable) + ? GL_TRUE + : GL_FALSE; } void RasterizerOpenGL::SyncStencilTest() { const auto& regs = Pica::g_state.regs; - state.stencil.test_enabled = regs.output_merger.stencil_test.enable && - regs.framebuffer.depth_format == Pica::Regs::DepthFormat::D24S8; - state.stencil.test_func = PicaToGL::CompareFunc(regs.output_merger.stencil_test.func); - state.stencil.test_ref = regs.output_merger.stencil_test.reference_value; - state.stencil.test_mask = regs.output_merger.stencil_test.input_mask; + state.stencil.test_enabled = + regs.framebuffer.output_merger.stencil_test.enable && + regs.framebuffer.framebuffer.depth_format == Pica::FramebufferRegs::DepthFormat::D24S8; + state.stencil.test_func = + PicaToGL::CompareFunc(regs.framebuffer.output_merger.stencil_test.func); + state.stencil.test_ref = regs.framebuffer.output_merger.stencil_test.reference_value; + state.stencil.test_mask = regs.framebuffer.output_merger.stencil_test.input_mask; state.stencil.action_stencil_fail = - PicaToGL::StencilOp(regs.output_merger.stencil_test.action_stencil_fail); + PicaToGL::StencilOp(regs.framebuffer.output_merger.stencil_test.action_stencil_fail); state.stencil.action_depth_fail = - PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_fail); + PicaToGL::StencilOp(regs.framebuffer.output_merger.stencil_test.action_depth_fail); state.stencil.action_depth_pass = - PicaToGL::StencilOp(regs.output_merger.stencil_test.action_depth_pass); + PicaToGL::StencilOp(regs.framebuffer.output_merger.stencil_test.action_depth_pass); } void RasterizerOpenGL::SyncDepthTest() { const auto& regs = Pica::g_state.regs; - state.depth.test_enabled = - regs.output_merger.depth_test_enable == 1 || regs.output_merger.depth_write_enable == 1; - state.depth.test_func = regs.output_merger.depth_test_enable == 1 - ? PicaToGL::CompareFunc(regs.output_merger.depth_test_func) - : GL_ALWAYS; + state.depth.test_enabled = regs.framebuffer.output_merger.depth_test_enable == 1 || + regs.framebuffer.output_merger.depth_write_enable == 1; + state.depth.test_func = + regs.framebuffer.output_merger.depth_test_enable == 1 + ? PicaToGL::CompareFunc(regs.framebuffer.output_merger.depth_test_func) + : GL_ALWAYS; } void RasterizerOpenGL::SyncCombinerColor() { - auto combiner_color = PicaToGL::ColorRGBA8(Pica::g_state.regs.tev_combiner_buffer_color.raw); + 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; @@ -1273,7 +1282,7 @@ void RasterizerOpenGL::SyncCombinerColor() { } void RasterizerOpenGL::SyncTevConstColor(int stage_index, - const Pica::Regs::TevStageConfig& tev_stage) { + const Pica::TexturingRegs::TevStageConfig& tev_stage) { auto const_color = PicaToGL::ColorRGBA8(tev_stage.const_color); if (const_color != uniform_block_data.data.const_color[stage_index]) { uniform_block_data.data.const_color[stage_index] = const_color; diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h index cc3e4bed5..ecf737438 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.h +++ b/src/video_core/renderer_opengl/gl_rasterizer.h @@ -16,10 +16,13 @@ #include "common/hash.h" #include "common/vector_math.h" #include "core/hw/gpu.h" -#include "video_core/pica.h" #include "video_core/pica_state.h" #include "video_core/pica_types.h" #include "video_core/rasterizer_interface.h" +#include "video_core/regs_framebuffer.h" +#include "video_core/regs_lighting.h" +#include "video_core/regs_rasterizer.h" +#include "video_core/regs_texturing.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" #include "video_core/renderer_opengl/gl_resource_manager.h" #include "video_core/renderer_opengl/gl_state.h" @@ -52,20 +55,20 @@ union PicaShaderConfig { const auto& regs = Pica::g_state.regs; - state.scissor_test_mode = regs.scissor_test.mode; + state.scissor_test_mode = regs.rasterizer.scissor_test.mode; - state.depthmap_enable = regs.depthmap_enable; + state.depthmap_enable = regs.rasterizer.depthmap_enable; - state.alpha_test_func = regs.output_merger.alpha_test.enable - ? regs.output_merger.alpha_test.func.Value() - : Pica::Regs::CompareFunc::Always; + state.alpha_test_func = regs.framebuffer.output_merger.alpha_test.enable + ? regs.framebuffer.output_merger.alpha_test.func.Value() + : Pica::FramebufferRegs::CompareFunc::Always; - state.texture0_type = regs.texture0.type; + state.texture0_type = regs.texturing.texture0.type; // Copy relevant tev stages fields. // We don't sync const_color here because of the high variance, it is a // shader uniform instead. - const auto& tev_stages = regs.GetTevStages(); + const auto& tev_stages = regs.texturing.GetTevStages(); DEBUG_ASSERT(state.tev_stages.size() == tev_stages.size()); for (size_t i = 0; i < tev_stages.size(); i++) { const auto& tev_stage = tev_stages[i]; @@ -75,16 +78,17 @@ union PicaShaderConfig { state.tev_stages[i].scales_raw = tev_stage.scales_raw; } - state.fog_mode = regs.fog_mode; - state.fog_flip = regs.fog_flip != 0; + state.fog_mode = regs.texturing.fog_mode; + state.fog_flip = regs.texturing.fog_flip != 0; - state.combiner_buffer_input = regs.tev_combiner_buffer_input.update_mask_rgb.Value() | - regs.tev_combiner_buffer_input.update_mask_a.Value() << 4; + state.combiner_buffer_input = + regs.texturing.tev_combiner_buffer_input.update_mask_rgb.Value() | + regs.texturing.tev_combiner_buffer_input.update_mask_a.Value() << 4; // Fragment lighting state.lighting.enable = !regs.lighting.disable; - state.lighting.src_num = regs.lighting.num_lights + 1; + state.lighting.src_num = regs.lighting.max_light_index + 1; for (unsigned light_index = 0; light_index < state.lighting.src_num; ++light_index) { unsigned num = regs.lighting.light_enable.GetNum(light_index); @@ -159,8 +163,8 @@ union PicaShaderConfig { u32 modifiers_raw; u32 ops_raw; u32 scales_raw; - explicit operator Pica::Regs::TevStageConfig() const noexcept { - Pica::Regs::TevStageConfig stage; + explicit operator Pica::TexturingRegs::TevStageConfig() const noexcept { + Pica::TexturingRegs::TevStageConfig stage; stage.sources_raw = sources_raw; stage.modifiers_raw = modifiers_raw; stage.ops_raw = ops_raw; @@ -171,14 +175,14 @@ union PicaShaderConfig { }; struct State { - Pica::Regs::CompareFunc alpha_test_func; - Pica::Regs::ScissorMode scissor_test_mode; - Pica::Regs::TextureConfig::TextureType texture0_type; + Pica::FramebufferRegs::CompareFunc alpha_test_func; + Pica::RasterizerRegs::ScissorMode scissor_test_mode; + Pica::TexturingRegs::TextureConfig::TextureType texture0_type; std::array<TevStageConfigRaw, 6> tev_stages; u8 combiner_buffer_input; - Pica::Regs::DepthBuffering depthmap_enable; - Pica::Regs::FogMode fog_mode; + Pica::RasterizerRegs::DepthBuffering depthmap_enable; + Pica::TexturingRegs::FogMode fog_mode; bool fog_flip; struct { @@ -191,18 +195,18 @@ union PicaShaderConfig { bool enable; unsigned src_num; - Pica::Regs::LightingBumpMode bump_mode; + Pica::LightingRegs::LightingBumpMode bump_mode; unsigned bump_selector; bool bump_renorm; bool clamp_highlights; - Pica::Regs::LightingConfig config; - Pica::Regs::LightingFresnelSelector fresnel_selector; + Pica::LightingRegs::LightingConfig config; + Pica::LightingRegs::LightingFresnelSelector fresnel_selector; struct { bool enable; bool abs_input; - Pica::Regs::LightingLutInput type; + Pica::LightingRegs::LightingLutInput type; float scale; } lut_d0, lut_d1, lut_fr, lut_rr, lut_rg, lut_rb; } lighting; @@ -251,7 +255,7 @@ public: private: struct SamplerInfo { - using TextureConfig = Pica::Regs::TextureConfig; + using TextureConfig = Pica::TexturingRegs::TextureConfig; OGLSampler sampler; @@ -398,7 +402,7 @@ private: void SyncCombinerColor(); /// Syncs the TEV constant color to match the PICA register - void SyncTevConstColor(int tev_index, const Pica::Regs::TevStageConfig& tev_stage); + void SyncTevConstColor(int tev_index, const Pica::TexturingRegs::TevStageConfig& tev_stage); /// Syncs the lighting global ambient color to match the PICA register void SyncGlobalAmbient(); diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index ef3b06a7b..456443e86 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp @@ -17,10 +17,11 @@ #include "common/vector_math.h" #include "core/frontend/emu_window.h" #include "core/memory.h" -#include "video_core/debug_utils/debug_utils.h" +#include "core/settings.h" #include "video_core/pica_state.h" #include "video_core/renderer_opengl/gl_rasterizer_cache.h" #include "video_core/renderer_opengl/gl_state.h" +#include "video_core/texture/texture_decode.h" #include "video_core/utils.h" #include "video_core/video_core.h" @@ -172,7 +173,6 @@ bool RasterizerCacheOpenGL::TryBlitSurfaces(CachedSurface* src_surface, const MathUtil::Rectangle<int>& src_rect, CachedSurface* dst_surface, const MathUtil::Rectangle<int>& dst_rect) { - using SurfaceType = CachedSurface::SurfaceType; if (!CachedSurface::CheckFormatsBlittable(src_surface->pixel_format, dst_surface->pixel_format)) { @@ -340,17 +340,16 @@ CachedSurface* RasterizerCacheOpenGL::GetSurface(const CachedSurface& params, bo std::vector<Math::Vec4<u8>> tex_buffer(params.width * params.height); - Pica::DebugUtils::TextureInfo tex_info; + Pica::Texture::TextureInfo tex_info; tex_info.width = params.width; tex_info.height = params.height; - tex_info.stride = - params.width * CachedSurface::GetFormatBpp(params.pixel_format) / 8; - tex_info.format = (Pica::Regs::TextureFormat)params.pixel_format; + tex_info.format = (Pica::TexturingRegs::TextureFormat)params.pixel_format; + tex_info.SetDefaultStride(); tex_info.physical_address = params.addr; for (unsigned y = 0; y < params.height; ++y) { for (unsigned x = 0; x < params.width; ++x) { - tex_buffer[x + params.width * y] = Pica::DebugUtils::LookupTexture( + tex_buffer[x + params.width * y] = Pica::Texture::LookupTexture( texture_src_data, x, params.height - 1 - y, tex_info); } } @@ -512,9 +511,10 @@ CachedSurface* RasterizerCacheOpenGL::GetSurfaceRect(const CachedSurface& params } CachedSurface* RasterizerCacheOpenGL::GetTextureSurface( - const Pica::Regs::FullTextureConfig& config) { - Pica::DebugUtils::TextureInfo info = - Pica::DebugUtils::TextureInfo::FromPicaRegister(config.config, config.format); + const Pica::TexturingRegs::FullTextureConfig& config) { + + Pica::Texture::TextureInfo info = + Pica::Texture::TextureInfo::FromPicaRegister(config.config, config.format); CachedSurface params; params.addr = info.physical_address; @@ -526,7 +526,9 @@ CachedSurface* RasterizerCacheOpenGL::GetTextureSurface( } std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> -RasterizerCacheOpenGL::GetFramebufferSurfaces(const Pica::Regs::FramebufferConfig& config) { +RasterizerCacheOpenGL::GetFramebufferSurfaces( + const Pica::FramebufferRegs::FramebufferConfig& config) { + const auto& regs = Pica::g_state.regs; // Make sur that framebuffers don't overlap if both color and depth are being used @@ -538,11 +540,12 @@ RasterizerCacheOpenGL::GetFramebufferSurfaces(const Pica::Regs::FramebufferConfi config.GetColorBufferPhysicalAddress(), fb_area * GPU::Regs::BytesPerPixel(GPU::Regs::PixelFormat(config.color_format.Value())), config.GetDepthBufferPhysicalAddress(), - fb_area * Pica::Regs::BytesPerDepthPixel(config.depth_format)); + fb_area * Pica::FramebufferRegs::BytesPerDepthPixel(config.depth_format)); bool using_color_fb = config.GetColorBufferPhysicalAddress() != 0; - bool using_depth_fb = config.GetDepthBufferPhysicalAddress() != 0 && - (regs.output_merger.depth_test_enable || - regs.output_merger.depth_write_enable || !framebuffers_overlap); + bool using_depth_fb = + config.GetDepthBufferPhysicalAddress() != 0 && + (regs.framebuffer.output_merger.depth_test_enable || + regs.framebuffer.output_merger.depth_write_enable || !framebuffers_overlap); if (framebuffers_overlap && using_color_fb && using_depth_fb) { LOG_CRITICAL(Render_OpenGL, "Color and depth framebuffer memory regions overlap; " diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index b50e8292b..aea20c693 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h @@ -8,13 +8,21 @@ #include <memory> #include <set> #include <tuple> +#ifdef __GNUC__ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-local-typedef" +#endif #include <boost/icl/interval_map.hpp> +#ifdef __GNUC__ +#pragma GCC diagnostic pop +#endif #include <glad/glad.h> #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" #include "core/hw/gpu.h" -#include "video_core/pica.h" +#include "video_core/regs_framebuffer.h" +#include "video_core/regs_texturing.h" #include "video_core/renderer_opengl/gl_resource_manager.h" namespace MathUtil { @@ -89,15 +97,15 @@ struct CachedSurface { return bpp_table[(unsigned int)format]; } - static PixelFormat PixelFormatFromTextureFormat(Pica::Regs::TextureFormat format) { + static PixelFormat PixelFormatFromTextureFormat(Pica::TexturingRegs::TextureFormat format) { return ((unsigned int)format < 14) ? (PixelFormat)format : PixelFormat::Invalid; } - static PixelFormat PixelFormatFromColorFormat(Pica::Regs::ColorFormat format) { + static PixelFormat PixelFormatFromColorFormat(Pica::FramebufferRegs::ColorFormat format) { return ((unsigned int)format < 5) ? (PixelFormat)format : PixelFormat::Invalid; } - static PixelFormat PixelFormatFromDepthFormat(Pica::Regs::DepthFormat format) { + static PixelFormat PixelFormatFromDepthFormat(Pica::FramebufferRegs::DepthFormat format) { return ((unsigned int)format < 4) ? (PixelFormat)((unsigned int)format + 14) : PixelFormat::Invalid; } @@ -205,12 +213,12 @@ public: bool load_if_create, MathUtil::Rectangle<int>& out_rect); /// Gets a surface based on the texture configuration - CachedSurface* GetTextureSurface(const Pica::Regs::FullTextureConfig& config); + CachedSurface* GetTextureSurface(const Pica::TexturingRegs::FullTextureConfig& config); /// Gets the color and depth surfaces and rect (resolution scaled) based on the framebuffer /// configuration std::tuple<CachedSurface*, CachedSurface*, MathUtil::Rectangle<int>> GetFramebufferSurfaces( - const Pica::Regs::FramebufferConfig& config); + const Pica::FramebufferRegs::FramebufferConfig& config); /// Attempt to get a surface that exactly matches the fill region and format CachedSurface* TryGetFillSurface(const GPU::Regs::MemoryFillConfig& config); diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp index 4c4f98ac9..7abdeba05 100644 --- a/src/video_core/renderer_opengl/gl_shader_gen.cpp +++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp @@ -7,13 +7,19 @@ #include "common/assert.h" #include "common/bit_field.h" #include "common/logging/log.h" -#include "video_core/pica.h" +#include "video_core/regs_framebuffer.h" +#include "video_core/regs_lighting.h" +#include "video_core/regs_rasterizer.h" +#include "video_core/regs_texturing.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_shader_gen.h" #include "video_core/renderer_opengl/gl_shader_util.h" -using Pica::Regs; -using TevStageConfig = Regs::TevStageConfig; +using Pica::FramebufferRegs; +using Pica::LightingRegs; +using Pica::RasterizerRegs; +using Pica::TexturingRegs; +using TevStageConfig = TexturingRegs::TevStageConfig; namespace GLShader { @@ -46,10 +52,10 @@ static void AppendSource(std::string& out, const PicaShaderConfig& config, case Source::Texture0: // Only unit 0 respects the texturing type (according to 3DBrew) switch (state.texture0_type) { - case Pica::Regs::TextureConfig::Texture2D: + case TexturingRegs::TextureConfig::Texture2D: out += "texture(tex[0], texcoord[0])"; break; - case Pica::Regs::TextureConfig::Projection2D: + case TexturingRegs::TextureConfig::Projection2D: out += "textureProj(tex[0], vec3(texcoord[0], texcoord0_w))"; break; default: @@ -276,8 +282,8 @@ static void AppendAlphaCombiner(std::string& out, TevStageConfig::Operation oper } /// Writes the if-statement condition used to evaluate alpha testing -static void AppendAlphaTestCondition(std::string& out, Regs::CompareFunc func) { - using CompareFunc = Regs::CompareFunc; +static void AppendAlphaTestCondition(std::string& out, FramebufferRegs::CompareFunc func) { + using CompareFunc = FramebufferRegs::CompareFunc; switch (func) { case CompareFunc::Never: out += "true"; @@ -307,7 +313,7 @@ static void AppendAlphaTestCondition(std::string& out, Regs::CompareFunc func) { /// Writes the code to emulate the specified TEV stage static void WriteTevStage(std::string& out, const PicaShaderConfig& config, unsigned index) { const auto stage = - static_cast<const Pica::Regs::TevStageConfig>(config.state.tev_stages[index]); + static_cast<const TexturingRegs::TevStageConfig>(config.state.tev_stages[index]); if (!IsPassThroughTevStage(stage)) { std::string index_name = std::to_string(index); @@ -364,7 +370,7 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { "vec3 refl_value = vec3(0.0);\n"; // Compute fragment normals - if (lighting.bump_mode == Pica::Regs::LightingBumpMode::NormalMap) { + if (lighting.bump_mode == LightingRegs::LightingBumpMode::NormalMap) { // Bump mapping is enabled using a normal map, read perturbation vector from the selected // texture std::string bump_selector = std::to_string(lighting.bump_selector); @@ -378,7 +384,7 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { "(1.0 - (surface_normal.x*surface_normal.x + surface_normal.y*surface_normal.y))"; out += "surface_normal.z = sqrt(max(" + val + ", 0.0));\n"; } - } else if (lighting.bump_mode == Pica::Regs::LightingBumpMode::TangentMap) { + } else if (lighting.bump_mode == LightingRegs::LightingBumpMode::TangentMap) { // Bump mapping is enabled using a tangent map LOG_CRITICAL(HW_GPU, "unimplemented bump mapping mode (tangent mapping)"); UNIMPLEMENTED(); @@ -392,23 +398,24 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { out += "vec3 normal = normalize(quaternion_rotate(normquat, surface_normal));\n"; // Gets the index into the specified lookup table for specular lighting - auto GetLutIndex = [&lighting](unsigned light_num, Regs::LightingLutInput input, bool abs) { + auto GetLutIndex = [&lighting](unsigned light_num, LightingRegs::LightingLutInput input, + bool abs) { const std::string half_angle = "normalize(normalize(view) + light_vector)"; std::string index; switch (input) { - case Regs::LightingLutInput::NH: + case LightingRegs::LightingLutInput::NH: index = "dot(normal, " + half_angle + ")"; break; - case Regs::LightingLutInput::VH: + case LightingRegs::LightingLutInput::VH: index = std::string("dot(normalize(view), " + half_angle + ")"); break; - case Regs::LightingLutInput::NV: + case LightingRegs::LightingLutInput::NV: index = std::string("dot(normal, normalize(view))"); break; - case Regs::LightingLutInput::LN: + case LightingRegs::LightingLutInput::LN: index = std::string("dot(light_vector, normal)"); break; @@ -432,7 +439,7 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { }; // Gets the lighting lookup table value given the specified sampler and index - auto GetLutValue = [](Regs::LightingSampler sampler, std::string lut_index) { + auto GetLutValue = [](LightingRegs::LightingSampler sampler, std::string lut_index) { return std::string("texture(lut[" + std::to_string((unsigned)sampler / 4) + "], " + lut_index + ")[" + std::to_string((unsigned)sampler & 3) + "]"); }; @@ -461,8 +468,8 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { light_src + ".position) + " + light_src + ".dist_atten_bias)"; index = "(OFFSET_256 + SCALE_256 * clamp(" + index + ", 0.0, 1.0))"; const unsigned lut_num = - ((unsigned)Regs::LightingSampler::DistanceAttenuation + light_config.num); - dist_atten = GetLutValue((Regs::LightingSampler)lut_num, index); + ((unsigned)LightingRegs::LightingSampler::DistanceAttenuation + light_config.num); + dist_atten = GetLutValue((LightingRegs::LightingSampler)lut_num, index); } // If enabled, clamp specular component if lighting result is negative @@ -472,24 +479,24 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { // Specular 0 component std::string d0_lut_value = "1.0"; if (lighting.lut_d0.enable && - Pica::Regs::IsLightingSamplerSupported(lighting.config, - Pica::Regs::LightingSampler::Distribution0)) { + LightingRegs::IsLightingSamplerSupported( + lighting.config, LightingRegs::LightingSampler::Distribution0)) { // Lookup specular "distribution 0" LUT value std::string index = GetLutIndex(light_config.num, lighting.lut_d0.type, lighting.lut_d0.abs_input); d0_lut_value = "(" + std::to_string(lighting.lut_d0.scale) + " * " + - GetLutValue(Regs::LightingSampler::Distribution0, index) + ")"; + GetLutValue(LightingRegs::LightingSampler::Distribution0, index) + ")"; } std::string specular_0 = "(" + d0_lut_value + " * " + light_src + ".specular_0)"; // If enabled, lookup ReflectRed value, otherwise, 1.0 is used if (lighting.lut_rr.enable && - Pica::Regs::IsLightingSamplerSupported(lighting.config, - Pica::Regs::LightingSampler::ReflectRed)) { + LightingRegs::IsLightingSamplerSupported(lighting.config, + LightingRegs::LightingSampler::ReflectRed)) { std::string index = GetLutIndex(light_config.num, lighting.lut_rr.type, lighting.lut_rr.abs_input); std::string value = "(" + std::to_string(lighting.lut_rr.scale) + " * " + - GetLutValue(Regs::LightingSampler::ReflectRed, index) + ")"; + GetLutValue(LightingRegs::LightingSampler::ReflectRed, index) + ")"; out += "refl_value.r = " + value + ";\n"; } else { out += "refl_value.r = 1.0;\n"; @@ -497,12 +504,13 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { // If enabled, lookup ReflectGreen value, otherwise, ReflectRed value is used if (lighting.lut_rg.enable && - Pica::Regs::IsLightingSamplerSupported(lighting.config, - Pica::Regs::LightingSampler::ReflectGreen)) { + LightingRegs::IsLightingSamplerSupported(lighting.config, + LightingRegs::LightingSampler::ReflectGreen)) { std::string index = GetLutIndex(light_config.num, lighting.lut_rg.type, lighting.lut_rg.abs_input); std::string value = "(" + std::to_string(lighting.lut_rg.scale) + " * " + - GetLutValue(Regs::LightingSampler::ReflectGreen, index) + ")"; + GetLutValue(LightingRegs::LightingSampler::ReflectGreen, index) + + ")"; out += "refl_value.g = " + value + ";\n"; } else { out += "refl_value.g = refl_value.r;\n"; @@ -510,12 +518,13 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { // If enabled, lookup ReflectBlue value, otherwise, ReflectRed value is used if (lighting.lut_rb.enable && - Pica::Regs::IsLightingSamplerSupported(lighting.config, - Pica::Regs::LightingSampler::ReflectBlue)) { + LightingRegs::IsLightingSamplerSupported(lighting.config, + LightingRegs::LightingSampler::ReflectBlue)) { std::string index = GetLutIndex(light_config.num, lighting.lut_rb.type, lighting.lut_rb.abs_input); std::string value = "(" + std::to_string(lighting.lut_rb.scale) + " * " + - GetLutValue(Regs::LightingSampler::ReflectBlue, index) + ")"; + GetLutValue(LightingRegs::LightingSampler::ReflectBlue, index) + + ")"; out += "refl_value.b = " + value + ";\n"; } else { out += "refl_value.b = refl_value.r;\n"; @@ -524,35 +533,39 @@ static void WriteLighting(std::string& out, const PicaShaderConfig& config) { // Specular 1 component std::string d1_lut_value = "1.0"; if (lighting.lut_d1.enable && - Pica::Regs::IsLightingSamplerSupported(lighting.config, - Pica::Regs::LightingSampler::Distribution1)) { + LightingRegs::IsLightingSamplerSupported( + lighting.config, LightingRegs::LightingSampler::Distribution1)) { // Lookup specular "distribution 1" LUT value std::string index = GetLutIndex(light_config.num, lighting.lut_d1.type, lighting.lut_d1.abs_input); d1_lut_value = "(" + std::to_string(lighting.lut_d1.scale) + " * " + - GetLutValue(Regs::LightingSampler::Distribution1, index) + ")"; + GetLutValue(LightingRegs::LightingSampler::Distribution1, index) + ")"; } std::string specular_1 = "(" + d1_lut_value + " * refl_value * " + light_src + ".specular_1)"; // Fresnel - if (lighting.lut_fr.enable && Pica::Regs::IsLightingSamplerSupported( - lighting.config, Pica::Regs::LightingSampler::Fresnel)) { + if (lighting.lut_fr.enable && + LightingRegs::IsLightingSamplerSupported(lighting.config, + LightingRegs::LightingSampler::Fresnel)) { // Lookup fresnel LUT value std::string index = GetLutIndex(light_config.num, lighting.lut_fr.type, lighting.lut_fr.abs_input); std::string value = "(" + std::to_string(lighting.lut_fr.scale) + " * " + - GetLutValue(Regs::LightingSampler::Fresnel, index) + ")"; + GetLutValue(LightingRegs::LightingSampler::Fresnel, index) + ")"; // Enabled for difffuse lighting alpha component - if (lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::PrimaryAlpha || - lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both) + if (lighting.fresnel_selector == LightingRegs::LightingFresnelSelector::PrimaryAlpha || + lighting.fresnel_selector == LightingRegs::LightingFresnelSelector::Both) { out += "diffuse_sum.a *= " + value + ";\n"; + } // Enabled for the specular lighting alpha component - if (lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::SecondaryAlpha || - lighting.fresnel_selector == Pica::Regs::LightingFresnelSelector::Both) + if (lighting.fresnel_selector == + LightingRegs::LightingFresnelSelector::SecondaryAlpha || + lighting.fresnel_selector == LightingRegs::LightingFresnelSelector::Both) { out += "specular_sum.a *= " + value + ";\n"; + } } // Compute primary fragment color (diffuse lighting) function @@ -633,16 +646,16 @@ vec4 secondary_fragment_color = vec4(0.0); )"; // Do not do any sort of processing if it's obvious we're not going to pass the alpha test - if (state.alpha_test_func == Regs::CompareFunc::Never) { + if (state.alpha_test_func == FramebufferRegs::CompareFunc::Never) { out += "discard; }"; return out; } // Append the scissor test - if (state.scissor_test_mode != Regs::ScissorMode::Disabled) { + if (state.scissor_test_mode != RasterizerRegs::ScissorMode::Disabled) { out += "if ("; // Negate the condition if we have to keep only the pixels outside the scissor box - if (state.scissor_test_mode == Regs::ScissorMode::Include) + if (state.scissor_test_mode == RasterizerRegs::ScissorMode::Include) out += "!"; out += "(gl_FragCoord.x >= scissor_x1 && " "gl_FragCoord.y >= scissor_y1 && " @@ -652,7 +665,7 @@ vec4 secondary_fragment_color = vec4(0.0); out += "float z_over_w = 1.0 - gl_FragCoord.z * 2.0;\n"; out += "float depth = z_over_w * depth_scale + depth_offset;\n"; - if (state.depthmap_enable == Pica::Regs::DepthBuffering::WBuffering) { + if (state.depthmap_enable == RasterizerRegs::DepthBuffering::WBuffering) { out += "depth /= gl_FragCoord.w;\n"; } @@ -666,14 +679,14 @@ vec4 secondary_fragment_color = vec4(0.0); for (size_t index = 0; index < state.tev_stages.size(); ++index) WriteTevStage(out, config, (unsigned)index); - if (state.alpha_test_func != Regs::CompareFunc::Always) { + if (state.alpha_test_func != FramebufferRegs::CompareFunc::Always) { out += "if ("; AppendAlphaTestCondition(out, state.alpha_test_func); out += ") discard;\n"; } // Append fog combiner - if (state.fog_mode == Regs::FogMode::Fog) { + if (state.fog_mode == TexturingRegs::FogMode::Fog) { // Get index into fog LUT if (state.fog_flip) { out += "float fog_index = (1.0 - depth) * 128.0;\n"; diff --git a/src/video_core/renderer_opengl/pica_to_gl.h b/src/video_core/renderer_opengl/pica_to_gl.h index cc49867c8..93d7b0b71 100644 --- a/src/video_core/renderer_opengl/pica_to_gl.h +++ b/src/video_core/renderer_opengl/pica_to_gl.h @@ -12,7 +12,9 @@ #include "common/common_funcs.h" #include "common/common_types.h" #include "common/logging/log.h" -#include "video_core/pica.h" +#include "video_core/regs_framebuffer.h" +#include "video_core/regs_lighting.h" +#include "video_core/regs_texturing.h" using GLvec2 = std::array<GLfloat, 2>; using GLvec3 = std::array<GLfloat, 3>; @@ -20,7 +22,7 @@ using GLvec4 = std::array<GLfloat, 4>; namespace PicaToGL { -inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) { +inline GLenum TextureFilterMode(Pica::TexturingRegs::TextureConfig::TextureFilter mode) { static const GLenum filter_mode_table[] = { GL_NEAREST, // TextureFilter::Nearest GL_LINEAR, // TextureFilter::Linear @@ -47,7 +49,7 @@ inline GLenum TextureFilterMode(Pica::Regs::TextureConfig::TextureFilter mode) { return gl_mode; } -inline GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) { +inline GLenum WrapMode(Pica::TexturingRegs::TextureConfig::WrapMode mode) { static const GLenum wrap_mode_table[] = { GL_CLAMP_TO_EDGE, // WrapMode::ClampToEdge GL_CLAMP_TO_BORDER, // WrapMode::ClampToBorder @@ -76,7 +78,7 @@ inline GLenum WrapMode(Pica::Regs::TextureConfig::WrapMode mode) { return gl_mode; } -inline GLenum BlendEquation(Pica::Regs::BlendEquation equation) { +inline GLenum BlendEquation(Pica::FramebufferRegs::BlendEquation equation) { static const GLenum blend_equation_table[] = { GL_FUNC_ADD, // BlendEquation::Add GL_FUNC_SUBTRACT, // BlendEquation::Subtract @@ -96,7 +98,7 @@ inline GLenum BlendEquation(Pica::Regs::BlendEquation equation) { return blend_equation_table[(unsigned)equation]; } -inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) { +inline GLenum BlendFunc(Pica::FramebufferRegs::BlendFactor factor) { static const GLenum blend_func_table[] = { GL_ZERO, // BlendFactor::Zero GL_ONE, // BlendFactor::One @@ -126,7 +128,7 @@ inline GLenum BlendFunc(Pica::Regs::BlendFactor factor) { return blend_func_table[(unsigned)factor]; } -inline GLenum LogicOp(Pica::Regs::LogicOp op) { +inline GLenum LogicOp(Pica::FramebufferRegs::LogicOp op) { static const GLenum logic_op_table[] = { GL_CLEAR, // Clear GL_AND, // And @@ -157,7 +159,7 @@ inline GLenum LogicOp(Pica::Regs::LogicOp op) { return logic_op_table[(unsigned)op]; } -inline GLenum CompareFunc(Pica::Regs::CompareFunc func) { +inline GLenum CompareFunc(Pica::FramebufferRegs::CompareFunc func) { static const GLenum compare_func_table[] = { GL_NEVER, // CompareFunc::Never GL_ALWAYS, // CompareFunc::Always @@ -180,7 +182,7 @@ inline GLenum CompareFunc(Pica::Regs::CompareFunc func) { return compare_func_table[(unsigned)func]; } -inline GLenum StencilOp(Pica::Regs::StencilAction action) { +inline GLenum StencilOp(Pica::FramebufferRegs::StencilAction action) { static const GLenum stencil_op_table[] = { GL_KEEP, // StencilAction::Keep GL_ZERO, // StencilAction::Zero @@ -210,7 +212,7 @@ inline GLvec4 ColorRGBA8(const u32 color) { }}; } -inline std::array<GLfloat, 3> LightColor(const Pica::Regs::LightColor& color) { +inline std::array<GLfloat, 3> LightColor(const Pica::LightingRegs::LightColor& color) { return {{ color.r / 255.0f, color.g / 255.0f, color.b / 255.0f, }}; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index 2aa90e5c1..e19375466 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -10,8 +10,8 @@ #include "common/assert.h" #include "common/bit_field.h" #include "common/logging/log.h" -#include "common/profiler_reporting.h" -#include "common/synchronized_wrapper.h" +#include "core/core.h" +#include "core/core_timing.h" #include "core/frontend/emu_window.h" #include "core/hw/gpu.h" #include "core/hw/hw.h" @@ -145,21 +145,16 @@ void RendererOpenGL::SwapBuffers() { DrawScreens(); - auto& profiler = Common::Profiling::GetProfilingManager(); - profiler.FinishFrame(); - { - auto aggregator = Common::Profiling::GetTimingResultsAggregator(); - aggregator->AddFrame(profiler.GetPreviousFrameResults()); - } + Core::System::GetInstance().perf_stats.EndSystemFrame(); // Swap buffers render_window->PollEvents(); render_window->SwapBuffers(); - prev_state.Apply(); - - profiler.BeginFrame(); + Core::System::GetInstance().frame_limiter.DoFrameLimiting(CoreTiming::GetGlobalTimeUs()); + Core::System::GetInstance().perf_stats.BeginSystemFrame(); + prev_state.Apply(); RefreshRasterizerSetting(); if (Pica::g_debug_context && Pica::g_debug_context->recorder) { |