summaryrefslogtreecommitdiffstats
path: root/src/video_core/renderer_opengl
diff options
context:
space:
mode:
authorLiam <byteslice@airmail.cc>2024-01-04 04:46:59 +0100
committerLiam <byteslice@airmail.cc>2024-01-31 17:27:20 +0100
commit80de01a5b4a7f57ec7850079fbd38fac76b9d08f (patch)
tree18086d7a71ffcd9f5bc6651aec20de37e3b1c33d /src/video_core/renderer_opengl
parentMerge pull request #12760 from liamwhite/mp-am (diff)
downloadyuzu-80de01a5b4a7f57ec7850079fbd38fac76b9d08f.tar
yuzu-80de01a5b4a7f57ec7850079fbd38fac76b9d08f.tar.gz
yuzu-80de01a5b4a7f57ec7850079fbd38fac76b9d08f.tar.bz2
yuzu-80de01a5b4a7f57ec7850079fbd38fac76b9d08f.tar.lz
yuzu-80de01a5b4a7f57ec7850079fbd38fac76b9d08f.tar.xz
yuzu-80de01a5b4a7f57ec7850079fbd38fac76b9d08f.tar.zst
yuzu-80de01a5b4a7f57ec7850079fbd38fac76b9d08f.zip
Diffstat (limited to 'src/video_core/renderer_opengl')
-rw-r--r--src/video_core/renderer_opengl/gl_fsr.cpp21
-rw-r--r--src/video_core/renderer_opengl/gl_fsr.h2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp28
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.h13
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp235
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.h32
6 files changed, 142 insertions, 189 deletions
diff --git a/src/video_core/renderer_opengl/gl_fsr.cpp b/src/video_core/renderer_opengl/gl_fsr.cpp
index 77262dcf1..429dcdc6c 100644
--- a/src/video_core/renderer_opengl/gl_fsr.cpp
+++ b/src/video_core/renderer_opengl/gl_fsr.cpp
@@ -25,7 +25,7 @@ FSR::~FSR() = default;
void FSR::Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen,
u32 input_image_width, u32 input_image_height,
- const Common::Rectangle<int>& crop_rect) {
+ const Common::Rectangle<f32>& crop_rect) {
const auto output_image_width = screen.GetWidth();
const auto output_image_height = screen.GetHeight();
@@ -57,14 +57,19 @@ void FSR::Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& sc
glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(output_image_width),
static_cast<GLfloat>(output_image_height));
- FsrConstants constants;
- FsrEasuConOffset(
- constants.data() + 0, constants.data() + 4, constants.data() + 8, constants.data() + 12,
+ const f32 input_width = static_cast<f32>(input_image_width);
+ const f32 input_height = static_cast<f32>(input_image_height);
+ const f32 output_width = static_cast<f32>(screen.GetWidth());
+ const f32 output_height = static_cast<f32>(screen.GetHeight());
+ const f32 viewport_width = (crop_rect.right - crop_rect.left) * input_width;
+ const f32 viewport_x = crop_rect.left * input_width;
+ const f32 viewport_height = (crop_rect.bottom - crop_rect.top) * input_height;
+ const f32 viewport_y = crop_rect.top * input_height;
- static_cast<f32>(crop_rect.GetWidth()), static_cast<f32>(crop_rect.GetHeight()),
- static_cast<f32>(input_image_width), static_cast<f32>(input_image_height),
- static_cast<f32>(output_image_width), static_cast<f32>(output_image_height),
- static_cast<f32>(crop_rect.left), static_cast<f32>(crop_rect.top));
+ FsrConstants constants;
+ FsrEasuConOffset(constants.data() + 0, constants.data() + 4, constants.data() + 8,
+ constants.data() + 12, viewport_width, viewport_height, input_width,
+ input_height, output_width, output_height, viewport_x, viewport_y);
glProgramUniform4uiv(fsr_easu_frag.handle, 0, sizeof(constants), std::data(constants));
diff --git a/src/video_core/renderer_opengl/gl_fsr.h b/src/video_core/renderer_opengl/gl_fsr.h
index 1f6ae3115..a5092e396 100644
--- a/src/video_core/renderer_opengl/gl_fsr.h
+++ b/src/video_core/renderer_opengl/gl_fsr.h
@@ -22,7 +22,7 @@ public:
void Draw(ProgramManager& program_manager, const Common::Rectangle<u32>& screen,
u32 input_image_width, u32 input_image_height,
- const Common::Rectangle<int>& crop_rect);
+ const Common::Rectangle<f32>& crop_rect);
void InitBuffers();
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index d5354ef2d..050a74cca 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -71,10 +71,10 @@ std::optional<VideoCore::QueryType> MaxwellToVideoCoreQuery(VideoCommon::QueryTy
RasterizerOpenGL::RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
Tegra::MaxwellDeviceMemoryManager& device_memory_,
- const Device& device_, ScreenInfo& screen_info_,
- ProgramManager& program_manager_, StateTracker& state_tracker_)
- : gpu(gpu_), device_memory(device_memory_), device(device_), screen_info(screen_info_),
- program_manager(program_manager_), state_tracker(state_tracker_),
+ const Device& device_, ProgramManager& program_manager_,
+ StateTracker& state_tracker_)
+ : gpu(gpu_), device_memory(device_memory_), device(device_), program_manager(program_manager_),
+ state_tracker(state_tracker_),
texture_cache_runtime(device, program_manager, state_tracker, staging_buffer_pool),
texture_cache(texture_cache_runtime, device_memory_),
buffer_cache_runtime(device, staging_buffer_pool),
@@ -739,10 +739,10 @@ void RasterizerOpenGL::AccelerateInlineToMemory(GPUVAddr address, size_t copy_si
query_cache.InvalidateRegion(*cpu_addr, copy_size);
}
-bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
- DAddr framebuffer_addr, u32 pixel_stride) {
+std::optional<FramebufferTextureInfo> RasterizerOpenGL::AccelerateDisplay(
+ const Tegra::FramebufferConfig& config, DAddr framebuffer_addr, u32 pixel_stride) {
if (framebuffer_addr == 0) {
- return false;
+ return {};
}
MICROPROFILE_SCOPE(OpenGL_CacheManagement);
@@ -750,16 +750,14 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
ImageView* const image_view{
texture_cache.TryFindFramebufferImageView(config, framebuffer_addr)};
if (!image_view) {
- return false;
+ return {};
}
- // Verify that the cached surface is the same size and format as the requested framebuffer
- // ASSERT_MSG(image_view->size.width == config.width, "Framebuffer width is different");
- // ASSERT_MSG(image_view->size.height == config.height, "Framebuffer height is different");
- screen_info.texture.width = image_view->size.width;
- screen_info.texture.height = image_view->size.height;
- screen_info.display_texture = image_view->Handle(Shader::TextureType::Color2D);
- return true;
+ FramebufferTextureInfo info{};
+ info.display_texture = image_view->Handle(Shader::TextureType::Color2D);
+ info.width = image_view->size.width;
+ info.height = image_view->size.height;
+ return info;
}
void RasterizerOpenGL::SyncState() {
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 34aa73526..ee82d9f3a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -37,7 +37,7 @@ class MemoryManager;
namespace OpenGL {
-struct ScreenInfo;
+struct FramebufferTextureInfo;
struct ShaderEntries;
struct BindlessSSBO {
@@ -76,8 +76,8 @@ class RasterizerOpenGL : public VideoCore::RasterizerInterface,
public:
explicit RasterizerOpenGL(Core::Frontend::EmuWindow& emu_window_, Tegra::GPU& gpu_,
Tegra::MaxwellDeviceMemoryManager& device_memory_,
- const Device& device_, ScreenInfo& screen_info_,
- ProgramManager& program_manager_, StateTracker& state_tracker_);
+ const Device& device_, ProgramManager& program_manager_,
+ StateTracker& state_tracker_);
~RasterizerOpenGL() override;
void Draw(bool is_indexed, u32 instance_count) override;
@@ -122,8 +122,6 @@ public:
Tegra::Engines::AccelerateDMAInterface& AccessAccelerateDMA() override;
void AccelerateInlineToMemory(GPUVAddr address, size_t copy_size,
std::span<const u8> memory) override;
- bool AccelerateDisplay(const Tegra::FramebufferConfig& config, DAddr framebuffer_addr,
- u32 pixel_stride) override;
void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
const VideoCore::DiskResourceLoadCallback& callback) override;
@@ -144,6 +142,10 @@ public:
return true;
}
+ std::optional<FramebufferTextureInfo> AccelerateDisplay(const Tegra::FramebufferConfig& config,
+ VAddr framebuffer_addr,
+ u32 pixel_stride);
+
private:
static constexpr size_t MAX_TEXTURES = 192;
static constexpr size_t MAX_IMAGES = 48;
@@ -237,7 +239,6 @@ private:
Tegra::MaxwellDeviceMemoryManager& device_memory;
const Device& device;
- ScreenInfo& screen_info;
ProgramManager& program_manager;
StateTracker& state_tracker;
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index b75376fdb..ea5ed3e2f 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -148,8 +148,7 @@ RendererOpenGL::RendererOpenGL(Core::TelemetrySession& telemetry_session_,
: RendererBase{emu_window_, std::move(context_)}, telemetry_session{telemetry_session_},
emu_window{emu_window_}, device_memory{device_memory_}, gpu{gpu_}, device{emu_window_},
state_tracker{}, program_manager{device},
- rasterizer(emu_window, gpu, device_memory, device, screen_info, program_manager,
- state_tracker) {
+ rasterizer(emu_window, gpu, device_memory, device, program_manager, state_tracker) {
if (Settings::values.renderer_debug && GLAD_GL_KHR_debug) {
glEnable(GL_DEBUG_OUTPUT);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
@@ -184,11 +183,11 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
if (!framebuffer) {
return;
}
- PrepareRendertarget(framebuffer);
- RenderScreenshot();
+
+ RenderScreenshot(*framebuffer);
state_tracker.BindFramebuffer(0);
- DrawScreen(emu_window.GetFramebufferLayout());
+ DrawScreen(*framebuffer, emu_window.GetFramebufferLayout());
++m_current_frame;
@@ -199,41 +198,37 @@ void RendererOpenGL::SwapBuffers(const Tegra::FramebufferConfig* framebuffer) {
render_window.OnFrameDisplayed();
}
-void RendererOpenGL::PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer) {
- if (!framebuffer) {
- return;
- }
+FramebufferTextureInfo RendererOpenGL::PrepareRenderTarget(
+ const Tegra::FramebufferConfig& framebuffer) {
// If framebuffer is provided, reload it from memory to a texture
- if (screen_info.texture.width != static_cast<GLsizei>(framebuffer->width) ||
- screen_info.texture.height != static_cast<GLsizei>(framebuffer->height) ||
- screen_info.texture.pixel_format != framebuffer->pixel_format ||
+ if (framebuffer_texture.width != static_cast<GLsizei>(framebuffer.width) ||
+ framebuffer_texture.height != static_cast<GLsizei>(framebuffer.height) ||
+ framebuffer_texture.pixel_format != framebuffer.pixel_format ||
gl_framebuffer_data.empty()) {
// Reallocate texture if the framebuffer size has changed.
// This is expected to not happen very often and hence should not be a
// performance problem.
- ConfigureFramebufferTexture(screen_info.texture, *framebuffer);
+ ConfigureFramebufferTexture(framebuffer);
}
- // Load the framebuffer from memory, draw it to the screen, and swap buffers
- LoadFBToScreenInfo(*framebuffer);
+ // Load the framebuffer from memory if needed
+ return LoadFBToScreenInfo(framebuffer);
}
-void RendererOpenGL::LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer) {
- // Framebuffer orientation handling
- framebuffer_transform_flags = framebuffer.transform_flags;
- framebuffer_crop_rect = framebuffer.crop_rect;
- framebuffer_width = framebuffer.width;
- framebuffer_height = framebuffer.height;
-
+FramebufferTextureInfo RendererOpenGL::LoadFBToScreenInfo(
+ const Tegra::FramebufferConfig& framebuffer) {
const VAddr framebuffer_addr{framebuffer.address + framebuffer.offset};
- screen_info.was_accelerated =
+ const auto accelerated_info =
rasterizer.AccelerateDisplay(framebuffer, framebuffer_addr, framebuffer.stride);
- if (screen_info.was_accelerated) {
- return;
+ if (accelerated_info) {
+ return *accelerated_info;
}
// Reset the screen info's display texture to its own permanent texture
- screen_info.display_texture = screen_info.texture.resource.handle;
+ FramebufferTextureInfo info{};
+ info.display_texture = framebuffer_texture.resource.handle;
+ info.width = framebuffer.width;
+ info.height = framebuffer.height;
// TODO(Rodrigo): Read this from HLE
constexpr u32 block_height_log2 = 4;
@@ -256,17 +251,13 @@ 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.
- 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());
+ glTextureSubImage2D(framebuffer_texture.resource.handle, 0, 0, 0, framebuffer.width,
+ framebuffer.height, framebuffer_texture.gl_format,
+ framebuffer_texture.gl_type, gl_framebuffer_data.data());
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-}
-void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
- const TextureInfo& texture) {
- 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);
+ return info;
}
void RendererOpenGL::InitOpenGLObjects() {
@@ -343,15 +334,15 @@ void RendererOpenGL::InitOpenGLObjects() {
glNamedBufferData(vertex_buffer.handle, sizeof(ScreenRectVertex) * 4, nullptr, GL_STREAM_DRAW);
// Allocate textures for the screen
- screen_info.texture.resource.Create(GL_TEXTURE_2D);
+ framebuffer_texture.resource.Create(GL_TEXTURE_2D);
- const GLuint texture = screen_info.texture.resource.handle;
+ const GLuint texture = framebuffer_texture.resource.handle;
glTextureStorage2D(texture, 1, GL_RGBA8, 1, 1);
- screen_info.display_texture = screen_info.texture.resource.handle;
-
// Clear screen to black
- LoadColorToActiveGLTexture(0, 0, 0, 0, screen_info.texture);
+ const u8 framebuffer_data[4] = {0, 0, 0, 0};
+ glClearTexImage(framebuffer_texture.resource.handle, 0, GL_RGBA, GL_UNSIGNED_BYTE,
+ framebuffer_data);
aa_framebuffer.Create();
@@ -380,60 +371,65 @@ void RendererOpenGL::AddTelemetryFields() {
telemetry_session.AddField(user_system, "GPU_OpenGL_Version", std::string(gl_version));
}
-void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
- const Tegra::FramebufferConfig& framebuffer) {
- texture.width = framebuffer.width;
- texture.height = framebuffer.height;
- texture.pixel_format = framebuffer.pixel_format;
+void RendererOpenGL::ConfigureFramebufferTexture(const Tegra::FramebufferConfig& framebuffer) {
+ framebuffer_texture.width = framebuffer.width;
+ framebuffer_texture.height = framebuffer.height;
+ framebuffer_texture.pixel_format = framebuffer.pixel_format;
const auto pixel_format{
VideoCore::Surface::PixelFormatFromGPUPixelFormat(framebuffer.pixel_format)};
const u32 bytes_per_pixel{VideoCore::Surface::BytesPerBlock(pixel_format)};
- gl_framebuffer_data.resize(texture.width * texture.height * bytes_per_pixel);
+ gl_framebuffer_data.resize(framebuffer_texture.width * framebuffer_texture.height *
+ bytes_per_pixel);
GLint internal_format;
switch (framebuffer.pixel_format) {
case Service::android::PixelFormat::Rgba8888:
internal_format = GL_RGBA8;
- texture.gl_format = GL_RGBA;
- texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ framebuffer_texture.gl_format = GL_RGBA;
+ framebuffer_texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
break;
case Service::android::PixelFormat::Rgb565:
internal_format = GL_RGB565;
- texture.gl_format = GL_RGB;
- texture.gl_type = GL_UNSIGNED_SHORT_5_6_5;
+ framebuffer_texture.gl_format = GL_RGB;
+ framebuffer_texture.gl_type = GL_UNSIGNED_SHORT_5_6_5;
break;
default:
internal_format = GL_RGBA8;
- texture.gl_format = GL_RGBA;
- texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ framebuffer_texture.gl_format = GL_RGBA;
+ framebuffer_texture.gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
// UNIMPLEMENTED_MSG("Unknown framebuffer pixel format: {}",
// static_cast<u32>(framebuffer.pixel_format));
break;
}
- texture.resource.Release();
- texture.resource.Create(GL_TEXTURE_2D);
- glTextureStorage2D(texture.resource.handle, 1, internal_format, texture.width, texture.height);
+ framebuffer_texture.resource.Release();
+ framebuffer_texture.resource.Create(GL_TEXTURE_2D);
+ glTextureStorage2D(framebuffer_texture.resource.handle, 1, internal_format,
+ framebuffer_texture.width, framebuffer_texture.height);
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));
+ Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
+ Settings::values.resolution_info.ScaleUp(framebuffer_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));
+ Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
+ Settings::values.resolution_info.ScaleUp(framebuffer_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));
+ Settings::values.resolution_info.ScaleUp(framebuffer_texture.width),
+ Settings::values.resolution_info.ScaleUp(framebuffer_texture.height));
}
-void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
+void RendererOpenGL::DrawScreen(const Tegra::FramebufferConfig& framebuffer,
+ const Layout::FramebufferLayout& layout) {
+ FramebufferTextureInfo info = PrepareRenderTarget(framebuffer);
+ const auto crop = Tegra::NormalizeCrop(framebuffer, info.width, info.height);
+
// TODO: Signal state tracker about these changes
state_tracker.NotifyScreenDrawVertexArray();
state_tracker.NotifyPolygonModes();
@@ -469,7 +465,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glDepthRangeIndexed(0, 0.0, 0.0);
- glBindTextureUnit(0, screen_info.display_texture);
+ glBindTextureUnit(0, info.display_texture);
auto anti_aliasing = Settings::values.anti_aliasing.GetValue();
if (anti_aliasing >= Settings::AntiAliasing::MaxEnum) {
@@ -480,22 +476,22 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
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();
+ auto viewport_width = info.width;
+ auto scissor_width = static_cast<u32>(crop.GetWidth());
if (scissor_width <= 0) {
scissor_width = viewport_width;
}
- auto viewport_height = screen_info.texture.height;
- auto scissor_height = framebuffer_crop_rect.GetHeight();
+ auto viewport_height = info.height;
+ auto scissor_height = static_cast<u32>(crop.GetHeight());
if (scissor_height <= 0) {
scissor_height = viewport_height;
}
- if (screen_info.was_accelerated) {
- viewport_width = Settings::values.resolution_info.ScaleUp(viewport_width);
- scissor_width = Settings::values.resolution_info.ScaleUp(scissor_width);
- viewport_height = Settings::values.resolution_info.ScaleUp(viewport_height);
- scissor_height = Settings::values.resolution_info.ScaleUp(scissor_height);
- }
+
+ viewport_width = Settings::values.resolution_info.ScaleUp(viewport_width);
+ scissor_width = Settings::values.resolution_info.ScaleUp(scissor_width);
+ viewport_height = Settings::values.resolution_info.ScaleUp(viewport_height);
+ scissor_height = Settings::values.resolution_info.ScaleUp(scissor_height);
+
glScissorIndexed(0, 0, 0, scissor_width, scissor_height);
glViewportIndexedf(0, 0.0f, 0.0f, static_cast<GLfloat>(viewport_width),
static_cast<GLfloat>(viewport_height));
@@ -536,7 +532,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
smaa_blending_weight_calculation_frag.handle);
glDrawArrays(GL_TRIANGLES, 0, 3);
- glBindTextureUnit(0, screen_info.display_texture);
+ glBindTextureUnit(0, info.display_texture);
glBindTextureUnit(1, smaa_blend_tex.handle);
glNamedFramebufferTexture(aa_framebuffer.handle, GL_COLOR_ATTACHMENT0,
aa_texture.handle, 0);
@@ -561,18 +557,10 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
fsr->InitBuffers();
}
- auto crop_rect = framebuffer_crop_rect;
- if (crop_rect.GetWidth() == 0) {
- crop_rect.right = framebuffer_width;
- }
- if (crop_rect.GetHeight() == 0) {
- crop_rect.bottom = framebuffer_height;
- }
- crop_rect = crop_rect.Scale(Settings::values.resolution_info.up_factor);
- const auto fsr_input_width = Settings::values.resolution_info.ScaleUp(framebuffer_width);
- const auto fsr_input_height = Settings::values.resolution_info.ScaleUp(framebuffer_height);
+ const auto fsr_input_width = Settings::values.resolution_info.ScaleUp(info.width);
+ const auto fsr_input_height = Settings::values.resolution_info.ScaleUp(info.height);
glBindSampler(0, present_sampler.handle);
- fsr->Draw(program_manager, layout.screen, fsr_input_width, fsr_input_height, crop_rect);
+ fsr->Draw(program_manager, layout.screen, fsr_input_width, fsr_input_height, crop);
} else {
if (fsr->AreBuffersInitialized()) {
fsr->ReleaseBuffers();
@@ -603,61 +591,34 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
glProgramUniformMatrix3x2fv(present_vertex.handle, ModelViewMatrixLocation, 1, GL_FALSE,
ortho_matrix.data());
- const auto& texcoords = screen_info.display_texcoords;
- auto left = texcoords.left;
- auto right = texcoords.right;
- if (framebuffer_transform_flags != Service::android::BufferTransformFlags::Unset) {
- if (framebuffer_transform_flags == Service::android::BufferTransformFlags::FlipV) {
- // Flip the framebuffer vertically
- left = texcoords.right;
- right = texcoords.left;
- } else {
- // Other transformations are unsupported
- LOG_CRITICAL(Render_OpenGL, "Unsupported framebuffer_transform_flags={}",
- framebuffer_transform_flags);
- UNIMPLEMENTED();
- }
- }
-
- ASSERT_MSG(framebuffer_crop_rect.left == 0, "Unimplemented");
-
- f32 left_start{};
- if (framebuffer_crop_rect.Top() > 0) {
- left_start = static_cast<f32>(framebuffer_crop_rect.Top()) /
- static_cast<f32>(framebuffer_crop_rect.Bottom());
- }
- f32 scale_u = static_cast<f32>(framebuffer_width) / static_cast<f32>(screen_info.texture.width);
- f32 scale_v =
- static_cast<f32>(framebuffer_height) / static_cast<f32>(screen_info.texture.height);
-
- if (Settings::values.scaling_filter.GetValue() != Settings::ScalingFilter::Fsr) {
- // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering
- // (e.g. handheld mode) on a 1920x1080 framebuffer.
- if (framebuffer_crop_rect.GetWidth() > 0) {
- scale_u = static_cast<f32>(framebuffer_crop_rect.GetWidth()) /
- static_cast<f32>(screen_info.texture.width);
- }
- if (framebuffer_crop_rect.GetHeight() > 0) {
- scale_v = static_cast<f32>(framebuffer_crop_rect.GetHeight()) /
- static_cast<f32>(screen_info.texture.height);
- }
- }
- if (Settings::values.anti_aliasing.GetValue() == Settings::AntiAliasing::Fxaa &&
- !screen_info.was_accelerated) {
- scale_u /= Settings::values.resolution_info.up_factor;
- scale_v /= Settings::values.resolution_info.up_factor;
+ f32 left, top, right, bottom;
+ if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) {
+ // FSR has already applied the crop, so we just want to render the image
+ // it has produced.
+ left = 0;
+ top = 0;
+ right = 1;
+ bottom = 1;
+ } else {
+ // Apply the precomputed crop.
+ left = crop.left;
+ top = crop.top;
+ right = crop.right;
+ bottom = crop.bottom;
}
+ // Map the coordinates to the screen.
const auto& screen = layout.screen;
+ const auto x = screen.left;
+ const auto y = screen.top;
+ const auto w = screen.GetWidth();
+ const auto h = screen.GetHeight();
+
const std::array vertices = {
- ScreenRectVertex(screen.left, screen.top, texcoords.top * scale_u,
- left_start + left * scale_v),
- ScreenRectVertex(screen.right, screen.top, texcoords.bottom * scale_u,
- left_start + left * scale_v),
- ScreenRectVertex(screen.left, screen.bottom, texcoords.top * scale_u,
- left_start + right * scale_v),
- ScreenRectVertex(screen.right, screen.bottom, texcoords.bottom * scale_u,
- left_start + right * scale_v),
+ ScreenRectVertex(x, y, left, top),
+ ScreenRectVertex(x + w, y, right, top),
+ ScreenRectVertex(x, y + h, left, bottom),
+ ScreenRectVertex(x + w, y + h, right, bottom),
};
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
@@ -701,7 +662,7 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
// program_manager.RestoreGuestPipeline();
}
-void RendererOpenGL::RenderScreenshot() {
+void RendererOpenGL::RenderScreenshot(const Tegra::FramebufferConfig& framebuffer) {
if (!renderer_settings.screenshot_requested) {
return;
}
@@ -723,7 +684,7 @@ void RendererOpenGL::RenderScreenshot() {
glRenderbufferStorage(GL_RENDERBUFFER, GL_SRGB8, layout.width, layout.height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderbuffer);
- DrawScreen(layout);
+ DrawScreen(framebuffer, layout);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
diff --git a/src/video_core/renderer_opengl/renderer_opengl.h b/src/video_core/renderer_opengl/renderer_opengl.h
index 18699610a..cde8c5702 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.h
+++ b/src/video_core/renderer_opengl/renderer_opengl.h
@@ -50,11 +50,10 @@ struct TextureInfo {
};
/// Structure used for storing information about the display target for the Switch screen
-struct ScreenInfo {
+struct FramebufferTextureInfo {
GLuint display_texture{};
- bool was_accelerated = false;
- const Common::Rectangle<float> display_texcoords{0.0f, 0.0f, 1.0f, 1.0f};
- TextureInfo texture;
+ u32 width;
+ u32 height;
};
class RendererOpenGL final : public VideoCore::RendererBase {
@@ -81,23 +80,18 @@ private:
void AddTelemetryFields();
- void ConfigureFramebufferTexture(TextureInfo& texture,
- const Tegra::FramebufferConfig& framebuffer);
+ void ConfigureFramebufferTexture(const Tegra::FramebufferConfig& framebuffer);
/// Draws the emulated screens to the emulator window.
- void DrawScreen(const Layout::FramebufferLayout& layout);
+ void DrawScreen(const Tegra::FramebufferConfig& framebuffer,
+ const Layout::FramebufferLayout& layout);
- void RenderScreenshot();
+ void RenderScreenshot(const Tegra::FramebufferConfig& framebuffer);
/// Loads framebuffer from emulated memory into the active OpenGL texture.
- void LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer);
+ FramebufferTextureInfo LoadFBToScreenInfo(const Tegra::FramebufferConfig& framebuffer);
- /// Fills active OpenGL texture with the given RGB color.Since the color is solid, the texture
- /// can be 1x1 but will stretch across whatever it's rendered on.
- void LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color_b, u8 color_a,
- const TextureInfo& texture);
-
- void PrepareRendertarget(const Tegra::FramebufferConfig* framebuffer);
+ FramebufferTextureInfo PrepareRenderTarget(const Tegra::FramebufferConfig& framebuffer);
Core::TelemetrySession& telemetry_session;
Core::Frontend::EmuWindow& emu_window;
@@ -126,7 +120,7 @@ private:
GLuint64EXT vertex_buffer_address = 0;
/// Display information for Switch screen
- ScreenInfo screen_info;
+ TextureInfo framebuffer_texture;
OGLTexture aa_texture;
OGLFramebuffer aa_framebuffer;
@@ -145,12 +139,6 @@ private:
/// OpenGL framebuffer data
std::vector<u8> gl_framebuffer_data;
-
- /// Used for transforming the framebuffer orientation
- Service::android::BufferTransformFlags framebuffer_transform_flags{};
- Common::Rectangle<int> framebuffer_crop_rect;
- u32 framebuffer_width;
- u32 framebuffer_height;
};
} // namespace OpenGL