rsx: Move blit target storage to the surface cache

This commit is contained in:
kd-11 2026-07-08 21:20:21 +03:00
parent 93dfd3a8ca
commit 5cd5e8435d
10 changed files with 228 additions and 154 deletions

View File

@ -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());

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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
{

View File

@ -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)
{

View File

@ -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,

View File

@ -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)