From 321c360dcbc1cd4f930c45a9c05f9c283aae1ed8 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 23 Mar 2018 18:05:56 +0300 Subject: [PATCH] rsx: Overhaul rendertarget sampling/shuffles - Reimplements render target views used for sampling - Optimizes access using an encoded control token - Adds proper encoding for 24-bit textures (DRGB8 -> ORGB/OBGR) - Adds proper encoding for ABGR textures (ABGR8 -> ARGB8) - Silence some compiler warnings as well - TODO: Real texture views for OGL current method is a hack --- rpcs3/Emu/RSX/Common/texture_cache.h | 27 ++++++++---------- rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp | 2 +- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 8 +++++- rpcs3/Emu/RSX/GL/GLOverlays.h | 1 + rpcs3/Emu/RSX/GL/GLRenderTargets.cpp | 26 +++++++++++++++-- rpcs3/Emu/RSX/GL/GLRenderTargets.h | 27 ++++++++++++++++-- rpcs3/Emu/RSX/GL/GLTextureCache.h | 6 ++-- rpcs3/Emu/RSX/RSXTexture.cpp | 6 ++++ rpcs3/Emu/RSX/RSXTexture.h | 1 + rpcs3/Emu/RSX/RSXThread.cpp | 10 +++---- rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp | 2 +- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 30 +++++++++++++------- rpcs3/Emu/RSX/VK/VKRenderTargets.h | 39 ++++++++------------------ rpcs3/Emu/RSX/VK/VKTextureCache.h | 18 ++++++------ rpcs3/Emu/RSX/rsx_decode.h | 2 +- rpcs3/Emu/RSX/rsx_utils.h | 6 ++++ 16 files changed, 131 insertions(+), 80 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 1829c635cf..7841ad8bf1 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -338,11 +338,6 @@ namespace rsx }; protected: - texture_channel_remap_t 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 }, - { CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP } - }; shared_mutex m_cache_mutex; std::unordered_map m_cache; @@ -1290,7 +1285,7 @@ namespace rsx template sampled_image_descriptor process_framebuffer_resource(commandbuffer_type& cmd, render_target_type texptr, u32 texaddr, u32 gcm_format, surface_store_type& m_rtts, - u16 tex_width, u16 tex_height, u16 tex_pitch, rsx::texture_dimension_extended extended_dimension, bool is_depth, const texture_channel_remap_t& remap) + u16 tex_width, u16 tex_height, u16 tex_pitch, rsx::texture_dimension_extended extended_dimension, bool is_depth, u32 encoded_remap, const texture_channel_remap_t& decoded_remap) { const u32 format = gcm_format & ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN); const auto surface_width = texptr->get_surface_width(); @@ -1350,7 +1345,7 @@ namespace rsx sampled_image_descriptor desc = { texptr->get_surface(), texaddr, format, 0, 0, rsx::apply_resolution_scale(surface_width, true), rsx::apply_resolution_scale(surface_height, true), texture_upload_context::framebuffer_storage, is_depth, 1.f, 1.f, - rsx::texture_dimension_extended::texture_dimension_cubemap, remap }; + rsx::texture_dimension_extended::texture_dimension_cubemap, decoded_remap }; desc.set_external_cubemap_resources(image_array); return desc; @@ -1385,7 +1380,7 @@ namespace rsx sampled_image_descriptor result = { texptr->get_surface(), texaddr, format, 0, 0, w, h, texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, - rsx::texture_dimension_extended::texture_dimension_2d, remap }; + rsx::texture_dimension_extended::texture_dimension_2d, decoded_remap }; result.external_subresource_desc.is_copy_cmd = true; result.external_subresource_desc.sections_to_copy.reserve(overlapping.size()); @@ -1474,13 +1469,13 @@ namespace rsx const auto h = rsx::apply_resolution_scale(internal_height, true); sampled_image_descriptor result = { texptr->get_surface(), texaddr, format, 0, 0, w, h, texture_upload_context::framebuffer_storage, - is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, remap }; + is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, decoded_remap }; result.external_subresource_desc.update_cached = update_subresource_cache; return result; } - return{ texptr->get_view(remap), texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d }; + return{ texptr->get_view(encoded_remap, decoded_remap), texture_upload_context::framebuffer_storage, is_depth, scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d }; } template @@ -1530,7 +1525,8 @@ namespace rsx if (test_framebuffer(texaddr)) { return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts, - tex_width, tex_height, tex_pitch, extended_dimension, false, tex.decoded_remap()); + tex_width, tex_height, tex_pitch, extended_dimension, false, tex.remap(), + tex.decoded_remap()); } else { @@ -1544,7 +1540,8 @@ namespace rsx if (test_framebuffer(texaddr)) { return process_framebuffer_resource(cmd, texptr, texaddr, tex.format(), m_rtts, - tex_width, tex_height, tex_pitch, extended_dimension, true, tex.decoded_remap()); + tex_width, tex_height, tex_pitch, extended_dimension, true, tex.remap(), + tex.decoded_remap()); } else { @@ -1665,7 +1662,7 @@ namespace rsx auto src_image = surface->get_raw_texture(); return{ src_image, surface->get_section_base(), format, offset_x, offset_y, tex_width, tex_height, texture_upload_context::blit_engine_dst, - surface->is_depth_texture(), scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, default_remap_vector }; + surface->is_depth_texture(), scale_x, scale_y, rsx::texture_dimension_extended::texture_dimension_2d, rsx::default_remap_vector }; } } } @@ -1926,7 +1923,7 @@ namespace rsx const u32 gcm_format = src_is_argb8 ? CELL_GCM_TEXTURE_A8R8G8B8 : CELL_GCM_TEXTURE_R5G6B5; vram_texture = upload_image_from_cpu(cmd, src_address, src.width, src.slice_h, 1, 1, src.pitch, gcm_format, texture_upload_context::blit_engine_src, - subresource_layout, rsx::texture_dimension_extended::texture_dimension_2d, rsx::texture_colorspace::rgb_linear, dst.swizzled, default_remap_vector)->get_raw_texture(); + subresource_layout, rsx::texture_dimension_extended::texture_dimension_2d, rsx::texture_colorspace::rgb_linear, dst.swizzled, rsx::default_remap_vector)->get_raw_texture(); m_texture_memory_in_use += src.pitch * src.slice_h; } @@ -2040,7 +2037,7 @@ namespace rsx dest_texture = create_new_texture(cmd, dst.rsx_address, dst.pitch * dst_dimensions.height, dst_dimensions.width, dst_dimensions.height, 1, 1, gcm_format, rsx::texture_upload_context::blit_engine_dst, rsx::texture_dimension_extended::texture_dimension_2d, - channel_order, rsx::texture_colorspace::rgb_linear, default_remap_vector)->get_raw_texture(); + channel_order, rsx::texture_colorspace::rgb_linear, rsx::default_remap_vector)->get_raw_texture(); m_texture_memory_in_use += dst.pitch * dst_dimensions.height; } diff --git a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp index 145dac2e26..3ba715446b 100644 --- a/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/GL/GLFragmentProgram.cpp @@ -302,7 +302,7 @@ void GLFragmentDecompilerThread::insertMainEnd(std::stringstream & OS) OS << "\n" << " fs_main(" + parameters + ");\n\n"; - glsl::insert_rop(OS, m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS); + glsl::insert_rop(OS, !!(m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS)); if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) { diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index c6ce63b34d..d6945146a7 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1344,13 +1344,19 @@ void GLGSRender::flip(int buffer) buffer_width = render_target_texture->width(); buffer_height = render_target_texture->height(); - image = render_target_texture->id(); + image = render_target_texture->get_view(); } else if (auto surface = m_gl_texture_cache.find_texture_from_dimensions(absolute_address)) { //Hack - this should be the first location to check for output //The render might have been done offscreen or in software and a blit used to display image = surface->get_raw_view(); + + //Reset color swizzle + glBindTexture(GL_TEXTURE_2D, image); + const GLenum rgba_shuffle[] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, (GLint*)rgba_shuffle); + surface->set_sampler_status(rsx::texture_sampler_status::status_uninitialized); } else { diff --git a/rpcs3/Emu/RSX/GL/GLOverlays.h b/rpcs3/Emu/RSX/GL/GLOverlays.h index cd13f1fb62..c521fa13f3 100644 --- a/rpcs3/Emu/RSX/GL/GLOverlays.h +++ b/rpcs3/Emu/RSX/GL/GLOverlays.h @@ -627,6 +627,7 @@ namespace gl program_handle.uniforms["x_offset"] = x_offset; program_handle.uniforms["y_offset"] = y_offset; program_handle.uniforms["gamma"] = gamma; + program_handle.uniforms["limit_range"] = (int)limited_rgb; glActiveTexture(GL_TEXTURE31); glBindTexture(GL_TEXTURE_2D, source); diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp index 2c2b169e71..73c4b6a909 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.cpp @@ -14,12 +14,29 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma case rsx::surface_color_format::a8r8g8b8: return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 }; - //These formats discard their alpha component (always 1) + //These formats discard their alpha component, forced to 0 or 1 + //All XBGR formats will have remapping before they can be read back in shaders as DRGB8 + //Prefix o = 1, z = 0 case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: + return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, + { ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; + case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: + return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, + { ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; + case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: + return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, + { ::gl::texture::channel::zero, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; + case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: + return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, + { ::gl::texture::channel::one, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } }; + case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: + return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, + { ::gl::texture::channel::zero, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } }; + case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, { ::gl::texture::channel::one, ::gl::texture::channel::r, ::gl::texture::channel::g, ::gl::texture::channel::b } }; @@ -40,10 +57,13 @@ color_format rsx::internals::surface_color_format_to_gl(rsx::surface_color_forma case rsx::surface_color_format::x32: return{ ::gl::texture::type::f32, ::gl::texture::format::r, true, 1, 4 }; + case rsx::surface_color_format::a8b8g8r8: + //NOTE: To sample this surface as ARGB8 (ABGR8 does not exist), swizzle will be applied by the application + return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1, + { ::gl::texture::channel::a, ::gl::texture::channel::b, ::gl::texture::channel::g, ::gl::texture::channel::r } }; + default: LOG_ERROR(RSX, "Surface color buffer: Unsupported surface color format (0x%x)", (u32)color_format); - - case rsx::surface_color_format::a8b8g8r8: return{ ::gl::texture::type::uint_8_8_8_8, ::gl::texture::format::bgra, false, 4, 1 }; } } diff --git a/rpcs3/Emu/RSX/GL/GLRenderTargets.h b/rpcs3/Emu/RSX/GL/GLRenderTargets.h index 1fe1a52dab..04f0e922f6 100644 --- a/rpcs3/Emu/RSX/GL/GLRenderTargets.h +++ b/rpcs3/Emu/RSX/GL/GLRenderTargets.h @@ -64,6 +64,8 @@ namespace gl texture::internal_format compatible_internal_format = texture::internal_format::rgba8; std::array native_component_mapping; + u32 current_remap_encoding = 0; + public: render_target *old_contents = nullptr; @@ -116,10 +118,29 @@ namespace gl return id(); } - u32 get_view(const std::pair, std::array>& remap) const + u32 get_view(u32 remap_encoding, const std::pair, std::array>& remap) { - bind(); - apply_swizzle_remap(GL_TEXTURE_2D, native_component_mapping, remap); + if (remap_encoding != current_remap_encoding) + { + current_remap_encoding = remap_encoding; + + bind(); + apply_swizzle_remap(GL_TEXTURE_2D, native_component_mapping, remap); + } + + return id(); + } + + u32 get_view() + { + //Get view with components in true native layout + //TODO: Implement real image views + const GLenum rgba_remap[4] = { GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA }; + glBindTexture(GL_TEXTURE_2D, id()); + glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_SWIZZLE_RGBA, (GLint*)rgba_remap); + + //Reset view encoding + current_remap_encoding = 0; return id(); } diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index b1ef0abdf5..4613f09e2c 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -713,8 +713,8 @@ namespace gl apply_component_mapping_flags(dst_type, gcm_format, rsx::texture_create_flags::default_component_order); } - if (memcmp(remap.first.data(), default_remap_vector.first.data(), 4) || - memcmp(remap.second.data(), default_remap_vector.second.data(), 4)) + if (memcmp(remap.first.data(), rsx::default_remap_vector.first.data(), 4) || + memcmp(remap.second.data(), rsx::default_remap_vector.second.data(), 4)) set_up_remap_vector(dst_id, dst_type, remap); return dst_id; @@ -810,7 +810,7 @@ namespace gl } } - u32 generate_cubemap_from_images(void*&, u32 gcm_format, u16 size, const std::array& sources, const texture_channel_remap_t& remap_vector) override + u32 generate_cubemap_from_images(void*&, u32 gcm_format, u16 size, const std::array& sources, const texture_channel_remap_t& /*remap_vector*/) override { const GLenum ifmt = gl::get_sized_internal_format(gcm_format); GLuint dst_id = 0; diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 27ee22185d..c5ee48d702 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -398,6 +398,12 @@ namespace rsx }; } + u32 vertex_texture::remap() const + { + //disabled + return 0xAAE4; + } + u8 vertex_texture::zfunc() const { return ((registers[NV4097_SET_VERTEX_TEXTURE_ADDRESS + (m_index * 8)] >> 28) & 0xf); diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index 6501d8d16a..0d132b8926 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -130,6 +130,7 @@ namespace rsx u8 signed_remap() const; std::pair, std::array> decoded_remap() const; + u32 remap() const; // Control0 bool enabled() const; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 13e7bc1753..0f8d34c8ad 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2246,9 +2246,9 @@ namespace rsx const auto elapsed = timestamp - performance_counters.last_update_timestamp; if (elapsed > idle) - performance_counters.approximate_load = (elapsed - idle) * 100 / elapsed; + performance_counters.approximate_load = (u32)((elapsed - idle) * 100 / elapsed); else - performance_counters.approximate_load = 0; + performance_counters.approximate_load = 0u; performance_counters.idle_time = 0; performance_counters.sampled_frames = 0; @@ -2423,7 +2423,7 @@ namespace rsx int retries = 0; while (!Emu.IsStopped()) { - for (int n = 0; n < occlusion_query_count; ++n) + for (u32 n = 0; n < occlusion_query_count; ++n) { if (m_occlusion_query_data[n].pending || m_occlusion_query_data[n].active) continue; @@ -2571,7 +2571,7 @@ namespace rsx if (!writer.forwarder) //No other queries in the chain, write result - write(writer.sink, ptimer->timestamp(), writer.type, result); + write(writer.sink, (u32)ptimer->timestamp(), writer.type, result); processed++; } @@ -2698,7 +2698,7 @@ namespace rsx //only zpass supported right now if (!writer.forwarder) //No other queries in the chain, write result - write(writer.sink, ptimer->timestamp(), writer.type, result); + write(writer.sink, (u32)ptimer->timestamp(), writer.type, result); processed++; } diff --git a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp index d25578142c..999cacbba5 100644 --- a/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp +++ b/rpcs3/Emu/RSX/VK/VKFragmentProgram.cpp @@ -324,7 +324,7 @@ void VKFragmentDecompilerThread::insertMainEnd(std::stringstream & OS) OS << "\n" << " fs_main(" + parameters + ");\n\n"; - glsl::insert_rop(OS, m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS); + glsl::insert_rop(OS, !!(m_ctrl & CELL_GCM_SHADER_CONTROL_32_BITS_EXPORTS)); if (m_ctrl & CELL_GCM_SHADER_CONTROL_DEPTH_EXPORT) { diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index cc9025dc5a..6eadd24bd3 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -52,23 +52,34 @@ namespace vk std::pair get_compatible_surface_format(rsx::surface_color_format color_format) { + const VkComponentMapping abgr = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }; + const VkComponentMapping o_rgb = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }; + const VkComponentMapping z_rgb = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ZERO }; + const VkComponentMapping o_bgr = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ONE }; + const VkComponentMapping z_bgr = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO }; + switch (color_format) { case rsx::surface_color_format::r5g6b5: return std::make_pair(VK_FORMAT_R5G6B5_UNORM_PACK16, vk::default_component_map()); case rsx::surface_color_format::a8r8g8b8: - case rsx::surface_color_format::a8b8g8r8: return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, vk::default_component_map()); + case rsx::surface_color_format::a8b8g8r8: + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, abgr); + case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, o_bgr); + case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, z_bgr); + case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, z_rgb); + case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: - { - VkComponentMapping no_alpha = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }; - return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, no_alpha); - } + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, o_rgb); case rsx::surface_color_format::w16z16y16x16: return std::make_pair(VK_FORMAT_R16G16B16A16_SFLOAT, vk::default_component_map()); @@ -77,11 +88,10 @@ namespace vk return std::make_pair(VK_FORMAT_R32G32B32A32_SFLOAT, vk::default_component_map()); case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, o_rgb); + case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: - { - VkComponentMapping no_alpha = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }; - return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, no_alpha); - } + return std::make_pair(VK_FORMAT_B8G8R8A8_UNORM, z_rgb); case rsx::surface_color_format::b8: { @@ -1287,7 +1297,7 @@ void VKGSRender::end() { auto rp = vk::get_render_pass_location(VK_FORMAT_UNDEFINED, ds->info.format, 0); auto render_pass = m_render_passes[rp]; - m_depth_converter->run(*m_current_command_buffer, ds->width(), ds->height(), ds, ds->old_contents->get_view(), render_pass, m_framebuffers_to_clean); + m_depth_converter->run(*m_current_command_buffer, ds->width(), ds->height(), ds, ds->old_contents->get_view(0xAAE4, rsx::default_remap_vector), render_pass, m_framebuffers_to_clean); ds->old_contents = nullptr; ds->dirty = false; diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index 89fdfb88cf..47abf51332 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -20,7 +20,7 @@ namespace vk u16 surface_height = 0; VkImageAspectFlags attachment_aspect_flag = VK_IMAGE_ASPECT_COLOR_BIT; - std::vector> views; + std::unordered_map> views; render_target *old_contents = nullptr; //Data occupying the memory location that this surface is replacing u64 frame_tag = 0; //frame id when invalidated, 0 if not invalid @@ -42,43 +42,26 @@ namespace vk mipmaps, layers, samples, initial_layout, tiling, usage, image_flags) {} - vk::image_view* get_view(const std::pair, std::array>& remap) + vk::image_view* get_view(u32 remap_encoding, const std::pair, std::array>& remap) { + auto found = views.find(remap_encoding); + if (found != views.end()) + { + return found->second.get(); + } + VkComponentMapping real_mapping = vk::apply_swizzle_remap ( {native_component_map.a, native_component_map.r, native_component_map.g, native_component_map.b }, remap ); - for (const auto& view : views) - { - if (view->info.components.a == real_mapping.a && - view->info.components.r == real_mapping.r && - view->info.components.g == real_mapping.g && - view->info.components.b == real_mapping.b) - { - return view.get(); - } - } - auto view = std::make_unique(*vk::get_current_renderer(), value, VK_IMAGE_VIEW_TYPE_2D, info.format, real_mapping, vk::get_image_subresource_range(0, 0, 1, 1, attachment_aspect_flag & ~(VK_IMAGE_ASPECT_STENCIL_BIT))); - views.push_back(std::move(view)); - return views.back().get(); - } - - vk::image_view* get_view() - { - if (views.empty()) - { - auto view = std::make_unique(*vk::get_current_renderer(), value, VK_IMAGE_VIEW_TYPE_2D, info.format, - native_component_map, vk::get_image_subresource_range(0, 0, 1, 1, attachment_aspect_flag & ~(VK_IMAGE_ASPECT_STENCIL_BIT))); - - views.push_back(std::move(view)); - } - - return views.back().get(); + auto result = view.get(); + views[remap_encoding] = std::move(view); + return result; } vk::image* get_surface() const override diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 548fbb9c18..838214b564 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -116,7 +116,7 @@ namespace vk if (context != rsx::texture_upload_context::framebuffer_storage) return uploaded_image_view.get(); else - return static_cast(vram_texture)->get_view(); + return static_cast(vram_texture)->get_view(0xAAE4, rsx::default_remap_vector); } vk::image* get_raw_texture() @@ -585,8 +585,8 @@ namespace vk view_swizzle = { remap[1], remap[2], remap[3], remap[0] }; } - if (memcmp(remap_vector.first.data(), default_remap_vector.first.data(), 4) || - memcmp(remap_vector.second.data(), default_remap_vector.second.data(), 4)) + if (memcmp(remap_vector.first.data(), rsx::default_remap_vector.first.data(), 4) || + memcmp(remap_vector.second.data(), rsx::default_remap_vector.second.data(), 4)) view_swizzle = vk::apply_swizzle_remap({view_swizzle.a, view_swizzle.r, view_swizzle.g, view_swizzle.b}, remap_vector); VkImageSubresourceRange view_range = { aspect & ~(VK_IMAGE_ASPECT_STENCIL_BIT), 0, 1, 0, 1 }; @@ -633,7 +633,7 @@ namespace vk } vk::image_view* generate_cubemap_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 size, - const std::array& sources, const texture_channel_remap_t& remap_vector) override + const std::array& sources, const texture_channel_remap_t& /*remap_vector*/) override { std::unique_ptr image; std::unique_ptr view; @@ -706,10 +706,10 @@ namespace vk } vk::image_view* generate_atlas_from_images(vk::command_buffer& cmd, u32 gcm_format, u16 width, u16 height, - const std::vector& sections_to_copy, const texture_channel_remap_t& remap_vector) override + const std::vector& sections_to_copy, const texture_channel_remap_t& /*remap_vector*/) override { auto result = create_temporary_subresource_view_impl(cmd, sections_to_copy.front().src, VK_IMAGE_TYPE_2D, - VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, default_remap_vector, false); + VK_IMAGE_VIEW_TYPE_2D, gcm_format, 0, 0, width, height, rsx::default_remap_vector, false); VkImage dst = result->info.image; VkImageAspectFlags aspect = VK_IMAGE_ASPECT_COLOR_BIT; @@ -940,7 +940,7 @@ namespace vk vk::image* image = section.get_raw_texture(); auto& view = section.get_view(); - VkComponentMapping mapping = apply_component_mapping_flags(gcm_format, expected_flags, default_remap_vector); + VkComponentMapping mapping = apply_component_mapping_flags(gcm_format, expected_flags, rsx::default_remap_vector); if (mapping.a != view->info.components.a || mapping.b != view->info.components.b || @@ -1110,7 +1110,7 @@ namespace vk return upload_texture(cmd, tex, m_rtts, cmd, m_memory_types, const_cast(m_submit_queue)); } - vk::image *upload_image_simple(vk::command_buffer& cmd, u32 address, u32 width, u32 height) + vk::image *upload_image_simple(vk::command_buffer& /*cmd*/, u32 address, u32 width, u32 height) { //Uploads a linear memory range as a BGRA8 texture auto image = std::make_unique(*m_device, m_memory_types.host_visible_coherent, @@ -1139,7 +1139,7 @@ namespace vk be_t* casted_src = (be_t*)src; u32* casted_dst = (u32*)dst; - for (int col = 0; col < width; ++col) + for (u32 col = 0; col < width; ++col) casted_dst[col] = casted_src[col]; src += row_pitch; diff --git a/rpcs3/Emu/RSX/rsx_decode.h b/rpcs3/Emu/RSX/rsx_decode.h index 5766948b1d..d307522a27 100644 --- a/rpcs3/Emu/RSX/rsx_decode.h +++ b/rpcs3/Emu/RSX/rsx_decode.h @@ -1919,7 +1919,7 @@ struct registers_decoder bool srgb_output_enabled() const { - return bool(m_data.raw_value); + return !!m_data.raw_value; } }; diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index ed700b7dc4..40478024d0 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -60,6 +60,12 @@ namespace rsx f32 gamma = 1.f; //NO GAMMA CORRECTION }; + 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 }, + { CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP } + }; + template void pad_texture(void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 output_height) {