diff options
| author | 2018-08-10 11:06:23 -0400 | |
|---|---|---|
| committer | 2018-08-10 11:06:23 -0400 | |
| commit | 7e6a73963ea8e208a8a3ae8cbd03aae30fe89e98 (patch) | |
| tree | 4bfd261505903e92c470468165db0c63858bbae8 | |
| parent | Merge pull request #995 from bunnei/gl-buff-bounds (diff) | |
| parent | textures: Refactor out for Texture/Depth FormatFromPixelFormat. (diff) | |
| download | yuzu-7e6a73963ea8e208a8a3ae8cbd03aae30fe89e98.tar.gz yuzu-7e6a73963ea8e208a8a3ae8cbd03aae30fe89e98.tar.xz yuzu-7e6a73963ea8e208a8a3ae8cbd03aae30fe89e98.zip | |
Merge pull request #1002 from bunnei/refactor-tex-fmt
textures: Refactor out for Texture/Depth FormatFromPixelFormat.
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | 31 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/gl_rasterizer_cache.h | 86 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.cpp | 85 | ||||
| -rw-r--r-- | src/video_core/textures/decoders.h | 4 | ||||
| -rw-r--r-- | src/yuzu/debugger/graphics/graphics_surface.cpp | 6 |
5 files changed, 31 insertions, 181 deletions
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp index 114d35ce6..885403cd0 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp | |||
| @@ -183,6 +183,21 @@ MathUtil::Rectangle<u32> SurfaceParams::GetRect() const { | |||
| 183 | return {0, actual_height, width, 0}; | 183 | return {0, actual_height, width, 0}; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | /// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN | ||
| 187 | static bool IsFormatBCn(PixelFormat format) { | ||
| 188 | switch (format) { | ||
| 189 | case PixelFormat::DXT1: | ||
| 190 | case PixelFormat::DXT23: | ||
| 191 | case PixelFormat::DXT45: | ||
| 192 | case PixelFormat::DXN1: | ||
| 193 | case PixelFormat::DXN2SNORM: | ||
| 194 | case PixelFormat::DXN2UNORM: | ||
| 195 | case PixelFormat::BC7U: | ||
| 196 | return true; | ||
| 197 | } | ||
| 198 | return false; | ||
| 199 | } | ||
| 200 | |||
| 186 | template <bool morton_to_gl, PixelFormat format> | 201 | template <bool morton_to_gl, PixelFormat format> |
| 187 | void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer, | 202 | void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer, |
| 188 | Tegra::GPUVAddr addr) { | 203 | Tegra::GPUVAddr addr) { |
| @@ -191,16 +206,12 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_bu | |||
| 191 | const auto& gpu = Core::System::GetInstance().GPU(); | 206 | const auto& gpu = Core::System::GetInstance().GPU(); |
| 192 | 207 | ||
| 193 | if (morton_to_gl) { | 208 | if (morton_to_gl) { |
| 194 | std::vector<u8> data; | 209 | // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual |
| 195 | if (SurfaceParams::GetFormatType(format) == SurfaceType::ColorTexture) { | 210 | // pixel values. |
| 196 | data = Tegra::Texture::UnswizzleTexture( | 211 | const u32 tile_size{IsFormatBCn(format) ? 4U : 1U}; |
| 197 | *gpu.memory_manager->GpuToCpuAddress(addr), | 212 | const std::vector<u8> data = |
| 198 | SurfaceParams::TextureFormatFromPixelFormat(format), stride, height, block_height); | 213 | Tegra::Texture::UnswizzleTexture(*gpu.memory_manager->GpuToCpuAddress(addr), tile_size, |
| 199 | } else { | 214 | bytes_per_pixel, stride, height, block_height); |
| 200 | data = Tegra::Texture::UnswizzleDepthTexture( | ||
| 201 | *gpu.memory_manager->GpuToCpuAddress(addr), | ||
| 202 | SurfaceParams::DepthFormatFromPixelFormat(format), stride, height, block_height); | ||
| 203 | } | ||
| 204 | const size_t size_to_copy{std::min(gl_buffer.size(), data.size())}; | 215 | const size_t size_to_copy{std::min(gl_buffer.size(), data.size())}; |
| 205 | gl_buffer.assign(data.begin(), data.begin() + size_to_copy); | 216 | gl_buffer.assign(data.begin(), data.begin() + size_to_copy); |
| 206 | } else { | 217 | } else { |
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h index 26e2ee203..36213c403 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h +++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h | |||
| @@ -348,92 +348,6 @@ struct SurfaceParams { | |||
| 348 | } | 348 | } |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | static Tegra::Texture::TextureFormat TextureFormatFromPixelFormat(PixelFormat format) { | ||
| 352 | // TODO(Subv): Properly implement this | ||
| 353 | switch (format) { | ||
| 354 | case PixelFormat::ABGR8: | ||
| 355 | case PixelFormat::SRGBA8: | ||
| 356 | return Tegra::Texture::TextureFormat::A8R8G8B8; | ||
| 357 | case PixelFormat::B5G6R5: | ||
| 358 | return Tegra::Texture::TextureFormat::B5G6R5; | ||
| 359 | case PixelFormat::A2B10G10R10: | ||
| 360 | return Tegra::Texture::TextureFormat::A2B10G10R10; | ||
| 361 | case PixelFormat::A1B5G5R5: | ||
| 362 | return Tegra::Texture::TextureFormat::A1B5G5R5; | ||
| 363 | case PixelFormat::R8: | ||
| 364 | return Tegra::Texture::TextureFormat::R8; | ||
| 365 | case PixelFormat::G8R8: | ||
| 366 | return Tegra::Texture::TextureFormat::G8R8; | ||
| 367 | case PixelFormat::RGBA16F: | ||
| 368 | return Tegra::Texture::TextureFormat::R16_G16_B16_A16; | ||
| 369 | case PixelFormat::R11FG11FB10F: | ||
| 370 | return Tegra::Texture::TextureFormat::BF10GF11RF11; | ||
| 371 | case PixelFormat::RGBA32UI: | ||
| 372 | return Tegra::Texture::TextureFormat::R32_G32_B32_A32; | ||
| 373 | case PixelFormat::DXT1: | ||
| 374 | return Tegra::Texture::TextureFormat::DXT1; | ||
| 375 | case PixelFormat::DXT23: | ||
| 376 | return Tegra::Texture::TextureFormat::DXT23; | ||
| 377 | case PixelFormat::DXT45: | ||
| 378 | return Tegra::Texture::TextureFormat::DXT45; | ||
| 379 | case PixelFormat::DXN1: | ||
| 380 | return Tegra::Texture::TextureFormat::DXN1; | ||
| 381 | case PixelFormat::DXN2UNORM: | ||
| 382 | case PixelFormat::DXN2SNORM: | ||
| 383 | return Tegra::Texture::TextureFormat::DXN2; | ||
| 384 | case PixelFormat::BC7U: | ||
| 385 | return Tegra::Texture::TextureFormat::BC7U; | ||
| 386 | case PixelFormat::ASTC_2D_4X4: | ||
| 387 | return Tegra::Texture::TextureFormat::ASTC_2D_4X4; | ||
| 388 | case PixelFormat::BGRA8: | ||
| 389 | // TODO(bunnei): This is fine for unswizzling (since we just need the right component | ||
| 390 | // sizes), but could be a bug if we used this function in different ways. | ||
| 391 | return Tegra::Texture::TextureFormat::A8R8G8B8; | ||
| 392 | case PixelFormat::RGBA32F: | ||
| 393 | return Tegra::Texture::TextureFormat::R32_G32_B32_A32; | ||
| 394 | case PixelFormat::RGB32F: | ||
| 395 | return Tegra::Texture::TextureFormat::R32_G32_B32; | ||
| 396 | case PixelFormat::RG32F: | ||
| 397 | return Tegra::Texture::TextureFormat::R32_G32; | ||
| 398 | case PixelFormat::R32F: | ||
| 399 | return Tegra::Texture::TextureFormat::R32; | ||
| 400 | case PixelFormat::R16F: | ||
| 401 | case PixelFormat::R16UNORM: | ||
| 402 | return Tegra::Texture::TextureFormat::R16; | ||
| 403 | case PixelFormat::Z32F: | ||
| 404 | return Tegra::Texture::TextureFormat::ZF32; | ||
| 405 | case PixelFormat::Z24S8: | ||
| 406 | return Tegra::Texture::TextureFormat::Z24S8; | ||
| 407 | case PixelFormat::RG16F: | ||
| 408 | case PixelFormat::RG16: | ||
| 409 | case PixelFormat::RG16UI: | ||
| 410 | case PixelFormat::RG16I: | ||
| 411 | case PixelFormat::RG16S: | ||
| 412 | return Tegra::Texture::TextureFormat::R16_G16; | ||
| 413 | default: | ||
| 414 | LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | ||
| 415 | UNREACHABLE(); | ||
| 416 | } | ||
| 417 | } | ||
| 418 | |||
| 419 | static Tegra::DepthFormat DepthFormatFromPixelFormat(PixelFormat format) { | ||
| 420 | switch (format) { | ||
| 421 | case PixelFormat::S8Z24: | ||
| 422 | return Tegra::DepthFormat::S8_Z24_UNORM; | ||
| 423 | case PixelFormat::Z24S8: | ||
| 424 | return Tegra::DepthFormat::Z24_S8_UNORM; | ||
| 425 | case PixelFormat::Z32F: | ||
| 426 | return Tegra::DepthFormat::Z32_FLOAT; | ||
| 427 | case PixelFormat::Z16: | ||
| 428 | return Tegra::DepthFormat::Z16_UNORM; | ||
| 429 | case PixelFormat::Z32FS8: | ||
| 430 | return Tegra::DepthFormat::Z32_S8_X24_FLOAT; | ||
| 431 | default: | ||
| 432 | LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format)); | ||
| 433 | UNREACHABLE(); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { | 351 | static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) { |
| 438 | // TODO(Subv): Implement more component types | 352 | // TODO(Subv): Implement more component types |
| 439 | switch (type) { | 353 | switch (type) { |
diff --git a/src/video_core/textures/decoders.cpp b/src/video_core/textures/decoders.cpp index 7ea66584c..70746a34e 100644 --- a/src/video_core/textures/decoders.cpp +++ b/src/video_core/textures/decoders.cpp | |||
| @@ -86,88 +86,11 @@ u32 BytesPerPixel(TextureFormat format) { | |||
| 86 | } | 86 | } |
| 87 | } | 87 | } |
| 88 | 88 | ||
| 89 | static u32 DepthBytesPerPixel(DepthFormat format) { | 89 | std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, |
| 90 | switch (format) { | 90 | u32 height, u32 block_height) { |
| 91 | case DepthFormat::Z16_UNORM: | ||
| 92 | return 2; | ||
| 93 | case DepthFormat::S8_Z24_UNORM: | ||
| 94 | case DepthFormat::Z24_S8_UNORM: | ||
| 95 | case DepthFormat::Z32_FLOAT: | ||
| 96 | return 4; | ||
| 97 | case DepthFormat::Z32_S8_X24_FLOAT: | ||
| 98 | return 8; | ||
| 99 | default: | ||
| 100 | UNIMPLEMENTED_MSG("Format not implemented"); | ||
| 101 | break; | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, | ||
| 106 | u32 block_height) { | ||
| 107 | u8* data = Memory::GetPointer(address); | ||
| 108 | u32 bytes_per_pixel = BytesPerPixel(format); | ||
| 109 | |||
| 110 | std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); | ||
| 111 | |||
| 112 | switch (format) { | ||
| 113 | case TextureFormat::DXT1: | ||
| 114 | case TextureFormat::DXT23: | ||
| 115 | case TextureFormat::DXT45: | ||
| 116 | case TextureFormat::DXN1: | ||
| 117 | case TextureFormat::DXN2: | ||
| 118 | case TextureFormat::BC7U: | ||
| 119 | // In the DXT and DXN formats, each 4x4 tile is swizzled instead of just individual pixel | ||
| 120 | // values. | ||
| 121 | CopySwizzledData(width / 4, height / 4, bytes_per_pixel, bytes_per_pixel, data, | ||
| 122 | unswizzled_data.data(), true, block_height); | ||
| 123 | break; | ||
| 124 | case TextureFormat::A8R8G8B8: | ||
| 125 | case TextureFormat::A2B10G10R10: | ||
| 126 | case TextureFormat::A1B5G5R5: | ||
| 127 | case TextureFormat::B5G6R5: | ||
| 128 | case TextureFormat::R8: | ||
| 129 | case TextureFormat::G8R8: | ||
| 130 | case TextureFormat::R16_G16_B16_A16: | ||
| 131 | case TextureFormat::R32_G32_B32_A32: | ||
| 132 | case TextureFormat::R32_G32: | ||
| 133 | case TextureFormat::R32: | ||
| 134 | case TextureFormat::R16: | ||
| 135 | case TextureFormat::R16_G16: | ||
| 136 | case TextureFormat::BF10GF11RF11: | ||
| 137 | case TextureFormat::ASTC_2D_4X4: | ||
| 138 | case TextureFormat::R32_G32_B32: | ||
| 139 | CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, | ||
| 140 | unswizzled_data.data(), true, block_height); | ||
| 141 | break; | ||
| 142 | default: | ||
| 143 | UNIMPLEMENTED_MSG("Format not implemented"); | ||
| 144 | break; | ||
| 145 | } | ||
| 146 | |||
| 147 | return unswizzled_data; | ||
| 148 | } | ||
| 149 | |||
| 150 | std::vector<u8> UnswizzleDepthTexture(VAddr address, DepthFormat format, u32 width, u32 height, | ||
| 151 | u32 block_height) { | ||
| 152 | u8* data = Memory::GetPointer(address); | ||
| 153 | u32 bytes_per_pixel = DepthBytesPerPixel(format); | ||
| 154 | |||
| 155 | std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); | 91 | std::vector<u8> unswizzled_data(width * height * bytes_per_pixel); |
| 156 | 92 | CopySwizzledData(width / tile_size, height / tile_size, bytes_per_pixel, bytes_per_pixel, | |
| 157 | switch (format) { | 93 | Memory::GetPointer(address), unswizzled_data.data(), true, block_height); |
| 158 | case DepthFormat::Z16_UNORM: | ||
| 159 | case DepthFormat::S8_Z24_UNORM: | ||
| 160 | case DepthFormat::Z24_S8_UNORM: | ||
| 161 | case DepthFormat::Z32_FLOAT: | ||
| 162 | case DepthFormat::Z32_S8_X24_FLOAT: | ||
| 163 | CopySwizzledData(width, height, bytes_per_pixel, bytes_per_pixel, data, | ||
| 164 | unswizzled_data.data(), true, block_height); | ||
| 165 | break; | ||
| 166 | default: | ||
| 167 | UNIMPLEMENTED_MSG("Format not implemented"); | ||
| 168 | break; | ||
| 169 | } | ||
| 170 | |||
| 171 | return unswizzled_data; | 94 | return unswizzled_data; |
| 172 | } | 95 | } |
| 173 | 96 | ||
diff --git a/src/video_core/textures/decoders.h b/src/video_core/textures/decoders.h index 73a4924d1..1f7b731be 100644 --- a/src/video_core/textures/decoders.h +++ b/src/video_core/textures/decoders.h | |||
| @@ -13,8 +13,8 @@ namespace Tegra::Texture { | |||
| 13 | /** | 13 | /** |
| 14 | * Unswizzles a swizzled texture without changing its format. | 14 | * Unswizzles a swizzled texture without changing its format. |
| 15 | */ | 15 | */ |
| 16 | std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, | 16 | std::vector<u8> UnswizzleTexture(VAddr address, u32 tile_size, u32 bytes_per_pixel, u32 width, |
| 17 | u32 block_height = TICEntry::DefaultBlockHeight); | 17 | u32 height, u32 block_height = TICEntry::DefaultBlockHeight); |
| 18 | 18 | ||
| 19 | /** | 19 | /** |
| 20 | * Unswizzles a swizzled depth texture without changing its format. | 20 | * Unswizzles a swizzled depth texture without changing its format. |
diff --git a/src/yuzu/debugger/graphics/graphics_surface.cpp b/src/yuzu/debugger/graphics/graphics_surface.cpp index 3f7103ab9..e037223c2 100644 --- a/src/yuzu/debugger/graphics/graphics_surface.cpp +++ b/src/yuzu/debugger/graphics/graphics_surface.cpp | |||
| @@ -383,8 +383,10 @@ void GraphicsSurfaceWidget::OnUpdate() { | |||
| 383 | QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); | 383 | QImage decoded_image(surface_width, surface_height, QImage::Format_ARGB32); |
| 384 | boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address); | 384 | boost::optional<VAddr> address = gpu.memory_manager->GpuToCpuAddress(surface_address); |
| 385 | 385 | ||
| 386 | auto unswizzled_data = | 386 | // TODO(bunnei): Will not work with BCn formats that swizzle 4x4 tiles. |
| 387 | Tegra::Texture::UnswizzleTexture(*address, surface_format, surface_width, surface_height); | 387 | // Needs to be fixed if we plan to use this feature more, otherwise we may remove it. |
| 388 | auto unswizzled_data = Tegra::Texture::UnswizzleTexture( | ||
| 389 | *address, 1, Tegra::Texture::BytesPerPixel(surface_format), surface_width, surface_height); | ||
| 388 | 390 | ||
| 389 | auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, | 391 | auto texture_data = Tegra::Texture::DecodeTexture(unswizzled_data, surface_format, |
| 390 | surface_width, surface_height); | 392 | surface_width, surface_height); |