From 9abbbb79ae687f14548f93334b0897e25dfc2caf Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 7 Apr 2018 18:16:52 +0300 Subject: [PATCH] rsx: Blit engine fixes - Ignore unlocked blit sections [TODO] - Do not attempt blit on hw if bytesize is unsupported - gl: Implement typeless memory transfers Uses pbo to handle type-agnostic memory transfer --- rpcs3/Emu/RSX/Common/texture_cache.h | 163 ++++++++++++++++++++++++--- rpcs3/Emu/RSX/GL/GLHelpers.h | 12 +- rpcs3/Emu/RSX/GL/GLRenderTargets.cpp | 2 +- rpcs3/Emu/RSX/GL/GLTexture.cpp | 63 ++++++++++- rpcs3/Emu/RSX/GL/GLTexture.h | 5 +- rpcs3/Emu/RSX/GL/GLTextureCache.h | 48 +++++++- rpcs3/Emu/RSX/VK/VKTextureCache.h | 3 +- rpcs3/Emu/RSX/rsx_cache.h | 41 ------- rpcs3/Emu/RSX/rsx_utils.h | 41 +++++++ 9 files changed, 304 insertions(+), 74 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 62c2898cc6..1ef66f5743 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -29,6 +29,34 @@ namespace rsx flush_once = 1 }; + struct typeless_xfer + { + bool src_is_typeless = false; + bool dst_is_typeless = false; + bool src_is_depth = false; + bool dst_is_depth = false; + u32 src_gcm_format = 0; + u32 dst_gcm_format = 0; + f32 src_scaling_hint = 1.f; + f32 dst_scaling_hint = 1.f; + + void analyse() + { + if (src_is_typeless && dst_is_typeless) + { + if (src_scaling_hint == dst_scaling_hint && + src_scaling_hint != 1.f) + { + if (src_is_depth == dst_is_depth) + { + src_is_typeless = dst_is_typeless = false; + src_scaling_hint = dst_scaling_hint = 1.f; + } + } + } + } + }; + struct cached_texture_section : public rsx::buffered_section { u16 width; @@ -76,7 +104,7 @@ namespace rsx if (depth && depth != this->depth) return false; - if (mipmaps && mipmaps != this->mipmaps) + if (mipmaps && mipmaps > this->mipmaps) return false; return true; @@ -1717,7 +1745,8 @@ namespace rsx { for (const auto &surface : overlapping_surfaces) { - if (surface->get_context() != rsx::texture_upload_context::blit_engine_dst) + if (surface->get_context() != rsx::texture_upload_context::blit_engine_dst || + !surface->is_locked()) continue; if (surface->get_width() >= tex_width && surface->get_height() >= tex_height) @@ -1791,19 +1820,23 @@ namespace rsx bool dst_is_argb8 = (dst.format == rsx::blit_engine::transfer_destination_format::a8r8g8b8); bool src_is_argb8 = (src.format == rsx::blit_engine::transfer_source_format::a8r8g8b8); + typeless_xfer typeless_info = {}; image_resource_type vram_texture = 0; image_resource_type dest_texture = 0; const u32 src_address = (u32)((u64)src.pixels - (u64)vm::base(0)); const u32 dst_address = (u32)((u64)dst.pixels - (u64)vm::base(0)); - float scale_x = dst.scale_x; - float scale_y = dst.scale_y; + f32 scale_x = dst.scale_x; + f32 scale_y = dst.scale_y; //Offset in x and y for src is 0 (it is already accounted for when getting pixels_src) //Reproject final clip onto source... - const u16 src_w = (const u16)((f32)dst.clip_width / scale_x); - const u16 src_h = (const u16)((f32)dst.clip_height / scale_y); + u16 src_w = (const u16)((f32)dst.clip_width / scale_x); + u16 src_h = (const u16)((f32)dst.clip_height / scale_y); + + u16 dst_w = dst.clip_width; + u16 dst_h = dst.clip_height; //Check if src/dst are parts of render targets auto dst_subres = m_rtts.get_surface_subresource_if_applicable(dst_address, dst.width, dst.clip_height, dst.pitch, true, false, false); @@ -1847,6 +1880,51 @@ namespace rsx if (!g_cfg.video.use_gpu_texture_scaling && !(src_is_render_target || dst_is_render_target)) return false; + if (src_is_render_target) + { + const auto surf = src_subres.surface; + auto src_bpp = surf->get_native_pitch() / surf->get_surface_width(); + auto expected_bpp = src_is_argb8 ? 4 : 2; + if (src_bpp != expected_bpp) + { + //Enable type scaling in src + typeless_info.src_is_typeless = true; + typeless_info.src_is_depth = src_subres.is_depth_surface; + typeless_info.src_scaling_hint = (f32)src_bpp / expected_bpp; + typeless_info.src_gcm_format = src_is_argb8 ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5; + + src_w = (u16)(src_w / typeless_info.src_scaling_hint); + if (!src_subres.is_clipped) + src_subres.w = (u16)(src_subres.w / typeless_info.src_scaling_hint); + else + src_subres = m_rtts.get_surface_subresource_if_applicable(src_address, src_w, src_h, src.pitch, true, false, false); + + verify(HERE), src_subres.surface != nullptr; + } + } + + if (dst_is_render_target) + { + auto dst_bpp = dst_subres.surface->get_native_pitch() / dst_subres.surface->get_surface_width(); + auto expected_bpp = dst_is_argb8 ? 4 : 2; + if (dst_bpp != expected_bpp) + { + //Enable type scaling in dst + typeless_info.dst_is_typeless = true; + typeless_info.dst_is_depth = dst_subres.is_depth_surface; + typeless_info.dst_scaling_hint = (f32)dst_bpp / expected_bpp; + typeless_info.dst_gcm_format = dst_is_argb8 ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5; + + dst_w = (u16)(dst_w / typeless_info.dst_scaling_hint); + if (!dst_subres.is_clipped) + dst_subres.w = (u16)(dst_subres.w / typeless_info.dst_scaling_hint); + else + dst_subres = m_rtts.get_surface_subresource_if_applicable(dst_address, dst_w, dst_h, dst.pitch, true, false, false); + + verify(HERE), dst_subres.surface != nullptr; + } + } + reader_lock lock(m_cache_mutex); //Check if trivial memcpy can perform the same task @@ -1870,7 +1948,7 @@ namespace rsx u16 max_dst_width = dst.width; u16 max_dst_height = dst.height; areai src_area = { 0, 0, src_w, src_h }; - areai dst_area = { 0, 0, dst.clip_width, dst.clip_height }; + areai dst_area = { 0, 0, dst_w, dst_h }; //1024 height is a hack (for ~720p buffers) //It is possible to have a large buffer that goes up to around 4kx4k but anything above 1280x720 is rare @@ -1948,7 +2026,7 @@ namespace rsx dest_texture = dst_subres.surface->get_surface(); - max_dst_width = dst_subres.surface->get_surface_width(); + max_dst_width = (u16)(dst_subres.surface->get_surface_width() * typeless_info.dst_scaling_hint); max_dst_height = dst_subres.surface->get_surface_height(); } @@ -2019,7 +2097,7 @@ namespace rsx u16 src_subres_h = src_subres.h; get_rsx_dimensions(src_subres_w, src_subres_h, src_subres.surface); - const int dst_width = (int)(src_subres_w * scale_x); + const int dst_width = (int)(src_subres_w * scale_x * typeless_info.src_scaling_hint); const int dst_height = (int)(src_subres_h * scale_y); dst_area.x2 = dst_area.x1 + dst_width; @@ -2055,14 +2133,37 @@ namespace rsx } else if (src_is_render_target && cached_dest) { - if (!cached_dest->has_compatible_format(src_subres.surface)) + switch (cached_dest->get_gcm_format()) + { + case CELL_GCM_TEXTURE_A8R8G8B8: + case CELL_GCM_TEXTURE_DEPTH24_D8: + format_mismatch = !dst_is_argb8; + break; + case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_DEPTH16: + format_mismatch = dst_is_argb8; + break; + default: format_mismatch = true; + break; + } } //TODO: Check for other types of format mismatch if (format_mismatch) { lock.upgrade(); + + //Mark for removal as the memory is not reusable now + if (cached_dest->is_locked()) + { + cached_dest->unprotect(); + m_cache[get_block_address(cached_dest->get_section_base())].remove_one(); + } + + cached_dest->set_dirty(true); + m_unreleased_texture_objects++; + invalidate_range_impl_base(cached_dest->get_section_base(), cached_dest->get_section_size(), true, false, false, true, std::forward(extras)...); dest_texture = 0; @@ -2097,7 +2198,7 @@ namespace rsx //Reproject clip offsets onto source to simplify blit if (dst.clip_x || dst.clip_y) { - const u16 scaled_clip_offset_x = (const u16)((f32)dst.clip_x / scale_x); + const u16 scaled_clip_offset_x = (const u16)((f32)dst.clip_x / (scale_x * typeless_info.src_scaling_hint)); const u16 scaled_clip_offset_y = (const u16)((f32)dst.clip_y / scale_y); src_area.x1 += scaled_clip_offset_x; @@ -2140,14 +2241,42 @@ namespace rsx cached_dest->touch(); } - const f32 scale = rsx::get_resolution_scale(); - if (src_is_render_target) - src_area = src_area * scale; + if (rsx::get_resolution_scale_percent() != 100) + { + const f32 resolution_scale = rsx::get_resolution_scale(); + if (src_is_render_target) + { + if (src_subres.surface->get_surface_width() > g_cfg.video.min_scalable_dimension) + { + src_area.x1 = (u16)(src_area.x1 * resolution_scale); + src_area.x2 = (u16)(src_area.x2 * resolution_scale); + } - if (dst_is_render_target) - dst_area = dst_area * scale; + if (src_subres.surface->get_surface_height() > g_cfg.video.min_scalable_dimension) + { + src_area.y1 = (u16)(src_area.y1 * resolution_scale); + src_area.y2 = (u16)(src_area.y2 * resolution_scale); + } + } - blitter.scale_image(vram_texture, dest_texture, src_area, dst_area, interpolate, is_depth_blit); + if (dst_is_render_target) + { + if (dst_subres.surface->get_surface_width() > g_cfg.video.min_scalable_dimension) + { + dst_area.x1 = (u16)(dst_area.x1 * resolution_scale); + dst_area.x2 = (u16)(dst_area.x2 * resolution_scale); + } + + if (dst_subres.surface->get_surface_height() > g_cfg.video.min_scalable_dimension) + { + dst_area.y1 = (u16)(dst_area.y1 * resolution_scale); + dst_area.y2 = (u16)(dst_area.y2 * resolution_scale); + } + } + } + + typeless_info.analyse(); + blitter.scale_image(vram_texture, dest_texture, src_area, dst_area, interpolate, is_depth_blit, typeless_info); notify_surface_changed(dst.rsx_address); blit_op_result result = true; diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index a06810716a..bae8dea9ee 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -737,24 +737,24 @@ namespace gl glGenBuffers(1, &m_id); } - void create(GLsizeiptr size, const void* data_ = nullptr) + void create(GLsizeiptr size, const void* data_ = nullptr, GLenum usage = GL_STREAM_DRAW) { create(); - data(size, data_); + data(size, data_, usage); } - void create(target target_, GLsizeiptr size, const void* data_ = nullptr) + void create(target target_, GLsizeiptr size, const void* data_ = nullptr, GLenum usage = GL_STREAM_DRAW) { create(); m_target = target_; - data(size, data_); + data(size, data_, usage); } - void data(GLsizeiptr size, const void* data_ = nullptr) + void data(GLsizeiptr size, const void* data_ = nullptr, GLenum usage = GL_STREAM_DRAW) { target target_ = current_target(); save_binding_state save(target_, *this); - glBufferData((GLenum)target_, size, data_, GL_STREAM_DRAW); + glBufferData((GLenum)target_, size, data_, usage); m_size = size; } diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 746d0855e5..42bd5396e4 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -80,7 +80,7 @@ depth_format rsx::internals::surface_depth_format_to_gl(rsx::surface_depth_forma LOG_ERROR(RSX, "Surface depth buffer: Unsupported surface depth format (0x%x)", (u32)depth_format); case rsx::surface_depth_format::z24s8: if (g_cfg.video.force_high_precision_z_buffer && ::gl::get_driver_caps().ARB_depth_buffer_float_supported) - return{ ::gl::texture::type::float32_uint8, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth32f_stencil8 }; + return{ ::gl::texture::type::uint_24_8, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth32f_stencil8 }; else return{ ::gl::texture::type::uint_24_8, ::gl::texture::format::depth_stencil, ::gl::texture::internal_format::depth24_stencil8 }; } diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 9bc7456241..4a89e7df4f 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "GLTexture.h" -#include "GLHelpers.h" #include "../GCM.h" #include "../RSXThread.h" #include "../RSXTexture.h" @@ -8,6 +7,8 @@ namespace gl { + static buffer g_typeless_transfer_buffer; + GLenum get_target(rsx::texture_dimension_extended type) { switch (type) @@ -90,6 +91,38 @@ namespace gl fmt::throw_exception("Compressed or unknown texture format 0x%x" HERE, texture_format); } + std::tuple get_format_type(texture::internal_format format) + { + switch (format) + { + case texture::internal_format::compressed_rgba_s3tc_dxt1: + case texture::internal_format::compressed_rgba_s3tc_dxt3: + case texture::internal_format::compressed_rgba_s3tc_dxt5: + return std::make_tuple(GL_RGBA, GL_UNSIGNED_BYTE, false); + case texture::internal_format::r8: + return std::make_tuple(GL_R, GL_UNSIGNED_BYTE, false); + case texture::internal_format::r32f: + return std::make_tuple(GL_R, GL_FLOAT, true); + case texture::internal_format::r5g6b5: + return std::make_tuple(GL_RGB, GL_UNSIGNED_SHORT_5_6_5, true); + case texture::internal_format::rg8: + return std::make_tuple(GL_RG, GL_UNSIGNED_BYTE, false); + case texture::internal_format::rgba8: + return std::make_tuple(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, false); + case texture::internal_format::rgba16f: + return std::make_tuple(GL_RGBA, GL_HALF_FLOAT, true); + case texture::internal_format::rgba32f: + return std::make_tuple(GL_RGBA, GL_FLOAT, true); + case texture::internal_format::depth16: + return std::make_tuple(GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, true); + case texture::internal_format::depth24_stencil8: + case texture::internal_format::depth32f_stencil8: + return std::make_tuple(GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, true); + default: + fmt::throw_exception("Unexpected internal format 0x%X" HERE, (u32)format); + } + } + GLenum get_srgb_format(GLenum in_format) { switch (in_format) @@ -562,4 +595,32 @@ namespace gl const GLenum gl_type = std::get<1>(format_type); fill_texture(type, mipmaps, gcm_format, width, height, depth, subresources_layout, is_swizzled, gl_format, gl_type, data_upload_buf); } + + void copy_typeless(texture * dst, const texture * src) + { + GLsizeiptr src_mem = src->width() * src->height(); + GLsizeiptr dst_mem = dst->width() * dst->height(); + + auto max_mem = std::max(src_mem, dst_mem) * 16; + if (!g_typeless_transfer_buffer || max_mem > g_typeless_transfer_buffer.size()) + { + if (g_typeless_transfer_buffer) g_typeless_transfer_buffer.remove(); + g_typeless_transfer_buffer.create(buffer::target::pixel_pack, max_mem, nullptr, GL_STATIC_COPY); + } + + auto format_type = get_format_type(src->get_internal_format()); + pixel_pack_settings pack_settings{}; + pack_settings.swap_bytes(std::get<2>(format_type)); + g_typeless_transfer_buffer.bind(buffer::target::pixel_pack); + src->copy_to(nullptr, (texture::format)std::get<0>(format_type), (texture::type)std::get<1>(format_type), pack_settings); + + format_type = get_format_type(dst->get_internal_format()); + pixel_unpack_settings unpack_settings{}; + unpack_settings.swap_bytes(std::get<2>(format_type)); + g_typeless_transfer_buffer.bind(buffer::target::pixel_unpack); + dst->copy_from(nullptr, (texture::format)std::get<0>(format_type), (texture::type)std::get<1>(format_type), unpack_settings); + + glBindBuffer(GL_PIXEL_PACK_BUFFER, GL_NONE); + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, GL_NONE); + } } diff --git a/rpcs3/Emu/RSX/GL/GLTexture.h b/rpcs3/Emu/RSX/GL/GLTexture.h index 43234b90c2..066da41ce6 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.h +++ b/rpcs3/Emu/RSX/GL/GLTexture.h @@ -1,6 +1,7 @@ #include "OpenGL.h" #include "../GCM.h" #include "../Common/TextureUtils.h" +#include "GLHelpers.h" namespace rsx { @@ -10,17 +11,17 @@ namespace rsx namespace gl { - class texture; - GLenum get_target(rsx::texture_dimension_extended type); GLenum get_sized_internal_format(u32 gcm_format); std::tuple get_format_type(u32 texture_format); + std::tuple get_format_type(texture::internal_format format); GLenum wrap_mode(rsx::texture_wrap_mode wrap); float max_aniso(rsx::texture_max_anisotropy aniso); std::array get_swizzle_remap(u32 texture_format); texture* create_texture(u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, rsx::texture_dimension_extended type, rsx::texture_colorspace colorspace); + void copy_typeless(texture* dst, const texture* src); /** * is_swizzled - determines whether input bytes are in morton order * subresources_layout - descriptor of the mipmap levels in memory diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index f1f938657b..04cbd47f1a 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -27,6 +27,7 @@ namespace gl class blitter; extern GLenum get_sized_internal_format(u32); + extern void copy_typeless(texture*, const texture*); extern blitter *g_hw_blitter; class blitter @@ -48,8 +49,38 @@ namespace gl blit_src.remove(); } - void scale_image(texture* src, texture* dst, areai src_rect, areai dst_rect, bool linear_interpolation, bool is_depth_copy) + void scale_image(const texture* src, texture* dst, areai src_rect, areai dst_rect, bool linear_interpolation, + bool is_depth_copy, const rsx::typeless_xfer& xfer_info) { + std::unique_ptr typeless_src; + std::unique_ptr typeless_dst; + u32 src_id = src->id(); + u32 dst_id = dst->id(); + + if (xfer_info.src_is_typeless) + { + const auto internal_width = (u16)(src->width() * xfer_info.src_scaling_hint); + const auto internal_fmt = get_sized_internal_format(xfer_info.src_gcm_format); + typeless_src = std::make_unique(GL_TEXTURE_2D, internal_width, src->height(), 1, 1, internal_fmt); + copy_typeless(typeless_src.get(), src); + + src_id = typeless_src->id(); + src_rect.x1 = (u16)(src_rect.x1 * xfer_info.src_scaling_hint); + src_rect.x2 = (u16)(src_rect.x2 * xfer_info.src_scaling_hint); + } + + if (xfer_info.dst_is_typeless) + { + const auto internal_width = (u16)(dst->width() * xfer_info.dst_scaling_hint); + const auto internal_fmt = get_sized_internal_format(xfer_info.dst_gcm_format); + typeless_dst = std::make_unique(GL_TEXTURE_2D, internal_width, dst->height(), 1, 1, internal_fmt); + copy_typeless(typeless_dst.get(), dst); + + dst_id = typeless_dst->id(); + dst_rect.x1 = (u16)(dst_rect.x1 * xfer_info.dst_scaling_hint); + dst_rect.x2 = (u16)(dst_rect.x2 * xfer_info.dst_scaling_hint); + } + s32 old_fbo = 0; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &old_fbo); @@ -57,11 +88,11 @@ namespace gl GLenum attachment = is_depth_copy ? GL_DEPTH_ATTACHMENT : GL_COLOR_ATTACHMENT0; blit_src.bind(); - glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, src->id(), 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, src_id, 0); blit_src.check(); blit_dst.bind(); - glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, dst->id(), 0); + glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, dst_id, 0); blit_dst.check(); GLboolean scissor_test_enabled = glIsEnabled(GL_SCISSOR_TEST); @@ -70,6 +101,12 @@ namespace gl blit_src.blit(blit_dst, src_rect, dst_rect, is_depth_copy ? buffers::depth : buffers::color, interp); + if (xfer_info.dst_is_typeless) + { + //Transfer contents from typeless dst back to original dst + copy_typeless(dst, typeless_dst.get()); + } + blit_src.bind(); glFramebufferTexture2D(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, GL_NONE, 0); @@ -360,7 +397,7 @@ namespace gl } bool linear_interp = false; //TODO: Make optional or detect full sized sources - g_hw_blitter->scale_image(vram_texture, scaled_texture.get(), src_area, dst_area, linear_interp, is_depth); + g_hw_blitter->scale_image(vram_texture, scaled_texture.get(), src_area, dst_area, linear_interp, is_depth, {}); target_texture = scaled_texture->id(); } } @@ -380,7 +417,7 @@ namespace gl if (GLenum err = glGetError()) { bool recovered = false; - if (target_texture == scaled_texture->id()) + if (scaled_texture && (target_texture == scaled_texture->id())) { if (get_driver_caps().EXT_dsa_supported) glGetTextureImageEXT(vram_texture->id(), GL_TEXTURE_2D, 0, (GLenum)format, (GLenum)type, nullptr); @@ -861,6 +898,7 @@ namespace gl cached.set_depth_flag(depth_flag); cached.set_view_flags(flags); cached.set_context(context); + cached.set_gcm_format(gcm_format); cached.set_sampler_status(rsx::texture_sampler_status::status_uninitialized); cached.set_image_type(type); diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 3cc881b3c2..c88da3936c 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -973,6 +973,7 @@ namespace vk region.create(width, height, section_depth, mipmaps, view, image, 0, true, gcm_format); region.set_dirty(false); region.set_context(context); + region.set_gcm_format(gcm_format); region.set_sampler_status(rsx::texture_sampler_status::status_uninitialized); region.set_image_type(type); @@ -1275,7 +1276,7 @@ namespace vk vk::image* deferred_op_src = nullptr; vk::image* deferred_op_dst = nullptr; - void scale_image(vk::image* src, vk::image* dst, areai src_area, areai dst_area, bool /*interpolate*/, bool is_depth) + void scale_image(vk::image* src, vk::image* dst, areai src_area, areai dst_area, bool /*interpolate*/, bool is_depth, const rsx::typeless_xfer& /*typeless*/) { VkImageAspectFlagBits aspect = VK_IMAGE_ASPECT_COLOR_BIT; if (is_depth) aspect = (VkImageAspectFlagBits)(src->info.format == VK_FORMAT_D16_UNORM ? VK_IMAGE_ASPECT_DEPTH_BIT : VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT); diff --git a/rpcs3/Emu/RSX/rsx_cache.h b/rpcs3/Emu/RSX/rsx_cache.h index a6fddafdc7..00cd01cede 100644 --- a/rpcs3/Emu/RSX/rsx_cache.h +++ b/rpcs3/Emu/RSX/rsx_cache.h @@ -9,47 +9,6 @@ namespace rsx { - struct blit_src_info - { - blit_engine::transfer_source_format format; - blit_engine::transfer_origin origin; - u16 offset_x; - u16 offset_y; - u16 width; - u16 height; - u16 slice_h; - u16 pitch; - void *pixels; - - bool compressed_x; - bool compressed_y; - u32 rsx_address; - }; - - struct blit_dst_info - { - blit_engine::transfer_destination_format format; - u16 offset_x; - u16 offset_y; - u16 width; - u16 height; - u16 pitch; - u16 clip_x; - u16 clip_y; - u16 clip_width; - u16 clip_height; - u16 max_tile_h; - f32 scale_x; - f32 scale_y; - - bool swizzled; - void *pixels; - - bool compressed_x; - bool compressed_y; - u32 rsx_address; - }; - enum protection_policy { protect_policy_one_page, //Only guard one page, preferrably one where this section 'wholly' fits diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index a56c9ef5a2..c9bd240056 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -60,6 +60,47 @@ namespace rsx f32 gamma = 1.f; //NO GAMMA CORRECTION }; + struct blit_src_info + { + blit_engine::transfer_source_format format; + blit_engine::transfer_origin origin; + u16 offset_x; + u16 offset_y; + u16 width; + u16 height; + u16 slice_h; + u16 pitch; + void *pixels; + + bool compressed_x; + bool compressed_y; + u32 rsx_address; + }; + + struct blit_dst_info + { + blit_engine::transfer_destination_format format; + u16 offset_x; + u16 offset_y; + u16 width; + u16 height; + u16 pitch; + u16 clip_x; + u16 clip_y; + u16 clip_width; + u16 clip_height; + u16 max_tile_h; + f32 scale_x; + f32 scale_y; + + bool swizzled; + void *pixels; + + bool compressed_x; + bool compressed_y; + u32 rsx_address; + }; + static const std::pair, std::array> default_remap_vector = { { CELL_GCM_TEXTURE_REMAP_FROM_A, CELL_GCM_TEXTURE_REMAP_FROM_R, CELL_GCM_TEXTURE_REMAP_FROM_G, CELL_GCM_TEXTURE_REMAP_FROM_B },