diff --git a/rpcs3/Emu/RSX/Common/surface_store.h b/rpcs3/Emu/RSX/Common/surface_store.h index 5289b7b8d7..7e04390553 100644 --- a/rpcs3/Emu/RSX/Common/surface_store.h +++ b/rpcs3/Emu/RSX/Common/surface_store.h @@ -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(extra_params)...); + new_surface_storage = Traits::create_new_surface(command_list, address, format, width, height, pitch, antialias, scaling_config, std::forward(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 + 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(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(extra_params)...); + } + u8 get_color_surface_count() const { return static_cast(m_bound_render_target_ids.size()); diff --git a/rpcs3/Emu/RSX/Common/surface_utils.h b/rpcs3/Emu/RSX/Common/surface_utils.h index 8ec97600bc..3e70e711b6 100644 --- a/rpcs3/Emu/RSX/Common/surface_utils.h +++ b/rpcs3/Emu/RSX/Common/surface_utils.h @@ -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 diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 81ff75b9a8..8a8195a678 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -1158,6 +1158,71 @@ namespace rsx return result; } + template + 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(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 - 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(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(extras)...); } template @@ -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(dst_dimensions.width), + .height = static_cast(dst_dimensions.height), + .depth = 1, + .mipmaps = 1, + .slice_h = static_cast(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(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 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(dst_base_address), static_cast::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(), + dst_surface->get_surface_height(), + 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; } } diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 1a59f0438b..25b349467a 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -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(), surface->get_surface_height(), 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); diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index f5e2252b92..1f4a2b825a 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -135,12 +135,12 @@ struct gl_render_target_traits static std::unique_ptr 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(resolution_scaling_config, static_cast(width), static_cast(height)); @@ -181,12 +181,12 @@ struct gl_render_target_traits static std::unique_ptr 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(resolution_scaling_config, static_cast(width), static_cast(height)); diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 48a4ba98a0..97f2637927 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -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; diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index e8acd2ec4c..d85cbb8404 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -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(), surface->get_surface_height(), 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 { diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp index 736b886a77..0994dd1e4a 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp @@ -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) { diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 7da26f3b5c..0ffa9b018f 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -196,12 +196,12 @@ namespace vk } static std::unique_ptr 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 rtt; const auto [width_, height_] = rsx::apply_resolution_scale(resolution_scaling_config, static_cast(width), static_cast(height)); - rtt = std::make_unique(device, device.get_memory_mapping().device_local, + auto pdev = vk::get_current_renderer(); + rtt = std::make_unique(*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 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 ds; const auto [width_, height_] = rsx::apply_resolution_scale(resolution_scaling_config, static_cast(width), static_cast(height)); - ds = std::make_unique(device, device.get_memory_mapping().device_local, + ds = std::make_unique(*pdev, pdev->get_memory_mapping().device_local, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, VK_IMAGE_TYPE_2D, requested_format, diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 85687c8c69..94a2a058bb 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -37,7 +37,7 @@ namespace vk std::unique_ptr managed_texture = nullptr; - //DMA relevant data + // DMA relevant data std::unique_ptr 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)