summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl/renderer_opengl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/renderer_opengl/renderer_opengl.cpp')
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp117
1 files changed, 44 insertions, 73 deletions
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index e37b65b38..5e3d862c6 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -98,8 +98,8 @@ static std::array<GLfloat, 3 * 2> MakeOrthographicMatrix(const float width, cons
return matrix;
}
-RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& window)
- : VideoCore::RendererBase{window} {}
+RendererOpenGL::RendererOpenGL(Core::Frontend::EmuWindow& window, Core::System& system)
+ : VideoCore::RendererBase{window}, system{system} {}
RendererOpenGL::~RendererOpenGL() = default;
@@ -107,7 +107,7 @@ RendererOpenGL::~RendererOpenGL() = default;
void RendererOpenGL::SwapBuffers(
std::optional<std::reference_wrapper<const Tegra::FramebufferConfig>> framebuffer) {
- Core::System::GetInstance().GetPerfStats().EndSystemFrame();
+ system.GetPerfStats().EndSystemFrame();
// Maintain the rasterizer's state as a priority
OpenGLState prev_state = OpenGLState::GetCurState();
@@ -137,8 +137,8 @@ void RendererOpenGL::SwapBuffers(
render_window.PollEvents();
- Core::System::GetInstance().FrameLimiter().DoFrameLimiting(CoreTiming::GetGlobalTimeUs());
- Core::System::GetInstance().GetPerfStats().BeginSystemFrame();
+ system.FrameLimiter().DoFrameLimiting(system.CoreTiming().GetGlobalTimeUs());
+ system.GetPerfStats().BeginSystemFrame();
// Restore the rasterizer state
prev_state.Apply();
@@ -164,17 +164,14 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
// Reset the screen info's display texture to its own permanent texture
screen_info.display_texture = screen_info.texture.resource.handle;
- Memory::RasterizerFlushVirtualRegion(framebuffer_addr, size_in_bytes,
- Memory::FlushMode::Flush);
+ rasterizer->FlushRegion(ToCacheAddr(Memory::GetPointer(framebuffer_addr)), size_in_bytes);
- VideoCore::MortonCopyPixels128(framebuffer.width, framebuffer.height, bytes_per_pixel, 4,
- Memory::GetPointer(framebuffer_addr),
- gl_framebuffer_data.data(), true);
+ constexpr u32 linear_bpp = 4;
+ VideoCore::MortonCopyPixels128(VideoCore::MortonSwizzleMode::MortonToLinear,
+ framebuffer.width, framebuffer.height, bytes_per_pixel,
+ linear_bpp, Memory::GetPointer(framebuffer_addr),
+ gl_framebuffer_data.data());
- state.texture_units[0].texture = screen_info.texture.resource.handle;
- state.Apply();
-
- glActiveTexture(GL_TEXTURE0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(framebuffer.stride));
// Update existing texture
@@ -182,14 +179,11 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
// they differ from the LCD resolution.
// TODO: Applications could theoretically crash yuzu here by specifying too large
// framebuffer sizes. We should make sure that this cannot happen.
- glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, framebuffer.width, framebuffer.height,
- screen_info.texture.gl_format, screen_info.texture.gl_type,
- gl_framebuffer_data.data());
+ glTextureSubImage2D(screen_info.texture.resource.handle, 0, 0, 0, framebuffer.width,
+ framebuffer.height, screen_info.texture.gl_format,
+ screen_info.texture.gl_type, gl_framebuffer_data.data());
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
- state.texture_units[0].texture = 0;
- state.Apply();
}
}
@@ -199,17 +193,8 @@ void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuf
*/
void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
const TextureInfo& texture) {
- state.texture_units[0].texture = texture.resource.handle;
- state.Apply();
-
- glActiveTexture(GL_TEXTURE0);
- u8 framebuffer_data[4] = {color_a, color_b, color_g, color_r};
-
- // Update existing texture
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer_data);
-
- state.texture_units[0].texture = 0;
- state.Apply();
+ const u8 framebuffer_data[4] = {color_a, color_b, color_g, color_r};
+ glClearTexImage(texture.resource.handle, 0, GL_RGBA, GL_UNSIGNED_BYTE, framebuffer_data);
}
/**
@@ -249,55 +234,57 @@ void RendererOpenGL::InitOpenGLObjects() {
sizeof(ScreenRectVertex));
// Allocate textures for the screen
- screen_info.texture.resource.Create();
+ screen_info.texture.resource.Create(GL_TEXTURE_2D);
- // Allocation of storage is deferred until the first frame, when we
- // know the framebuffer size.
-
- state.texture_units[0].texture = screen_info.texture.resource.handle;
- state.Apply();
-
- glActiveTexture(GL_TEXTURE0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ const GLuint texture = screen_info.texture.resource.handle;
+ glTextureStorage2D(texture, 1, GL_RGBA8, 1, 1);
screen_info.display_texture = screen_info.texture.resource.handle;
- state.texture_units[0].texture = 0;
- state.Apply();
-
// Clear screen to black
LoadColorToActiveGLTexture(0, 0, 0, 0, screen_info.texture);
}
+void RendererOpenGL::AddTelemetryFields() {
+ const char* const gl_version{reinterpret_cast<char const*>(glGetString(GL_VERSION))};
+ const char* const gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))};
+ const char* const gpu_model{reinterpret_cast<char const*>(glGetString(GL_RENDERER))};
+
+ LOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version);
+ LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor);
+ LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model);
+
+ auto& telemetry_session = system.TelemetrySession();
+ telemetry_session.AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor);
+ telemetry_session.AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model);
+ telemetry_session.AddField(Telemetry::FieldType::UserSystem, "GPU_OpenGL_Version", gl_version);
+}
+
void RendererOpenGL::CreateRasterizer() {
if (rasterizer) {
return;
}
// Initialize sRGB Usage
OpenGLState::ClearsRGBUsed();
- rasterizer = std::make_unique<RasterizerOpenGL>(render_window, screen_info);
+ rasterizer = std::make_unique<RasterizerOpenGL>(render_window, system, screen_info);
}
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
const Tegra::FramebufferConfig& framebuffer) {
-
texture.width = framebuffer.width;
texture.height = framebuffer.height;
+ texture.pixel_format = framebuffer.pixel_format;
GLint internal_format;
switch (framebuffer.pixel_format) {
case Tegra::FramebufferConfig::PixelFormat::ABGR8:
- internal_format = GL_RGBA;
+ internal_format = GL_RGBA8;
texture.gl_format = GL_RGBA;
texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
gl_framebuffer_data.resize(texture.width * texture.height * 4);
break;
default:
- internal_format = GL_RGBA;
+ internal_format = GL_RGBA8;
texture.gl_format = GL_RGBA;
texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
gl_framebuffer_data.resize(texture.width * texture.height * 4);
@@ -306,15 +293,9 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
UNREACHABLE();
}
- state.texture_units[0].texture = texture.resource.handle;
- state.Apply();
-
- glActiveTexture(GL_TEXTURE0);
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, texture.width, texture.height, 0,
- texture.gl_format, texture.gl_type, nullptr);
-
- state.texture_units[0].texture = 0;
- state.Apply();
+ texture.resource.Release();
+ texture.resource.Create(GL_TEXTURE_2D);
+ glTextureStorage2D(texture.resource.handle, 1, internal_format, texture.width, texture.height);
}
void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x, float y, float w,
@@ -356,7 +337,6 @@ void RendererOpenGL::DrawScreenTriangles(const ScreenInfo& screen_info, float x,
}};
state.texture_units[0].texture = screen_info.display_texture;
- state.texture_units[0].swizzle = {GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA};
// Workaround brigthness problems in SMO by enabling sRGB in the final output
// if it has been used in the frame. Needed because of this bug in QT: QTBUG-50987
state.framebuffer_srgb.enabled = OpenGLState::GetsRGBUsed();
@@ -417,7 +397,8 @@ void RendererOpenGL::CaptureScreenshot() {
GLuint renderbuffer;
glGenRenderbuffers(1, &renderbuffer);
glBindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
- glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB8, layout.width, layout.height);
+ glRenderbufferStorage(GL_RENDERBUFFER, state.GetsRGBUsed() ? GL_SRGB8 : GL_RGB8, layout.width,
+ layout.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
DrawScreen(layout);
@@ -501,17 +482,7 @@ bool RendererOpenGL::Init() {
glDebugMessageCallback(DebugHandler, nullptr);
}
- const char* gl_version{reinterpret_cast<char const*>(glGetString(GL_VERSION))};
- const char* gpu_vendor{reinterpret_cast<char const*>(glGetString(GL_VENDOR))};
- const char* gpu_model{reinterpret_cast<char const*>(glGetString(GL_RENDERER))};
-
- LOG_INFO(Render_OpenGL, "GL_VERSION: {}", gl_version);
- LOG_INFO(Render_OpenGL, "GL_VENDOR: {}", gpu_vendor);
- LOG_INFO(Render_OpenGL, "GL_RENDERER: {}", gpu_model);
-
- Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Vendor", gpu_vendor);
- Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_Model", gpu_model);
- Core::Telemetry().AddField(Telemetry::FieldType::UserSystem, "GPU_OpenGL_Version", gl_version);
+ AddTelemetryFields();
if (!GLAD_GL_VERSION_4_3) {
return false;