diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index ff934431ad..628504929f 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -1440,17 +1440,18 @@ namespace rsx texture.border_type() ^ 1); } - u32 get_remap_encoding(const std::pair, std::array>& remap) + u32 get_remap_encoding(const texture_channel_remap_t& remap) { u32 encode = 0; - encode |= (remap.first[0] << 0); - encode |= (remap.first[1] << 2); - encode |= (remap.first[2] << 4); - encode |= (remap.first[3] << 6); - encode |= (remap.second[0] << 8); - encode |= (remap.second[1] << 10); - encode |= (remap.second[2] << 12); - encode |= (remap.second[3] << 14); + encode |= (remap.channel_map[0] << 0); + encode |= (remap.channel_map[1] << 2); + encode |= (remap.channel_map[2] << 4); + encode |= (remap.channel_map[3] << 6); + + encode |= (remap.control_map[0] << 8); + encode |= (remap.control_map[1] << 10); + encode |= (remap.control_map[2] << 12); + encode |= (remap.control_map[3] << 14); return encode; } diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index 17069587c2..718d4e2d34 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -1,6 +1,7 @@ #pragma once #include "io_buffer.h" +#include "../color_utils.h" #include "../RSXTexture.h" #include @@ -276,7 +277,7 @@ namespace rsx /** * Reverse encoding */ - u32 get_remap_encoding(const std::pair, std::array>& remap); + u32 get_remap_encoding(const texture_channel_remap_t& remap); /** * Get gcm texel layout. Returns diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 3ece7e883d..71dace8198 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -1837,7 +1837,6 @@ namespace rsx commandbuffer_type& cmd, const image_section_attributes_t& attr, const size3f& scale, - u32 encoded_remap, const texture_channel_remap_t& remap, const texture_cache_search_options& options, const utils::address_range& memory_range, @@ -1849,7 +1848,7 @@ namespace rsx // Most mesh textures are stored as compressed to make the most of the limited memory if (auto cached_texture = find_texture_from_dimensions(attr.address, attr.gcm_format, attr.width, attr.height, attr.depth)) { - return{ cached_texture->get_view(encoded_remap, remap), cached_texture->get_context(), cached_texture->get_format_class(), scale, cached_texture->get_image_type() }; + return{ cached_texture->get_view(remap), cached_texture->get_context(), cached_texture->get_format_class(), scale, cached_texture->get_image_type() }; } } else @@ -1863,7 +1862,7 @@ namespace rsx const bool force_convert = !render_target_format_is_compatible(texptr, attr.gcm_format); auto result = helpers::process_framebuffer_resource_fast( - cmd, texptr, attr, scale, extended_dimension, encoded_remap, remap, true, force_convert); + cmd, texptr, attr, scale, extended_dimension, remap, true, force_convert); if (!options.skip_texture_barriers && result.is_cyclic_reference) { @@ -1887,7 +1886,7 @@ namespace rsx const bool force_convert = !render_target_format_is_compatible(last.surface, attr.gcm_format); return helpers::process_framebuffer_resource_fast( - cmd, last.surface, attr, scale, extended_dimension, encoded_remap, remap, false, force_convert); + cmd, last.surface, attr, scale, extended_dimension, remap, false, force_convert); } return {}; @@ -1941,7 +1940,7 @@ namespace rsx break; } - return{ cached_texture->get_view(encoded_remap, remap), cached_texture->get_context(), cached_texture->get_format_class(), scale, cached_texture->get_image_type() }; + return{ cached_texture->get_view(remap), cached_texture->get_context(), cached_texture->get_format_class(), scale, cached_texture->get_image_type() }; } } @@ -2016,7 +2015,7 @@ namespace rsx { // Clipped view auto viewed_image = last->get_raw_texture(); - sampled_image_descriptor result = { viewed_image->get_view(encoded_remap, remap), last->get_context(), + sampled_image_descriptor result = { viewed_image->get_view(remap), last->get_context(), viewed_image->format_class(), scale, extended_dimension, false, viewed_image->samples() }; helpers::calculate_sample_clip_parameters(result, position2i(0, 0), size2i(attr.width, attr.height), size2i(normalized_width, last->get_height())); @@ -2029,7 +2028,7 @@ namespace rsx } auto result = helpers::merge_cache_resources( - cmd, overlapping_fbos, overlapping_locals, attr, scale, extended_dimension, encoded_remap, remap, _pool); + cmd, overlapping_fbos, overlapping_locals, attr, scale, extended_dimension, remap, _pool); const bool is_simple_subresource_copy = (result.external_subresource_desc.op == deferred_request_command::copy_image_static) || @@ -2048,13 +2047,12 @@ namespace rsx position2i(result.external_subresource_desc.x, result.external_subresource_desc.y), size2i(result.external_subresource_desc.width, result.external_subresource_desc.height), size2i(result.external_subresource_desc.external_handle->width(), result.external_subresource_desc.external_handle->height()), - encoded_remap, remap, false); + remap, false); } else { helpers::convert_image_blit_to_clip_descriptor( result, - encoded_remap, remap, false); } @@ -2348,7 +2346,7 @@ namespace rsx const auto lookup_range = utils::address_range::start_length(attributes.address, attributes.pitch * required_surface_height); reader_lock lock(m_cache_mutex); - auto result = fast_texture_search(cmd, attributes, scale, tex.remap(), tex.decoded_remap(), + auto result = fast_texture_search(cmd, attributes, scale, tex.decoded_remap(), options, lookup_range, extended_dimension, m_rtts, std::forward(extras)...); @@ -2423,7 +2421,7 @@ namespace rsx } const auto range = utils::address_range::start_length(attr2.address, attr2.pitch * attr2.height); - auto ret = fast_texture_search(cmd, attr2, scale, tex.remap(), tex.decoded_remap(), + auto ret = fast_texture_search(cmd, attr2, scale, tex.decoded_remap(), options, range, extended_dimension, m_rtts, std::forward(extras)...); if (!ret.validate() || @@ -2488,7 +2486,7 @@ namespace rsx auto uploaded = upload_image_from_cpu(cmd, tex_range, attributes.width, attributes.height, attributes.depth, tex.get_exact_mipmap_count(), attributes.pitch, attributes.gcm_format, texture_upload_context::shader_read, subresources_layout, extended_dimension, attributes.swizzled); - return{ uploaded->get_view(tex.remap(), tex.decoded_remap()), + return{ uploaded->get_view(tex.decoded_remap()), texture_upload_context::shader_read, format_class, scale, extended_dimension }; } diff --git a/rpcs3/Emu/RSX/Common/texture_cache_helpers.h b/rpcs3/Emu/RSX/Common/texture_cache_helpers.h index e70eed7401..617f3b75db 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache_helpers.h +++ b/rpcs3/Emu/RSX/Common/texture_cache_helpers.h @@ -5,8 +5,6 @@ namespace rsx { - using texture_channel_remap_t = std::pair, std::array>; - // Defines pixel operation to be performed on a surface before it is ready for use enum surface_transform : u32 { @@ -551,11 +549,10 @@ namespace rsx const position2i& offset, const size2i& desired_dimensions, const size2i& actual_dimensions, - u32 encoded_remap, const texture_channel_remap_t& decoded_remap, bool cyclic_reference) { - desc.image_handle = desc.external_subresource_desc.as_viewable()->get_view(encoded_remap, decoded_remap); + desc.image_handle = desc.external_subresource_desc.as_viewable()->get_view(decoded_remap); desc.ref_address = desc.external_subresource_desc.external_ref_addr; desc.is_cyclic_reference = cyclic_reference; desc.samples = desc.external_subresource_desc.external_handle->samples(); @@ -567,7 +564,6 @@ namespace rsx template void convert_image_blit_to_clip_descriptor( sampled_image_descriptor& desc, - u32 encoded_remap, const texture_channel_remap_t& decoded_remap, bool cyclic_reference) { @@ -602,7 +598,6 @@ namespace rsx position2i(section.src_x, section.src_y), size2i(section.src_w, section.src_h), size2i(surface_width, surface_height), - encoded_remap, decoded_remap, cyclic_reference); } @@ -613,7 +608,7 @@ namespace rsx const image_section_attributes_t& attr, const size3f& scale, texture_dimension_extended extended_dimension, - u32 encoded_remap, const texture_channel_remap_t& decoded_remap, + const texture_channel_remap_t& decoded_remap, bool surface_is_rop_target, bool force_convert) { @@ -710,7 +705,7 @@ namespace rsx texptr->memory_barrier(cmd, access_type); auto viewed_surface = texptr->get_surface(access_type); - sampled_image_descriptor result = { viewed_surface->get_view(encoded_remap, decoded_remap), texture_upload_context::framebuffer_storage, + sampled_image_descriptor result = { viewed_surface->get_view(decoded_remap), texture_upload_context::framebuffer_storage, texptr->format_class(), scale, rsx::texture_dimension_extended::texture_dimension_2d, surface_is_rop_target, viewed_surface->samples() }; if (requires_clip) @@ -746,7 +741,7 @@ namespace rsx const image_section_attributes_t& attr, const size3f& scale, texture_dimension_extended extended_dimension, - u32 /*encoded_remap*/, const texture_channel_remap_t& decoded_remap, + const texture_channel_remap_t& decoded_remap, int select_hint = -1) { ensure((select_hint & 0x1) == select_hint); diff --git a/rpcs3/Emu/RSX/GL/GLCompute.cpp b/rpcs3/Emu/RSX/GL/GLCompute.cpp index 58bc8e5660..12ed12344c 100644 --- a/rpcs3/Emu/RSX/GL/GLCompute.cpp +++ b/rpcs3/Emu/RSX/GL/GLCompute.cpp @@ -344,8 +344,8 @@ namespace gl m_program.uniforms["region_offset"] = color2i(region.x, region.y); m_program.uniforms["region_size"] = color2i(region.width, region.height); - auto depth_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::depth); - auto stencil_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::stencil); + auto depth_view = src->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY), gl::image_aspect::depth); + auto stencil_view = src->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY), gl::image_aspect::stencil); if (!m_sampler) { @@ -396,7 +396,7 @@ namespace gl m_program.uniforms["is_bgra"] = (layout.format == static_cast(gl::texture::format::bgra)); m_program.uniforms["block_width"] = static_cast(layout.size); - auto data_view = src->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::color); + auto data_view = src->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY), gl::image_aspect::color); if (!m_sampler) { diff --git a/rpcs3/Emu/RSX/GL/GLDraw.cpp b/rpcs3/Emu/RSX/GL/GLDraw.cpp index 8061f5a180..b25b0afde5 100644 --- a/rpcs3/Emu/RSX/GL/GLDraw.cpp +++ b/rpcs3/Emu/RSX/GL/GLDraw.cpp @@ -447,7 +447,7 @@ void GLGSRender::bind_texture_env() if (current_fragment_program.texture_state.redirected_textures & (1 << i)) { auto root_texture = static_cast(view->image()); - auto stencil_view = root_texture->get_view(gl::GL_REMAP_IDENTITY, rsx::default_remap_vector, gl::image_aspect::stencil); + auto stencil_view = root_texture->get_view(rsx::default_remap_vector.with_encoding(gl::GL_REMAP_IDENTITY), gl::image_aspect::stencil); stencil_view->bind(cmd, GL_STENCIL_MIRRORS_START + i); } } diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index c79ecf44bc..9a11e08c18 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -807,37 +807,9 @@ namespace gl } } - std::array apply_swizzle_remap(const std::array& swizzle_remap, const std::pair, std::array>& decoded_remap) + std::array apply_swizzle_remap(const std::array& swizzle_remap, const rsx::texture_channel_remap_t& decoded_remap) { - //Remapping tables; format is A-R-G-B - //Remap input table. Contains channel index to read color from - const auto remap_inputs = decoded_remap.first; - - //Remap control table. Controls whether the remap value is used, or force either 0 or 1 - const auto remap_lookup = decoded_remap.second; - - std::array remap_values; - - for (u8 channel = 0; channel < 4; ++channel) - { - switch (remap_lookup[channel]) - { - default: - rsx_log.error("Unknown remap function 0x%X", remap_lookup[channel]); - [[fallthrough]]; - case CELL_GCM_TEXTURE_REMAP_REMAP: - remap_values[channel] = swizzle_remap[remap_inputs[channel]]; - break; - case CELL_GCM_TEXTURE_REMAP_ZERO: - remap_values[channel] = GL_ZERO; - break; - case CELL_GCM_TEXTURE_REMAP_ONE: - remap_values[channel] = GL_ONE; - break; - } - } - - return remap_values; + return decoded_remap.remap(swizzle_remap, GL_ZERO, GL_ONE); } void upload_texture(gl::command_context& cmd, texture* dst, u32 gcm_format, bool is_swizzled, const std::vector& subresources_layout) diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp index 77541c4ce8..7da909ad97 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.cpp +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.cpp @@ -181,8 +181,7 @@ namespace gl dst->set_native_component_layout(components); } - const auto encoding = rsx::get_remap_encoding(remap); - return dst->get_view(encoding, remap); + return dst->get_view(remap); } void texture_cache::copy_transfer_regions_impl(gl::command_context& cmd, gl::texture* dst_image, const std::vector& sources) const diff --git a/rpcs3/Emu/RSX/GL/GLTextureCache.h b/rpcs3/Emu/RSX/GL/GLTextureCache.h index 31b63f2cb7..36146d813d 100644 --- a/rpcs3/Emu/RSX/GL/GLTextureCache.h +++ b/rpcs3/Emu/RSX/GL/GLTextureCache.h @@ -385,9 +385,9 @@ namespace gl return format; } - gl::texture_view* get_view(u32 remap_encoding, const std::pair, std::array>& remap) + gl::texture_view* get_view(const rsx::texture_channel_remap_t& remap) { - return vram_texture->get_view(remap_encoding, remap); + return vram_texture->get_view(remap); } gl::viewable_image* get_raw_texture() const @@ -402,7 +402,7 @@ namespace gl gl::texture_view* get_raw_view() { - return vram_texture->get_view(GL_REMAP_IDENTITY, rsx::default_remap_vector); + return vram_texture->get_view(rsx::default_remap_vector.with_encoding(GL_REMAP_IDENTITY)); } bool is_depth_texture() const diff --git a/rpcs3/Emu/RSX/GL/glutils/image.cpp b/rpcs3/Emu/RSX/GL/glutils/image.cpp index 31de23c7a5..7876cf6dc3 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.cpp +++ b/rpcs3/Emu/RSX/GL/glutils/image.cpp @@ -306,13 +306,13 @@ namespace gl m_id = GL_NONE; } - texture_view* viewable_image::get_view(u32 remap_encoding, const std::pair, std::array>& remap_, GLenum aspect_flags) + texture_view* viewable_image::get_view(const rsx::texture_channel_remap_t& remap_, GLenum aspect_flags) { auto remap = remap_; const u64 view_aspect = static_cast(aspect_flags) & aspect(); ensure(view_aspect); - const u64 key = static_cast(remap_encoding) | (view_aspect << 32); + const u64 key = static_cast(remap.encoded) | (view_aspect << 32); if (auto found = views.find(key); found != views.end()) { @@ -323,7 +323,7 @@ namespace gl std::array mapping; GLenum* swizzle = nullptr; - if (remap_encoding != GL_REMAP_IDENTITY) + if (remap.encoded != GL_REMAP_IDENTITY) { mapping = apply_swizzle_remap(get_native_component_layout(), remap); swizzle = mapping.data(); diff --git a/rpcs3/Emu/RSX/GL/glutils/image.h b/rpcs3/Emu/RSX/GL/glutils/image.h index 7e45ab7616..791762d558 100644 --- a/rpcs3/Emu/RSX/GL/glutils/image.h +++ b/rpcs3/Emu/RSX/GL/glutils/image.h @@ -459,10 +459,10 @@ namespace gl public: using texture::texture; - texture_view* get_view(u32 remap_encoding, const std::pair, std::array>& remap, GLenum aspect_flags = image_aspect::color | image_aspect::depth); + texture_view* get_view(const rsx::texture_channel_remap_t& remap, GLenum aspect_flags = image_aspect::color | image_aspect::depth); void set_native_component_layout(const std::array& layout); }; // Texture helpers - std::array apply_swizzle_remap(const std::array& swizzle_remap, const std::pair, std::array>& decoded_remap); + std::array apply_swizzle_remap(const std::array& swizzle_remap, const rsx::texture_channel_remap_t& decoded_remap); } diff --git a/rpcs3/Emu/RSX/RSXTexture.cpp b/rpcs3/Emu/RSX/RSXTexture.cpp index 3af6c4c395..2e309b0eb9 100644 --- a/rpcs3/Emu/RSX/RSXTexture.cpp +++ b/rpcs3/Emu/RSX/RSXTexture.cpp @@ -165,7 +165,7 @@ namespace rsx return (registers[NV4097_SET_TEXTURE_CONTROL1 + (m_index * 8)]); } - std::pair, std::array> fragment_texture::decoded_remap() const + rsx::texture_channel_remap_t fragment_texture::decoded_remap() const { u32 remap_ctl = registers[NV4097_SET_TEXTURE_CONTROL1 + (m_index * 8)]; u32 remap_override = (remap_ctl >> 16) & 0xFFFF; @@ -359,18 +359,14 @@ namespace rsx return std::min(ensure(mipmap()), max_mipmap_count); } - std::pair, std::array> vertex_texture::decoded_remap() const + rsx::texture_channel_remap_t vertex_texture::decoded_remap() const { - return - { - { 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 } - }; + return rsx::default_remap_vector; } u32 vertex_texture::remap() const { - //disabled + // disabled return 0xAAE4; } diff --git a/rpcs3/Emu/RSX/RSXTexture.h b/rpcs3/Emu/RSX/RSXTexture.h index e4d58cec6d..1f536a29e6 100644 --- a/rpcs3/Emu/RSX/RSXTexture.h +++ b/rpcs3/Emu/RSX/RSXTexture.h @@ -1,5 +1,6 @@ #pragma once #include "gcm_enums.h" +#include "color_utils.h" namespace rsx { @@ -58,14 +59,7 @@ namespace rsx // Control1 u32 remap() const; - - /** - * returns a pair of arrays - * First array is a redirection table into the channel indices - * Second array is a lookup reference deciding whether to use the redirection table or use constants 0 and 1 - * Both arrays have components in A-R-G-B format - */ - std::pair, std::array> decoded_remap() const; + rsx::texture_channel_remap_t decoded_remap() const; // Filter f32 bias() const; @@ -119,7 +113,7 @@ namespace rsx rsx::texture_wrap_mode wrap_t() const; rsx::texture_wrap_mode wrap_r() const; - std::pair, std::array> decoded_remap() const; + rsx::texture_channel_remap_t decoded_remap() const; u32 remap() const; // Control0 diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 933436a041..8bb11d3fb2 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -538,7 +538,7 @@ bool VKGSRender::bind_texture_env() { // Stencil mirror required auto root_image = static_cast(view->image()); - auto stencil_view = root_image->get_view(0xAAE4, rsx::default_remap_vector, VK_IMAGE_ASPECT_STENCIL_BIT); + auto stencil_view = root_image->get_view(rsx::default_remap_vector, VK_IMAGE_ASPECT_STENCIL_BIT); if (!m_stencil_mirror_sampler) { diff --git a/rpcs3/Emu/RSX/VK/VKOverlays.cpp b/rpcs3/Emu/RSX/VK/VKOverlays.cpp index 8aeac2ed3f..b46b8be4a3 100644 --- a/rpcs3/Emu/RSX/VK/VKOverlays.cpp +++ b/rpcs3/Emu/RSX/VK/VKOverlays.cpp @@ -908,7 +908,7 @@ namespace vk for (auto& img : src) { img->push_layout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - views.push_back(img->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector)); + views.push_back(img->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY))); } if (views.size() < 2) diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp index d789e578e7..899c6593e0 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.cpp @@ -899,15 +899,15 @@ namespace vk m_cyclic_ref_tracker.reset(); } - image_view* render_target::get_view(u32 remap_encoding, const std::pair, std::array>& remap, VkImageAspectFlags mask) + image_view* render_target::get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) { - if (remap_encoding == VK_REMAP_VIEW_MULTISAMPLED) + if (remap.encoded == VK_REMAP_VIEW_MULTISAMPLED) { // Special remap flag, intercept here - return vk::viewable_image::get_view(VK_REMAP_IDENTITY, remap, mask); + return vk::viewable_image::get_view(remap.with_encoding(VK_REMAP_IDENTITY), mask); } - return vk::viewable_image::get_view(remap_encoding, remap, mask); + return vk::viewable_image::get_view(remap, mask); } void render_target::memory_barrier(vk::command_buffer& cmd, rsx::surface_access access) diff --git a/rpcs3/Emu/RSX/VK/VKRenderTargets.h b/rpcs3/Emu/RSX/VK/VKRenderTargets.h index e1d1d5230a..fa9d7d06ef 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderTargets.h +++ b/rpcs3/Emu/RSX/VK/VKRenderTargets.h @@ -113,7 +113,7 @@ namespace vk bool matches_dimensions(u16 _width, u16 _height) const; void reset_surface_counters(); - image_view* get_view(u32 remap_encoding, const std::pair, std::array>& remap, + image_view* get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT) override; // Memory management diff --git a/rpcs3/Emu/RSX/VK/VKResolveHelper.h b/rpcs3/Emu/RSX/VK/VKResolveHelper.h index 171b1cc8c4..ab9e827db9 100644 --- a/rpcs3/Emu/RSX/VK/VKResolveHelper.h +++ b/rpcs3/Emu/RSX/VK/VKResolveHelper.h @@ -119,8 +119,8 @@ namespace vk void bind_resources() override { - auto msaa_view = multisampled->get_view(VK_REMAP_VIEW_MULTISAMPLED, rsx::default_remap_vector); - auto resolved_view = resolve->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector); + auto msaa_view = multisampled->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_VIEW_MULTISAMPLED)); + auto resolved_view = resolve->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY)); m_program->bind_uniform({ VK_NULL_HANDLE, msaa_view->value, multisampled->current_layout }, "multisampled", VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_descriptor_set); m_program->bind_uniform({ VK_NULL_HANDLE, resolved_view->value, resolve->current_layout }, "resolve", VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, m_descriptor_set); } @@ -277,7 +277,7 @@ namespace vk void run(vk::command_buffer& cmd, vk::viewable_image* msaa_image, vk::viewable_image* resolve_image, VkRenderPass render_pass) { update_sample_configuration(msaa_image); - auto src_view = msaa_image->get_view(VK_REMAP_VIEW_MULTISAMPLED, rsx::default_remap_vector); + auto src_view = msaa_image->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_VIEW_MULTISAMPLED)); overlay_pass::run( cmd, @@ -308,7 +308,7 @@ namespace vk renderpass_config.set_multisample_shading_rate(1.f); update_sample_configuration(msaa_image); - auto src_view = resolve_image->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector); + auto src_view = resolve_image->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY)); overlay_pass::run( cmd, @@ -372,7 +372,7 @@ namespace vk void run(vk::command_buffer& cmd, vk::viewable_image* msaa_image, vk::viewable_image* resolve_image, VkRenderPass render_pass) { update_sample_configuration(msaa_image); - auto stencil_view = msaa_image->get_view(VK_REMAP_VIEW_MULTISAMPLED, rsx::default_remap_vector, VK_IMAGE_ASPECT_STENCIL_BIT); + auto stencil_view = msaa_image->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_VIEW_MULTISAMPLED), VK_IMAGE_ASPECT_STENCIL_BIT); region.rect.extent.width = resolve_image->width(); region.rect.extent.height = resolve_image->height(); @@ -442,7 +442,7 @@ namespace vk renderpass_config.set_multisample_shading_rate(1.f); update_sample_configuration(msaa_image); - auto stencil_view = resolve_image->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector, VK_IMAGE_ASPECT_STENCIL_BIT); + auto stencil_view = resolve_image->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY), VK_IMAGE_ASPECT_STENCIL_BIT); region.rect.extent.width = resolve_image->width(); region.rect.extent.height = resolve_image->height(); @@ -486,8 +486,8 @@ namespace vk void run(vk::command_buffer& cmd, vk::viewable_image* msaa_image, vk::viewable_image* resolve_image, VkRenderPass render_pass) { update_sample_configuration(msaa_image); - auto depth_view = msaa_image->get_view(VK_REMAP_VIEW_MULTISAMPLED, rsx::default_remap_vector, VK_IMAGE_ASPECT_DEPTH_BIT); - auto stencil_view = msaa_image->get_view(VK_REMAP_VIEW_MULTISAMPLED, rsx::default_remap_vector, VK_IMAGE_ASPECT_STENCIL_BIT); + auto depth_view = msaa_image->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_VIEW_MULTISAMPLED), VK_IMAGE_ASPECT_DEPTH_BIT); + auto stencil_view = msaa_image->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_VIEW_MULTISAMPLED), VK_IMAGE_ASPECT_STENCIL_BIT); overlay_pass::run( cmd, @@ -531,8 +531,8 @@ namespace vk renderpass_config.set_multisample_shading_rate(1.f); update_sample_configuration(msaa_image); - auto depth_view = resolve_image->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector, VK_IMAGE_ASPECT_DEPTH_BIT); - auto stencil_view = resolve_image->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector, VK_IMAGE_ASPECT_STENCIL_BIT); + auto depth_view = resolve_image->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY), VK_IMAGE_ASPECT_DEPTH_BIT); + auto stencil_view = resolve_image->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY), VK_IMAGE_ASPECT_STENCIL_BIT); overlay_pass::run( cmd, diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp index 9535d54331..503474e6ac 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.cpp +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.cpp @@ -709,7 +709,7 @@ namespace vk image->set_debug_name("Temp view"); image->set_native_component_layout(view_swizzle); - auto view = image->get_view(rsx::get_remap_encoding(remap_vector), remap_vector); + auto view = image->get_view(remap_vector); if (copy) { diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 691a257f2c..4696062c70 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -144,16 +144,16 @@ namespace vk return !exists() || managed_texture; } - vk::image_view* get_view(u32 remap_encoding, const std::pair, std::array>& remap) + vk::image_view* get_view(const rsx::texture_channel_remap_t& remap) { ensure(vram_texture != nullptr); - return vram_texture->get_view(remap_encoding, remap); + return vram_texture->get_view(remap); } vk::image_view* get_raw_view() { ensure(vram_texture != nullptr); - return vram_texture->get_view(0xAAE4, rsx::default_remap_vector); + return vram_texture->get_view(rsx::default_remap_vector); } vk::viewable_image* get_raw_texture() diff --git a/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp b/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp index 7cfaedabf2..c256070490 100644 --- a/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp +++ b/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp @@ -117,8 +117,8 @@ namespace vk void fsr_pass::run(const vk::command_buffer& cmd, vk::viewable_image* src, vk::viewable_image* dst, const size2u& input_size, const size2u& output_size) { - m_input_image = src->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector); - m_output_image = dst->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector); + m_input_image = src->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY)); + m_output_image = dst->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY)); m_input_size = input_size; m_output_size = output_size; diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.cpp b/rpcs3/Emu/RSX/VK/vkutils/image.cpp index 350923a983..56b5fc083a 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/image.cpp @@ -411,8 +411,9 @@ namespace vk return result; } - image_view* viewable_image::get_view(u32 remap_encoding, const std::pair, std::array>& remap, VkImageAspectFlags mask) + image_view* viewable_image::get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask) { + u32 remap_encoding = remap.encoded; if (remap_encoding == VK_REMAP_IDENTITY) { if (native_component_map.a == VK_COMPONENT_SWIZZLE_A && diff --git a/rpcs3/Emu/RSX/VK/vkutils/image.h b/rpcs3/Emu/RSX/VK/vkutils/image.h index 4a0372d226..a37c7676b4 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image.h +++ b/rpcs3/Emu/RSX/VK/vkutils/image.h @@ -134,7 +134,7 @@ namespace vk public: using image::image; - virtual image_view* get_view(u32 remap_encoding, const std::pair, std::array>& remap, + virtual image_view* get_view(const rsx::texture_channel_remap_t& remap, VkImageAspectFlags mask = VK_IMAGE_ASPECT_COLOR_BIT | VK_IMAGE_ASPECT_DEPTH_BIT); void set_native_component_layout(VkComponentMapping new_layout); diff --git a/rpcs3/Emu/RSX/VK/vkutils/image_helpers.cpp b/rpcs3/Emu/RSX/VK/vkutils/image_helpers.cpp index ba6e095a21..fdebf35f37 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image_helpers.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/image_helpers.cpp @@ -3,6 +3,7 @@ #include "image.h" #include "util/logs.hpp" #include "../VKRenderPass.h" +#include "../../color_utils.h" #include "../../gcm_enums.h" namespace vk @@ -30,29 +31,10 @@ namespace vk } } - VkComponentMapping apply_swizzle_remap(const std::array& base_remap, const std::pair, std::array>& remap_vector) + VkComponentMapping apply_swizzle_remap(const std::array& base_remap, const rsx::texture_channel_remap_t& remap_vector) { - VkComponentSwizzle final_mapping[4] = {}; - - for (u8 channel = 0; channel < 4; ++channel) - { - switch (remap_vector.second[channel]) - { - case CELL_GCM_TEXTURE_REMAP_ONE: - final_mapping[channel] = VK_COMPONENT_SWIZZLE_ONE; - break; - case CELL_GCM_TEXTURE_REMAP_ZERO: - final_mapping[channel] = VK_COMPONENT_SWIZZLE_ZERO; - break; - case CELL_GCM_TEXTURE_REMAP_REMAP: - final_mapping[channel] = base_remap[remap_vector.first[channel]]; - break; - default: - rsx_log.error("Unknown remap lookup value %d", remap_vector.second[channel]); - } - } - - return{ final_mapping[1], final_mapping[2], final_mapping[3], final_mapping[0] }; + const auto final_mapping = remap_vector.remap(base_remap, VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_ONE); + return { final_mapping[1], final_mapping[2], final_mapping[3], final_mapping[0] }; } void change_image_layout(const vk::command_buffer& cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, const VkImageSubresourceRange& range, diff --git a/rpcs3/Emu/RSX/VK/vkutils/image_helpers.h b/rpcs3/Emu/RSX/VK/vkutils/image_helpers.h index eb9c4bd1a1..3e794d59fe 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/image_helpers.h +++ b/rpcs3/Emu/RSX/VK/vkutils/image_helpers.h @@ -1,6 +1,11 @@ #pragma once #include "../VulkanAPI.h" +namespace rsx +{ + struct texture_channel_remap_t; +} + namespace vk { class image; @@ -9,7 +14,7 @@ namespace vk extern VkComponentMapping default_component_map; VkImageAspectFlags get_aspect_flags(VkFormat format); - VkComponentMapping apply_swizzle_remap(const std::array& base_remap, const std::pair, std::array>& remap_vector); + VkComponentMapping apply_swizzle_remap(const std::array& base_remap, const rsx::texture_channel_remap_t& remap_vector); void change_image_layout(const vk::command_buffer& cmd, VkImage image, VkImageLayout current_layout, VkImageLayout new_layout, const VkImageSubresourceRange& range, u32 src_queue_family = VK_QUEUE_FAMILY_IGNORED, u32 dst_queue_family = VK_QUEUE_FAMILY_IGNORED, diff --git a/rpcs3/Emu/RSX/VK/vkutils/scratch.cpp b/rpcs3/Emu/RSX/VK/vkutils/scratch.cpp index ac79bea00e..a34c90091b 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/scratch.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/scratch.cpp @@ -61,7 +61,7 @@ namespace vk if (auto found = g_null_image_views.find(type); found != g_null_image_views.end()) { - return found->second->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector); + return found->second->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY)); } VkImageType image_type; @@ -118,7 +118,7 @@ namespace vk tex->change_layout(cmd, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); // Return view - return tex->get_view(VK_REMAP_IDENTITY, rsx::default_remap_vector); + return tex->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY)); } vk::image* get_typeless_helper(VkFormat format, rsx::format_class format_class, u32 requested_width, u32 requested_height) diff --git a/rpcs3/Emu/RSX/color_utils.h b/rpcs3/Emu/RSX/color_utils.h new file mode 100644 index 0000000000..f40d29c224 --- /dev/null +++ b/rpcs3/Emu/RSX/color_utils.h @@ -0,0 +1,227 @@ +#pragma once + +#include +#include +#include "gcm_enums.h" + +namespace rsx +{ + struct texture_channel_remap_t + { + u32 encoded; + std::array control_map; + std::array channel_map; + + template + std::array remap(const std::array& components, T select_zero, T select_one) const + { + std::array remapped{}; + for (u8 channel = 0; channel < 4; ++channel) + { + switch (control_map[channel]) + { + default: + [[fallthrough]]; + case CELL_GCM_TEXTURE_REMAP_REMAP: + remapped[channel] = components[channel_map[channel]]; + break; + case CELL_GCM_TEXTURE_REMAP_ZERO: + remapped[channel] = select_zero; + break; + case CELL_GCM_TEXTURE_REMAP_ONE: + remapped[channel] = select_one; + break; + } + } + return remapped; + } + + template + requires std::is_integral_v || std::is_floating_point_v + std::array remap(const std::array& components) const + { + return remap(components, static_cast(0), static_cast(1)); + } + + template + requires std::is_integral_v || std::is_enum_v + texture_channel_remap_t with_encoding(T encoding) const + { + texture_channel_remap_t result = *this; + result.encoded = encoding; + return result; + } + }; + + static const texture_channel_remap_t default_remap_vector = + { + .encoded = 0xAAE4, + .control_map = { CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP, CELL_GCM_TEXTURE_REMAP_REMAP }, + .channel_map = { CELL_GCM_TEXTURE_REMAP_FROM_A, CELL_GCM_TEXTURE_REMAP_FROM_R, CELL_GCM_TEXTURE_REMAP_FROM_G, CELL_GCM_TEXTURE_REMAP_FROM_B } + }; + + static inline texture_channel_remap_t decode_remap_encoding(u32 remap_ctl) + { + // Remapping tables; format is A-R-G-B + // Remap input table. Contains channel index to read color from + texture_channel_remap_t result = + { + .encoded = remap_ctl + }; + + result.channel_map = + { + static_cast(remap_ctl & 0x3), + static_cast((remap_ctl >> 2) & 0x3), + static_cast((remap_ctl >> 4) & 0x3), + static_cast((remap_ctl >> 6) & 0x3), + }; + + // Remap control table. Controls whether the remap value is used, or force either 0 or 1 + result.control_map = + { + static_cast((remap_ctl >> 8) & 0x3), + static_cast((remap_ctl >> 10) & 0x3), + static_cast((remap_ctl >> 12) & 0x3), + static_cast((remap_ctl >> 14) & 0x3), + }; + + return result; + } + + // Convert color write mask for G8B8 to R8G8 + static inline u32 get_g8b8_r8g8_clearmask(u32 mask) + { + u32 result = 0; + if (mask & RSX_GCM_CLEAR_GREEN_BIT) result |= RSX_GCM_CLEAR_GREEN_BIT; + if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT; + + return result; + } + + static inline void get_g8b8_r8g8_colormask(bool& red, bool&/*green*/, bool& blue, bool& alpha) + { + red = blue; + blue = false; + alpha = false; + } + + static inline void get_g8b8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/) + { + red = blue; + } + + static inline u32 get_abgr8_clearmask(u32 mask) + { + u32 result = 0; + if (mask & RSX_GCM_CLEAR_RED_BIT) result |= RSX_GCM_CLEAR_BLUE_BIT; + if (mask & RSX_GCM_CLEAR_GREEN_BIT) result |= RSX_GCM_CLEAR_GREEN_BIT; + if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT; + if (mask & RSX_GCM_CLEAR_ALPHA_BIT) result |= RSX_GCM_CLEAR_ALPHA_BIT; + return result; + } + + static inline void get_abgr8_colormask(bool& red, bool& /*green*/, bool& blue, bool& /*alpha*/) + { + std::swap(red, blue); + } + + static inline void get_abgr8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/) + { + std::swap(red, blue); + } + + template + requires std::is_integral_v&& std::is_integral_v + u8 renormalize_color8(T input, U base) + { + // Base will be some POT-1 value + const int value = static_cast(input & base); + return static_cast((value * 255) / base); + } + + static inline void get_rgb565_clear_color(u8& red, u8& green, u8& blue, u8& /*alpha*/) + { + // RSX clear color is just a memcpy, so in this case the input is ARGB8 so only BG have the 16-bit input + const u16 raw_value = static_cast(green) << 8 | blue; + blue = renormalize_color8(raw_value, 0x1f); + green = renormalize_color8(raw_value >> 5, 0x3f); + red = renormalize_color8(raw_value >> 11, 0x1f); + } + + static inline void get_a1rgb555_clear_color(u8& red, u8& green, u8& blue, u8& alpha, u8 alpha_override) + { + // RSX clear color is just a memcpy, so in this case the input is ARGB8 so only BG have the 16-bit input + const u16 raw_value = static_cast(green) << 8 | blue; + blue = renormalize_color8(raw_value, 0x1f); + green = renormalize_color8(raw_value >> 5, 0x1f); + red = renormalize_color8(raw_value >> 10, 0x1f); + + // Alpha can technically be encoded into the clear but the format normally just injects constants. + // Will require hardware tests when possible to determine which approach makes more sense. + // alpha = static_cast((raw_value & (1 << 15)) ? 255 : 0); + alpha = alpha_override; + } + + static inline u32 get_b8_clearmask(u32 mask) + { + u32 result = 0; + if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT; + return result; + } + + static inline void get_b8_colormask(bool& red, bool& green, bool& blue, bool& alpha) + { + red = blue; + green = false; + blue = false; + alpha = false; + } + + static inline void get_b8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/) + { + std::swap(red, blue); + } + + static inline color4f decode_border_color(u32 colorref) + { + color4f result; + result.b = (colorref & 0xFF) / 255.f; + result.g = ((colorref >> 8) & 0xFF) / 255.f; + result.r = ((colorref >> 16) & 0xFF) / 255.f; + result.a = ((colorref >> 24) & 0xFF) / 255.f; + return result; + } + + static inline const std::array get_write_output_mask(rsx::surface_color_format format) + { + constexpr std::array rgba = { true, true, true, true }; + constexpr std::array rgb = { true, true, true, false }; + constexpr std::array rg = { true, true, false, false }; + constexpr std::array r = { true, false, false, false }; + + switch (format) + { + case rsx::surface_color_format::a8r8g8b8: + case rsx::surface_color_format::a8b8g8r8: + case rsx::surface_color_format::w16z16y16x16: + case rsx::surface_color_format::w32z32y32x32: + return rgba; + case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: + case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: + case rsx::surface_color_format::r5g6b5: + case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: + case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: + case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: + case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: + return rgb; + case rsx::surface_color_format::g8b8: + return rg; + case rsx::surface_color_format::b8: + case rsx::surface_color_format::x32: + return r; + default: + fmt::throw_exception("Unknown surface format 0x%x", static_cast(format)); + } + } +} diff --git a/rpcs3/Emu/RSX/rsx_utils.h b/rpcs3/Emu/RSX/rsx_utils.h index d97c5ff62c..513d3c1bb8 100644 --- a/rpcs3/Emu/RSX/rsx_utils.h +++ b/rpcs3/Emu/RSX/rsx_utils.h @@ -216,36 +216,6 @@ namespace rsx bool swizzled; }; - 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 } - }; - - static inline std::pair, std::array> decode_remap_encoding(u32 remap_ctl) - { - // Remapping tables; format is A-R-G-B - // Remap input table. Contains channel index to read color from - const std::array remap_inputs = - { - static_cast(remap_ctl & 0x3), - static_cast((remap_ctl >> 2) & 0x3), - static_cast((remap_ctl >> 4) & 0x3), - static_cast((remap_ctl >> 6) & 0x3), - }; - - // Remap control table. Controls whether the remap value is used, or force either 0 or 1 - const std::array remap_lookup = - { - static_cast((remap_ctl >> 8) & 0x3), - static_cast((remap_ctl >> 10) & 0x3), - static_cast((remap_ctl >> 12) & 0x3), - static_cast((remap_ctl >> 14) & 0x3), - }; - - return std::make_pair(remap_inputs, remap_lookup); - } - template void pad_texture(void* input_pixels, void* output_pixels, u16 input_width, u16 input_height, u16 output_width, u16 /*output_height*/) { @@ -774,142 +744,6 @@ namespace rsx return (index + index_base) & 0x000FFFFF; } - // Convert color write mask for G8B8 to R8G8 - static inline u32 get_g8b8_r8g8_clearmask(u32 mask) - { - u32 result = 0; - if (mask & RSX_GCM_CLEAR_GREEN_BIT) result |= RSX_GCM_CLEAR_GREEN_BIT; - if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT; - - return result; - } - - static inline void get_g8b8_r8g8_colormask(bool &red, bool &/*green*/, bool &blue, bool &alpha) - { - red = blue; - blue = false; - alpha = false; - } - - static inline void get_g8b8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/) - { - red = blue; - } - - static inline u32 get_abgr8_clearmask(u32 mask) - { - u32 result = 0; - if (mask & RSX_GCM_CLEAR_RED_BIT) result |= RSX_GCM_CLEAR_BLUE_BIT; - if (mask & RSX_GCM_CLEAR_GREEN_BIT) result |= RSX_GCM_CLEAR_GREEN_BIT; - if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT; - if (mask & RSX_GCM_CLEAR_ALPHA_BIT) result |= RSX_GCM_CLEAR_ALPHA_BIT; - return result; - } - - static inline void get_abgr8_colormask(bool& red, bool& /*green*/, bool& blue, bool& /*alpha*/) - { - std::swap(red, blue); - } - - static inline void get_abgr8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/) - { - std::swap(red, blue); - } - - template - requires std::is_integral_v && std::is_integral_v - u8 renormalize_color8(T input, U base) - { - // Base will be some POT-1 value - const int value = static_cast(input & base); - return static_cast((value * 255) / base); - } - - static inline void get_rgb565_clear_color(u8& red, u8& green, u8& blue, u8& /*alpha*/) - { - // RSX clear color is just a memcpy, so in this case the input is ARGB8 so only BG have the 16-bit input - const u16 raw_value = static_cast(green) << 8 | blue; - blue = renormalize_color8(raw_value, 0x1f); - green = renormalize_color8(raw_value >> 5, 0x3f); - red = renormalize_color8(raw_value >> 11, 0x1f); - } - - static inline void get_a1rgb555_clear_color(u8& red, u8& green, u8& blue, u8& alpha, u8 alpha_override) - { - // RSX clear color is just a memcpy, so in this case the input is ARGB8 so only BG have the 16-bit input - const u16 raw_value = static_cast(green) << 8 | blue; - blue = renormalize_color8(raw_value, 0x1f); - green = renormalize_color8(raw_value >> 5, 0x1f); - red = renormalize_color8(raw_value >> 10, 0x1f); - - // Alpha can technically be encoded into the clear but the format normally just injects constants. - // Will require hardware tests when possible to determine which approach makes more sense. - // alpha = static_cast((raw_value & (1 << 15)) ? 255 : 0); - alpha = alpha_override; - } - - static inline u32 get_b8_clearmask(u32 mask) - { - u32 result = 0; - if (mask & RSX_GCM_CLEAR_BLUE_BIT) result |= RSX_GCM_CLEAR_RED_BIT; - return result; - } - - static inline void get_b8_colormask(bool& red, bool& green, bool& blue, bool& alpha) - { - red = blue; - green = false; - blue = false; - alpha = false; - } - - static inline void get_b8_clear_color(u8& red, u8& /*green*/, u8& blue, u8& /*alpha*/) - { - std::swap(red, blue); - } - - static inline color4f decode_border_color(u32 colorref) - { - color4f result; - result.b = (colorref & 0xFF) / 255.f; - result.g = ((colorref >> 8) & 0xFF) / 255.f; - result.r = ((colorref >> 16) & 0xFF) / 255.f; - result.a = ((colorref >> 24) & 0xFF) / 255.f; - return result; - } - - static inline const std::array get_write_output_mask(rsx::surface_color_format format) - { - constexpr std::array rgba = { true, true, true, true }; - constexpr std::array rgb = { true, true, true, false }; - constexpr std::array rg = { true, true, false, false }; - constexpr std::array r = { true, false, false, false }; - - switch (format) - { - case rsx::surface_color_format::a8r8g8b8: - case rsx::surface_color_format::a8b8g8r8: - case rsx::surface_color_format::w16z16y16x16: - case rsx::surface_color_format::w32z32y32x32: - return rgba; - case rsx::surface_color_format::x1r5g5b5_z1r5g5b5: - case rsx::surface_color_format::x1r5g5b5_o1r5g5b5: - case rsx::surface_color_format::r5g6b5: - case rsx::surface_color_format::x8r8g8b8_z8r8g8b8: - case rsx::surface_color_format::x8r8g8b8_o8r8g8b8: - case rsx::surface_color_format::x8b8g8r8_z8b8g8r8: - case rsx::surface_color_format::x8b8g8r8_o8b8g8r8: - return rgb; - case rsx::surface_color_format::g8b8: - return rg; - case rsx::surface_color_format::b8: - case rsx::surface_color_format::x32: - return r; - default: - fmt::throw_exception("Unknown surface format 0x%x", static_cast(format)); - } - } - template static inline To decode_fxp(u32 bits) { diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index d5d8d5e562..191008cfbc 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -597,6 +597,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 1152d2ebb5..2476bcf852 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -2608,6 +2608,9 @@ Emu\GPU\RSX\Utils + + Emu\GPU\RSX\Utils +