diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer.cpp | 19 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/gl_shader_cache.cpp | 6 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.cpp | 124 | ||||
-rw-r--r-- | src/video_core/renderer_opengl/renderer_opengl.h | 15 |
4 files changed, 132 insertions, 32 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index f71a316b6..a44b8c454 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -138,9 +138,6 @@ void RasterizerOpenGL::LoadDiskResources(u64 title_id, std::stop_token stop_load void RasterizerOpenGL::Clear(u32 layer_count) { MICROPROFILE_SCOPE(OpenGL_Clears); - if (!maxwell3d->ShouldExecute()) { - return; - } const auto& regs = maxwell3d->regs; bool use_color{}; @@ -224,16 +221,18 @@ void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { SyncState(); - const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(maxwell3d->regs.draw.topology); + const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); + + const GLenum primitive_mode = MaxwellToGL::PrimitiveTopology(draw_state.topology); BeginTransformFeedback(pipeline, primitive_mode); - const GLuint base_instance = static_cast<GLuint>(maxwell3d->regs.global_base_instance_index); + const GLuint base_instance = static_cast<GLuint>(draw_state.base_instance); const GLsizei num_instances = static_cast<GLsizei>(instance_count); if (is_indexed) { - const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.global_base_vertex_index); - const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.index_buffer.count); + const GLint base_vertex = static_cast<GLint>(draw_state.base_index); + const GLsizei num_vertices = static_cast<GLsizei>(draw_state.index_buffer.count); const GLvoid* const offset = buffer_cache_runtime.IndexOffset(); - const GLenum format = MaxwellToGL::IndexFormat(maxwell3d->regs.index_buffer.format); + const GLenum format = MaxwellToGL::IndexFormat(draw_state.index_buffer.format); if (num_instances == 1 && base_instance == 0 && base_vertex == 0) { glDrawElements(primitive_mode, num_vertices, format, offset); } else if (num_instances == 1 && base_instance == 0) { @@ -252,8 +251,8 @@ void RasterizerOpenGL::Draw(bool is_indexed, u32 instance_count) { base_instance); } } else { - const GLint base_vertex = static_cast<GLint>(maxwell3d->regs.vertex_buffer.first); - const GLsizei num_vertices = static_cast<GLsizei>(maxwell3d->regs.vertex_buffer.count); + const GLint base_vertex = static_cast<GLint>(draw_state.vertex_buffer.first); + const GLsizei num_vertices = static_cast<GLsizei>(draw_state.vertex_buffer.count); if (num_instances == 1 && base_instance == 0) { glDrawArrays(primitive_mode, base_vertex, num_vertices); } else if (base_instance == 0) { diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp index a38060100..a59d0d24e 100644 --- a/src/video_core/renderer_opengl/gl_shader_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp @@ -22,6 +22,7 @@ #include "shader_recompiler/frontend/maxwell/control_flow.h" #include "shader_recompiler/frontend/maxwell/translate_program.h" #include "shader_recompiler/profile.h" +#include "video_core/engines/draw_manager.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/maxwell_3d.h" #include "video_core/memory_manager.h" @@ -327,7 +328,7 @@ GraphicsPipeline* ShaderCache::CurrentGraphicsPipeline() { const auto& regs{maxwell3d->regs}; graphics_key.raw = 0; graphics_key.early_z.Assign(regs.mandated_early_z != 0 ? 1 : 0); - graphics_key.gs_input_topology.Assign(regs.draw.topology.Value()); + graphics_key.gs_input_topology.Assign(maxwell3d->draw_manager->GetDrawState().topology); graphics_key.tessellation_primitive.Assign(regs.tessellation.params.domain_type.Value()); graphics_key.tessellation_spacing.Assign(regs.tessellation.params.spacing.Value()); graphics_key.tessellation_clockwise.Assign( @@ -371,7 +372,8 @@ GraphicsPipeline* ShaderCache::BuiltPipeline(GraphicsPipeline* pipeline) const n // If games are using a small index count, we can assume these are full screen quads. // Usually these shaders are only used once for building textures so we can assume they // can't be built async - if (maxwell3d->regs.index_buffer.count <= 6 || maxwell3d->regs.vertex_buffer.count <= 6) { + const auto& draw_state = maxwell3d->draw_manager->GetDrawState(); + if (draw_state.index_buffer.count <= 6 || draw_state.vertex_buffer.count <= 6) { return pipeline; } return nullptr; diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index f29462f7c..5b5e178ad 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp @@ -22,12 +22,21 @@ #include "video_core/host_shaders/opengl_present_frag.h" #include "video_core/host_shaders/opengl_present_scaleforce_frag.h" #include "video_core/host_shaders/opengl_present_vert.h" +#include "video_core/host_shaders/opengl_smaa_glsl.h" #include "video_core/host_shaders/present_bicubic_frag.h" #include "video_core/host_shaders/present_gaussian_frag.h" +#include "video_core/host_shaders/smaa_blending_weight_calculation_frag.h" +#include "video_core/host_shaders/smaa_blending_weight_calculation_vert.h" +#include "video_core/host_shaders/smaa_edge_detection_frag.h" +#include "video_core/host_shaders/smaa_edge_detection_vert.h" +#include "video_core/host_shaders/smaa_neighborhood_blending_frag.h" +#include "video_core/host_shaders/smaa_neighborhood_blending_vert.h" #include "video_core/renderer_opengl/gl_rasterizer.h" #include "video_core/renderer_opengl/gl_shader_manager.h" #include "video_core/renderer_opengl/gl_shader_util.h" #include "video_core/renderer_opengl/renderer_opengl.h" +#include "video_core/smaa_area_tex.h" +#include "video_core/smaa_search_tex.h" #include "video_core/textures/decoders.h" namespace OpenGL { @@ -258,6 +267,28 @@ void RendererOpenGL::InitOpenGLObjects() { // Create shader programs fxaa_vertex = CreateProgram(HostShaders::FXAA_VERT, GL_VERTEX_SHADER); fxaa_fragment = CreateProgram(HostShaders::FXAA_FRAG, GL_FRAGMENT_SHADER); + + const auto SmaaShader = [](std::string_view specialized_source, GLenum stage) { + std::string shader_source{specialized_source}; + constexpr std::string_view include_string = "#include \"opengl_smaa.glsl\""; + const std::size_t pos = shader_source.find(include_string); + ASSERT(pos != std::string::npos); + shader_source.replace(pos, include_string.size(), HostShaders::OPENGL_SMAA_GLSL); + return CreateProgram(shader_source, stage); + }; + + smaa_edge_detection_vert = SmaaShader(HostShaders::SMAA_EDGE_DETECTION_VERT, GL_VERTEX_SHADER); + smaa_edge_detection_frag = + SmaaShader(HostShaders::SMAA_EDGE_DETECTION_FRAG, GL_FRAGMENT_SHADER); + smaa_blending_weight_calculation_vert = + SmaaShader(HostShaders::SMAA_BLENDING_WEIGHT_CALCULATION_VERT, GL_VERTEX_SHADER); + smaa_blending_weight_calculation_frag = + SmaaShader(HostShaders::SMAA_BLENDING_WEIGHT_CALCULATION_FRAG, GL_FRAGMENT_SHADER); + smaa_neighborhood_blending_vert = + SmaaShader(HostShaders::SMAA_NEIGHBORHOOD_BLENDING_VERT, GL_VERTEX_SHADER); + smaa_neighborhood_blending_frag = + SmaaShader(HostShaders::SMAA_NEIGHBORHOOD_BLENDING_FRAG, GL_FRAGMENT_SHADER); + present_vertex = CreateProgram(HostShaders::OPENGL_PRESENT_VERT, GL_VERTEX_SHADER); present_bilinear_fragment = CreateProgram(HostShaders::OPENGL_PRESENT_FRAG, GL_FRAGMENT_SHADER); present_bicubic_fragment = CreateProgram(HostShaders::PRESENT_BICUBIC_FRAG, GL_FRAGMENT_SHADER); @@ -293,7 +324,16 @@ void RendererOpenGL::InitOpenGLObjects() { // Clear screen to black LoadColorToActiveGLTexture(0, 0, 0, 0, screen_info.texture); - fxaa_framebuffer.Create(); + aa_framebuffer.Create(); + + smaa_area_tex.Create(GL_TEXTURE_2D); + glTextureStorage2D(smaa_area_tex.handle, 1, GL_RG8, AREATEX_WIDTH, AREATEX_HEIGHT); + glTextureSubImage2D(smaa_area_tex.handle, 0, 0, 0, AREATEX_WIDTH, AREATEX_HEIGHT, GL_RG, + GL_UNSIGNED_BYTE, areaTexBytes); + smaa_search_tex.Create(GL_TEXTURE_2D); + glTextureStorage2D(smaa_search_tex.handle, 1, GL_R8, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT); + glTextureSubImage2D(smaa_search_tex.handle, 0, 0, 0, SEARCHTEX_WIDTH, SEARCHTEX_HEIGHT, GL_RED, + GL_UNSIGNED_BYTE, searchTexBytes); } void RendererOpenGL::AddTelemetryFields() { @@ -346,13 +386,22 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, texture.resource.Release(); texture.resource.Create(GL_TEXTURE_2D); glTextureStorage2D(texture.resource.handle, 1, internal_format, texture.width, texture.height); - fxaa_texture.Release(); - fxaa_texture.Create(GL_TEXTURE_2D); - glTextureStorage2D(fxaa_texture.handle, 1, GL_RGBA16F, + aa_texture.Release(); + aa_texture.Create(GL_TEXTURE_2D); + glTextureStorage2D(aa_texture.handle, 1, GL_RGBA16F, + Settings::values.resolution_info.ScaleUp(screen_info.texture.width), + Settings::values.resolution_info.ScaleUp(screen_info.texture.height)); + glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0, aa_texture.handle, 0); + smaa_edges_tex.Release(); + smaa_edges_tex.Create(GL_TEXTURE_2D); + glTextureStorage2D(smaa_edges_tex.handle, 1, GL_RG16F, + Settings::values.resolution_info.ScaleUp(screen_info.texture.width), + Settings::values.resolution_info.ScaleUp(screen_info.texture.height)); + smaa_blend_tex.Release(); + smaa_blend_tex.Create(GL_TEXTURE_2D); + glTextureStorage2D(smaa_blend_tex.handle, 1, GL_RGBA16F, Settings::values.resolution_info.ScaleUp(screen_info.texture.width), Settings::values.resolution_info.ScaleUp(screen_info.texture.height)); - glNamedFramebufferTexture(fxaa_framebuffer.handle, GL_COLOR_ATTACHMENT0, fxaa_texture.handle, - 0); } void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { @@ -377,11 +426,6 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { state_tracker.ClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE); - // Update background color before drawing - glClearColor(Settings::values.bg_red.GetValue() / 255.0f, - Settings::values.bg_green.GetValue() / 255.0f, - Settings::values.bg_blue.GetValue() / 255.0f, 1.0f); - glEnable(GL_CULL_FACE); glDisable(GL_COLOR_LOGIC_OP); glDisable(GL_DEPTH_TEST); @@ -394,12 +438,12 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { glCullFace(GL_BACK); glFrontFace(GL_CW); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + glDepthRangeIndexed(0, 0.0, 0.0); glBindTextureUnit(0, screen_info.display_texture); - if (Settings::values.anti_aliasing.GetValue() == Settings::AntiAliasing::Fxaa) { - program_manager.BindPresentPrograms(fxaa_vertex.handle, fxaa_fragment.handle); - + const auto anti_aliasing = Settings::values.anti_aliasing.GetValue(); + if (anti_aliasing != Settings::AntiAliasing::None) { glEnablei(GL_SCISSOR_TEST, 0); auto viewport_width = screen_info.texture.width; auto scissor_width = framebuffer_crop_rect.GetWidth(); @@ -420,21 +464,60 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { glScissorIndexed(0, 0, 0, scissor_width, scissor_height); glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(viewport_width), static_cast<GLfloat>(viewport_height)); - glDepthRangeIndexed(0, 0.0, 0.0); glBindSampler(0, present_sampler.handle); GLint old_read_fb; GLint old_draw_fb; glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &old_read_fb); glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &old_draw_fb); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fxaa_framebuffer.handle); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + switch (anti_aliasing) { + case Settings::AntiAliasing::Fxaa: { + program_manager.BindPresentPrograms(fxaa_vertex.handle, fxaa_fragment.handle); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, aa_framebuffer.handle); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } break; + case Settings::AntiAliasing::Smaa: { + glClearColor(0, 0, 0, 0); + glFrontFace(GL_CCW); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, aa_framebuffer.handle); + glBindSampler(1, present_sampler.handle); + glBindSampler(2, present_sampler.handle); + + glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0, + smaa_edges_tex.handle, 0); + glClear(GL_COLOR_BUFFER_BIT); + program_manager.BindPresentPrograms(smaa_edge_detection_vert.handle, + smaa_edge_detection_frag.handle); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glBindTextureUnit(0, smaa_edges_tex.handle); + glBindTextureUnit(1, smaa_area_tex.handle); + glBindTextureUnit(2, smaa_search_tex.handle); + glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0, + smaa_blend_tex.handle, 0); + glClear(GL_COLOR_BUFFER_BIT); + program_manager.BindPresentPrograms(smaa_blending_weight_calculation_vert.handle, + smaa_blending_weight_calculation_frag.handle); + glDrawArrays(GL_TRIANGLES, 0, 3); + + glBindTextureUnit(0, screen_info.display_texture); + glBindTextureUnit(1, smaa_blend_tex.handle); + glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0, + aa_texture.handle, 0); + program_manager.BindPresentPrograms(smaa_neighborhood_blending_vert.handle, + smaa_neighborhood_blending_frag.handle); + glDrawArrays(GL_TRIANGLES, 0, 3); + glFrontFace(GL_CW); + } break; + default: + UNREACHABLE(); + } glBindFramebuffer(GL_READ_FRAMEBUFFER, old_read_fb); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, old_draw_fb); - glBindTextureUnit(0, fxaa_texture.handle); + glBindTextureUnit(0, aa_texture.handle); } const std::array ortho_matrix = MakeOrthographicMatrix(static_cast<float>(layout.width), static_cast<float>(layout.height)); @@ -551,6 +634,11 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { glBindSampler(0, present_sampler_nn.handle); } + // Update background color before drawing + glClearColor(Settings::values.bg_red.GetValue() / 255.0f, + Settings::values.bg_green.GetValue() / 255.0f, + Settings::values.bg_blue.GetValue() / 255.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h index 1a32e739d..cc97d7b26 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.h +++ b/src/video_core/renderer_opengl/renderer_opengl.h @@ -127,8 +127,19 @@ private: /// Display information for Switch screen ScreenInfo screen_info; - OGLTexture fxaa_texture; - OGLFramebuffer fxaa_framebuffer; + OGLTexture aa_texture; + OGLFramebuffer aa_framebuffer; + + OGLProgram smaa_edge_detection_vert; + OGLProgram smaa_blending_weight_calculation_vert; + OGLProgram smaa_neighborhood_blending_vert; + OGLProgram smaa_edge_detection_frag; + OGLProgram smaa_blending_weight_calculation_frag; + OGLProgram smaa_neighborhood_blending_frag; + OGLTexture smaa_area_tex; + OGLTexture smaa_search_tex; + OGLTexture smaa_edges_tex; + OGLTexture smaa_blend_tex; /// OpenGL framebuffer data std::vector<u8> gl_framebuffer_data; |