diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.cpp b/rpcs3/Emu/RSX/Common/TextureUtils.cpp index 7fe0431baf..4c92f18aaa 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.cpp +++ b/rpcs3/Emu/RSX/Common/TextureUtils.cpp @@ -847,6 +847,16 @@ namespace rsx } } + bool texture_format_ex::hw_SNORM_possible() const + { + return (texel_remap_control & SEXT_MASK) == (get_host_format_snorm_mask(format()) << SEXT_OFFSET); + } + + bool texture_format_ex::hw_SRGB_possible() const + { + return (texel_remap_control & GAMMA_CTRL_MASK) == GAMMA_RGB_MASK; + } + std::vector get_subresources_layout(const rsx::fragment_texture& texture) { return get_subresources_layout_impl(texture); @@ -1255,6 +1265,32 @@ namespace rsx fmt::throw_exception("Unknown format 0x%x", texture_format); } + /** + * Returns a channel mask in ARGB that can be SNORM-converted + * Some formats have a hardcoded constant in one lane which we cannot SNORM-interpret in hardware. + */ + u32 get_host_format_snorm_mask(u32 format) + { + switch (format) + { + case CELL_GCM_TEXTURE_B8: + case CELL_GCM_TEXTURE_R5G6B5: + case CELL_GCM_TEXTURE_R6G5B5: + case CELL_GCM_TEXTURE_D1R5G5B5: + case CELL_GCM_TEXTURE_D8R8G8B8: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + // Hardcoded alpha formats + return 0b1110; + + case CELL_GCM_TEXTURE_X16: + // This one is a mess. X and Z are hardcoded. Not supported. + // Fall through instead of throw + default: + return 0b1111; + } + } + /** * A texture is stored as an array of blocks, where a block is a pixel for standard texture * but is a structure containing several pixels for compressed format diff --git a/rpcs3/Emu/RSX/Common/TextureUtils.h b/rpcs3/Emu/RSX/Common/TextureUtils.h index 551052f0ad..f8d899a6ca 100644 --- a/rpcs3/Emu/RSX/Common/TextureUtils.h +++ b/rpcs3/Emu/RSX/Common/TextureUtils.h @@ -147,8 +147,8 @@ namespace rsx bool valid() const { return format_bits != 0; } u32 format() const { return format_bits & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN); } - bool hw_SNORM_possible() const { return (texel_remap_control & SEXT_MASK) == SEXT_MASK; } - bool hw_SRGB_possible() const { return (texel_remap_control & GAMMA_CTRL_MASK) == GAMMA_RGB_MASK; } + bool hw_SNORM_possible() const; + bool hw_SRGB_possible() const; //private: u32 format_bits = 0; @@ -296,6 +296,12 @@ namespace rsx */ rsx::flags32_t get_format_features(u32 texture_format); + /** + * Returns a channel mask in ARGB that can be SNORM-converted + * Some formats have a hardcoded constant in one lane which we cannot SNORM-interpret in hardware. + */ + u32 get_host_format_snorm_mask(u32 format); + /** * Returns number of texel rows encoded in one pitch-length line of bytes */