summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp19
-rw-r--r--src/video_core/renderer_opengl/gl_shader_cache.cpp6
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp124
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h15
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;