|
|
|
@@ -1,6 +1,7 @@
|
|
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "surface_utils.h"
|
|
|
|
|
#include "simple_array.hpp"
|
|
|
|
|
#include "../gcm_enums.h"
|
|
|
|
|
#include "../rsx_utils.h"
|
|
|
|
|
#include <list>
|
|
|
|
@@ -56,10 +57,9 @@ namespace rsx
|
|
|
|
|
rsx::surface_raster_type m_active_raster_type = rsx::surface_raster_type::linear;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
std::pair<u8, u8> m_bound_render_targets_config = {};
|
|
|
|
|
rsx::simple_array<u8> m_bound_render_target_ids = {};
|
|
|
|
|
std::array<std::pair<u32, surface_type>, 4> m_bound_render_targets = {};
|
|
|
|
|
std::pair<u32, surface_type> m_bound_depth_stencil = {};
|
|
|
|
|
u8 m_bound_buffers_count = 0;
|
|
|
|
|
|
|
|
|
|
// List of sections derived from a section that has been split and invalidated
|
|
|
|
|
std::vector<surface_type> orphaned_surfaces;
|
|
|
|
@@ -840,23 +840,19 @@ namespace rsx
|
|
|
|
|
cache_tag = rsx::get_shared_tag();
|
|
|
|
|
m_invalidate_on_write = (antialias != rsx::surface_antialiasing::center_1_sample);
|
|
|
|
|
m_active_raster_type = raster_type;
|
|
|
|
|
m_bound_buffers_count = 0;
|
|
|
|
|
|
|
|
|
|
// Make previous RTTs sampleable
|
|
|
|
|
for (int i = m_bound_render_targets_config.first, count = 0;
|
|
|
|
|
count < m_bound_render_targets_config.second;
|
|
|
|
|
++i, ++count)
|
|
|
|
|
for (const auto& i : m_bound_render_target_ids)
|
|
|
|
|
{
|
|
|
|
|
auto &rtt = m_bound_render_targets[i];
|
|
|
|
|
Traits::prepare_surface_for_sampling(command_list, std::get<1>(rtt));
|
|
|
|
|
rtt = std::make_pair(0, nullptr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto rtt_indices = utility::get_rtt_indexes(set_surface_target);
|
|
|
|
|
if (!rtt_indices.empty()) [[likely]]
|
|
|
|
|
m_bound_render_target_ids.clear();
|
|
|
|
|
if (const auto rtt_indices = utility::get_rtt_indexes(set_surface_target);
|
|
|
|
|
!rtt_indices.empty()) [[likely]]
|
|
|
|
|
{
|
|
|
|
|
m_bound_render_targets_config = { rtt_indices.front(), 0 };
|
|
|
|
|
|
|
|
|
|
// Create/Reuse requested rtts
|
|
|
|
|
for (u8 surface_index : rtt_indices)
|
|
|
|
|
{
|
|
|
|
@@ -867,14 +863,9 @@ namespace rsx
|
|
|
|
|
bind_address_as_render_targets(command_list, surface_addresses[surface_index], color_format, antialias,
|
|
|
|
|
clip_width, clip_height, surface_pitch[surface_index], std::forward<Args>(extra_params)...));
|
|
|
|
|
|
|
|
|
|
++m_bound_render_targets_config.second;
|
|
|
|
|
++m_bound_buffers_count;
|
|
|
|
|
m_bound_render_target_ids.push_back(surface_index);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_bound_render_targets_config = { 0, 0 };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Same for depth buffer
|
|
|
|
|
if (std::get<1>(m_bound_depth_stencil) != nullptr)
|
|
|
|
@@ -887,8 +878,6 @@ namespace rsx
|
|
|
|
|
m_bound_depth_stencil = std::make_pair(address_z,
|
|
|
|
|
bind_address_as_depth_stencil(command_list, address_z, depth_format, antialias,
|
|
|
|
|
clip_width, clip_height, zeta_pitch, std::forward<Args>(extra_params)...));
|
|
|
|
|
|
|
|
|
|
++m_bound_buffers_count;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@@ -898,7 +887,7 @@ namespace rsx
|
|
|
|
|
|
|
|
|
|
u8 get_color_surface_count() const
|
|
|
|
|
{
|
|
|
|
|
return m_bound_render_targets_config.second;
|
|
|
|
|
return static_cast<u8>(m_bound_render_target_ids.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
surface_type get_surface_at(u32 address)
|
|
|
|
@@ -947,14 +936,15 @@ namespace rsx
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool address_is_bound(u32 address) const
|
|
|
|
|
inline bool address_is_bound(u32 address) const
|
|
|
|
|
{
|
|
|
|
|
for (int i = m_bound_render_targets_config.first, count = 0;
|
|
|
|
|
count < m_bound_render_targets_config.second;
|
|
|
|
|
++i, ++count)
|
|
|
|
|
ensure(address);
|
|
|
|
|
for (int i = 0; i < 4; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (m_bound_render_targets[i].first == address)
|
|
|
|
|
{
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (m_bound_depth_stencil.first == address);
|
|
|
|
@@ -1127,21 +1117,33 @@ namespace rsx
|
|
|
|
|
// TODO: Take WCB/WDB into account. Should speed this up a bit by skipping sync_tag calls
|
|
|
|
|
write_tag = rsx::get_shared_tag();
|
|
|
|
|
|
|
|
|
|
for (u8 i = m_bound_render_targets_config.first, count = 0;
|
|
|
|
|
count < m_bound_render_targets_config.second;
|
|
|
|
|
++count, ++i)
|
|
|
|
|
for (const auto& i : m_bound_render_target_ids)
|
|
|
|
|
{
|
|
|
|
|
if (auto surface = m_bound_render_targets[i].second;
|
|
|
|
|
surface && color_mrt_writes_enabled[i])
|
|
|
|
|
if (color_mrt_writes_enabled[i])
|
|
|
|
|
{
|
|
|
|
|
surface->on_write(write_tag);
|
|
|
|
|
auto surface = m_bound_render_targets[i].second;
|
|
|
|
|
if (surface->last_use_tag > cache_tag) [[ likely ]]
|
|
|
|
|
{
|
|
|
|
|
surface->on_write_fast(write_tag);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
surface->on_write(write_tag, rsx::surface_state_flags::require_resolve, m_active_raster_type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (auto zsurface = m_bound_depth_stencil.second;
|
|
|
|
|
zsurface && depth_stencil_writes_enabled)
|
|
|
|
|
{
|
|
|
|
|
zsurface->on_write(write_tag);
|
|
|
|
|
if (zsurface->last_use_tag > cache_tag) [[ likely ]]
|
|
|
|
|
{
|
|
|
|
|
zsurface->on_write_fast(write_tag);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
zsurface->on_write(write_tag, rsx::surface_state_flags::require_resolve, m_active_raster_type);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -1164,7 +1166,7 @@ namespace rsx
|
|
|
|
|
ensure(m_active_memory_used == 0);
|
|
|
|
|
|
|
|
|
|
m_bound_depth_stencil = std::make_pair(0, nullptr);
|
|
|
|
|
m_bound_render_targets_config = { 0, 0 };
|
|
|
|
|
m_bound_render_target_ids.clear();
|
|
|
|
|
for (auto &rtt : m_bound_render_targets)
|
|
|
|
|
{
|
|
|
|
|
rtt = std::make_pair(0, nullptr);
|
|
|
|
|