diff options
Diffstat (limited to 'src/video_core/textures/texture.h')
| -rw-r--r-- | src/video_core/textures/texture.h | 239 |
1 files changed, 131 insertions, 108 deletions
diff --git a/src/video_core/textures/texture.h b/src/video_core/textures/texture.h index bbc7e3eaf..c1d14335e 100644 --- a/src/video_core/textures/texture.h +++ b/src/video_core/textures/texture.h | |||
| @@ -53,27 +53,27 @@ enum class TextureFormat : u32 { | |||
| 53 | BC4 = 0x27, | 53 | BC4 = 0x27, |
| 54 | BC5 = 0x28, | 54 | BC5 = 0x28, |
| 55 | S8D24 = 0x29, | 55 | S8D24 = 0x29, |
| 56 | X8Z24 = 0x2a, | 56 | X8D24 = 0x2a, |
| 57 | D24S8 = 0x2b, | 57 | D24S8 = 0x2b, |
| 58 | X4V4Z24__COV4R4V = 0x2c, | 58 | X4V4D24__COV4R4V = 0x2c, |
| 59 | X4V4Z24__COV8R8V = 0x2d, | 59 | X4V4D24__COV8R8V = 0x2d, |
| 60 | V8Z24__COV4R12V = 0x2e, | 60 | V8D24__COV4R12V = 0x2e, |
| 61 | D32 = 0x2f, | 61 | D32 = 0x2f, |
| 62 | D32S8 = 0x30, | 62 | D32S8 = 0x30, |
| 63 | X8Z24_X20V4S8__COV4R4V = 0x31, | 63 | X8D24_X20V4S8__COV4R4V = 0x31, |
| 64 | X8Z24_X20V4S8__COV8R8V = 0x32, | 64 | X8D24_X20V4S8__COV8R8V = 0x32, |
| 65 | ZF32_X20V4X8__COV4R4V = 0x33, | 65 | D32_X20V4X8__COV4R4V = 0x33, |
| 66 | ZF32_X20V4X8__COV8R8V = 0x34, | 66 | D32_X20V4X8__COV8R8V = 0x34, |
| 67 | ZF32_X20V4S8__COV4R4V = 0x35, | 67 | D32_X20V4S8__COV4R4V = 0x35, |
| 68 | ZF32_X20V4S8__COV8R8V = 0x36, | 68 | D32_X20V4S8__COV8R8V = 0x36, |
| 69 | X8Z24_X16V8S8__COV4R12V = 0x37, | 69 | X8D24_X16V8S8__COV4R12V = 0x37, |
| 70 | ZF32_X16V8X8__COV4R12V = 0x38, | 70 | D32_X16V8X8__COV4R12V = 0x38, |
| 71 | ZF32_X16V8S8__COV4R12V = 0x39, | 71 | D32_X16V8S8__COV4R12V = 0x39, |
| 72 | D16 = 0x3a, | 72 | D16 = 0x3a, |
| 73 | V8Z24__COV8R24V = 0x3b, | 73 | V8D24__COV8R24V = 0x3b, |
| 74 | X8Z24_X16V8S8__COV8R24V = 0x3c, | 74 | X8D24_X16V8S8__COV8R24V = 0x3c, |
| 75 | ZF32_X16V8X8__COV8R24V = 0x3d, | 75 | D32_X16V8X8__COV8R24V = 0x3d, |
| 76 | ZF32_X16V8S8__COV8R24V = 0x3e, | 76 | D32_X16V8S8__COV8R24V = 0x3e, |
| 77 | ASTC_2D_4X4 = 0x40, | 77 | ASTC_2D_4X4 = 0x40, |
| 78 | ASTC_2D_5X5 = 0x41, | 78 | ASTC_2D_5X5 = 0x41, |
| 79 | ASTC_2D_6X6 = 0x42, | 79 | ASTC_2D_6X6 = 0x42, |
| @@ -146,7 +146,7 @@ enum class MsaaMode : u32 { | |||
| 146 | }; | 146 | }; |
| 147 | 147 | ||
| 148 | union TextureHandle { | 148 | union TextureHandle { |
| 149 | /* implicit */ TextureHandle(u32 raw_) : raw{raw_} {} | 149 | /* implicit */ constexpr TextureHandle(u32 raw_) : raw{raw_} {} |
| 150 | 150 | ||
| 151 | u32 raw; | 151 | u32 raw; |
| 152 | BitField<0, 20, u32> tic_id; | 152 | BitField<0, 20, u32> tic_id; |
| @@ -155,124 +155,124 @@ union TextureHandle { | |||
| 155 | static_assert(sizeof(TextureHandle) == 4, "TextureHandle has wrong size"); | 155 | static_assert(sizeof(TextureHandle) == 4, "TextureHandle has wrong size"); |
| 156 | 156 | ||
| 157 | struct TICEntry { | 157 | struct TICEntry { |
| 158 | static constexpr u32 DefaultBlockHeight = 16; | ||
| 159 | static constexpr u32 DefaultBlockDepth = 1; | ||
| 160 | |||
| 161 | union { | ||
| 162 | u32 raw; | ||
| 163 | BitField<0, 7, TextureFormat> format; | ||
| 164 | BitField<7, 3, ComponentType> r_type; | ||
| 165 | BitField<10, 3, ComponentType> g_type; | ||
| 166 | BitField<13, 3, ComponentType> b_type; | ||
| 167 | BitField<16, 3, ComponentType> a_type; | ||
| 168 | |||
| 169 | BitField<19, 3, SwizzleSource> x_source; | ||
| 170 | BitField<22, 3, SwizzleSource> y_source; | ||
| 171 | BitField<25, 3, SwizzleSource> z_source; | ||
| 172 | BitField<28, 3, SwizzleSource> w_source; | ||
| 173 | }; | ||
| 174 | u32 address_low; | ||
| 175 | union { | 158 | union { |
| 176 | BitField<0, 16, u32> address_high; | 159 | struct { |
| 177 | BitField<21, 3, TICHeaderVersion> header_version; | 160 | union { |
| 178 | }; | 161 | BitField<0, 7, TextureFormat> format; |
| 179 | union { | 162 | BitField<7, 3, ComponentType> r_type; |
| 180 | BitField<0, 3, u32> block_width; | 163 | BitField<10, 3, ComponentType> g_type; |
| 181 | BitField<3, 3, u32> block_height; | 164 | BitField<13, 3, ComponentType> b_type; |
| 182 | BitField<6, 3, u32> block_depth; | 165 | BitField<16, 3, ComponentType> a_type; |
| 166 | |||
| 167 | BitField<19, 3, SwizzleSource> x_source; | ||
| 168 | BitField<22, 3, SwizzleSource> y_source; | ||
| 169 | BitField<25, 3, SwizzleSource> z_source; | ||
| 170 | BitField<28, 3, SwizzleSource> w_source; | ||
| 171 | }; | ||
| 172 | u32 address_low; | ||
| 173 | union { | ||
| 174 | BitField<0, 16, u32> address_high; | ||
| 175 | BitField<16, 5, u32> layer_base_3_7; | ||
| 176 | BitField<21, 3, TICHeaderVersion> header_version; | ||
| 177 | BitField<24, 1, u32> load_store_hint; | ||
| 178 | BitField<25, 4, u32> view_coherency_hash; | ||
| 179 | BitField<29, 3, u32> layer_base_8_10; | ||
| 180 | }; | ||
| 181 | union { | ||
| 182 | BitField<0, 3, u32> block_width; | ||
| 183 | BitField<3, 3, u32> block_height; | ||
| 184 | BitField<6, 3, u32> block_depth; | ||
| 183 | 185 | ||
| 184 | BitField<10, 3, u32> tile_width_spacing; | 186 | BitField<10, 3, u32> tile_width_spacing; |
| 185 | 187 | ||
| 186 | // High 16 bits of the pitch value | 188 | // High 16 bits of the pitch value |
| 187 | BitField<0, 16, u32> pitch_high; | 189 | BitField<0, 16, u32> pitch_high; |
| 188 | BitField<26, 1, u32> use_header_opt_control; | 190 | BitField<26, 1, u32> use_header_opt_control; |
| 189 | BitField<27, 1, u32> depth_texture; | 191 | BitField<27, 1, u32> depth_texture; |
| 190 | BitField<28, 4, u32> max_mip_level; | 192 | BitField<28, 4, u32> max_mip_level; |
| 191 | 193 | ||
| 192 | BitField<0, 16, u32> buffer_high_width_minus_one; | 194 | BitField<0, 16, u32> buffer_high_width_minus_one; |
| 193 | }; | 195 | }; |
| 194 | union { | 196 | union { |
| 195 | BitField<0, 16, u32> width_minus_1; | 197 | BitField<0, 16, u32> width_minus_one; |
| 196 | BitField<22, 1, u32> srgb_conversion; | 198 | BitField<16, 3, u32> layer_base_0_2; |
| 197 | BitField<23, 4, TextureType> texture_type; | 199 | BitField<22, 1, u32> srgb_conversion; |
| 198 | BitField<29, 3, u32> border_size; | 200 | BitField<23, 4, TextureType> texture_type; |
| 201 | BitField<29, 3, u32> border_size; | ||
| 199 | 202 | ||
| 200 | BitField<0, 16, u32> buffer_low_width_minus_one; | 203 | BitField<0, 16, u32> buffer_low_width_minus_one; |
| 201 | }; | 204 | }; |
| 202 | union { | 205 | union { |
| 203 | BitField<0, 16, u32> height_minus_1; | 206 | BitField<0, 16, u32> height_minus_1; |
| 204 | BitField<16, 14, u32> depth_minus_1; | 207 | BitField<16, 14, u32> depth_minus_1; |
| 205 | }; | 208 | BitField<30, 1, u32> is_sparse; |
| 206 | union { | 209 | BitField<31, 1, u32> normalized_coords; |
| 207 | BitField<6, 13, u32> mip_lod_bias; | 210 | }; |
| 208 | BitField<27, 3, u32> max_anisotropy; | 211 | union { |
| 212 | BitField<6, 13, u32> mip_lod_bias; | ||
| 213 | BitField<27, 3, u32> max_anisotropy; | ||
| 214 | }; | ||
| 215 | union { | ||
| 216 | BitField<0, 4, u32> res_min_mip_level; | ||
| 217 | BitField<4, 4, u32> res_max_mip_level; | ||
| 218 | BitField<8, 4, MsaaMode> msaa_mode; | ||
| 219 | BitField<12, 12, u32> min_lod_clamp; | ||
| 220 | }; | ||
| 221 | }; | ||
| 222 | std::array<u64, 4> raw; | ||
| 209 | }; | 223 | }; |
| 210 | 224 | ||
| 211 | union { | 225 | constexpr bool operator==(const TICEntry& rhs) const noexcept { |
| 212 | BitField<0, 4, u32> res_min_mip_level; | 226 | return raw == rhs.raw; |
| 213 | BitField<4, 4, u32> res_max_mip_level; | 227 | } |
| 214 | BitField<8, 4, MsaaMode> msaa_mode; | ||
| 215 | BitField<12, 12, u32> min_lod_clamp; | ||
| 216 | }; | ||
| 217 | 228 | ||
| 218 | GPUVAddr Address() const { | 229 | constexpr bool operator!=(const TICEntry& rhs) const noexcept { |
| 230 | return raw != rhs.raw; | ||
| 231 | } | ||
| 232 | |||
| 233 | constexpr GPUVAddr Address() const { | ||
| 219 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | address_low); | 234 | return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | address_low); |
| 220 | } | 235 | } |
| 221 | 236 | ||
| 222 | u32 Pitch() const { | 237 | constexpr u32 Pitch() const { |
| 223 | ASSERT(header_version == TICHeaderVersion::Pitch || | 238 | ASSERT(header_version == TICHeaderVersion::Pitch || |
| 224 | header_version == TICHeaderVersion::PitchColorKey); | 239 | header_version == TICHeaderVersion::PitchColorKey); |
| 225 | // The pitch value is 21 bits, and is 32B aligned. | 240 | // The pitch value is 21 bits, and is 32B aligned. |
| 226 | return pitch_high << 5; | 241 | return pitch_high << 5; |
| 227 | } | 242 | } |
| 228 | 243 | ||
| 229 | u32 Width() const { | 244 | constexpr u32 Width() const { |
| 230 | if (header_version != TICHeaderVersion::OneDBuffer) { | 245 | if (header_version != TICHeaderVersion::OneDBuffer) { |
| 231 | return width_minus_1 + 1; | 246 | return width_minus_one + 1; |
| 232 | } | 247 | } |
| 233 | return ((buffer_high_width_minus_one << 16) | buffer_low_width_minus_one) + 1; | 248 | return (buffer_high_width_minus_one << 16 | buffer_low_width_minus_one) + 1; |
| 234 | } | 249 | } |
| 235 | 250 | ||
| 236 | u32 Height() const { | 251 | constexpr u32 Height() const { |
| 237 | return height_minus_1 + 1; | 252 | return height_minus_1 + 1; |
| 238 | } | 253 | } |
| 239 | 254 | ||
| 240 | u32 Depth() const { | 255 | constexpr u32 Depth() const { |
| 241 | return depth_minus_1 + 1; | 256 | return depth_minus_1 + 1; |
| 242 | } | 257 | } |
| 243 | 258 | ||
| 244 | u32 BlockWidth() const { | 259 | constexpr u32 BaseLayer() const { |
| 245 | ASSERT(IsTiled()); | 260 | return layer_base_0_2 | layer_base_3_7 << 3 | layer_base_8_10 << 8; |
| 246 | return block_width; | ||
| 247 | } | ||
| 248 | |||
| 249 | u32 BlockHeight() const { | ||
| 250 | ASSERT(IsTiled()); | ||
| 251 | return block_height; | ||
| 252 | } | ||
| 253 | |||
| 254 | u32 BlockDepth() const { | ||
| 255 | ASSERT(IsTiled()); | ||
| 256 | return block_depth; | ||
| 257 | } | 261 | } |
| 258 | 262 | ||
| 259 | bool IsTiled() const { | 263 | constexpr bool IsBlockLinear() const { |
| 260 | return header_version == TICHeaderVersion::BlockLinear || | 264 | return header_version == TICHeaderVersion::BlockLinear || |
| 261 | header_version == TICHeaderVersion::BlockLinearColorKey; | 265 | header_version == TICHeaderVersion::BlockLinearColorKey; |
| 262 | } | 266 | } |
| 263 | 267 | ||
| 264 | bool IsLineal() const { | 268 | constexpr bool IsPitchLinear() const { |
| 265 | return header_version == TICHeaderVersion::Pitch || | 269 | return header_version == TICHeaderVersion::Pitch || |
| 266 | header_version == TICHeaderVersion::PitchColorKey; | 270 | header_version == TICHeaderVersion::PitchColorKey; |
| 267 | } | 271 | } |
| 268 | 272 | ||
| 269 | bool IsBuffer() const { | 273 | constexpr bool IsBuffer() const { |
| 270 | return header_version == TICHeaderVersion::OneDBuffer; | 274 | return header_version == TICHeaderVersion::OneDBuffer; |
| 271 | } | 275 | } |
| 272 | |||
| 273 | bool IsSrgbConversionEnabled() const { | ||
| 274 | return srgb_conversion != 0; | ||
| 275 | } | ||
| 276 | }; | 276 | }; |
| 277 | static_assert(sizeof(TICEntry) == 0x20, "TICEntry has wrong size"); | 277 | static_assert(sizeof(TICEntry) == 0x20, "TICEntry has wrong size"); |
| 278 | 278 | ||
| @@ -309,6 +309,12 @@ enum class TextureMipmapFilter : u32 { | |||
| 309 | Linear = 3, | 309 | Linear = 3, |
| 310 | }; | 310 | }; |
| 311 | 311 | ||
| 312 | enum class SamplerReduction : u32 { | ||
| 313 | WeightedAverage = 0, | ||
| 314 | Min = 1, | ||
| 315 | Max = 2, | ||
| 316 | }; | ||
| 317 | |||
| 312 | enum class Anisotropy { | 318 | enum class Anisotropy { |
| 313 | Default, | 319 | Default, |
| 314 | Filter2x, | 320 | Filter2x, |
| @@ -333,8 +339,12 @@ struct TSCEntry { | |||
| 333 | BitField<0, 2, TextureFilter> mag_filter; | 339 | BitField<0, 2, TextureFilter> mag_filter; |
| 334 | BitField<4, 2, TextureFilter> min_filter; | 340 | BitField<4, 2, TextureFilter> min_filter; |
| 335 | BitField<6, 2, TextureMipmapFilter> mipmap_filter; | 341 | BitField<6, 2, TextureMipmapFilter> mipmap_filter; |
| 342 | BitField<8, 1, u32> cubemap_anisotropy; | ||
| 336 | BitField<9, 1, u32> cubemap_interface_filtering; | 343 | BitField<9, 1, u32> cubemap_interface_filtering; |
| 344 | BitField<10, 2, SamplerReduction> reduction_filter; | ||
| 337 | BitField<12, 13, u32> mip_lod_bias; | 345 | BitField<12, 13, u32> mip_lod_bias; |
| 346 | BitField<25, 1, u32> float_coord_normalization; | ||
| 347 | BitField<26, 5, u32> trilin_opt; | ||
| 338 | }; | 348 | }; |
| 339 | union { | 349 | union { |
| 340 | BitField<0, 12, u32> min_lod_clamp; | 350 | BitField<0, 12, u32> min_lod_clamp; |
| @@ -347,32 +357,45 @@ struct TSCEntry { | |||
| 347 | }; | 357 | }; |
| 348 | std::array<f32, 4> border_color; | 358 | std::array<f32, 4> border_color; |
| 349 | }; | 359 | }; |
| 350 | std::array<u8, 0x20> raw; | 360 | std::array<u64, 4> raw; |
| 351 | }; | 361 | }; |
| 352 | 362 | ||
| 353 | std::array<float, 4> GetBorderColor() const noexcept; | 363 | constexpr bool operator==(const TSCEntry& rhs) const noexcept { |
| 364 | return raw == rhs.raw; | ||
| 365 | } | ||
| 366 | |||
| 367 | constexpr bool operator!=(const TSCEntry& rhs) const noexcept { | ||
| 368 | return raw != rhs.raw; | ||
| 369 | } | ||
| 370 | |||
| 371 | std::array<float, 4> BorderColor() const noexcept; | ||
| 354 | 372 | ||
| 355 | float GetMaxAnisotropy() const noexcept; | 373 | float MaxAnisotropy() const noexcept; |
| 356 | 374 | ||
| 357 | float GetMinLod() const { | 375 | float MinLod() const { |
| 358 | return static_cast<float>(min_lod_clamp) / 256.0f; | 376 | return static_cast<float>(min_lod_clamp) / 256.0f; |
| 359 | } | 377 | } |
| 360 | 378 | ||
| 361 | float GetMaxLod() const { | 379 | float MaxLod() const { |
| 362 | return static_cast<float>(max_lod_clamp) / 256.0f; | 380 | return static_cast<float>(max_lod_clamp) / 256.0f; |
| 363 | } | 381 | } |
| 364 | 382 | ||
| 365 | float GetLodBias() const { | 383 | float LodBias() const { |
| 366 | // Sign extend the 13-bit value. | 384 | // Sign extend the 13-bit value. |
| 367 | constexpr u32 mask = 1U << (13 - 1); | 385 | static constexpr u32 mask = 1U << (13 - 1); |
| 368 | return static_cast<float>(static_cast<s32>((mip_lod_bias ^ mask) - mask)) / 256.0f; | 386 | return static_cast<float>(static_cast<s32>((mip_lod_bias ^ mask) - mask)) / 256.0f; |
| 369 | } | 387 | } |
| 370 | }; | 388 | }; |
| 371 | static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); | 389 | static_assert(sizeof(TSCEntry) == 0x20, "TSCEntry has wrong size"); |
| 372 | 390 | ||
| 373 | struct FullTextureInfo { | 391 | } // namespace Tegra::Texture |
| 374 | TICEntry tic; | 392 | |
| 375 | TSCEntry tsc; | 393 | template <> |
| 394 | struct std::hash<Tegra::Texture::TICEntry> { | ||
| 395 | size_t operator()(const Tegra::Texture::TICEntry& tic) const noexcept; | ||
| 376 | }; | 396 | }; |
| 377 | 397 | ||
| 378 | } // namespace Tegra::Texture | 398 | template <> |
| 399 | struct std::hash<Tegra::Texture::TSCEntry> { | ||
| 400 | size_t operator()(const Tegra::Texture::TSCEntry& tsc) const noexcept; | ||
| 401 | }; | ||