diff --git a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp index 6e1ec3c1b2..13cf23d71d 100644 --- a/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp +++ b/rpcs3/Emu/RSX/Common/FragmentProgramDecompiler.cpp @@ -616,6 +616,8 @@ std::string FragmentProgramDecompiler::Decompile() case RSX_FP_OPCODE_KIL: SetDst("discard", false); break; default: + int prev_force_unit = forced_unit; + if (forced_unit == FORCE_NONE) { if (SIP()) break; @@ -634,7 +636,7 @@ std::string FragmentProgramDecompiler::Decompile() if (handle_scb(opcode)) break; } - LOG_ERROR(RSX, "Unknown/illegal instruction: 0x%x (forced unit %d)", opcode, forced_unit); + LOG_ERROR(RSX, "Unknown/illegal instruction: 0x%x (forced unit %d)", opcode, prev_force_unit); break; } diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index b6c12ac512..7d0f478f65 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -150,17 +150,30 @@ std::vector get_subresources_layout(const rsx::texture & bool is_swizzled = !(texture.format() & CELL_GCM_TEXTURE_LN); switch (format) { - case CELL_GCM_TEXTURE_D8R8G8B8: - case CELL_GCM_TEXTURE_A8R8G8B8: - return get_subresources_layout_impl<1, u32>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled); + 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_HILO8: + case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: case CELL_GCM_TEXTURE_DEPTH16: + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // Untested case CELL_GCM_TEXTURE_D1R5G5B5: case CELL_GCM_TEXTURE_A1R5G5B5: - case CELL_GCM_TEXTURE_R5G5B5A1: case CELL_GCM_TEXTURE_A4R4G4B4: + case CELL_GCM_TEXTURE_R5G5B5A1: case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_R6G5B5: case CELL_GCM_TEXTURE_G8B8: + case CELL_GCM_TEXTURE_X16: return get_subresources_layout_impl<1, u16>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled); + case CELL_GCM_TEXTURE_DEPTH24_D8: // Untested + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // Untested + case CELL_GCM_TEXTURE_D8R8G8B8: + case CELL_GCM_TEXTURE_A8R8G8B8: + case CELL_GCM_TEXTURE_Y16_X16: + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + return get_subresources_layout_impl<1, u32>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled); case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return get_subresources_layout_impl<1, u64>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled); case CELL_GCM_TEXTURE_COMPRESSED_DXT1: @@ -168,10 +181,8 @@ std::vector get_subresources_layout(const rsx::texture & case CELL_GCM_TEXTURE_COMPRESSED_DXT23: case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return get_subresources_layout_impl<4, u128>(pixels, w, h, depth, layer, texture.get_exact_mipmap_count(), texture.pitch(), !is_swizzled); - 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); } - throw EXCEPTION("Wrong format %d", format); + throw EXCEPTION("Wrong format 0x%x", format); } void upload_texture_subresource(gsl::span dst_buffer, const rsx_subresource_layout &src_layout, int format, bool is_swizzled, size_t dst_row_pitch_multiple_of) @@ -181,43 +192,69 @@ void upload_texture_subresource(gsl::span dst_buffer, const rsx_subre u16 depth = src_layout.depth; switch (format) { - case CELL_GCM_TEXTURE_A8R8G8B8: - case CELL_GCM_TEXTURE_D8R8G8B8: - if (is_swizzled) - copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_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), gsl::as_span(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); - break; - case CELL_GCM_TEXTURE_DEPTH16: - case CELL_GCM_TEXTURE_D1R5G5B5: - case CELL_GCM_TEXTURE_A1R5G5B5: - case CELL_GCM_TEXTURE_R5G5B5A1: - case CELL_GCM_TEXTURE_A4R4G4B4: - case CELL_GCM_TEXTURE_R5G6B5: - case CELL_GCM_TEXTURE_G8B8: - if (is_swizzled) - copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_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), gsl::as_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); - break; - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: - copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); - break; - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: - copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_span(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); - break; - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: - copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_span(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); - break; case CELL_GCM_TEXTURE_B8: + { if (is_swizzled) copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_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), gsl::as_span(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); 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_HILO8: + case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: + case CELL_GCM_TEXTURE_DEPTH16: + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: // Untested + case CELL_GCM_TEXTURE_D1R5G5B5: + case CELL_GCM_TEXTURE_A1R5G5B5: + case CELL_GCM_TEXTURE_A4R4G4B4: + case CELL_GCM_TEXTURE_R5G5B5A1: + 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), gsl::as_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), gsl::as_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); + break; + } + + case CELL_GCM_TEXTURE_DEPTH24_D8: // Untested + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: // Untested + case CELL_GCM_TEXTURE_A8R8G8B8: + case CELL_GCM_TEXTURE_D8R8G8B8: + { + if (is_swizzled) + copy_unmodified_block_swizzled::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_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), gsl::as_span(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); + break; + } + + case CELL_GCM_TEXTURE_Y16_X16: + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); + break; + + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_span>(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); + break; + + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: + copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_span(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); + break; + + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: + copy_unmodified_block::copy_mipmap_level(as_span_workaround(dst_buffer), gsl::as_span(src_layout.data), w, h, depth, get_row_pitch_in_block(w, dst_row_pitch_multiple_of), src_layout.pitch_in_bytes); + break; + default: - throw EXCEPTION("Wrong format %d", format); + throw EXCEPTION("Wrong format 0x%x", format); } } @@ -230,37 +267,37 @@ u8 get_format_block_size_in_bytes(int format) switch (format) { case CELL_GCM_TEXTURE_B8: return 1; + case CELL_GCM_TEXTURE_X16: + case CELL_GCM_TEXTURE_G8B8: + case CELL_GCM_TEXTURE_R6G5B5: + case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_D1R5G5B5: + case CELL_GCM_TEXTURE_R5G5B5A1: case CELL_GCM_TEXTURE_A1R5G5B5: case CELL_GCM_TEXTURE_A4R4G4B4: - case CELL_GCM_TEXTURE_R5G6B5: return 2; - case CELL_GCM_TEXTURE_A8R8G8B8: return 4; - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return 8; - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return 16; - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return 16; - case CELL_GCM_TEXTURE_G8B8: return 2; - case CELL_GCM_TEXTURE_R6G5B5: - case CELL_GCM_TEXTURE_DEPTH24_D8: - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return 4; case CELL_GCM_TEXTURE_DEPTH16: case CELL_GCM_TEXTURE_DEPTH16_FLOAT: - case CELL_GCM_TEXTURE_X16: return 2; - case CELL_GCM_TEXTURE_Y16_X16: return 4; - case CELL_GCM_TEXTURE_R5G5B5A1: return 2; - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return 8; - case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return 16; - case CELL_GCM_TEXTURE_X32_FLOAT: return 4; - case CELL_GCM_TEXTURE_D1R5G5B5: return 2; - case CELL_GCM_TEXTURE_Y16_X16_FLOAT: - case CELL_GCM_TEXTURE_D8R8G8B8: - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return 4; 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: + case ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN) & CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return 2; + case CELL_GCM_TEXTURE_A8R8G8B8: + case CELL_GCM_TEXTURE_D8R8G8B8: + case CELL_GCM_TEXTURE_DEPTH24_D8: + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: + case CELL_GCM_TEXTURE_X32_FLOAT: + case CELL_GCM_TEXTURE_Y16_X16: + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return 4; + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return 8; + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return 16; default: - LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format); - return 0; + LOG_ERROR(RSX, "Unimplemented block size in bytes for texture format: 0x%x", format); + return 1; } } @@ -269,37 +306,37 @@ u8 get_format_block_size_in_texel(int format) switch (format) { case CELL_GCM_TEXTURE_B8: + case CELL_GCM_TEXTURE_G8B8: + case CELL_GCM_TEXTURE_D8R8G8B8: + case CELL_GCM_TEXTURE_D1R5G5B5: case CELL_GCM_TEXTURE_A1R5G5B5: case CELL_GCM_TEXTURE_A4R4G4B4: - case CELL_GCM_TEXTURE_R5G6B5: - case CELL_GCM_TEXTURE_A8R8G8B8: return 1; - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return 4; - case CELL_GCM_TEXTURE_G8B8: + case CELL_GCM_TEXTURE_A8R8G8B8: + case CELL_GCM_TEXTURE_R5G5B5A1: case CELL_GCM_TEXTURE_R6G5B5: + case CELL_GCM_TEXTURE_R5G6B5: case CELL_GCM_TEXTURE_DEPTH24_D8: case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: case CELL_GCM_TEXTURE_DEPTH16: case CELL_GCM_TEXTURE_DEPTH16_FLOAT: case CELL_GCM_TEXTURE_X16: case CELL_GCM_TEXTURE_Y16_X16: - case CELL_GCM_TEXTURE_R5G5B5A1: + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: case CELL_GCM_TEXTURE_X32_FLOAT: - case CELL_GCM_TEXTURE_D1R5G5B5: - case CELL_GCM_TEXTURE_Y16_X16_FLOAT: - case CELL_GCM_TEXTURE_D8R8G8B8: return 1; - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return 2; 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: + 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_DXT1: + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return 4; default: - LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format); - return 0; + LOG_ERROR(RSX, "Unimplemented block size in texels for texture format: 0x%x", format); + return 1; } } @@ -337,62 +374,65 @@ size_t get_texture_size(const rsx::texture &texture) // TODO: Take mipmaps into account switch (format) { - 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: - default: - LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format); - return 0; case CELL_GCM_TEXTURE_B8: return w * h; + case CELL_GCM_TEXTURE_G8B8: + return w * h * 2; + case CELL_GCM_TEXTURE_R5G5B5A1: + return w * h * 4; + case CELL_GCM_TEXTURE_D8R8G8B8: + return w * h * 4; + case CELL_GCM_TEXTURE_A8R8G8B8: + return w * h * 4; + case CELL_GCM_TEXTURE_D1R5G5B5: + return w * h * 2; case CELL_GCM_TEXTURE_A1R5G5B5: return w * h * 2; case CELL_GCM_TEXTURE_A4R4G4B4: return w * h * 2; + case CELL_GCM_TEXTURE_R6G5B5: + return w * h * 2; case CELL_GCM_TEXTURE_R5G6B5: return w * h * 2; - case CELL_GCM_TEXTURE_A8R8G8B8: - return w * h * 4; case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return w * h / 6; case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return w * h / 4; case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return w * h / 4; - case CELL_GCM_TEXTURE_G8B8: + case CELL_GCM_TEXTURE_DEPTH16: return w * h * 2; - case CELL_GCM_TEXTURE_R6G5B5: + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return w * h * 2; case CELL_GCM_TEXTURE_DEPTH24_D8: return w * h * 4; case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return w * h * 4; - case CELL_GCM_TEXTURE_DEPTH16: - return w * h * 2; - case CELL_GCM_TEXTURE_DEPTH16_FLOAT: - return w * h * 2; case CELL_GCM_TEXTURE_X16: return w * h * 2; case CELL_GCM_TEXTURE_Y16_X16: return w * h * 4; - case CELL_GCM_TEXTURE_R5G5B5A1: - return w * h * 2; + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + return w * h * 4; + case CELL_GCM_TEXTURE_X32_FLOAT: + return w * h * 4; case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return w * h * 8; case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return w * h * 16; - case CELL_GCM_TEXTURE_X32_FLOAT: - return w * h * 4; - case CELL_GCM_TEXTURE_D1R5G5B5: - return w * h * 2; - case CELL_GCM_TEXTURE_Y16_X16_FLOAT: - return w * h * 4; - case CELL_GCM_TEXTURE_D8R8G8B8: - return w * h * 4; case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return w * h * 4; case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return w * h * 4; + case CELL_GCM_TEXTURE_COMPRESSED_HILO8: + return w * h; + case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: + return w * h; + 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 w * h * 2; + default: + LOG_ERROR(RSX, "Unimplemented texture size for texture format: 0x%x", format); + return 0; } } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp index ae5ad79ee5..03478f5640 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Formats.cpp @@ -147,26 +147,26 @@ DXGI_FORMAT get_texture_format(u8 format) case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return DXGI_FORMAT_BC2_UNORM; case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return DXGI_FORMAT_BC3_UNORM; case CELL_GCM_TEXTURE_G8B8: return DXGI_FORMAT_G8R8_G8B8_UNORM; - case CELL_GCM_TEXTURE_R6G5B5: /*Not native*/ return DXGI_FORMAT_R8G8B8A8_UNORM; - case CELL_GCM_TEXTURE_DEPTH24_D8: return DXGI_FORMAT_R32_UINT; - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return DXGI_FORMAT_R32_FLOAT; - case CELL_GCM_TEXTURE_DEPTH16: return DXGI_FORMAT_R16_UNORM; - case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return DXGI_FORMAT_R16_FLOAT; + case CELL_GCM_TEXTURE_R6G5B5: return DXGI_FORMAT_B5G6R5_UNORM; + case CELL_GCM_TEXTURE_DEPTH24_D8: return DXGI_FORMAT_R32_UINT; // Untested + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return DXGI_FORMAT_R32_FLOAT; // Untested + case CELL_GCM_TEXTURE_DEPTH16: return DXGI_FORMAT_R16_UINT; // Untested + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return DXGI_FORMAT_R16_FLOAT; // Untested case CELL_GCM_TEXTURE_X16: return DXGI_FORMAT_R16_UNORM; case CELL_GCM_TEXTURE_Y16_X16: return DXGI_FORMAT_R16G16_UNORM; + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return DXGI_FORMAT_R16G16_FLOAT; + case CELL_GCM_TEXTURE_X32_FLOAT: return DXGI_FORMAT_R32_FLOAT; case CELL_GCM_TEXTURE_R5G5B5A1: return DXGI_FORMAT_B5G5R5A1_UNORM; case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return DXGI_FORMAT_R16G16B16A16_FLOAT; case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return DXGI_FORMAT_R32G32B32A32_FLOAT; - case CELL_GCM_TEXTURE_X32_FLOAT: return DXGI_FORMAT_R32_FLOAT; case CELL_GCM_TEXTURE_D1R5G5B5: return DXGI_FORMAT_B5G5R5A1_UNORM; case CELL_GCM_TEXTURE_D8R8G8B8: return DXGI_FORMAT_R8G8B8A8_UNORM; case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return DXGI_FORMAT_G8R8_G8B8_UNORM; case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: return DXGI_FORMAT_R8G8_B8G8_UNORM; - case CELL_GCM_TEXTURE_Y16_X16_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: + 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; break; } throw EXCEPTION("Invalid or unsupported texture format (0x%x)", format); diff --git a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp index 3778d0e72f..160b2ee844 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp +++ b/rpcs3/Emu/RSX/D3D12/D3D12Texture.cpp @@ -251,13 +251,30 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz switch (format) { - 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: default: - LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format); + LOG_ERROR(RSX, "Unimplemented mapping for texture format: 0x%x", format); break; + + case CELL_GCM_TEXTURE_COMPRESSED_HILO8: + case CELL_GCM_TEXTURE_COMPRESSED_DXT1: + case CELL_GCM_TEXTURE_COMPRESSED_DXT23: + case CELL_GCM_TEXTURE_COMPRESSED_DXT45: + case CELL_GCM_TEXTURE_DEPTH24_D8: + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: + case CELL_GCM_TEXTURE_DEPTH16: + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: + case CELL_GCM_TEXTURE_X32_FLOAT: + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: + case CELL_GCM_TEXTURE_R5G5B5A1: + case CELL_GCM_TEXTURE_D1R5G5B5: + 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; + case CELL_GCM_TEXTURE_B8: shared_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0, @@ -265,11 +282,65 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0, D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0); break; - case CELL_GCM_TEXTURE_A1R5G5B5: - case CELL_GCM_TEXTURE_A4R4G4B4: - case CELL_GCM_TEXTURE_R5G6B5: - shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + + case CELL_GCM_TEXTURE_G8B8: + 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, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2); break; + + case CELL_GCM_TEXTURE_R6G5B5: // TODO: Remap it to another format here, so it's not glitched out + shared_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0); + break; + + case CELL_GCM_TEXTURE_X16: + shared_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0); + break; + + case CELL_GCM_TEXTURE_Y16_X16: + case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: + 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_0, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0); + break; + + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + shared_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1); + break; + + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + shared_resource_view_desc.Shader4ComponentMapping = D3D12_ENCODE_SHADER_4_COMPONENT_MAPPING( + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_3, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_2, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_1, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0); + 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: + 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, + D3D12_SHADER_COMPONENT_MAPPING_FROM_MEMORY_COMPONENT_0, + D3D12_SHADER_COMPONENT_MAPPING_FORCE_VALUE_0); + break; + case CELL_GCM_TEXTURE_A8R8G8B8: case CELL_GCM_TEXTURE_D8R8G8B8: { @@ -279,6 +350,7 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz u8 remap_r = (textures[i].remap() >> 2) & 0x3; u8 remap_g = (textures[i].remap() >> 4) & 0x3; u8 remap_b = (textures[i].remap() >> 6) & 0x3; + if (is_render_target) { // ARGB format @@ -327,33 +399,6 @@ void D3D12GSRender::upload_textures(ID3D12GraphicsCommandList *command_list, siz break; } - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: - case CELL_GCM_TEXTURE_G8B8: - case CELL_GCM_TEXTURE_R6G5B5: - case CELL_GCM_TEXTURE_DEPTH24_D8: - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: - case CELL_GCM_TEXTURE_DEPTH16: - case CELL_GCM_TEXTURE_DEPTH16_FLOAT: - case CELL_GCM_TEXTURE_X16: - case CELL_GCM_TEXTURE_Y16_X16: - case CELL_GCM_TEXTURE_R5G5B5A1: - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: - case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: - case CELL_GCM_TEXTURE_X32_FLOAT: - case CELL_GCM_TEXTURE_D1R5G5B5: - shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - break; - case CELL_GCM_TEXTURE_Y16_X16_FLOAT: - shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - break; - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: - shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - break; - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: - shared_resource_view_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - break; } m_device->CreateShaderResourceView(vram_texture, &shared_resource_view_desc, diff --git a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp index e6050b94d0..42c91c725a 100644 --- a/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp +++ b/rpcs3/Emu/RSX/GL/rsx_gl_texture.cpp @@ -248,7 +248,7 @@ namespace rsx case CELL_GCM_TEXTURE_COMPRESSED_HILO8: case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: default: - LOG_ERROR(RSX, "Unimplemented Texture format : 0x%x", format); + LOG_ERROR(RSX, "Unimplemented pitch modifier for texture format: 0x%x", format); return 0; 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: diff --git a/rpcs3/Emu/RSX/VK/VKFormats.cpp b/rpcs3/Emu/RSX/VK/VKFormats.cpp index 295a4efe44..5123f3a901 100644 --- a/rpcs3/Emu/RSX/VK/VKFormats.cpp +++ b/rpcs3/Emu/RSX/VK/VKFormats.cpp @@ -108,40 +108,69 @@ VkComponentMapping get_component_mapping(u32 format, u8 swizzle_mask) switch (format) { - case CELL_GCM_TEXTURE_B8: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }; - case CELL_GCM_TEXTURE_A1R5G5B5: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_A4R4G4B4: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_R5G6B5: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; + case CELL_GCM_TEXTURE_A1R5G5B5: + case CELL_GCM_TEXTURE_R5G5B5A1: + case CELL_GCM_TEXTURE_R6G5B5: + case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_DEPTH24_D8: + case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: + case CELL_GCM_TEXTURE_DEPTH16: + case CELL_GCM_TEXTURE_DEPTH16_FLOAT: + case CELL_GCM_TEXTURE_X32_FLOAT: + case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: + 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: + return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; + + case CELL_GCM_TEXTURE_B8: + return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_R }; + + case CELL_GCM_TEXTURE_G8B8: + return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G }; + + case CELL_GCM_TEXTURE_X16: + return { VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_R }; + + case CELL_GCM_TEXTURE_Y16_X16: + return { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R }; + + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: + return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G }; + + case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: + return { VK_COMPONENT_SWIZZLE_A, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R }; + + case CELL_GCM_TEXTURE_A4R4G4B4: + { + VkComponentSwizzle map_table[] = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; + return { map_table[remap_r], map_table[remap_g], map_table[remap_b], map_table[remap_a] }; + } + + case CELL_GCM_TEXTURE_D1R5G5B5: + return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }; + + case CELL_GCM_TEXTURE_COMPRESSED_HILO8: + return { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R }; + + case CELL_GCM_TEXTURE_COMPRESSED_HILO_S8: + return { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R }; + + + 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 { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ZERO }; + + case CELL_GCM_TEXTURE_D8R8G8B8: case CELL_GCM_TEXTURE_A8R8G8B8: { VkComponentSwizzle map_table[] = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_A }; return { map_table[remap_r], map_table[remap_g], map_table[remap_b], map_table[remap_a] }; } - case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };; - case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_G8B8: return { VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE, VK_COMPONENT_SWIZZLE_ONE }; - case CELL_GCM_TEXTURE_R6G5B5: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_DEPTH24_D8: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_DEPTH16: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_X16: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_Y16_X16: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_R5G5B5A1: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_X32_FLOAT: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_D1R5G5B5: return { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_ONE }; - case CELL_GCM_TEXTURE_D8R8G8B8: - { - VkComponentSwizzle map_table[] = { VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_ONE }; - return{ map_table[remap_r], map_table[remap_g], map_table[remap_b], map_table[remap_a] }; } - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8:return{ VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; - } - throw EXCEPTION("Invalid or unsupported texture format (0x%x)", format); + throw EXCEPTION("Invalid or unsupported component mapping for texture format (0x%x)", format); } } \ No newline at end of file diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 772234150c..0b14fd1518 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -65,30 +65,35 @@ namespace vk { case CELL_GCM_TEXTURE_B8: return VK_FORMAT_R8_UNORM; case CELL_GCM_TEXTURE_A1R5G5B5: return VK_FORMAT_A1R5G5B5_UNORM_PACK16; - case CELL_GCM_TEXTURE_A4R4G4B4: return VK_FORMAT_B4G4R4A4_UNORM_PACK16; + case CELL_GCM_TEXTURE_A4R4G4B4: return VK_FORMAT_R4G4B4A4_UNORM_PACK16; case CELL_GCM_TEXTURE_R5G6B5: return VK_FORMAT_R5G6B5_UNORM_PACK16; case CELL_GCM_TEXTURE_A8R8G8B8: return VK_FORMAT_B8G8R8A8_UNORM; case CELL_GCM_TEXTURE_COMPRESSED_DXT1: return VK_FORMAT_BC1_RGBA_UNORM_BLOCK; case CELL_GCM_TEXTURE_COMPRESSED_DXT23: return VK_FORMAT_BC2_UNORM_BLOCK; case CELL_GCM_TEXTURE_COMPRESSED_DXT45: return VK_FORMAT_BC3_UNORM_BLOCK; case CELL_GCM_TEXTURE_G8B8: return VK_FORMAT_R8G8_UNORM; - case CELL_GCM_TEXTURE_R6G5B5: return VK_FORMAT_R5G6B5_UNORM_PACK16; //Expand, discard high bit? + case CELL_GCM_TEXTURE_R6G5B5: return VK_FORMAT_R5G6B5_UNORM_PACK16; // Expand, discard high bit? case CELL_GCM_TEXTURE_DEPTH24_D8: return VK_FORMAT_R32_UINT; case CELL_GCM_TEXTURE_DEPTH24_D8_FLOAT: return VK_FORMAT_R32_SFLOAT; - case CELL_GCM_TEXTURE_DEPTH16: return VK_FORMAT_R16_UNORM; + case CELL_GCM_TEXTURE_DEPTH16: return VK_FORMAT_R16_UINT; case CELL_GCM_TEXTURE_DEPTH16_FLOAT: return VK_FORMAT_R16_SFLOAT; case CELL_GCM_TEXTURE_X16: return VK_FORMAT_R16_UNORM; case CELL_GCM_TEXTURE_Y16_X16: return VK_FORMAT_R16G16_UNORM; + case CELL_GCM_TEXTURE_Y16_X16_FLOAT: return VK_FORMAT_R16G16_UNORM; case CELL_GCM_TEXTURE_R5G5B5A1: return VK_FORMAT_R5G5B5A1_UNORM_PACK16; case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: return VK_FORMAT_R16G16B16A16_SFLOAT; case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: return VK_FORMAT_R32G32B32A32_SFLOAT; 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_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 } - throw EXCEPTION("Invalid or unsupported texture format (0x%x)", format); + throw EXCEPTION("Invalid or unsupported sampler format for texture format (0x%x)", format); } VkAllocationCallbacks default_callbacks() diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp index f10a030ac2..ad209aecfc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp @@ -721,8 +721,9 @@ s32 UTF8toUTF32() s32 jstrchk(vm::cptr jstr) { - cellL10n.warning("jstrchk(jstr=*0x%x) -> utf8", jstr); + cellL10n.todo("jstrchk(jstr=*0x%x) -> utf8", jstr); + // TODO: Actually detect the type of the string return L10N_STR_UTF8; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.h b/rpcs3/Emu/SysCalls/Modules/cellL10n.h index 04c39af03a..9e3ec71b97 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.h +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.h @@ -25,7 +25,8 @@ enum }; // CodePages -enum { +enum +{ L10N_UTF8 = 0, L10N_UTF16, L10N_UTF32, diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index fb98adc097..44ad101ed3 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -316,7 +316,7 @@ s32 pngDecOpen(PPUThread& ppu, PHandle handle, PPStream png_stream, PSrc source, // Check for if the buffer structure allocation failed if (!buffer) { - throw EXCEPTION("Memory allocation for the buffer PNG reading structure failed."); + throw EXCEPTION("Memory allocation for the PNG buffer structure failed."); } // We might not be reading from a file stream @@ -328,6 +328,12 @@ s32 pngDecOpen(PPUThread& ppu, PHandle handle, PPStream png_stream, PSrc source, // Open the buffer/file and check the header u8 header[8]; + // Need to test it somewhere + if (stream->source.fileOffset != 0) + { + throw EXCEPTION("Non-0 file offset not supported."); + } + // Depending on the source type, get the first 8 bytes if (source->srcSelect == CELL_PNGDEC_FILE) { @@ -564,7 +570,11 @@ s32 pngDecodeData(PPUThread& ppu, PHandle handle, PStream stream, vm::ptr da // Get the amount of output bytes per line const u32 bytes_per_line = data_control_param->outputBytesPerLine; + // Whether to recaculate bytes per row + bool recalculate_bytes_per_row = false; + // Check if the game is expecting the number of bytes per line to be lower, than the actual bytes per line on the image. (Arkedo Pixel for example) + // In such case we strip the bit depth to be lower. if ((bytes_per_line < stream->out_param.outputWidthByte) && stream->out_param.outputBitDepth != 8) { // Check if the packing is really 1 byte per 1 pixel @@ -575,18 +585,7 @@ s32 pngDecodeData(PPUThread& ppu, PHandle handle, PStream stream, vm::ptr da // Scale 16 bit depth down to 8 bit depth. PS3 uses png_set_strip_16, since png_set_scale_16 wasn't available back then. png_set_strip_16(stream->png_ptr); - - // We need to tell libpng to update the info structure, since we modified the info - png_read_update_info(stream->png_ptr, stream->info_ptr); - - // Recalculate the outputWidthByte value, and recalculate the image size - stream->out_param.outputWidthByte = png_get_rowbytes(stream->png_ptr, stream->info_ptr); - - // What do we do if bytes_per_line is still samller? Something probably went wrong, but this should never happen anyway. - if (bytes_per_line < stream->out_param.outputWidthByte) - { - throw EXCEPTION("bytesPerLine is still smaller than outputWidthByte: %d", stream->out_param.outputWidthByte); - } + recalculate_bytes_per_row = true; } // Check if the outputWidthByte is smaller than the intended output length of a line. For example an image might be in RGB, but we need to output 4 components, so we need to perform alpha padding. else if (stream->out_param.outputWidthByte < (stream->out_param.outputWidth * stream->out_param.outputComponents)) @@ -600,18 +599,31 @@ s32 pngDecodeData(PPUThread& ppu, PHandle handle, PStream stream, vm::ptr da // We need to fill alpha (before or after, depending on the output colour format) using the fixed alpha value passed by the game. png_set_add_alpha(stream->png_ptr, stream->fixed_alpha_colour, stream->out_param.outputColorSpace == CELL_PNGDEC_RGBA ? PNG_FILLER_AFTER : PNG_FILLER_BEFORE); - - // We need to tell libpng to update the info structure, since we modified the info - png_read_update_info(stream->png_ptr, stream->info_ptr); - - // Calculate the actual needed output image size - stream->out_param.outputWidthByte = stream->out_param.outputWidth * stream->out_param.outputComponents; + recalculate_bytes_per_row = true; } + // We decode as RGBA, so we need to swap the alpha else if (stream->out_param.outputColorSpace == CELL_PNGDEC_ARGB) { // Swap the alpha channel for the ARGB output format, if the padding isn't needed png_set_swap_alpha(stream->png_ptr); } + // Sometimes games pass in a RBG/RGBA image and want it as grayscale + else if ((stream->out_param.outputColorSpace == CELL_PNGDEC_GRAYSCALE_ALPHA || stream->out_param.outputColorSpace == CELL_PNGDEC_GRAYSCALE) + && (stream->info.colorSpace == CELL_PNGDEC_RGB || stream->info.colorSpace == CELL_PNGDEC_RGBA)) + { + // Tell libpng to convert it to grayscale + png_set_rgb_to_gray(stream->png_ptr, PNG_ERROR_ACTION_NONE, PNG_RGB_TO_GRAY_DEFAULT, PNG_RGB_TO_GRAY_DEFAULT); + recalculate_bytes_per_row = true; + } + + if (recalculate_bytes_per_row) + { + // Update the info structure + png_read_update_info(stream->png_ptr, stream->info_ptr); + + // Recalculate the bytes per row + stream->out_param.outputWidthByte = png_get_rowbytes(stream->png_ptr, stream->info_ptr); + } // Calculate the image size u32 image_size = stream->out_param.outputWidthByte * stream->out_param.outputHeight; @@ -634,23 +646,22 @@ s32 pngDecodeData(PPUThread& ppu, PHandle handle, PStream stream, vm::ptr da // Check if the image needs to be flipped const bool flip = stream->out_param.outputMode == CELL_PNGDEC_BOTTOM_TO_TOP; + // Copy the result to the output buffer switch (stream->out_param.outputColorSpace) { case CELL_PNGDEC_RGB: - { - throw EXCEPTION("RGB colour format."); - break; - } - case CELL_PNGDEC_RGBA: + case CELL_PNGDEC_ARGB: + case CELL_PNGDEC_GRAYSCALE_ALPHA: { - // Check if we need to flip the image or leave empty space at the end of a line + // Check if we need to flip the image or need to leave empty bytes at the end of a line if ((bytes_per_line > stream->out_param.outputWidthByte) || flip) { // Get how many bytes per line we need to output - bytesPerLine is total amount of bytes per line, rest is unused and the game can do as it pleases. const u32 line_size = std::min(bytes_per_line, stream->out_param.outputWidth * 4); - // If the game wants more bytes per line to be output, than the image has, then we simply copy what we have for each line, and continue on the next line, leaving empty space at the end of the line. + // If the game wants more bytes per line to be output, than the image has, then we simply copy what we have for each line, + // and continue on the next line, thus leaving empty bytes at the end of the line. for (u32 i = 0; i < stream->out_param.outputHeight; i++) { const u32 dst = i * bytes_per_line; @@ -666,28 +677,6 @@ s32 pngDecodeData(PPUThread& ppu, PHandle handle, PStream stream, vm::ptr da break; } - case CELL_PNGDEC_ARGB: - { - // Check if we need to flip the image or leave empty space at the end of a line - if ((bytes_per_line > stream->out_param.outputWidthByte) || flip) - { - // Haven't found a game to test this with - throw EXCEPTION("ARGB is big."); - - // Flipping is untested - if (flip) - { - throw EXCEPTION("Flipping is not yet supported."); - } - } - else - { - // We can simply copy the output to the data pointer specified by the game, since we already do alpha channel transformations in libpng, if needed - memcpy(data.get_ptr(), png.data(), image_size); - } - break; - } - default: throw EXCEPTION("Unsupported color space (%d)", stream->out_param.outputColorSpace); } @@ -696,7 +685,7 @@ s32 pngDecodeData(PPUThread& ppu, PHandle handle, PStream stream, vm::ptr da png_get_text(stream->png_ptr, stream->info_ptr, nullptr, &text_chunks); // Set the chunk information and the previously obtained number of text chunks - data_out_info->numText = text_chunks; + data_out_info->numText = (u32)text_chunks; data_out_info->chunkInformation = pngDecGetChunkInformation(stream, true); data_out_info->numUnknownChunk = 0; // TODO: Get this somehow. Does anything even use or need this?