mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-11-29 14:57:41 -05:00
renderer_opengl: Reintroduce dirty flags for render targets
This commit is contained in:
parent
9e74e6988b
commit
dacf83ac02
9 changed files with 195 additions and 13 deletions
|
@ -99,11 +99,12 @@ void oglEnablei(GLenum cap, bool state, GLuint index) {
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
RasterizerOpenGL::RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
||||||
ScreenInfo& info, GLShader::ProgramManager& program_manager)
|
ScreenInfo& info, GLShader::ProgramManager& program_manager,
|
||||||
: RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device},
|
StateTracker& state_tracker)
|
||||||
|
: RasterizerAccelerated{system.Memory()}, texture_cache{system, *this, device, state_tracker},
|
||||||
shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system},
|
shader_cache{*this, system, emu_window, device}, query_cache{system, *this}, system{system},
|
||||||
screen_info{info}, program_manager{program_manager}, buffer_cache{*this, system, device,
|
screen_info{info}, program_manager{program_manager}, state_tracker{state_tracker},
|
||||||
STREAM_BUFFER_SIZE} {
|
buffer_cache{*this, system, device, STREAM_BUFFER_SIZE} {
|
||||||
CheckExtensions();
|
CheckExtensions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,9 +321,17 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||||
shader_cache.LoadDiskCache(stop_loading, callback);
|
shader_cache.LoadDiskCache(stop_loading, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RasterizerOpenGL::SetupDirtyFlags() {
|
||||||
|
state_tracker.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::ConfigureFramebuffers() {
|
void RasterizerOpenGL::ConfigureFramebuffers() {
|
||||||
MICROPROFILE_SCOPE(OpenGL_Framebuffer);
|
MICROPROFILE_SCOPE(OpenGL_Framebuffer);
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
|
if (!gpu.dirty.flags[VideoCommon::Dirty::RenderTargets]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gpu.dirty.flags[VideoCommon::Dirty::RenderTargets] = false;
|
||||||
|
|
||||||
texture_cache.GuardRenderTargets(true);
|
texture_cache.GuardRenderTargets(true);
|
||||||
|
|
||||||
|
@ -361,8 +370,6 @@ void RasterizerOpenGL::ConfigureFramebuffers() {
|
||||||
|
|
||||||
void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color_fb, bool using_depth_fb,
|
void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color_fb, bool using_depth_fb,
|
||||||
bool using_stencil_fb) {
|
bool using_stencil_fb) {
|
||||||
using VideoCore::Surface::SurfaceType;
|
|
||||||
|
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
const auto& regs = gpu.regs;
|
const auto& regs = gpu.regs;
|
||||||
|
|
||||||
|
@ -381,6 +388,7 @@ void RasterizerOpenGL::ConfigureClearFramebuffer(bool using_color_fb, bool using
|
||||||
key.colors[0] = color_surface;
|
key.colors[0] = color_surface;
|
||||||
key.zeta = depth_surface;
|
key.zeta = depth_surface;
|
||||||
|
|
||||||
|
state_tracker.NotifyFramebuffer();
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key));
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer_cache.GetFramebuffer(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "video_core/renderer_opengl/gl_shader_cache.h"
|
#include "video_core/renderer_opengl/gl_shader_cache.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_decompiler.h"
|
#include "video_core/renderer_opengl/gl_shader_decompiler.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||||
|
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
||||||
#include "video_core/renderer_opengl/gl_texture_cache.h"
|
#include "video_core/renderer_opengl/gl_texture_cache.h"
|
||||||
#include "video_core/renderer_opengl/utils.h"
|
#include "video_core/renderer_opengl/utils.h"
|
||||||
#include "video_core/textures/texture.h"
|
#include "video_core/textures/texture.h"
|
||||||
|
@ -54,7 +55,8 @@ struct DrawParameters;
|
||||||
class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
|
class RasterizerOpenGL : public VideoCore::RasterizerAccelerated {
|
||||||
public:
|
public:
|
||||||
explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
explicit RasterizerOpenGL(Core::System& system, Core::Frontend::EmuWindow& emu_window,
|
||||||
ScreenInfo& info, GLShader::ProgramManager& program_manager);
|
ScreenInfo& info, GLShader::ProgramManager& program_manager,
|
||||||
|
StateTracker& state_tracker);
|
||||||
~RasterizerOpenGL() override;
|
~RasterizerOpenGL() override;
|
||||||
|
|
||||||
void Draw(bool is_indexed, bool is_instanced) override;
|
void Draw(bool is_indexed, bool is_instanced) override;
|
||||||
|
@ -75,6 +77,7 @@ public:
|
||||||
u32 pixel_stride) override;
|
u32 pixel_stride) override;
|
||||||
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
void LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||||
const VideoCore::DiskResourceLoadCallback& callback) override;
|
const VideoCore::DiskResourceLoadCallback& callback) override;
|
||||||
|
void SetupDirtyFlags() override;
|
||||||
|
|
||||||
/// Returns true when there are commands queued to the OpenGL server.
|
/// Returns true when there are commands queued to the OpenGL server.
|
||||||
bool AnyCommandQueued() const {
|
bool AnyCommandQueued() const {
|
||||||
|
@ -216,6 +219,7 @@ private:
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
ScreenInfo& screen_info;
|
ScreenInfo& screen_info;
|
||||||
GLShader::ProgramManager& program_manager;
|
GLShader::ProgramManager& program_manager;
|
||||||
|
StateTracker& state_tracker;
|
||||||
|
|
||||||
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
|
static constexpr std::size_t STREAM_BUFFER_SIZE = 128 * 1024 * 1024;
|
||||||
OGLBufferCache buffer_cache;
|
OGLBufferCache buffer_cache;
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
// Copyright 2019 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
|
#include "video_core/gpu.h"
|
||||||
|
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
||||||
|
|
||||||
|
#define OFF(field_name) MAXWELL3D_REG_INDEX(field_name)
|
||||||
|
#define NUM(field_name) (sizeof(Maxwell3D::Regs::field_name) / sizeof(u32))
|
||||||
|
|
||||||
|
namespace OpenGL {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
using namespace Dirty;
|
||||||
|
using namespace VideoCommon::Dirty;
|
||||||
|
using Tegra::Engines::Maxwell3D;
|
||||||
|
using Regs = Maxwell3D::Regs;
|
||||||
|
using Dirty = std::remove_reference_t<decltype(Maxwell3D::dirty)>;
|
||||||
|
using Tables = std::remove_reference_t<decltype(Maxwell3D::dirty.tables)>;
|
||||||
|
using Table = std::remove_reference_t<decltype(Maxwell3D::dirty.tables[0])>;
|
||||||
|
|
||||||
|
template <typename Integer>
|
||||||
|
void FillBlock(Table& table, std::size_t begin, std::size_t num, Integer dirty_index) {
|
||||||
|
const auto it = std::begin(table) + begin;
|
||||||
|
std::fill(it, it + num, static_cast<u8>(dirty_index));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Integer1, typename Integer2>
|
||||||
|
void FillBlock(Tables& tables, std::size_t begin, std::size_t num, Integer1 index_a,
|
||||||
|
Integer2 index_b) {
|
||||||
|
FillBlock(tables[0], begin, num, index_a);
|
||||||
|
FillBlock(tables[1], begin, num, index_b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetupDirtyRenderTargets(Tables& tables) {
|
||||||
|
static constexpr std::size_t num_per_rt = NUM(rt[0]);
|
||||||
|
static constexpr std::size_t begin = OFF(rt);
|
||||||
|
static constexpr std::size_t num = num_per_rt * Regs::NumRenderTargets;
|
||||||
|
for (std::size_t rt = 0; rt < Regs::NumRenderTargets; ++rt) {
|
||||||
|
FillBlock(tables[0], begin + rt * num_per_rt, num_per_rt, ColorBuffer0 + rt);
|
||||||
|
}
|
||||||
|
FillBlock(tables[1], begin, num, RenderTargets);
|
||||||
|
|
||||||
|
static constexpr std::array zeta_flags{ZetaBuffer, RenderTargets};
|
||||||
|
for (std::size_t i = 0; i < std::size(zeta_flags); ++i) {
|
||||||
|
const u8 flag = zeta_flags[i];
|
||||||
|
auto& table = tables[i];
|
||||||
|
table[OFF(zeta_enable)] = flag;
|
||||||
|
table[OFF(zeta_width)] = flag;
|
||||||
|
table[OFF(zeta_height)] = flag;
|
||||||
|
FillBlock(table, OFF(zeta), NUM(zeta), flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // Anonymous namespace
|
||||||
|
|
||||||
|
StateTracker::StateTracker(Core::System& system) : system{system} {}
|
||||||
|
|
||||||
|
void StateTracker::Initialize() {
|
||||||
|
auto& dirty = system.GPU().Maxwell3D().dirty;
|
||||||
|
std::size_t entry_index = 0;
|
||||||
|
const auto AddEntry = [&dirty, &entry_index](std::size_t dirty_register) {
|
||||||
|
dirty.on_write_stores[entry_index++] = static_cast<u8>(dirty_register);
|
||||||
|
};
|
||||||
|
|
||||||
|
AddEntry(RenderTargets);
|
||||||
|
for (std::size_t i = 0; i < Regs::NumRenderTargets; ++i) {
|
||||||
|
AddEntry(ColorBuffer0 + i);
|
||||||
|
}
|
||||||
|
AddEntry(ZetaBuffer);
|
||||||
|
|
||||||
|
auto& tables = dirty.tables;
|
||||||
|
SetupDirtyRenderTargets(tables);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace OpenGL
|
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2019 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
#include "video_core/dirty_flags.h"
|
||||||
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
|
|
||||||
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace OpenGL {
|
||||||
|
|
||||||
|
namespace Dirty {
|
||||||
|
enum : u8 {
|
||||||
|
First = VideoCommon::Dirty::LastCommonEntry,
|
||||||
|
|
||||||
|
VertexFormats,
|
||||||
|
VertexBuffers,
|
||||||
|
VertexInstances,
|
||||||
|
Shaders,
|
||||||
|
Viewports,
|
||||||
|
CullTestEnable,
|
||||||
|
FrontFace,
|
||||||
|
CullFace,
|
||||||
|
PrimitiveRestart,
|
||||||
|
DepthTest,
|
||||||
|
StencilTest,
|
||||||
|
ColorMask,
|
||||||
|
BlendState,
|
||||||
|
PolygonOffset,
|
||||||
|
|
||||||
|
VertexBuffer0 = PolygonOffset + 8,
|
||||||
|
VertexInstance0 = VertexBuffer0 + 32,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class StateTracker {
|
||||||
|
public:
|
||||||
|
explicit StateTracker(Core::System& system);
|
||||||
|
|
||||||
|
void Initialize();
|
||||||
|
|
||||||
|
void NotifyFramebuffer() {
|
||||||
|
auto& flags = system.GPU().Maxwell3D().dirty.flags;
|
||||||
|
flags[VideoCommon::Dirty::RenderTargets] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Core::System& system;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OpenGL
|
|
@ -10,6 +10,7 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "video_core/morton.h"
|
#include "video_core/morton.h"
|
||||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||||
|
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
||||||
#include "video_core/renderer_opengl/gl_texture_cache.h"
|
#include "video_core/renderer_opengl/gl_texture_cache.h"
|
||||||
#include "video_core/renderer_opengl/utils.h"
|
#include "video_core/renderer_opengl/utils.h"
|
||||||
#include "video_core/texture_cache/surface_base.h"
|
#include "video_core/texture_cache/surface_base.h"
|
||||||
|
@ -479,8 +480,8 @@ OGLTextureView CachedSurfaceView::CreateTextureView() const {
|
||||||
|
|
||||||
TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system,
|
TextureCacheOpenGL::TextureCacheOpenGL(Core::System& system,
|
||||||
VideoCore::RasterizerInterface& rasterizer,
|
VideoCore::RasterizerInterface& rasterizer,
|
||||||
const Device& device)
|
const Device& device, StateTracker& state_tracker)
|
||||||
: TextureCacheBase{system, rasterizer} {
|
: TextureCacheBase{system, rasterizer}, state_tracker{state_tracker} {
|
||||||
src_framebuffer.Create();
|
src_framebuffer.Create();
|
||||||
dst_framebuffer.Create();
|
dst_framebuffer.Create();
|
||||||
}
|
}
|
||||||
|
@ -518,6 +519,8 @@ void TextureCacheOpenGL::ImageBlit(View& src_view, View& dst_view,
|
||||||
UNIMPLEMENTED_IF(dst_params.target == SurfaceTarget::Texture3D);
|
UNIMPLEMENTED_IF(dst_params.target == SurfaceTarget::Texture3D);
|
||||||
|
|
||||||
// TODO: Signal state tracker about these changes
|
// TODO: Signal state tracker about these changes
|
||||||
|
state_tracker.NotifyFramebuffer();
|
||||||
|
|
||||||
if (dst_params.srgb_conversion) {
|
if (dst_params.srgb_conversion) {
|
||||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -27,6 +27,7 @@ using VideoCommon::ViewParams;
|
||||||
class CachedSurfaceView;
|
class CachedSurfaceView;
|
||||||
class CachedSurface;
|
class CachedSurface;
|
||||||
class TextureCacheOpenGL;
|
class TextureCacheOpenGL;
|
||||||
|
class StateTracker;
|
||||||
|
|
||||||
using Surface = std::shared_ptr<CachedSurface>;
|
using Surface = std::shared_ptr<CachedSurface>;
|
||||||
using View = std::shared_ptr<CachedSurfaceView>;
|
using View = std::shared_ptr<CachedSurfaceView>;
|
||||||
|
@ -127,7 +128,7 @@ private:
|
||||||
class TextureCacheOpenGL final : public TextureCacheBase {
|
class TextureCacheOpenGL final : public TextureCacheBase {
|
||||||
public:
|
public:
|
||||||
explicit TextureCacheOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
explicit TextureCacheOpenGL(Core::System& system, VideoCore::RasterizerInterface& rasterizer,
|
||||||
const Device& device);
|
const Device& device, StateTracker& state_tracker);
|
||||||
~TextureCacheOpenGL();
|
~TextureCacheOpenGL();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -144,6 +145,8 @@ protected:
|
||||||
private:
|
private:
|
||||||
GLuint FetchPBO(std::size_t buffer_size);
|
GLuint FetchPBO(std::size_t buffer_size);
|
||||||
|
|
||||||
|
StateTracker& state_tracker;
|
||||||
|
|
||||||
OGLFramebuffer src_framebuffer;
|
OGLFramebuffer src_framebuffer;
|
||||||
OGLFramebuffer dst_framebuffer;
|
OGLFramebuffer dst_framebuffer;
|
||||||
std::unordered_map<u32, OGLBuffer> copy_pbo_cache;
|
std::unordered_map<u32, OGLBuffer> copy_pbo_cache;
|
||||||
|
|
|
@ -482,8 +482,8 @@ void RendererOpenGL::CreateRasterizer() {
|
||||||
if (rasterizer) {
|
if (rasterizer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
rasterizer =
|
rasterizer = std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info,
|
||||||
std::make_unique<RasterizerOpenGL>(system, emu_window, screen_info, program_manager);
|
program_manager, state_tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
|
void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture,
|
||||||
|
@ -576,6 +576,8 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
|
||||||
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
|
glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
|
||||||
|
|
||||||
// TODO: Signal state tracker about these changes
|
// TODO: Signal state tracker about these changes
|
||||||
|
state_tracker.NotifyFramebuffer();
|
||||||
|
|
||||||
program_manager.UseVertexShader(vertex_program.handle);
|
program_manager.UseVertexShader(vertex_program.handle);
|
||||||
program_manager.UseGeometryShader(0);
|
program_manager.UseGeometryShader(0);
|
||||||
program_manager.UseFragmentShader(fragment_program.handle);
|
program_manager.UseFragmentShader(fragment_program.handle);
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
#include "video_core/renderer_opengl/gl_resource_manager.h"
|
||||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||||
|
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
|
@ -91,6 +92,8 @@ private:
|
||||||
Core::Frontend::EmuWindow& emu_window;
|
Core::Frontend::EmuWindow& emu_window;
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
|
||||||
|
StateTracker state_tracker{system};
|
||||||
|
|
||||||
// OpenGL object IDs
|
// OpenGL object IDs
|
||||||
OGLBuffer vertex_buffer;
|
OGLBuffer vertex_buffer;
|
||||||
OGLProgram vertex_program;
|
OGLProgram vertex_program;
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
|
#include "video_core/dirty_flags.h"
|
||||||
#include "video_core/engines/fermi_2d.h"
|
#include "video_core/engines/fermi_2d.h"
|
||||||
#include "video_core/engines/maxwell_3d.h"
|
#include "video_core/engines/maxwell_3d.h"
|
||||||
#include "video_core/gpu.h"
|
#include "video_core/gpu.h"
|
||||||
|
@ -142,6 +143,10 @@ public:
|
||||||
TView GetDepthBufferSurface(bool preserve_contents) {
|
TView GetDepthBufferSurface(bool preserve_contents) {
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
auto& maxwell3d = system.GPU().Maxwell3D();
|
auto& maxwell3d = system.GPU().Maxwell3D();
|
||||||
|
if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ZetaBuffer]) {
|
||||||
|
return depth_buffer.view;
|
||||||
|
}
|
||||||
|
maxwell3d.dirty.flags[VideoCommon::Dirty::ZetaBuffer] = false;
|
||||||
|
|
||||||
const auto& regs{maxwell3d.regs};
|
const auto& regs{maxwell3d.regs};
|
||||||
const auto gpu_addr{regs.zeta.Address()};
|
const auto gpu_addr{regs.zeta.Address()};
|
||||||
|
@ -170,6 +175,10 @@ public:
|
||||||
std::lock_guard lock{mutex};
|
std::lock_guard lock{mutex};
|
||||||
ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets);
|
ASSERT(index < Tegra::Engines::Maxwell3D::Regs::NumRenderTargets);
|
||||||
auto& maxwell3d = system.GPU().Maxwell3D();
|
auto& maxwell3d = system.GPU().Maxwell3D();
|
||||||
|
if (!maxwell3d.dirty.flags[VideoCommon::Dirty::ColorBuffer0 + index]) {
|
||||||
|
return render_targets[index].view;
|
||||||
|
}
|
||||||
|
maxwell3d.dirty.flags[VideoCommon::Dirty::ColorBuffer0 + index] = false;
|
||||||
|
|
||||||
const auto& regs{maxwell3d.regs};
|
const auto& regs{maxwell3d.regs};
|
||||||
if (index >= regs.rt_control.count || regs.rt[index].Address() == 0 ||
|
if (index >= regs.rt_control.count || regs.rt[index].Address() == 0 ||
|
||||||
|
@ -310,7 +319,16 @@ protected:
|
||||||
// and reading it from a separate buffer.
|
// and reading it from a separate buffer.
|
||||||
virtual void BufferCopy(TSurface& src_surface, TSurface& dst_surface) = 0;
|
virtual void BufferCopy(TSurface& src_surface, TSurface& dst_surface) = 0;
|
||||||
|
|
||||||
void ManageRenderTargetUnregister([[maybe_unused]] TSurface& surface) {}
|
void ManageRenderTargetUnregister(TSurface& surface) {
|
||||||
|
auto& dirty = system.GPU().Maxwell3D().dirty;
|
||||||
|
const u32 index = surface->GetRenderTarget();
|
||||||
|
if (index == DEPTH_RT) {
|
||||||
|
dirty.flags[VideoCommon::Dirty::ZetaBuffer] = true;
|
||||||
|
} else {
|
||||||
|
dirty.flags[VideoCommon::Dirty::ColorBuffer0 + index] = true;
|
||||||
|
}
|
||||||
|
dirty.flags[VideoCommon::Dirty::RenderTargets] = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Register(TSurface surface) {
|
void Register(TSurface surface) {
|
||||||
const GPUVAddr gpu_addr = surface->GetGpuAddr();
|
const GPUVAddr gpu_addr = surface->GetGpuAddr();
|
||||||
|
|
Loading…
Reference in a new issue