summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar bunnei2018-08-10 11:06:23 -0400
committerGravatar GitHub2018-08-10 11:06:23 -0400
commit7e6a73963ea8e208a8a3ae8cbd03aae30fe89e98 (patch)
tree4bfd261505903e92c470468165db0c63858bbae8
parentMerge pull request #995 from bunnei/gl-buff-bounds (diff)
parenttextures: Refactor out for Texture/Depth FormatFromPixelFormat. (diff)
downloadyuzu-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.cpp31
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h86
-rw-r--r--src/video_core/textures/decoders.cpp85
-rw-r--r--src/video_core/textures/decoders.h4
-rw-r--r--src/yuzu/debugger/graphics/graphics_surface.cpp6
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
187static 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
186template <bool morton_to_gl, PixelFormat format> 201template <bool morton_to_gl, PixelFormat format>
187void MortonCopy(u32 stride, u32 block_height, u32 height, std::vector<u8>& gl_buffer, 202void 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
89static u32 DepthBytesPerPixel(DepthFormat format) { 89std::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
105std::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
150std::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 */
16std::vector<u8> UnswizzleTexture(VAddr address, TextureFormat format, u32 width, u32 height, 16std::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);