From 32490005114397b843b1dffdbe498e7053fc52f3 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sat, 30 Mar 2019 14:33:14 +0300 Subject: [PATCH] rsx: Improvements to texture scanning - Removes CPU-only transforms that broke GPU-side code. -- Channels in GPU compute are laid out in cell-order, but CPU was uploading in favorable order and compensating with swizzles. -- This leads to 2 different layouts depending on the location of the data (CPU vs GPU) - Implement R8G8_R8B8 interleaved format decode - General improvements --- rpcs3/Emu/RSX/Common/TextureUtils.cpp | 94 +++++++++++++++++++-------- rpcs3/Emu/RSX/Common/texture_cache.h | 4 ++ rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp | 4 +- rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp | 8 +-- rpcs3/Emu/RSX/GL/GLHelpers.h | 1 + rpcs3/Emu/RSX/GL/GLTexture.cpp | 33 +++++----- rpcs3/Emu/RSX/VK/VKFormats.cpp | 22 +++---- rpcs3/Emu/RSX/VK/VKTexture.cpp | 2 +- rpcs3/Emu/RSX/VK/VKTextureCache.h | 6 +- rpcs3/Emu/RSX/gcm_enums.h | 4 +- 10 files changed, 108 insertions(+), 70 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index b1b2ab1da5..1ef35d6989 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -4,7 +4,6 @@ #include "../RSXThread.h" #include "../rsx_utils.h" - namespace { // FIXME: GSL as_span break build if template parameter is non const with current revision. @@ -36,7 +35,6 @@ struct copy_unmodified_block template static void copy_mipmap_level(gsl::span dst, gsl::span src, u16 width_in_block, u16 row_count, u16 depth, u32 dst_pitch_in_block, u32 src_pitch_in_block) { - size_t row_element_count = dst_pitch_in_block; static_assert(sizeof(T) == sizeof(U), "Type size doesn't match."); for (int row = 0; row < row_count * depth; ++row) copy(dst.subspan(row * dst_pitch_in_block, width_in_block), src.subspan(row * src_pitch_in_block, width_in_block)); @@ -132,6 +130,42 @@ struct copy_unmodified_block_vtc } }; +struct copy_decoded_rb_rg_block +{ + template + static void copy_mipmap_level(gsl::span dst, gsl::span src, u16 width_in_block, u16 row_count, u16 depth, u32 dst_pitch_in_block, u32 src_pitch_in_block) + { + static_assert(sizeof(T) == 4, "Type size doesn't match."); + static_assert(sizeof(U) == 2, "Type size doesn't match."); + + u32 src_offset = 0; + u32 dst_offset = 0; + for (int row = 0; row < row_count * depth; ++row) + { + for (int col = 0; col < width_in_block; col += 2) + { + // Process 2 pixels at a time and write in BGRA format + const u16 src0 = src[src_offset + col]; // R,B + const u16 src1 = src[src_offset + col + 1]; // R,G + const u32 blue = (src0 & 0xFF00) >> 8; + const u32 green = (src1 & 0xFF00); + const u32 data0 = blue | green | (src0 & 0xFF) << 16 | 0xFF << 24; + const u32 data1 = blue | green | (src1 & 0xFF) << 16 | 0xFF << 24; + + dst[dst_offset + col] = data0; + if (!(width_in_block & 0x1)) + { + // If size is even, fill in the second pixel + dst[dst_offset + col + 1] = data1; + } + } + + src_offset += src_pitch_in_block; + dst_offset += dst_pitch_in_block; + } + } +}; + namespace { /** @@ -232,8 +266,8 @@ std::vector get_subresources_layout_impl(const RsxTextur { case CELL_GCM_TEXTURE_B8: return get_subresources_layout_impl<1, u8>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled); - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: case CELL_GCM_TEXTURE_COMPRESSED_HILO8: case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: case CELL_GCM_TEXTURE_DEPTH16: @@ -289,6 +323,8 @@ void upload_texture_subresource(gsl::span dst_buffer, const rsx_subre if (w > pitch) return; + // NOTE: Avoid block optimization for formats that can be modified internally by the GPU itself + // Since the gpu code does not attempt to do wide translations (e.g WZYX32->XYZW32), only perform, per-channel transform and use proper swizzles to get the proper output switch (format) { case CELL_GCM_TEXTURE_B8: @@ -300,10 +336,15 @@ void upload_texture_subresource(gsl::span dst_buffer, const rsx_subre break; } - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: { - copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_block); + copy_decoded_rb_rg_block::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_block); + break; + } + + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + { + copy_decoded_rb_rg_block::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_block); break; } @@ -319,7 +360,6 @@ void upload_texture_subresource(gsl::span dst_buffer, const rsx_subre case CELL_GCM_TEXTURE_R5G6B5: case CELL_GCM_TEXTURE_R6G5B5: case CELL_GCM_TEXTURE_G8B8: - case CELL_GCM_TEXTURE_X16: { if (is_swizzled) copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of)); @@ -348,32 +388,36 @@ void upload_texture_subresource(gsl::span dst_buffer, const rsx_subre break; } + // NOTE: Textures with WZYX notations refer to arbitrary data and not color swizzles as in common GPU lang + // WZYX actually maps directly as a RGBA16 format in Cell memory! R=W, not R=X + + case CELL_GCM_TEXTURE_X16: case CELL_GCM_TEXTURE_Y16_X16: case CELL_GCM_TEXTURE_Y16_X16_FLOAT: - case CELL_GCM_TEXTURE_X32_FLOAT: - { - if (is_swizzled) - copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of)); - else - copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_block); - break; - } - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: { + const auto block_size_in_words = get_format_block_size_in_bytes(format) / 2; + const auto words_per_row = (w * block_size_in_words); + const auto src_pitch_in_words = (src_layout.pitch_in_block * block_size_in_words); + if (is_swizzled) - copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of)); + copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), words_per_row, h, depth, get_row_pitch_in_block(words_per_row, dst_row_pitch_multiple_of)); else - copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_block); + copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), words_per_row, h, depth, get_row_pitch_in_block(words_per_row, dst_row_pitch_multiple_of), src_pitch_in_words); break; } + case CELL_GCM_TEXTURE_X32_FLOAT: case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: { + const auto block_size_in_words = get_format_block_size_in_bytes(format) / 4; + const auto words_per_row = (w * block_size_in_words); + const auto src_pitch_in_words = (src_layout.pitch_in_block * block_size_in_words); + if (is_swizzled) - copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of)); + copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), words_per_row, h, depth, get_row_pitch_in_block(words_per_row, dst_row_pitch_multiple_of)); else - copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_block); + copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), as_const_span>(src_layout.data), words_per_row, h, depth, get_row_pitch_in_block(words_per_row, dst_row_pitch_multiple_of), src_pitch_in_words); break; } @@ -435,9 +479,7 @@ u8 get_format_block_size_in_bytes(int format) case CELL_GCM_TEXTURE_DEPTH16: case CELL_GCM_TEXTURE_DEPTH16_FLOAT: case CELL_GCM_TEXTURE_COMPRESSED_HILO8: - case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return 2; + case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return 2; case CELL_GCM_TEXTURE_A8R8G8B8: case CELL_GCM_TEXTURE_D8R8G8B8: case CELL_GCM_TEXTURE_DEPTH24_D8: @@ -484,10 +526,8 @@ u8 get_format_block_size_in_texel(int format) case CELL_GCM_TEXTURE_X32_FLOAT: case CELL_GCM_TEXTURE_COMPRESSED_HILO8: case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return 1; case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return 2; + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return 1; case CELL_GCM_TEXTURE_COMPRESSED_DXT1: case CELL_GCM_TEXTURE_COMPRESSED_DXT23: case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return 4; diff --git a/rpcs3/Emu/RSX/Common/texture_cache.h b/rpcs3/Emu/RSX/Common/texture_cache.h index 4cef5efb73..d145e892de 100644 --- a/rpcs3/Emu/RSX/Common/texture_cache.h +++ b/rpcs3/Emu/RSX/Common/texture_cache.h @@ -998,6 +998,10 @@ namespace rsx case CELL_GCM_TEXTURE_COMPRESSED_DXT1: case CELL_GCM_TEXTURE_COMPRESSED_DXT23: case CELL_GCM_TEXTURE_COMPRESSED_DXT45: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + case CELL_GCM_TEXTURE_COMPRESSED_HILO8: + case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return true; } } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index 81568faed8..1dd1d54c3a 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -1,4 +1,4 @@ -#ifdef _MSC_VER +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" #include "D3D12Formats.h" @@ -166,8 +166,6 @@ DXGI_FORMAT get_texture_format(u8 format) case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM; case CELL_GCM_TEXTURE_COMPRESSED_HILO8: return DXGI_FORMAT_G8R8_G8B8_UNORM; case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return DXGI_FORMAT_R8G8_SNORM; - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return DXGI_FORMAT_G8R8_G8B8_UNORM; - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM; } fmt::throw_exception("Invalid texture format (0x%x)" HERE, (u32)format); } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 4248f60ccd..5d04207b41 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -1,4 +1,4 @@ -#ifdef _MSC_VER +#ifdef _MSC_VER #include "stdafx.h" #include "stdafx_d3d12.h" #include "D3D12GSRender.h" @@ -304,8 +304,6 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz case CELL_GCM_TEXTURE_A1R5G5B5: case CELL_GCM_TEXTURE_A4R4G4B4: case CELL_GCM_TEXTURE_R5G6B5: - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; break; @@ -391,8 +389,8 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1); break; - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: shared_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2, diff --git a/rpcs3/Emu/RSX/GL/GLHelpers.h b/rpcs3/Emu/RSX/GL/GLHelpers.h index 6c99b8c9ee..16f119c824 100644 --- a/rpcs3/Emu/RSX/GL/GLHelpers.h +++ b/rpcs3/Emu/RSX/GL/GLHelpers.h @@ -1581,6 +1581,7 @@ namespace gl m_aspect_flags = image_aspect::depth; break; } + case GL_DEPTH_COMPONENT32: // Unimplemented decode case GL_DEPTH24_STENCIL8: case GL_DEPTH32F_STENCIL8: { diff --git a/rpcs3/Emu/RSX/GL/GLTexture.cpp b/rpcs3/Emu/RSX/GL/GLTexture.cpp index 2dc011c80b..a342d03f81 100644 --- a/rpcs3/Emu/RSX/GL/GLTexture.cpp +++ b/rpcs3/Emu/RSX/GL/GLTexture.cpp @@ -33,7 +33,7 @@ namespace gl case CELL_GCM_TEXTURE_G8B8: return GL_RG8; case CELL_GCM_TEXTURE_R6G5B5: return GL_RGB565; case CELL_GCM_TEXTURE_DEPTH24_D8: return GL_DEPTH24_STENCIL8; - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return GL_DEPTH_COMPONENT24; + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return GL_DEPTH_COMPONENT32; case CELL_GCM_TEXTURE_DEPTH16: return GL_DEPTH_COMPONENT16; case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return GL_DEPTH_COMPONENT16; case CELL_GCM_TEXTURE_X16: return GL_R16; @@ -50,8 +50,8 @@ namespace gl case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; case CELL_GCM_TEXTURE_COMPRESSED_HILO8: return GL_RG8; case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return GL_RG8; - case ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return GL_RG8; - case ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return GL_RG8; + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return GL_RGBA8; + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return GL_RGBA8; } fmt::throw_exception("Unknown texture format 0x%x" HERE, texture_format); } @@ -85,8 +85,8 @@ namespace gl case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return std::make_tuple(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_UNSIGNED_BYTE); case CELL_GCM_TEXTURE_COMPRESSED_HILO8: return std::make_tuple(GL_RG, GL_UNSIGNED_BYTE); case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return std::make_tuple(GL_RG, GL_BYTE); - case ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return std::make_tuple(GL_RG, GL_UNSIGNED_BYTE); - case ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return std::make_tuple(GL_RG, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_BYTE); + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return std::make_tuple(GL_BGRA, GL_UNSIGNED_BYTE); } fmt::throw_exception("Compressed or unknown texture format 0x%x" HERE, texture_format); } @@ -329,8 +329,8 @@ namespace gl case CELL_GCM_TEXTURE_Y16_X16_FLOAT: case CELL_GCM_TEXTURE_COMPRESSED_HILO8: case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: - case ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return false; case CELL_GCM_TEXTURE_COMPRESSED_DXT1: case CELL_GCM_TEXTURE_COMPRESSED_DXT23: @@ -353,8 +353,8 @@ namespace gl case CELL_GCM_TEXTURE_COMPRESSED_DXT1: case CELL_GCM_TEXTURE_COMPRESSED_DXT23: case CELL_GCM_TEXTURE_COMPRESSED_DXT45: - case ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_UN | CELL_GCM_TEXTURE_LN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return{ GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE }; case CELL_GCM_TEXTURE_DEPTH24_D8: @@ -380,14 +380,14 @@ namespace gl return{ GL_GREEN, GL_RED, GL_GREEN, GL_RED }; case CELL_GCM_TEXTURE_Y16_X16: - return{ GL_RED, GL_GREEN, GL_RED, GL_GREEN }; + return{ GL_GREEN, GL_RED, GL_GREEN, GL_RED }; case CELL_GCM_TEXTURE_Y16_X16_FLOAT: - return{ GL_GREEN, GL_RED, GL_GREEN, GL_RED }; + return{ GL_RED, GL_GREEN, GL_RED, GL_GREEN }; case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: - return{ GL_RED, GL_ALPHA, GL_BLUE, GL_GREEN }; + return{ GL_ALPHA, GL_RED, GL_GREEN, GL_BLUE }; case CELL_GCM_TEXTURE_D1R5G5B5: case CELL_GCM_TEXTURE_D8R8G8B8: @@ -576,9 +576,6 @@ namespace gl void upload_texture(GLuint id, u32 gcm_format, u16 width, u16 height, u16 depth, u16 mipmaps, bool is_swizzled, rsx::texture_dimension_extended type, const std::vector& subresources_layout) { - size_t texture_data_sz = get_placed_texture_storage_size(width, height, depth, gcm_format, mipmaps, type == rsx::texture_dimension_extended::texture_dimension_cubemap, 256, 512); - std::vector data_upload_buf(texture_data_sz); - GLenum target; switch (type) { @@ -602,8 +599,12 @@ namespace gl glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); glTexParameteri(target, GL_TEXTURE_BASE_LEVEL, 0); glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, mipmaps - 1); + // The rest of sampler state is now handled by sampler state objects + + // Calculate staging buffer size + size_t texture_data_sz = depth * height * width * get_format_block_size_in_bytes(gcm_format); + std::vector data_upload_buf(texture_data_sz); - //The rest of sampler state is now handled by sampler state objects const auto format_type = get_format_type(gcm_format); const GLenum gl_format = std::get<0>(format_type); const GLenum gl_type = std::get<1>(format_type); diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index d8333ffb8b..b17ca45216 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -1,4 +1,4 @@ -#include "stdafx.h" +#include "stdafx.h" #include "VKFormats.h" namespace vk @@ -155,8 +155,6 @@ namespace vk case CELL_GCM_TEXTURE_COMPRESSED_DXT1: case CELL_GCM_TEXTURE_COMPRESSED_DXT23: case CELL_GCM_TEXTURE_COMPRESSED_DXT45: - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: mapping = { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break; case CELL_GCM_TEXTURE_DEPTH24_D8: @@ -182,14 +180,14 @@ namespace vk mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }; break; case CELL_GCM_TEXTURE_Y16_X16: - mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G }; break; + mapping = { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R }; break; case CELL_GCM_TEXTURE_Y16_X16_FLOAT: - mapping = { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R }; break; + mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G }; break; case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: - mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G }; break; + mapping = { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break; case CELL_GCM_TEXTURE_D8R8G8B8: mapping = { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }; break; @@ -201,9 +199,9 @@ namespace vk case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: mapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G }; break; - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: - mapping = { VK_COMPONENT_SWIZZLE_ZERO, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_R }; break; + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + mapping = { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B }; break; case CELL_GCM_TEXTURE_A8R8G8B8: mapping = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }; break; @@ -242,12 +240,10 @@ namespace vk case CELL_GCM_TEXTURE_X32_FLOAT: return VK_FORMAT_R32_SFLOAT; case CELL_GCM_TEXTURE_D1R5G5B5: return VK_FORMAT_A1R5G5B5_UNORM_PACK16; case CELL_GCM_TEXTURE_D8R8G8B8: return VK_FORMAT_B8G8R8A8_UNORM; - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return VK_FORMAT_A8B8G8R8_UNORM_PACK32; // Expand - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return VK_FORMAT_R8G8B8A8_UNORM; // Expand case CELL_GCM_TEXTURE_COMPRESSED_HILO8: return VK_FORMAT_R8G8_UNORM; case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: return VK_FORMAT_R8G8_SNORM; - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return VK_FORMAT_R8G8_UNORM; // Not right - case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return VK_FORMAT_R8G8_UNORM; // Not right + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return VK_FORMAT_B8G8R8A8_UNORM; + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return VK_FORMAT_B8G8R8A8_UNORM; } fmt::throw_exception("Invalid or unsupported sampler format for texture format (0x%x)" HERE, format); } diff --git a/rpcs3/Emu/RSX/VK/VKTexture.cpp b/rpcs3/Emu/RSX/VK/VKTexture.cpp index 2864e09692..be1599526f 100644 --- a/rpcs3/Emu/RSX/VK/VKTexture.cpp +++ b/rpcs3/Emu/RSX/VK/VKTexture.cpp @@ -557,7 +557,7 @@ namespace vk { u32 mipmap_level = 0; u32 block_in_pixel = get_format_block_size_in_texel(format); - u8 block_size_in_bytes = get_format_block_size_in_bytes(format); + u8 block_size_in_bytes = get_format_block_size_in_bytes(format); for (const rsx_subresource_layout &layout : subresource_layout) { diff --git a/rpcs3/Emu/RSX/VK/VKTextureCache.h b/rpcs3/Emu/RSX/VK/VKTextureCache.h index 335fd28fc6..d12ecacd9d 100644 --- a/rpcs3/Emu/RSX/VK/VKTextureCache.h +++ b/rpcs3/Emu/RSX/VK/VKTextureCache.h @@ -701,9 +701,9 @@ namespace vk VkComponentMapping view_swizzle; if (!source || dst_format != source->info.format) { - //This is a data cast operation - //Use native mapping for the new type - //TODO: Also simulate the readback+reupload step (very tricky) + // This is a data cast operation + // Use native mapping for the new type + // TODO: Also simulate the readback+reupload step (very tricky) const auto remap = get_component_mapping(gcm_format); view_swizzle = { remap[1], remap[2], remap[3], remap[0] }; } diff --git a/rpcs3/Emu/RSX/gcm_enums.h b/rpcs3/Emu/RSX/gcm_enums.h index a101863763..9518528245 100644 --- a/rpcs3/Emu/RSX/gcm_enums.h +++ b/rpcs3/Emu/RSX/gcm_enums.h @@ -450,6 +450,8 @@ enum CELL_GCM_TEXTURE_COMPRESSED_DXT23 = 0x87, CELL_GCM_TEXTURE_COMPRESSED_DXT45 = 0x88, CELL_GCM_TEXTURE_G8B8 = 0x8B, + CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 = 0x8D, + CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 = 0x8E, CELL_GCM_TEXTURE_R6G5B5 = 0x8F, CELL_GCM_TEXTURE_DEPTH24_D8 = 0x90, CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT = 0x91, @@ -466,8 +468,6 @@ enum CELL_GCM_TEXTURE_D1R5G5B5 = 0x9D, CELL_GCM_TEXTURE_D8R8G8B8 = 0x9E, CELL_GCM_TEXTURE_Y16_X16_FLOAT = 0x9F, - CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 = 0xAD, - CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 = 0xAE, // Swizzle Flag CELL_GCM_TEXTURE_SZ = 0x00,