forked from eden-emu/eden
		
	texture_cache: Use a table instead of switch for texture formats
Use a large flat array to look up texture formats. This allows us to properly implement formats with different component types. It should also be faster.
This commit is contained in:
		
							parent
							
								
									48a1687f51
								
							
						
					
					
						commit
						80eacdf89b
					
				
					 9 changed files with 290 additions and 261 deletions
				
			
		|  | @ -127,6 +127,8 @@ add_library(video_core STATIC | |||
|     shader/track.cpp | ||||
|     surface.cpp | ||||
|     surface.h | ||||
|     texture_cache/format_lookup_table.cpp | ||||
|     texture_cache/format_lookup_table.h | ||||
|     texture_cache/surface_base.cpp | ||||
|     texture_cache/surface_base.h | ||||
|     texture_cache/surface_params.cpp | ||||
|  |  | |||
|  | @ -742,14 +742,6 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const { | |||
|     Texture::TICEntry tic_entry; | ||||
|     memory_manager.ReadBlockUnsafe(tic_address_gpu, &tic_entry, sizeof(Texture::TICEntry)); | ||||
| 
 | ||||
|     [[maybe_unused]] const auto r_type{tic_entry.r_type.Value()}; | ||||
|     [[maybe_unused]] const auto g_type{tic_entry.g_type.Value()}; | ||||
|     [[maybe_unused]] const auto b_type{tic_entry.b_type.Value()}; | ||||
|     [[maybe_unused]] const auto a_type{tic_entry.a_type.Value()}; | ||||
| 
 | ||||
|     // TODO(Subv): Different data types for separate components are not supported
 | ||||
|     DEBUG_ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); | ||||
| 
 | ||||
|     return tic_entry; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -168,242 +168,6 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) | |||
|     } | ||||
| } | ||||
| 
 | ||||
| PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format, | ||||
|                                          Tegra::Texture::ComponentType component_type, | ||||
|                                          bool is_srgb) { | ||||
|     // TODO(Subv): Properly implement this
 | ||||
|     switch (format) { | ||||
|     case Tegra::Texture::TextureFormat::A8R8G8B8: | ||||
|         if (is_srgb) { | ||||
|             return PixelFormat::RGBA8_SRGB; | ||||
|         } | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::ABGR8U; | ||||
|         case Tegra::Texture::ComponentType::SNORM: | ||||
|             return PixelFormat::ABGR8S; | ||||
|         case Tegra::Texture::ComponentType::UINT: | ||||
|             return PixelFormat::ABGR8UI; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::B5G6R5: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::B5G6R5U; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::A2B10G10R10: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::A2B10G10R10U; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::A1B5G5R5: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::A1B5G5R5U; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::A4B4G4R4: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::R4G4B4A4U; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::R8: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::R8U; | ||||
|         case Tegra::Texture::ComponentType::UINT: | ||||
|             return PixelFormat::R8UI; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::G8R8: | ||||
|         // TextureFormat::G8R8 is actually ordered red then green, as such we can use
 | ||||
|         // PixelFormat::RG8U and PixelFormat::RG8S. This was tested with The Legend of Zelda: Breath
 | ||||
|         // of the Wild, which uses this format to render the hearts on the UI.
 | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::RG8U; | ||||
|         case Tegra::Texture::ComponentType::SNORM: | ||||
|             return PixelFormat::RG8S; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::R16_G16_B16_A16: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::RGBA16U; | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::RGBA16F; | ||||
|         case Tegra::Texture::ComponentType::UINT: | ||||
|             return PixelFormat::RGBA16UI; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::BF10GF11RF11: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::R11FG11FB10F; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::R32_G32_B32_A32: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::RGBA32F; | ||||
|         case Tegra::Texture::ComponentType::UINT: | ||||
|             return PixelFormat::RGBA32UI; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::R32_G32: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::RG32F; | ||||
|         case Tegra::Texture::ComponentType::UINT: | ||||
|             return PixelFormat::RG32UI; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::R32_G32_B32: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::RGB32F; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::R16: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::R16F; | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::R16U; | ||||
|         case Tegra::Texture::ComponentType::SNORM: | ||||
|             return PixelFormat::R16S; | ||||
|         case Tegra::Texture::ComponentType::UINT: | ||||
|             return PixelFormat::R16UI; | ||||
|         case Tegra::Texture::ComponentType::SINT: | ||||
|             return PixelFormat::R16I; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::R32: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::R32F; | ||||
|         case Tegra::Texture::ComponentType::UINT: | ||||
|             return PixelFormat::R32UI; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::E5B9G9R9_SHAREDEXP: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::E5B9G9R9F; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::ZF32: | ||||
|         return PixelFormat::Z32F; | ||||
|     case Tegra::Texture::TextureFormat::Z16: | ||||
|         return PixelFormat::Z16; | ||||
|     case Tegra::Texture::TextureFormat::S8Z24: | ||||
|         return PixelFormat::S8Z24; | ||||
|     case Tegra::Texture::TextureFormat::ZF32_X24S8: | ||||
|         return PixelFormat::Z32FS8; | ||||
|     case Tegra::Texture::TextureFormat::DXT1: | ||||
|         return is_srgb ? PixelFormat::DXT1_SRGB : PixelFormat::DXT1; | ||||
|     case Tegra::Texture::TextureFormat::DXT23: | ||||
|         return is_srgb ? PixelFormat::DXT23_SRGB : PixelFormat::DXT23; | ||||
|     case Tegra::Texture::TextureFormat::DXT45: | ||||
|         return is_srgb ? PixelFormat::DXT45_SRGB : PixelFormat::DXT45; | ||||
|     case Tegra::Texture::TextureFormat::DXN1: | ||||
|         return PixelFormat::DXN1; | ||||
|     case Tegra::Texture::TextureFormat::DXN2: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::DXN2UNORM; | ||||
|         case Tegra::Texture::ComponentType::SNORM: | ||||
|             return PixelFormat::DXN2SNORM; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     case Tegra::Texture::TextureFormat::BC7U: | ||||
|         return is_srgb ? PixelFormat::BC7U_SRGB : PixelFormat::BC7U; | ||||
|     case Tegra::Texture::TextureFormat::BC6H_UF16: | ||||
|         return PixelFormat::BC6H_UF16; | ||||
|     case Tegra::Texture::TextureFormat::BC6H_SF16: | ||||
|         return PixelFormat::BC6H_SF16; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_4X4: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_5X4: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_5X5: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_5X5_SRGB : PixelFormat::ASTC_2D_5X5; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_8X8: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_8X5: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_8X5_SRGB : PixelFormat::ASTC_2D_8X5; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_10X8: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_10X8_SRGB : PixelFormat::ASTC_2D_10X8; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_6X6: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_6X6_SRGB : PixelFormat::ASTC_2D_6X6; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_10X10: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_10X10_SRGB : PixelFormat::ASTC_2D_10X10; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_12X12: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_12X12_SRGB : PixelFormat::ASTC_2D_12X12; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_8X6: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_8X6_SRGB : PixelFormat::ASTC_2D_8X6; | ||||
|     case Tegra::Texture::TextureFormat::ASTC_2D_6X5: | ||||
|         return is_srgb ? PixelFormat::ASTC_2D_6X5_SRGB : PixelFormat::ASTC_2D_6X5; | ||||
|     case Tegra::Texture::TextureFormat::R16_G16: | ||||
|         switch (component_type) { | ||||
|         case Tegra::Texture::ComponentType::FLOAT: | ||||
|             return PixelFormat::RG16F; | ||||
|         case Tegra::Texture::ComponentType::UNORM: | ||||
|             return PixelFormat::RG16; | ||||
|         case Tegra::Texture::ComponentType::SNORM: | ||||
|             return PixelFormat::RG16S; | ||||
|         case Tegra::Texture::ComponentType::UINT: | ||||
|             return PixelFormat::RG16UI; | ||||
|         case Tegra::Texture::ComponentType::SINT: | ||||
|             return PixelFormat::RG16I; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|         break; | ||||
|     default: | ||||
|         break; | ||||
|     } | ||||
|     LOG_CRITICAL(HW_GPU, "Unimplemented format={}, component_type={}", static_cast<u32>(format), | ||||
|                  static_cast<u32>(component_type)); | ||||
|     UNREACHABLE(); | ||||
|     return PixelFormat::ABGR8U; | ||||
| } | ||||
| 
 | ||||
| PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) { | ||||
|     switch (format) { | ||||
|     case Tegra::FramebufferConfig::PixelFormat::ABGR8: | ||||
|  |  | |||
|  | @ -106,7 +106,6 @@ enum class PixelFormat { | |||
|     Max = MaxDepthStencilFormat, | ||||
|     Invalid = 255, | ||||
| }; | ||||
| 
 | ||||
| static constexpr std::size_t MaxPixelFormat = static_cast<std::size_t>(PixelFormat::Max); | ||||
| 
 | ||||
| enum class SurfaceType { | ||||
|  | @ -600,10 +599,6 @@ PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format); | |||
| 
 | ||||
| PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format); | ||||
| 
 | ||||
| PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format, | ||||
|                                          Tegra::Texture::ComponentType component_type, | ||||
|                                          bool is_srgb); | ||||
| 
 | ||||
| PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format); | ||||
| 
 | ||||
| SurfaceType GetFormatType(PixelFormat pixel_format); | ||||
|  |  | |||
							
								
								
									
										214
									
								
								src/video_core/texture_cache/format_lookup_table.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										214
									
								
								src/video_core/texture_cache/format_lookup_table.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,214 @@ | |||
| // Copyright 2019 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <array> | ||||
| #include "common/common_types.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "video_core/texture_cache/format_lookup_table.h" | ||||
| 
 | ||||
| namespace VideoCommon { | ||||
| 
 | ||||
| using Tegra::Texture::ComponentType; | ||||
| using Tegra::Texture::TextureFormat; | ||||
| using VideoCore::Surface::PixelFormat; | ||||
| 
 | ||||
| namespace { | ||||
| 
 | ||||
| static constexpr auto SNORM = ComponentType::SNORM; | ||||
| static constexpr auto UNORM = ComponentType::UNORM; | ||||
| static constexpr auto SINT = ComponentType::SINT; | ||||
| static constexpr auto UINT = ComponentType::UINT; | ||||
| static constexpr auto SNORM_FORCE_FP16 = ComponentType::SNORM_FORCE_FP16; | ||||
| static constexpr auto UNORM_FORCE_FP16 = ComponentType::UNORM_FORCE_FP16; | ||||
| static constexpr auto FLOAT = ComponentType::FLOAT; | ||||
| static constexpr bool C = false; // Normal color
 | ||||
| static constexpr bool S = true;  // Srgb
 | ||||
| 
 | ||||
| struct Table { | ||||
|     constexpr Table(TextureFormat texture_format, bool is_srgb, ComponentType red_component, | ||||
|                     ComponentType green_component, ComponentType blue_component, | ||||
|                     ComponentType alpha_component, PixelFormat pixel_format) | ||||
|         : texture_format{static_cast<u32>(texture_format)}, | ||||
|           pixel_format{static_cast<u32>(pixel_format)}, red_component{static_cast<u32>( | ||||
|                                                             red_component)}, | ||||
|           green_component{static_cast<u32>(green_component)}, blue_component{static_cast<u32>( | ||||
|                                                                   blue_component)}, | ||||
|           alpha_component{static_cast<u32>(alpha_component)}, is_srgb{is_srgb ? 1U : 0U} {} | ||||
| 
 | ||||
|     u32 texture_format : 8; | ||||
|     u32 pixel_format : 8; | ||||
|     u32 red_component : 3; | ||||
|     u32 green_component : 3; | ||||
|     u32 blue_component : 3; | ||||
|     u32 alpha_component : 3; | ||||
|     u32 is_srgb : 1; | ||||
| }; | ||||
| constexpr std::array<Table, 74> DefinitionTable = {{ | ||||
|     {TextureFormat::A8R8G8B8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ABGR8U}, | ||||
|     {TextureFormat::A8R8G8B8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::ABGR8S}, | ||||
|     {TextureFormat::A8R8G8B8, C, UINT, UINT, UINT, UINT, PixelFormat::ABGR8UI}, | ||||
|     {TextureFormat::A8R8G8B8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::RGBA8_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::B5G6R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::B5G6R5U}, | ||||
| 
 | ||||
|     {TextureFormat::A2B10G10R10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A2B10G10R10U}, | ||||
| 
 | ||||
|     {TextureFormat::A1B5G5R5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::A1B5G5R5U}, | ||||
| 
 | ||||
|     {TextureFormat::A4B4G4R4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R4G4B4A4U}, | ||||
| 
 | ||||
|     {TextureFormat::R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R8U}, | ||||
|     {TextureFormat::R8, C, UINT, UINT, UINT, UINT, PixelFormat::R8UI}, | ||||
| 
 | ||||
|     {TextureFormat::G8R8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RG8U}, | ||||
|     {TextureFormat::G8R8, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RG8S}, | ||||
| 
 | ||||
|     {TextureFormat::R16_G16_B16_A16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RGBA16U}, | ||||
|     {TextureFormat::R16_G16_B16_A16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGBA16F}, | ||||
|     {TextureFormat::R16_G16_B16_A16, C, UINT, UINT, UINT, UINT, PixelFormat::RGBA16UI}, | ||||
| 
 | ||||
|     {TextureFormat::R16_G16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RG16F}, | ||||
|     {TextureFormat::R16_G16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::RG16}, | ||||
|     {TextureFormat::R16_G16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::RG16S}, | ||||
|     {TextureFormat::R16_G16, C, UINT, UINT, UINT, UINT, PixelFormat::RG16UI}, | ||||
|     {TextureFormat::R16_G16, C, SINT, SINT, SINT, SINT, PixelFormat::RG16I}, | ||||
| 
 | ||||
|     {TextureFormat::R16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R16F}, | ||||
|     {TextureFormat::R16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::R16U}, | ||||
|     {TextureFormat::R16, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::R16S}, | ||||
|     {TextureFormat::R16, C, UINT, UINT, UINT, UINT, PixelFormat::R16UI}, | ||||
|     {TextureFormat::R16, C, SINT, SINT, SINT, SINT, PixelFormat::R16I}, | ||||
| 
 | ||||
|     {TextureFormat::BF10GF11RF11, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R11FG11FB10F}, | ||||
| 
 | ||||
|     {TextureFormat::R32_G32_B32_A32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGBA32F}, | ||||
|     {TextureFormat::R32_G32_B32_A32, C, UINT, UINT, UINT, UINT, PixelFormat::RGBA32UI}, | ||||
| 
 | ||||
|     {TextureFormat::R32_G32_B32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RGB32F}, | ||||
| 
 | ||||
|     {TextureFormat::R32_G32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::RG32F}, | ||||
|     {TextureFormat::R32_G32, C, UINT, UINT, UINT, UINT, PixelFormat::RG32UI}, | ||||
| 
 | ||||
|     {TextureFormat::R32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::R32F}, | ||||
|     {TextureFormat::R32, C, UINT, UINT, UINT, UINT, PixelFormat::R32UI}, | ||||
| 
 | ||||
|     {TextureFormat::E5B9G9R9_SHAREDEXP, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::E5B9G9R9F}, | ||||
| 
 | ||||
|     {TextureFormat::ZF32, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::Z32F}, | ||||
|     {TextureFormat::Z16, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::Z16}, | ||||
|     {TextureFormat::S8Z24, C, UINT, UNORM, UNORM, UNORM, PixelFormat::S8Z24}, | ||||
|     {TextureFormat::ZF32_X24S8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::Z32FS8}, | ||||
| 
 | ||||
|     {TextureFormat::DXT1, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT1}, | ||||
|     {TextureFormat::DXT1, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT1_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::DXT23, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT23}, | ||||
|     {TextureFormat::DXT23, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT23_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::DXT45, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT45}, | ||||
|     {TextureFormat::DXT45, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXT45_SRGB}, | ||||
| 
 | ||||
|     // TODO: Use a different pixel format for SNORM
 | ||||
|     {TextureFormat::DXN1, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXN1}, | ||||
|     {TextureFormat::DXN1, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::DXN1}, | ||||
| 
 | ||||
|     {TextureFormat::DXN2, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::DXN2UNORM}, | ||||
|     {TextureFormat::DXN2, C, SNORM, SNORM, SNORM, SNORM, PixelFormat::DXN2SNORM}, | ||||
| 
 | ||||
|     {TextureFormat::BC7U, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7U}, | ||||
|     {TextureFormat::BC7U, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::BC7U_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::BC6H_SF16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_SF16}, | ||||
|     {TextureFormat::BC6H_UF16, C, FLOAT, FLOAT, FLOAT, FLOAT, PixelFormat::BC6H_UF16}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_4X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4}, | ||||
|     {TextureFormat::ASTC_2D_4X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_4X4_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_5X4, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4}, | ||||
|     {TextureFormat::ASTC_2D_5X4, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X4_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_5X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5}, | ||||
|     {TextureFormat::ASTC_2D_5X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_5X5_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_8X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8}, | ||||
|     {TextureFormat::ASTC_2D_8X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X8_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_8X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5}, | ||||
|     {TextureFormat::ASTC_2D_8X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X5_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_10X8, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8}, | ||||
|     {TextureFormat::ASTC_2D_10X8, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X8_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_6X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6}, | ||||
|     {TextureFormat::ASTC_2D_6X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X6_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_10X10, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10}, | ||||
|     {TextureFormat::ASTC_2D_10X10, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_10X10_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_12X12, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12}, | ||||
|     {TextureFormat::ASTC_2D_12X12, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_12X12_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_8X6, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6}, | ||||
|     {TextureFormat::ASTC_2D_8X6, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_8X6_SRGB}, | ||||
| 
 | ||||
|     {TextureFormat::ASTC_2D_6X5, C, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5}, | ||||
|     {TextureFormat::ASTC_2D_6X5, S, UNORM, UNORM, UNORM, UNORM, PixelFormat::ASTC_2D_6X5_SRGB}, | ||||
| }}; | ||||
| 
 | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| FormatLookupTable::FormatLookupTable() { | ||||
|     table.fill(static_cast<u8>(PixelFormat::Invalid)); | ||||
| 
 | ||||
|     for (const auto entry : DefinitionTable) { | ||||
|         table[CalculateIndex(static_cast<TextureFormat>(entry.texture_format), entry.is_srgb != 0, | ||||
|                              static_cast<ComponentType>(entry.red_component), | ||||
|                              static_cast<ComponentType>(entry.green_component), | ||||
|                              static_cast<ComponentType>(entry.blue_component), | ||||
|                              static_cast<ComponentType>(entry.alpha_component))] = | ||||
|             static_cast<u8>(entry.pixel_format); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| PixelFormat FormatLookupTable::GetPixelFormat(TextureFormat format, bool is_srgb, | ||||
|                                               ComponentType red_component, | ||||
|                                               ComponentType green_component, | ||||
|                                               ComponentType blue_component, | ||||
|                                               ComponentType alpha_component) const noexcept { | ||||
|     const auto pixel_format = static_cast<PixelFormat>(table[CalculateIndex( | ||||
|         format, is_srgb, red_component, green_component, blue_component, alpha_component)]); | ||||
|     // [[likely]]
 | ||||
|     if (pixel_format != PixelFormat::Invalid) { | ||||
|         return pixel_format; | ||||
|     } | ||||
|     UNIMPLEMENTED_MSG("texture format={} srgb={} components={{{} {} {} {}}}", | ||||
|                       static_cast<int>(format), is_srgb, static_cast<int>(red_component), | ||||
|                       static_cast<int>(green_component), static_cast<int>(blue_component), | ||||
|                       static_cast<int>(alpha_component)); | ||||
|     return PixelFormat::ABGR8U; | ||||
| } | ||||
| 
 | ||||
| void FormatLookupTable::Set(TextureFormat format, bool is_srgb, ComponentType red_component, | ||||
|                             ComponentType green_component, ComponentType blue_component, | ||||
|                             ComponentType alpha_component, PixelFormat pixel_format) {} | ||||
| 
 | ||||
| std::size_t FormatLookupTable::CalculateIndex(TextureFormat format, bool is_srgb, | ||||
|                                               ComponentType red_component, | ||||
|                                               ComponentType green_component, | ||||
|                                               ComponentType blue_component, | ||||
|                                               ComponentType alpha_component) noexcept { | ||||
|     const auto format_index = static_cast<std::size_t>(format); | ||||
|     const auto red_index = static_cast<std::size_t>(red_component); | ||||
|     const auto green_index = static_cast<std::size_t>(red_component); | ||||
|     const auto blue_index = static_cast<std::size_t>(red_component); | ||||
|     const auto alpha_index = static_cast<std::size_t>(red_component); | ||||
|     const std::size_t srgb_index = is_srgb ? 1 : 0; | ||||
| 
 | ||||
|     return format_index * PerFormat + | ||||
|            srgb_index * PerComponent * PerComponent * PerComponent * PerComponent + | ||||
|            alpha_index * PerComponent * PerComponent * PerComponent + | ||||
|            blue_index * PerComponent * PerComponent + green_index * PerComponent + red_index; | ||||
| } | ||||
| 
 | ||||
| } // namespace VideoCommon
 | ||||
							
								
								
									
										51
									
								
								src/video_core/texture_cache/format_lookup_table.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								src/video_core/texture_cache/format_lookup_table.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,51 @@ | |||
| // Copyright 2019 yuzu Emulator Project
 | ||||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <array> | ||||
| #include <numeric> | ||||
| #include "video_core/surface.h" | ||||
| #include "video_core/textures/texture.h" | ||||
| 
 | ||||
| namespace VideoCommon { | ||||
| 
 | ||||
| class FormatLookupTable { | ||||
| public: | ||||
|     explicit FormatLookupTable(); | ||||
| 
 | ||||
|     VideoCore::Surface::PixelFormat GetPixelFormat( | ||||
|         Tegra::Texture::TextureFormat format, bool is_srgb, | ||||
|         Tegra::Texture::ComponentType red_component, Tegra::Texture::ComponentType green_component, | ||||
|         Tegra::Texture::ComponentType blue_component, | ||||
|         Tegra::Texture::ComponentType alpha_component) const noexcept; | ||||
| 
 | ||||
| private: | ||||
|     static_assert(VideoCore::Surface::MaxPixelFormat <= std::numeric_limits<u8>::max()); | ||||
| 
 | ||||
|     static constexpr std::size_t NumTextureFormats = 128; | ||||
| 
 | ||||
|     static constexpr std::size_t PerComponent = 8; | ||||
|     static constexpr std::size_t PerComponents2 = PerComponent * PerComponent; | ||||
|     static constexpr std::size_t PerComponents3 = PerComponents2 * PerComponent; | ||||
|     static constexpr std::size_t PerComponents4 = PerComponents3 * PerComponent; | ||||
|     static constexpr std::size_t PerFormat = PerComponents4 * 2; | ||||
| 
 | ||||
|     static std::size_t CalculateIndex(Tegra::Texture::TextureFormat format, bool is_srgb, | ||||
|                                       Tegra::Texture::ComponentType red_component, | ||||
|                                       Tegra::Texture::ComponentType green_component, | ||||
|                                       Tegra::Texture::ComponentType blue_component, | ||||
|                                       Tegra::Texture::ComponentType alpha_component) noexcept; | ||||
| 
 | ||||
|     void Set(Tegra::Texture::TextureFormat format, bool is_srgb, | ||||
|              Tegra::Texture::ComponentType red_component, | ||||
|              Tegra::Texture::ComponentType green_component, | ||||
|              Tegra::Texture::ComponentType blue_component, | ||||
|              Tegra::Texture::ComponentType alpha_component, | ||||
|              VideoCore::Surface::PixelFormat pixel_format); | ||||
| 
 | ||||
|     std::array<u8, NumTextureFormats * PerFormat> table; | ||||
| }; | ||||
| 
 | ||||
| } // namespace VideoCommon
 | ||||
|  | @ -2,13 +2,16 @@ | |||
| // Licensed under GPLv2 or any later version
 | ||||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <map> | ||||
| #include <algorithm> | ||||
| #include <string> | ||||
| #include <tuple> | ||||
| 
 | ||||
| #include "common/alignment.h" | ||||
| #include "common/bit_util.h" | ||||
| #include "core/core.h" | ||||
| #include "video_core/engines/shader_bytecode.h" | ||||
| #include "video_core/surface.h" | ||||
| #include "video_core/texture_cache/format_lookup_table.h" | ||||
| #include "video_core/texture_cache/surface_params.h" | ||||
| 
 | ||||
| namespace VideoCommon { | ||||
|  | @ -16,7 +19,6 @@ namespace VideoCommon { | |||
| using VideoCore::Surface::PixelFormat; | ||||
| using VideoCore::Surface::PixelFormatFromDepthFormat; | ||||
| using VideoCore::Surface::PixelFormatFromRenderTargetFormat; | ||||
| using VideoCore::Surface::PixelFormatFromTextureFormat; | ||||
| using VideoCore::Surface::SurfaceTarget; | ||||
| using VideoCore::Surface::SurfaceTargetFromTextureType; | ||||
| using VideoCore::Surface::SurfaceType; | ||||
|  | @ -66,7 +68,8 @@ constexpr u32 GetMipmapSize(bool uncompressed, u32 mip_size, u32 tile) { | |||
| 
 | ||||
| } // Anonymous namespace
 | ||||
| 
 | ||||
| SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& tic, | ||||
| SurfaceParams SurfaceParams::CreateForTexture(const FormatLookupTable& lookup_table, | ||||
|                                               const Tegra::Texture::TICEntry& tic, | ||||
|                                               const VideoCommon::Shader::Sampler& entry) { | ||||
|     SurfaceParams params; | ||||
|     params.is_tiled = tic.IsTiled(); | ||||
|  | @ -75,8 +78,8 @@ SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& ti | |||
|     params.block_height = params.is_tiled ? tic.BlockHeight() : 0, | ||||
|     params.block_depth = params.is_tiled ? tic.BlockDepth() : 0, | ||||
|     params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1; | ||||
|     params.pixel_format = | ||||
|         PixelFormatFromTextureFormat(tic.format, tic.r_type.Value(), params.srgb_conversion); | ||||
|     params.pixel_format = lookup_table.GetPixelFormat( | ||||
|         tic.format, params.srgb_conversion, tic.r_type, tic.g_type, tic.b_type, tic.a_type); | ||||
|     params.type = GetFormatType(params.pixel_format); | ||||
|     if (entry.IsShadow() && params.type == SurfaceType::ColorTexture) { | ||||
|         switch (params.pixel_format) { | ||||
|  | @ -124,7 +127,8 @@ SurfaceParams SurfaceParams::CreateForTexture(const Tegra::Texture::TICEntry& ti | |||
|     return params; | ||||
| } | ||||
| 
 | ||||
| SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, | ||||
| SurfaceParams SurfaceParams::CreateForImage(const FormatLookupTable& lookup_table, | ||||
|                                             const Tegra::Texture::TICEntry& tic, | ||||
|                                             const VideoCommon::Shader::Image& entry) { | ||||
|     SurfaceParams params; | ||||
|     params.is_tiled = tic.IsTiled(); | ||||
|  | @ -133,8 +137,8 @@ SurfaceParams SurfaceParams::CreateForImage(const Tegra::Texture::TICEntry& tic, | |||
|     params.block_height = params.is_tiled ? tic.BlockHeight() : 0, | ||||
|     params.block_depth = params.is_tiled ? tic.BlockDepth() : 0, | ||||
|     params.tile_width_spacing = params.is_tiled ? (1 << tic.tile_width_spacing.Value()) : 1; | ||||
|     params.pixel_format = | ||||
|         PixelFormatFromTextureFormat(tic.format, tic.r_type.Value(), params.srgb_conversion); | ||||
|     params.pixel_format = lookup_table.GetPixelFormat( | ||||
|         tic.format, params.srgb_conversion, tic.r_type, tic.g_type, tic.b_type, tic.a_type); | ||||
|     params.type = GetFormatType(params.pixel_format); | ||||
|     params.type = GetFormatType(params.pixel_format); | ||||
|     params.target = ImageTypeToSurfaceTarget(entry.GetType()); | ||||
|  |  | |||
|  | @ -16,16 +16,20 @@ | |||
| 
 | ||||
| namespace VideoCommon { | ||||
| 
 | ||||
| class FormatLookupTable; | ||||
| 
 | ||||
| using VideoCore::Surface::SurfaceCompression; | ||||
| 
 | ||||
| class SurfaceParams { | ||||
| public: | ||||
|     /// Creates SurfaceCachedParams from a texture configuration.
 | ||||
|     static SurfaceParams CreateForTexture(const Tegra::Texture::TICEntry& tic, | ||||
|     static SurfaceParams CreateForTexture(const FormatLookupTable& lookup_table, | ||||
|                                           const Tegra::Texture::TICEntry& tic, | ||||
|                                           const VideoCommon::Shader::Sampler& entry); | ||||
| 
 | ||||
|     /// Creates SurfaceCachedParams from an image configuration.
 | ||||
|     static SurfaceParams CreateForImage(const Tegra::Texture::TICEntry& tic, | ||||
|     static SurfaceParams CreateForImage(const FormatLookupTable& lookup_table, | ||||
|                                         const Tegra::Texture::TICEntry& tic, | ||||
|                                         const VideoCommon::Shader::Image& entry); | ||||
| 
 | ||||
|     /// Creates SurfaceCachedParams for a depth buffer configuration.
 | ||||
|  |  | |||
|  | @ -29,6 +29,7 @@ | |||
| #include "video_core/rasterizer_interface.h" | ||||
| #include "video_core/surface.h" | ||||
| #include "video_core/texture_cache/copy_params.h" | ||||
| #include "video_core/texture_cache/format_lookup_table.h" | ||||
| #include "video_core/texture_cache/surface_base.h" | ||||
| #include "video_core/texture_cache/surface_params.h" | ||||
| #include "video_core/texture_cache/surface_view.h" | ||||
|  | @ -96,7 +97,7 @@ public: | |||
|         if (!gpu_addr) { | ||||
|             return {}; | ||||
|         } | ||||
|         const auto params{SurfaceParams::CreateForTexture(tic, entry)}; | ||||
|         const auto params{SurfaceParams::CreateForTexture(format_lookup_table, tic, entry)}; | ||||
|         const auto [surface, view] = GetSurface(gpu_addr, params, true, false); | ||||
|         if (guard_samplers) { | ||||
|             sampled_textures.push_back(surface); | ||||
|  | @ -111,7 +112,7 @@ public: | |||
|         if (!gpu_addr) { | ||||
|             return {}; | ||||
|         } | ||||
|         const auto params{SurfaceParams::CreateForImage(tic, entry)}; | ||||
|         const auto params{SurfaceParams::CreateForImage(format_lookup_table, tic, entry)}; | ||||
|         const auto [surface, view] = GetSurface(gpu_addr, params, true, false); | ||||
|         if (guard_samplers) { | ||||
|             sampled_textures.push_back(surface); | ||||
|  | @ -953,6 +954,8 @@ private: | |||
| 
 | ||||
|     VideoCore::RasterizerInterface& rasterizer; | ||||
| 
 | ||||
|     FormatLookupTable format_lookup_table; | ||||
| 
 | ||||
|     u64 ticks{}; | ||||
| 
 | ||||
|     // Guards the cache for protection conflicts.
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 ReinUsesLisp
						ReinUsesLisp