Remove Framebuffer reconfiguration and restrict rendertarget protection
This commit is contained in:
parent
5192521dc3
commit
1bbc9debfb
|
@ -461,15 +461,15 @@ void RasterizerOpenGL::LoadDiskResources(const std::atomic_bool& stop_loading,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
|
std::pair<bool, bool> RasterizerOpenGL::ConfigureFramebuffers(
|
||||||
OpenGLState& current_state, bool must_reconfigure, bool using_color_fb, bool using_depth_fb,
|
OpenGLState& current_state, bool using_color_fb, bool using_depth_fb, bool preserve_contents,
|
||||||
bool preserve_contents, std::optional<std::size_t> single_color_target) {
|
std::optional<std::size_t> single_color_target) {
|
||||||
MICROPROFILE_SCOPE(OpenGL_Framebuffer);
|
MICROPROFILE_SCOPE(OpenGL_Framebuffer);
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
const auto& regs = gpu.regs;
|
const auto& regs = gpu.regs;
|
||||||
|
|
||||||
const FramebufferConfigState fb_config_state{using_color_fb, using_depth_fb, preserve_contents,
|
const FramebufferConfigState fb_config_state{using_color_fb, using_depth_fb, preserve_contents,
|
||||||
single_color_target};
|
single_color_target};
|
||||||
if (!must_reconfigure && fb_config_state == current_framebuffer_config_state &&
|
if (fb_config_state == current_framebuffer_config_state &&
|
||||||
gpu.dirty_flags.color_buffer.none() && !gpu.dirty_flags.zeta_buffer) {
|
gpu.dirty_flags.color_buffer.none() && !gpu.dirty_flags.zeta_buffer) {
|
||||||
// Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or
|
// Only skip if the previous ConfigureFramebuffers call was from the same kind (multiple or
|
||||||
// single color targets). This is done because the guest registers may not change but the
|
// single color targets). This is done because the guest registers may not change but the
|
||||||
|
@ -622,9 +622,8 @@ void RasterizerOpenGL::Clear() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto [clear_depth, clear_stencil] =
|
const auto [clear_depth, clear_stencil] = ConfigureFramebuffers(
|
||||||
ConfigureFramebuffers(clear_state, false, use_color, use_depth || use_stencil, false,
|
clear_state, use_color, use_depth || use_stencil, false, regs.clear_buffers.RT.Value());
|
||||||
regs.clear_buffers.RT.Value());
|
|
||||||
if (regs.clear_flags.scissor) {
|
if (regs.clear_flags.scissor) {
|
||||||
SyncScissorTest(clear_state);
|
SyncScissorTest(clear_state);
|
||||||
}
|
}
|
||||||
|
@ -659,7 +658,6 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
auto& gpu = system.GPU().Maxwell3D();
|
auto& gpu = system.GPU().Maxwell3D();
|
||||||
const auto& regs = gpu.regs;
|
const auto& regs = gpu.regs;
|
||||||
|
|
||||||
ConfigureFramebuffers(state);
|
|
||||||
SyncColorMask();
|
SyncColorMask();
|
||||||
SyncFragmentColorClampState();
|
SyncFragmentColorClampState();
|
||||||
SyncMultiSampleState();
|
SyncMultiSampleState();
|
||||||
|
@ -706,9 +704,7 @@ void RasterizerOpenGL::DrawArrays() {
|
||||||
DrawParameters params = SetupDraw();
|
DrawParameters params = SetupDraw();
|
||||||
SetupShaders(params.primitive_mode);
|
SetupShaders(params.primitive_mode);
|
||||||
|
|
||||||
if (texture_cache.ConsumeReconfigurationFlag()) {
|
ConfigureFramebuffers(state);
|
||||||
ConfigureFramebuffers(state, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
buffer_cache.Unmap();
|
buffer_cache.Unmap();
|
||||||
|
|
||||||
|
|
|
@ -111,9 +111,8 @@ private:
|
||||||
* (requires using_depth_fb to be true)
|
* (requires using_depth_fb to be true)
|
||||||
*/
|
*/
|
||||||
std::pair<bool, bool> ConfigureFramebuffers(
|
std::pair<bool, bool> ConfigureFramebuffers(
|
||||||
OpenGLState& current_state, bool must_reconfigure = false, bool use_color_fb = true,
|
OpenGLState& current_state, bool use_color_fb = true, bool using_depth_fb = true,
|
||||||
bool using_depth_fb = true, bool preserve_contents = true,
|
bool preserve_contents = true, std::optional<std::size_t> single_color_target = {});
|
||||||
std::optional<std::size_t> single_color_target = {});
|
|
||||||
|
|
||||||
/// Configures the current constbuffers to use for the draw command.
|
/// Configures the current constbuffers to use for the draw command.
|
||||||
void SetupDrawConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
|
void SetupDrawConstBuffers(Tegra::Engines::Maxwell3D::Regs::ShaderStage stage,
|
||||||
|
|
|
@ -218,12 +218,12 @@ public:
|
||||||
virtual void DownloadTexture(std::vector<u8>& staging_buffer) = 0;
|
virtual void DownloadTexture(std::vector<u8>& staging_buffer) = 0;
|
||||||
|
|
||||||
void MarkAsModified(const bool is_modified_, const u64 tick) {
|
void MarkAsModified(const bool is_modified_, const u64 tick) {
|
||||||
is_modified = is_modified_ || is_protected;
|
is_modified = is_modified_ || is_target;
|
||||||
modification_tick = tick;
|
modification_tick = tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkAsProtected(const bool is_protected) {
|
void MarkAsRenderTarget(const bool is_target) {
|
||||||
this->is_protected = is_protected;
|
this->is_target = is_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MarkAsPicked(const bool is_picked) {
|
void MarkAsPicked(const bool is_picked) {
|
||||||
|
@ -235,7 +235,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsProtected() const {
|
bool IsProtected() const {
|
||||||
return is_protected;
|
// Only 3D Slices are to be protected
|
||||||
|
return is_target && params.block_depth > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsRenderTarget() const {
|
||||||
|
return is_target;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsRegistered() const {
|
bool IsRegistered() const {
|
||||||
|
@ -307,7 +312,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_modified{};
|
bool is_modified{};
|
||||||
bool is_protected{};
|
bool is_target{};
|
||||||
bool is_registered{};
|
bool is_registered{};
|
||||||
bool is_picked{};
|
bool is_picked{};
|
||||||
u64 modification_tick{};
|
u64 modification_tick{};
|
||||||
|
|
|
@ -105,11 +105,11 @@ public:
|
||||||
regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)};
|
regs.zeta.memory_layout.block_depth, regs.zeta.memory_layout.type)};
|
||||||
auto surface_view = GetSurface(gpu_addr, depth_params, preserve_contents);
|
auto surface_view = GetSurface(gpu_addr, depth_params, preserve_contents);
|
||||||
if (depth_buffer.target)
|
if (depth_buffer.target)
|
||||||
depth_buffer.target->MarkAsProtected(false);
|
depth_buffer.target->MarkAsRenderTarget(false);
|
||||||
depth_buffer.target = surface_view.first;
|
depth_buffer.target = surface_view.first;
|
||||||
depth_buffer.view = surface_view.second;
|
depth_buffer.view = surface_view.second;
|
||||||
if (depth_buffer.target)
|
if (depth_buffer.target)
|
||||||
depth_buffer.target->MarkAsProtected(true);
|
depth_buffer.target->MarkAsRenderTarget(true);
|
||||||
return surface_view.second;
|
return surface_view.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,11 +138,11 @@ public:
|
||||||
auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index),
|
auto surface_view = GetSurface(gpu_addr, SurfaceParams::CreateForFramebuffer(system, index),
|
||||||
preserve_contents);
|
preserve_contents);
|
||||||
if (render_targets[index].target)
|
if (render_targets[index].target)
|
||||||
render_targets[index].target->MarkAsProtected(false);
|
render_targets[index].target->MarkAsRenderTarget(false);
|
||||||
render_targets[index].target = surface_view.first;
|
render_targets[index].target = surface_view.first;
|
||||||
render_targets[index].view = surface_view.second;
|
render_targets[index].view = surface_view.second;
|
||||||
if (render_targets[index].target)
|
if (render_targets[index].target)
|
||||||
render_targets[index].target->MarkAsProtected(true);
|
render_targets[index].target->MarkAsRenderTarget(true);
|
||||||
return surface_view.second;
|
return surface_view.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,7 +158,7 @@ public:
|
||||||
|
|
||||||
void SetEmptyDepthBuffer() {
|
void SetEmptyDepthBuffer() {
|
||||||
if (depth_buffer.target != nullptr) {
|
if (depth_buffer.target != nullptr) {
|
||||||
depth_buffer.target->MarkAsProtected(false);
|
depth_buffer.target->MarkAsRenderTarget(false);
|
||||||
depth_buffer.target = nullptr;
|
depth_buffer.target = nullptr;
|
||||||
depth_buffer.view = nullptr;
|
depth_buffer.view = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ public:
|
||||||
|
|
||||||
void SetEmptyColorBuffer(std::size_t index) {
|
void SetEmptyColorBuffer(std::size_t index) {
|
||||||
if (render_targets[index].target != nullptr) {
|
if (render_targets[index].target != nullptr) {
|
||||||
render_targets[index].target->MarkAsProtected(false);
|
render_targets[index].target->MarkAsRenderTarget(false);
|
||||||
render_targets[index].target = nullptr;
|
render_targets[index].target = nullptr;
|
||||||
render_targets[index].view = nullptr;
|
render_targets[index].view = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -200,12 +200,6 @@ public:
|
||||||
return ++ticks;
|
return ++ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ConsumeReconfigurationFlag() {
|
|
||||||
const bool result = force_reconfiguration;
|
|
||||||
force_reconfiguration = false;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer)
|
TextureCache(Core::System& system, VideoCore::RasterizerInterface& rasterizer)
|
||||||
: system{system}, rasterizer{rasterizer} {
|
: system{system}, rasterizer{rasterizer} {
|
||||||
|
@ -242,8 +236,8 @@ protected:
|
||||||
rasterizer.UpdatePagesCachedCount(*cpu_addr, size, 1);
|
rasterizer.UpdatePagesCachedCount(*cpu_addr, size, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Unregister(TSurface surface, const bool force_unregister = false) {
|
void Unregister(TSurface surface) {
|
||||||
if (surface->IsProtected() && !force_unregister) {
|
if (surface->IsProtected()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const GPUVAddr gpu_addr = surface->GetGpuAddr();
|
const GPUVAddr gpu_addr = surface->GetGpuAddr();
|
||||||
|
@ -392,10 +386,8 @@ private:
|
||||||
std::min(src_params.height, dst_height), 1);
|
std::min(src_params.height, dst_height), 1);
|
||||||
ImageCopy(surface, new_surface, copy_params);
|
ImageCopy(surface, new_surface, copy_params);
|
||||||
}
|
}
|
||||||
force_reconfiguration = false;
|
|
||||||
for (auto surface : overlaps) {
|
for (auto surface : overlaps) {
|
||||||
force_reconfiguration |= surface->IsProtected();
|
Unregister(surface);
|
||||||
Unregister(surface, true);
|
|
||||||
}
|
}
|
||||||
new_surface->MarkAsModified(modified, Tick());
|
new_surface->MarkAsModified(modified, Tick());
|
||||||
Register(new_surface);
|
Register(new_surface);
|
||||||
|
@ -567,10 +559,6 @@ private:
|
||||||
|
|
||||||
u64 ticks{};
|
u64 ticks{};
|
||||||
|
|
||||||
// Sometimes Setup Textures can hit a surface that's on the render target, when this happens
|
|
||||||
// we force a reconfiguration of the frame buffer after setup.
|
|
||||||
bool force_reconfiguration;
|
|
||||||
|
|
||||||
// The internal Cache is different for the Texture Cache. It's based on buckets
|
// The internal Cache is different for the Texture Cache. It's based on buckets
|
||||||
// of 1MB. This fits better for the purpose of this cache as textures are normaly
|
// of 1MB. This fits better for the purpose of this cache as textures are normaly
|
||||||
// large in size.
|
// large in size.
|
||||||
|
|
Reference in New Issue