mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-07-10 01:54:46 -06:00
rsx: Move blit target storage to the surface cache
This commit is contained in:
parent
93dfd3a8ca
commit
5cd5e8435d
@ -532,7 +532,7 @@ namespace rsx
|
||||
if (!new_surface)
|
||||
{
|
||||
ensure(store);
|
||||
new_surface_storage = Traits::create_new_surface(address, format, width, height, pitch, antialias, scaling_config, std::forward<Args>(extra_params)...);
|
||||
new_surface_storage = Traits::create_new_surface(command_list, address, format, width, height, pitch, antialias, scaling_config, std::forward<Args>(extra_params)...);
|
||||
new_surface = Traits::get(new_surface_storage);
|
||||
Traits::prepare_surface_for_drawing(command_list, new_surface);
|
||||
allocate_rsx_memory(new_surface);
|
||||
@ -1027,6 +1027,39 @@ namespace rsx
|
||||
}
|
||||
}
|
||||
|
||||
// Create surface on-demand from an RSX image description
|
||||
template <typename ...Args>
|
||||
surface_type create_surface_from_rsx_section(
|
||||
command_list_type command_list,
|
||||
const rsx::image_section_attributes_t& attributes,
|
||||
Args&&... extra_params)
|
||||
{
|
||||
if (rsx::classify_format(attributes.gcm_format) == RSX_FORMAT_CLASS_COLOR)
|
||||
{
|
||||
return bind_address_as_render_targets(
|
||||
command_list,
|
||||
attributes.address,
|
||||
rsx::get_compatible_surface_color_format(attributes.gcm_format),
|
||||
rsx::surface_antialiasing::center_1_sample,
|
||||
attributes.width,
|
||||
attributes.height,
|
||||
attributes.pitch,
|
||||
{},
|
||||
std::forward<Args>(extra_params)...);
|
||||
}
|
||||
|
||||
return bind_address_as_depth_stencil(
|
||||
command_list,
|
||||
attributes.address,
|
||||
rsx::get_compatible_surface_depth_format(attributes.gcm_format),
|
||||
rsx::surface_antialiasing::center_1_sample,
|
||||
attributes.width,
|
||||
attributes.height,
|
||||
attributes.pitch,
|
||||
{},
|
||||
std::forward<Args>(extra_params)...);
|
||||
}
|
||||
|
||||
u8 get_color_surface_count() const
|
||||
{
|
||||
return static_cast<u8>(m_bound_render_target_ids.size());
|
||||
|
||||
@ -12,10 +12,11 @@ namespace rsx
|
||||
{
|
||||
enum surface_state_flags : u32
|
||||
{
|
||||
ready = 0,
|
||||
erase_bkgnd = 1,
|
||||
require_resolve = 2,
|
||||
require_unresolve = 4
|
||||
ready = 0x00,
|
||||
erase_bkgnd = 0x01,
|
||||
require_resolve = 0x02,
|
||||
require_unresolve = 0x04,
|
||||
force_data_load = 0x08
|
||||
};
|
||||
|
||||
enum class surface_sample_layout : u32
|
||||
|
||||
@ -1158,6 +1158,71 @@ namespace rsx
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename ...FlushArgs, typename ...Args>
|
||||
void lock_memory_region_impl(commandbuffer_type& cmd, image_storage_type* image, const address_range32& rsx_range, bool is_active_surface, u16 width, u16 height, u32 pitch, Args&&... extras)
|
||||
{
|
||||
// Find a cached section to use
|
||||
image_section_attributes_t search_desc = { .gcm_format = RSX_GCM_FORMAT_IGNORED, .width = width, .height = height };
|
||||
section_storage_type& region = *find_cached_texture(rsx_range, search_desc, true, true, false);
|
||||
|
||||
// Prepare and initialize fbo region
|
||||
if (region.exists() && region.get_context() != texture_upload_context::framebuffer_storage)
|
||||
{
|
||||
//This space was being used for other purposes other than framebuffer storage
|
||||
//Delete used resources before attaching it to framebuffer memory
|
||||
read_only_tex_invalidate = true;
|
||||
}
|
||||
|
||||
if (!region.is_locked() || region.get_context() != texture_upload_context::framebuffer_storage)
|
||||
{
|
||||
// Invalidate sections from surface cache occupying same address range
|
||||
invalidate_range_impl_base(cmd, rsx_range, invalidation_cause::superseded_by_fbo);
|
||||
}
|
||||
|
||||
if (!region.is_locked() || region.can_be_reused())
|
||||
{
|
||||
// New region, we must prepare it
|
||||
region.reset(rsx_range);
|
||||
no_access_range = region.get_min_max(no_access_range, rsx::section_bounds::locked_range);
|
||||
region.set_context(texture_upload_context::framebuffer_storage);
|
||||
region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Re-using clean fbo region
|
||||
ensure(region.matches(rsx_range));
|
||||
ensure(region.get_context() == texture_upload_context::framebuffer_storage);
|
||||
ensure(region.get_image_type() == rsx::texture_dimension_extended::texture_dimension_2d);
|
||||
}
|
||||
|
||||
region.create(width, height, 1, 1, image, pitch, false, std::forward<Args>(extras)...);
|
||||
region.reprotect(utils::protection::no, { 0, rsx_range.length() });
|
||||
|
||||
region.set_dirty(false);
|
||||
region.touch(m_cache_update_tag);
|
||||
|
||||
if (is_active_surface)
|
||||
{
|
||||
// Add to flush always cache
|
||||
if (region.get_memory_read_flags() != memory_read_flags::flush_always)
|
||||
{
|
||||
region.set_memory_read_flags(memory_read_flags::flush_always, false);
|
||||
update_flush_always_cache(region, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
AUDIT(m_flush_always_cache.find(region.get_section_range()) != m_flush_always_cache.end());
|
||||
}
|
||||
}
|
||||
|
||||
update_cache_tag();
|
||||
|
||||
#ifdef TEXTURE_CACHE_DEBUG
|
||||
// Check that the cache makes sense
|
||||
tex_cache_checker.verify();
|
||||
#endif // TEXTURE_CACHE_DEBUG
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
texture_cache() : m_storage(this), m_predictor(this) {}
|
||||
@ -1345,72 +1410,13 @@ namespace rsx
|
||||
}
|
||||
|
||||
template <typename ...FlushArgs, typename ...Args>
|
||||
void lock_memory_region(commandbuffer_type& cmd, image_storage_type* image, const address_range32 &rsx_range, bool is_active_surface, u16 width, u16 height, u32 pitch, Args&&... extras)
|
||||
void lock_memory_region(commandbuffer_type& cmd, image_storage_type* image, const address_range32& rsx_range, bool is_active_surface, u16 width, u16 height, u32 pitch, Args&&... extras)
|
||||
{
|
||||
AUDIT(g_cfg.video.write_color_buffers || g_cfg.video.write_depth_buffer); // this method is only called when either WCB or WDB are enabled
|
||||
|
||||
std::lock_guard lock(m_cache_mutex);
|
||||
|
||||
// Find a cached section to use
|
||||
image_section_attributes_t search_desc = { .gcm_format = RSX_GCM_FORMAT_IGNORED, .width = width, .height = height };
|
||||
section_storage_type& region = *find_cached_texture(rsx_range, search_desc, true, true, false);
|
||||
|
||||
// Prepare and initialize fbo region
|
||||
if (region.exists() && region.get_context() != texture_upload_context::framebuffer_storage)
|
||||
{
|
||||
//This space was being used for other purposes other than framebuffer storage
|
||||
//Delete used resources before attaching it to framebuffer memory
|
||||
read_only_tex_invalidate = true;
|
||||
}
|
||||
|
||||
if (!region.is_locked() || region.get_context() != texture_upload_context::framebuffer_storage)
|
||||
{
|
||||
// Invalidate sections from surface cache occupying same address range
|
||||
invalidate_range_impl_base(cmd, rsx_range, invalidation_cause::superseded_by_fbo);
|
||||
}
|
||||
|
||||
if (!region.is_locked() || region.can_be_reused())
|
||||
{
|
||||
// New region, we must prepare it
|
||||
region.reset(rsx_range);
|
||||
no_access_range = region.get_min_max(no_access_range, rsx::section_bounds::locked_range);
|
||||
region.set_context(texture_upload_context::framebuffer_storage);
|
||||
region.set_image_type(rsx::texture_dimension_extended::texture_dimension_2d);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Re-using clean fbo region
|
||||
ensure(region.matches(rsx_range));
|
||||
ensure(region.get_context() == texture_upload_context::framebuffer_storage);
|
||||
ensure(region.get_image_type() == rsx::texture_dimension_extended::texture_dimension_2d);
|
||||
}
|
||||
|
||||
region.create(width, height, 1, 1, image, pitch, false, std::forward<Args>(extras)...);
|
||||
region.reprotect(utils::protection::no, { 0, rsx_range.length() });
|
||||
|
||||
region.set_dirty(false);
|
||||
region.touch(m_cache_update_tag);
|
||||
|
||||
if (is_active_surface)
|
||||
{
|
||||
// Add to flush always cache
|
||||
if (region.get_memory_read_flags() != memory_read_flags::flush_always)
|
||||
{
|
||||
region.set_memory_read_flags(memory_read_flags::flush_always, false);
|
||||
update_flush_always_cache(region, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
AUDIT(m_flush_always_cache.find(region.get_section_range()) != m_flush_always_cache.end());
|
||||
}
|
||||
}
|
||||
|
||||
update_cache_tag();
|
||||
|
||||
#ifdef TEXTURE_CACHE_DEBUG
|
||||
// Check that the cache makes sense
|
||||
tex_cache_checker.verify();
|
||||
#endif // TEXTURE_CACHE_DEBUG
|
||||
lock_memory_region_impl(cmd, image, rsx_range, is_active_surface, width, height, pitch, std::forward<Args>(extras)...);
|
||||
}
|
||||
|
||||
template <typename ...Args>
|
||||
@ -3290,7 +3296,7 @@ namespace rsx
|
||||
else
|
||||
{
|
||||
// render target data is already in correct swizzle layout
|
||||
auto channel_order = src_is_render_target ? rsx::component_order::native :
|
||||
[[maybe_unused]] auto channel_order = src_is_render_target ? rsx::component_order::native :
|
||||
dst_is_argb8 ? rsx::component_order::default_ :
|
||||
rsx::component_order::swapped_native;
|
||||
|
||||
@ -3300,11 +3306,33 @@ namespace rsx
|
||||
dst_area.y1 += dst_offset.y;
|
||||
dst_area.y2 += dst_offset.y;
|
||||
|
||||
// We have to create the surface in the surface cache
|
||||
rsx::image_section_attributes_t section_attr
|
||||
{
|
||||
.address = rsx_range.start,
|
||||
.gcm_format = preferred_dst_format,
|
||||
.pitch = dst.pitch,
|
||||
.width = static_cast<u16>(dst_dimensions.width),
|
||||
.height = static_cast<u16>(dst_dimensions.height),
|
||||
.depth = 1,
|
||||
.mipmaps = 1,
|
||||
.slice_h = static_cast<u16>(dst_dimensions.height),
|
||||
.bpp = dst_bpp,
|
||||
.swizzled = false,
|
||||
.edge_clamped = false
|
||||
};
|
||||
|
||||
auto dst_surface = m_rtts.create_surface_from_rsx_section(
|
||||
cmd,
|
||||
section_attr,
|
||||
std::forward<Args>(extras)...);
|
||||
|
||||
ensure(dst_surface, "Failed to create target surface");
|
||||
|
||||
if (!dst_area.x1 && !dst_area.y1 && dst_area.x2 == dst_dimensions.width && dst_area.y2 == dst_dimensions.height)
|
||||
{
|
||||
cached_dest = create_new_texture(cmd, rsx_range, dst_dimensions.width, dst_dimensions.height, 1, 1, dst.pitch,
|
||||
preferred_dst_format, rsx::texture_upload_context::blit_engine_dst, rsx::texture_dimension_extended::texture_dimension_2d,
|
||||
dst.swizzled, channel_order, 0);
|
||||
// Nothing to do, not even a background erase is needed here
|
||||
dst_surface->state_flags &= ~rsx::surface_state_flags::erase_bkgnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3313,25 +3341,24 @@ namespace rsx
|
||||
const auto prot_range = dst_range.to_page_range();
|
||||
utils::memory_protect(vm::base(prot_range.start), prot_range.length(), utils::protection::no);
|
||||
|
||||
const auto pitch_in_block = dst.pitch / dst_bpp;
|
||||
std::vector<rsx::subresource_layout> subresource_layout;
|
||||
rsx::subresource_layout subres = {};
|
||||
subres.width_in_block = subres.width_in_texel = dst_dimensions.width;
|
||||
subres.height_in_block = subres.height_in_texel = dst_dimensions.height;
|
||||
subres.pitch_in_block = pitch_in_block;
|
||||
subres.depth = 1;
|
||||
subres.data = { vm::get_super_ptr<const std::byte>(dst_base_address), static_cast<std::span<const std::byte>::size_type>(dst.pitch * dst_dimensions.height) };
|
||||
subresource_layout.push_back(std::move(subres));
|
||||
|
||||
cached_dest = upload_image_from_cpu(cmd, rsx_range, dst_dimensions.width, dst_dimensions.height, 1, 1, dst.pitch,
|
||||
preferred_dst_format, rsx::texture_upload_context::blit_engine_dst, subresource_layout,
|
||||
rsx::texture_dimension_extended::texture_dimension_2d, dst.swizzled);
|
||||
|
||||
set_component_order(*cached_dest, preferred_dst_format, channel_order);
|
||||
dst_surface->state_flags |= rsx::surface_state_flags::force_data_load | rsx::surface_state_flags::erase_bkgnd;
|
||||
// set_component_order(*cached_dest, preferred_dst_format, channel_order);
|
||||
}
|
||||
|
||||
dest_texture = cached_dest->get_raw_texture();
|
||||
typeless_info.dst_context = texture_upload_context::blit_engine_dst;
|
||||
// Lock this for readback. That also creates a matching section
|
||||
lock_memory_region_impl(
|
||||
cmd, dst_surface, dst_surface->get_memory_range(), false,
|
||||
dst_surface->get_surface_width<rsx::surface_metrics::pixels>(),
|
||||
dst_surface->get_surface_height<rsx::surface_metrics::pixels>(),
|
||||
dst_surface->get_rsx_pitch(),
|
||||
dst_surface);
|
||||
|
||||
// Fake RTT cache hit
|
||||
dst_subres.surface = dst_surface;
|
||||
dst_is_render_target = true;
|
||||
|
||||
dest_texture = dst_surface->get_surface(rsx::surface_access::transfer_write);
|
||||
typeless_info.dst_context = texture_upload_context::framebuffer_storage;
|
||||
typeless_info.dst_gcm_format = preferred_dst_format;
|
||||
}
|
||||
}
|
||||
|
||||
@ -325,10 +325,6 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool /*
|
||||
|
||||
if (!m_rtts.orphaned_surfaces.empty())
|
||||
{
|
||||
gl::texture::format format;
|
||||
gl::texture::type type;
|
||||
bool swap_bytes;
|
||||
|
||||
for (auto& [base_addr, surface] : m_rtts.orphaned_surfaces)
|
||||
{
|
||||
bool lock = surface->is_depth_surface() ? !!g_cfg.video.write_depth_buffer :
|
||||
@ -354,31 +350,15 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool /*
|
||||
continue;
|
||||
}
|
||||
|
||||
if (surface->is_depth_surface())
|
||||
{
|
||||
const auto depth_format_gl = rsx::internals::surface_depth_format_to_gl(surface->get_surface_depth_format());
|
||||
format = depth_format_gl.format;
|
||||
type = depth_format_gl.type;
|
||||
swap_bytes = (type != gl::texture::type::uint_24_8);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto color_format_gl = rsx::internals::surface_color_format_to_gl(surface->get_surface_color_format());
|
||||
format = color_format_gl.format;
|
||||
type = color_format_gl.type;
|
||||
swap_bytes = color_format_gl.swap_bytes;
|
||||
}
|
||||
|
||||
m_gl_texture_cache.lock_memory_region(
|
||||
cmd, surface, surface->get_memory_range(), false,
|
||||
surface->get_surface_width<rsx::surface_metrics::pixels>(), surface->get_surface_height<rsx::surface_metrics::pixels>(), surface->get_rsx_pitch(),
|
||||
format, type, swap_bytes);
|
||||
surface);
|
||||
}
|
||||
|
||||
m_rtts.orphaned_surfaces.clear();
|
||||
}
|
||||
|
||||
const auto color_format = rsx::internals::surface_color_format_to_gl(m_framebuffer_layout.color_format);
|
||||
for (u8 i = 0; i < rsx::limits::color_buffers_count; ++i)
|
||||
{
|
||||
if (!m_surface_info[i].address || !m_surface_info[i].pitch) continue;
|
||||
@ -390,7 +370,7 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool /*
|
||||
m_gl_texture_cache.lock_memory_region(
|
||||
cmd, m_rtts.m_bound_render_targets[i].second, surface_range, true,
|
||||
m_surface_info[i].width, m_surface_info[i].height, m_surface_info[i].pitch,
|
||||
color_format.format, color_format.type, color_format.swap_bytes);
|
||||
m_rtts.m_bound_render_targets[i].second);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -403,11 +383,10 @@ void GLGSRender::init_buffers(rsx::framebuffer_creation_context context, bool /*
|
||||
const auto surface_range = m_depth_surface_info.get_memory_range();
|
||||
if (g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
const auto depth_format_gl = rsx::internals::surface_depth_format_to_gl(m_framebuffer_layout.depth_format);
|
||||
m_gl_texture_cache.lock_memory_region(
|
||||
cmd, m_rtts.m_bound_depth_stencil.second, surface_range, true,
|
||||
m_depth_surface_info.width, m_depth_surface_info.height, m_depth_surface_info.pitch,
|
||||
depth_format_gl.format, depth_format_gl.type, depth_format_gl.type != gl::texture::type::uint_24_8);
|
||||
m_rtts.m_bound_depth_stencil.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -472,15 +451,17 @@ void gl::render_target::load_memory(gl::command_context& cmd)
|
||||
}
|
||||
}
|
||||
|
||||
state_flags &= ~rsx::surface_state_flags::erase_bkgnd;
|
||||
state_flags &= ~(rsx::surface_state_flags::erase_bkgnd | rsx::surface_state_flags::force_data_load);
|
||||
}
|
||||
|
||||
void gl::render_target::initialize_memory(gl::command_context& cmd, rsx::surface_access access)
|
||||
{
|
||||
const bool memory_load = is_depth_surface() ?
|
||||
const bool read_buffers_config = is_depth_surface() ?
|
||||
!!g_cfg.video.read_depth_buffer :
|
||||
!!g_cfg.video.read_color_buffers;
|
||||
|
||||
const bool memory_load = (state_flags & rsx::surface_state_flags::force_data_load) || read_buffers_config;
|
||||
|
||||
if (!memory_load)
|
||||
{
|
||||
clear_memory(cmd);
|
||||
|
||||
@ -135,12 +135,12 @@ struct gl_render_target_traits
|
||||
|
||||
static
|
||||
std::unique_ptr<gl::render_target> create_new_surface(
|
||||
gl::command_context&,
|
||||
u32 address,
|
||||
rsx::surface_color_format surface_color_format,
|
||||
usz width, usz height, usz pitch,
|
||||
rsx::surface_antialiasing antialias,
|
||||
const rsx::surface_scaling_config_t& resolution_scaling_config
|
||||
)
|
||||
const rsx::surface_scaling_config_t& resolution_scaling_config)
|
||||
{
|
||||
auto format = rsx::internals::surface_color_format_to_gl(surface_color_format);
|
||||
const auto [width_, height_] = rsx::apply_resolution_scale<true>(resolution_scaling_config, static_cast<u16>(width), static_cast<u16>(height));
|
||||
@ -181,12 +181,12 @@ struct gl_render_target_traits
|
||||
|
||||
static
|
||||
std::unique_ptr<gl::render_target> create_new_surface(
|
||||
u32 address,
|
||||
rsx::surface_depth_format2 surface_depth_format,
|
||||
usz width, usz height, usz pitch,
|
||||
rsx::surface_antialiasing antialias,
|
||||
const rsx::surface_scaling_config_t& resolution_scaling_config
|
||||
)
|
||||
gl::command_context&,
|
||||
u32 address,
|
||||
rsx::surface_depth_format2 surface_depth_format,
|
||||
usz width, usz height, usz pitch,
|
||||
rsx::surface_antialiasing antialias,
|
||||
const rsx::surface_scaling_config_t& resolution_scaling_config)
|
||||
{
|
||||
auto format = rsx::internals::surface_depth_format_to_gl(surface_depth_format);
|
||||
const auto [width_, height_] = rsx::apply_resolution_scale<true>(resolution_scaling_config, static_cast<u16>(width), static_cast<u16>(height));
|
||||
|
||||
@ -120,6 +120,30 @@ namespace gl
|
||||
baseclass::on_section_resources_created();
|
||||
}
|
||||
|
||||
void create(u16 w, u16 h, u16 depth, u16 mipmaps, gl::texture* image, u32 rsx_pitch, bool managed, const gl::render_target* surface)
|
||||
{
|
||||
gl::texture::format format;
|
||||
gl::texture::type type;
|
||||
bool swap_bytes;
|
||||
|
||||
if (surface->is_depth_surface())
|
||||
{
|
||||
const auto depth_format_gl = rsx::internals::surface_depth_format_to_gl(surface->get_surface_depth_format());
|
||||
format = depth_format_gl.format;
|
||||
type = depth_format_gl.type;
|
||||
swap_bytes = (type != gl::texture::type::uint_24_8);
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto color_format_gl = rsx::internals::surface_color_format_to_gl(surface->get_surface_color_format());
|
||||
format = color_format_gl.format;
|
||||
type = color_format_gl.type;
|
||||
swap_bytes = color_format_gl.swap_bytes;
|
||||
}
|
||||
|
||||
create(w, h, depth, mipmaps, image, rsx_pitch, managed, format, type, swap_bytes);
|
||||
}
|
||||
|
||||
void set_dimensions(u32 width, u32 height, u32 /*depth*/, u32 pitch)
|
||||
{
|
||||
this->width = width;
|
||||
|
||||
@ -2480,8 +2480,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||
m_framebuffer_layout.target, m_framebuffer_layout.aa_mode, m_framebuffer_layout.raster_type,
|
||||
m_framebuffer_layout.color_addresses, m_framebuffer_layout.zeta_address,
|
||||
m_framebuffer_layout.actual_color_pitch, m_framebuffer_layout.actual_zeta_pitch,
|
||||
resolution_scaling_config,
|
||||
(*m_device), *m_current_command_buffer);
|
||||
resolution_scaling_config);
|
||||
|
||||
// Reset framebuffer information
|
||||
const auto color_bpp = get_format_block_size_in_bytes(m_framebuffer_layout.color_format);
|
||||
@ -2572,9 +2571,6 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||
|
||||
if (!m_rtts.orphaned_surfaces.empty())
|
||||
{
|
||||
u32 gcm_format;
|
||||
bool swap_bytes;
|
||||
|
||||
for (auto& [base_addr, surface] : m_rtts.orphaned_surfaces)
|
||||
{
|
||||
bool lock = surface->is_depth_surface() ? !!g_cfg.video.write_depth_buffer :
|
||||
@ -2600,28 +2596,15 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (surface->is_depth_surface())
|
||||
{
|
||||
gcm_format = (surface->get_surface_depth_format() != rsx::surface_depth_format::z16) ? CELL_GCM_TEXTURE_DEPTH16 : CELL_GCM_TEXTURE_DEPTH24_D8;
|
||||
swap_bytes = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto info = get_compatible_gcm_format(surface->get_surface_color_format());
|
||||
gcm_format = info.first;
|
||||
swap_bytes = info.second;
|
||||
}
|
||||
|
||||
m_texture_cache.lock_memory_region(
|
||||
*m_current_command_buffer, surface, surface->get_memory_range(), false,
|
||||
surface->get_surface_width<rsx::surface_metrics::pixels>(), surface->get_surface_height<rsx::surface_metrics::pixels>(), surface->get_rsx_pitch(),
|
||||
gcm_format, swap_bytes);
|
||||
surface);
|
||||
}
|
||||
|
||||
m_rtts.orphaned_surfaces.clear();
|
||||
}
|
||||
|
||||
const auto color_fmt_info = get_compatible_gcm_format(m_framebuffer_layout.color_format);
|
||||
for (u8 index : m_draw_buffers)
|
||||
{
|
||||
if (!m_surface_info[index].address || !m_surface_info[index].pitch) continue;
|
||||
@ -2632,7 +2615,7 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||
m_texture_cache.lock_memory_region(
|
||||
*m_current_command_buffer, m_rtts.m_bound_render_targets[index].second, surface_range, true,
|
||||
m_surface_info[index].width, m_surface_info[index].height, m_framebuffer_layout.actual_color_pitch[index],
|
||||
color_fmt_info.first, color_fmt_info.second);
|
||||
m_rtts.m_bound_render_targets[index].second);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2645,10 +2628,10 @@ void VKGSRender::prepare_rtts(rsx::framebuffer_creation_context context)
|
||||
const utils::address_range32 surface_range = m_depth_surface_info.get_memory_range();
|
||||
if (g_cfg.video.write_depth_buffer)
|
||||
{
|
||||
const u32 gcm_format = (m_depth_surface_info.depth_format == rsx::surface_depth_format::z16) ? CELL_GCM_TEXTURE_DEPTH16 : CELL_GCM_TEXTURE_DEPTH24_D8;
|
||||
m_texture_cache.lock_memory_region(
|
||||
*m_current_command_buffer, m_rtts.m_bound_depth_stencil.second, surface_range, true,
|
||||
m_depth_surface_info.width, m_depth_surface_info.height, m_framebuffer_layout.actual_zeta_pitch, gcm_format, true);
|
||||
m_depth_surface_info.width, m_depth_surface_info.height, m_framebuffer_layout.actual_zeta_pitch,
|
||||
m_rtts.m_bound_depth_stencil.second);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -794,13 +794,16 @@ namespace vk
|
||||
}
|
||||
}
|
||||
|
||||
state_flags &= ~rsx::surface_state_flags::erase_bkgnd;
|
||||
state_flags &= ~(rsx::surface_state_flags::erase_bkgnd | rsx::surface_state_flags::force_data_load);
|
||||
}
|
||||
|
||||
void render_target::initialize_memory(vk::command_buffer& cmd, rsx::surface_access access)
|
||||
{
|
||||
const bool is_depth = is_depth_surface();
|
||||
const bool should_read_buffers = is_depth ? !!g_cfg.video.read_depth_buffer : !!g_cfg.video.read_color_buffers;
|
||||
const bool read_buffers_config = is_depth_surface() ?
|
||||
!!g_cfg.video.read_depth_buffer :
|
||||
!!g_cfg.video.read_color_buffers;
|
||||
|
||||
const bool should_read_buffers = (state_flags & rsx::surface_state_flags::force_data_load) || read_buffers_config;
|
||||
|
||||
if (!should_read_buffers)
|
||||
{
|
||||
|
||||
@ -196,12 +196,12 @@ namespace vk
|
||||
}
|
||||
|
||||
static std::unique_ptr<vk::render_target> create_new_surface(
|
||||
const vk::command_buffer& cmd,
|
||||
u32 address,
|
||||
rsx::surface_color_format format,
|
||||
usz width, usz height, usz pitch,
|
||||
rsx::surface_antialiasing antialias,
|
||||
const rsx::surface_scaling_config_t& resolution_scaling_config,
|
||||
vk::render_device& device, vk::command_buffer& cmd)
|
||||
const rsx::surface_scaling_config_t& resolution_scaling_config)
|
||||
{
|
||||
const auto fmt = vk::get_compatible_surface_format(format);
|
||||
VkFormat requested_format = fmt.first;
|
||||
@ -234,7 +234,8 @@ namespace vk
|
||||
std::unique_ptr<vk::render_target> rtt;
|
||||
const auto [width_, height_] = rsx::apply_resolution_scale<true>(resolution_scaling_config, static_cast<u16>(width), static_cast<u16>(height));
|
||||
|
||||
rtt = std::make_unique<vk::render_target>(device, device.get_memory_mapping().device_local,
|
||||
auto pdev = vk::get_current_renderer();
|
||||
rtt = std::make_unique<vk::render_target>(*pdev, pdev->get_memory_mapping().device_local,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
VK_IMAGE_TYPE_2D,
|
||||
requested_format,
|
||||
@ -268,14 +269,15 @@ namespace vk
|
||||
}
|
||||
|
||||
static std::unique_ptr<vk::render_target> create_new_surface(
|
||||
const vk::command_buffer& cmd,
|
||||
u32 address,
|
||||
rsx::surface_depth_format2 format,
|
||||
usz width, usz height, usz pitch,
|
||||
rsx::surface_antialiasing antialias,
|
||||
const rsx::surface_scaling_config_t& resolution_scaling_config,
|
||||
vk::render_device& device, vk::command_buffer& cmd)
|
||||
const rsx::surface_scaling_config_t& resolution_scaling_config)
|
||||
{
|
||||
const VkFormat requested_format = vk::get_compatible_depth_surface_format(device.get_formats_support(), format);
|
||||
auto pdev = vk::get_current_renderer();
|
||||
const VkFormat requested_format = vk::get_compatible_depth_surface_format(pdev->get_formats_support(), format);
|
||||
|
||||
u8 samples;
|
||||
rsx::surface_sample_layout sample_layout;
|
||||
@ -301,7 +303,7 @@ namespace vk
|
||||
std::unique_ptr<vk::render_target> ds;
|
||||
const auto [width_, height_] = rsx::apply_resolution_scale<true>(resolution_scaling_config, static_cast<u16>(width), static_cast<u16>(height));
|
||||
|
||||
ds = std::make_unique<vk::render_target>(device, device.get_memory_mapping().device_local,
|
||||
ds = std::make_unique<vk::render_target>(*pdev, pdev->get_memory_mapping().device_local,
|
||||
VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT,
|
||||
VK_IMAGE_TYPE_2D,
|
||||
requested_format,
|
||||
|
||||
@ -37,7 +37,7 @@ namespace vk
|
||||
|
||||
std::unique_ptr<vk::viewable_image> managed_texture = nullptr;
|
||||
|
||||
//DMA relevant data
|
||||
// DMA relevant data
|
||||
std::unique_ptr<vk::event> dma_fence;
|
||||
vk::render_device* m_device = nullptr;
|
||||
vk::viewable_image* vram_texture = nullptr;
|
||||
@ -99,6 +99,26 @@ namespace vk
|
||||
baseclass::on_section_resources_created();
|
||||
}
|
||||
|
||||
void create(u16 w, u16 h, u16 depth, u16 mipmaps, vk::image* image, u32 rsx_pitch, bool managed, const vk::render_target* surface)
|
||||
{
|
||||
u32 gcm_format;
|
||||
bool swap_bytes;
|
||||
|
||||
if (surface->is_depth_surface())
|
||||
{
|
||||
gcm_format = (surface->get_surface_depth_format() != rsx::surface_depth_format::z16) ? CELL_GCM_TEXTURE_DEPTH16 : CELL_GCM_TEXTURE_DEPTH24_D8;
|
||||
swap_bytes = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
auto info = get_compatible_gcm_format(surface->get_surface_color_format());
|
||||
gcm_format = info.first;
|
||||
swap_bytes = info.second;
|
||||
}
|
||||
|
||||
create(w, h, depth, mipmaps, image, rsx_pitch, managed, gcm_format, swap_bytes);
|
||||
}
|
||||
|
||||
void release_dma_resources()
|
||||
{
|
||||
if (dma_fence)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user