summaryrefslogtreecommitdiff
path: root/src/video_core/surface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/video_core/surface.cpp')
-rw-r--r--src/video_core/surface.cpp499
1 files changed, 499 insertions, 0 deletions
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
new file mode 100644
index 000000000..d9a97e30b
--- /dev/null
+++ b/src/video_core/surface.cpp
@@ -0,0 +1,499 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_types.h"
6#include "common/math_util.h"
7#include "video_core/surface.h"
8
9namespace VideoCore::Surface {
10
11SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type) {
12 switch (texture_type) {
13 case Tegra::Texture::TextureType::Texture1D:
14 return SurfaceTarget::Texture1D;
15 case Tegra::Texture::TextureType::Texture2D:
16 case Tegra::Texture::TextureType::Texture2DNoMipmap:
17 return SurfaceTarget::Texture2D;
18 case Tegra::Texture::TextureType::Texture3D:
19 return SurfaceTarget::Texture3D;
20 case Tegra::Texture::TextureType::TextureCubemap:
21 return SurfaceTarget::TextureCubemap;
22 case Tegra::Texture::TextureType::Texture1DArray:
23 return SurfaceTarget::Texture1DArray;
24 case Tegra::Texture::TextureType::Texture2DArray:
25 return SurfaceTarget::Texture2DArray;
26 default:
27 LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", static_cast<u32>(texture_type));
28 UNREACHABLE();
29 return SurfaceTarget::Texture2D;
30 }
31}
32
33bool SurfaceTargetIsLayered(SurfaceTarget target) {
34 switch (target) {
35 case SurfaceTarget::Texture1D:
36 case SurfaceTarget::Texture2D:
37 case SurfaceTarget::Texture3D:
38 return false;
39 case SurfaceTarget::Texture1DArray:
40 case SurfaceTarget::Texture2DArray:
41 case SurfaceTarget::TextureCubemap:
42 return true;
43 default:
44 LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
45 UNREACHABLE();
46 return false;
47 }
48}
49
50PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
51 switch (format) {
52 case Tegra::DepthFormat::S8_Z24_UNORM:
53 return PixelFormat::S8Z24;
54 case Tegra::DepthFormat::Z24_S8_UNORM:
55 return PixelFormat::Z24S8;
56 case Tegra::DepthFormat::Z32_FLOAT:
57 return PixelFormat::Z32F;
58 case Tegra::DepthFormat::Z16_UNORM:
59 return PixelFormat::Z16;
60 case Tegra::DepthFormat::Z32_S8_X24_FLOAT:
61 return PixelFormat::Z32FS8;
62 default:
63 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
64 UNREACHABLE();
65 }
66}
67
68PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
69 switch (format) {
70 // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the
71 // gamma.
72 case Tegra::RenderTargetFormat::RGBA8_SRGB:
73 return PixelFormat::RGBA8_SRGB;
74 case Tegra::RenderTargetFormat::RGBA8_UNORM:
75 return PixelFormat::ABGR8U;
76 case Tegra::RenderTargetFormat::RGBA8_SNORM:
77 return PixelFormat::ABGR8S;
78 case Tegra::RenderTargetFormat::RGBA8_UINT:
79 return PixelFormat::ABGR8UI;
80 case Tegra::RenderTargetFormat::BGRA8_SRGB:
81 return PixelFormat::BGRA8_SRGB;
82 case Tegra::RenderTargetFormat::BGRA8_UNORM:
83 return PixelFormat::BGRA8;
84 case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
85 return PixelFormat::A2B10G10R10U;
86 case Tegra::RenderTargetFormat::RGBA16_FLOAT:
87 return PixelFormat::RGBA16F;
88 case Tegra::RenderTargetFormat::RGBA16_UNORM:
89 return PixelFormat::RGBA16U;
90 case Tegra::RenderTargetFormat::RGBA16_UINT:
91 return PixelFormat::RGBA16UI;
92 case Tegra::RenderTargetFormat::RGBA32_FLOAT:
93 return PixelFormat::RGBA32F;
94 case Tegra::RenderTargetFormat::RG32_FLOAT:
95 return PixelFormat::RG32F;
96 case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
97 return PixelFormat::R11FG11FB10F;
98 case Tegra::RenderTargetFormat::B5G6R5_UNORM:
99 return PixelFormat::B5G6R5U;
100 case Tegra::RenderTargetFormat::BGR5A1_UNORM:
101 return PixelFormat::A1B5G5R5U;
102 case Tegra::RenderTargetFormat::RGBA32_UINT:
103 return PixelFormat::RGBA32UI;
104 case Tegra::RenderTargetFormat::R8_UNORM:
105 return PixelFormat::R8U;
106 case Tegra::RenderTargetFormat::R8_UINT:
107 return PixelFormat::R8UI;
108 case Tegra::RenderTargetFormat::RG16_FLOAT:
109 return PixelFormat::RG16F;
110 case Tegra::RenderTargetFormat::RG16_UINT:
111 return PixelFormat::RG16UI;
112 case Tegra::RenderTargetFormat::RG16_SINT:
113 return PixelFormat::RG16I;
114 case Tegra::RenderTargetFormat::RG16_UNORM:
115 return PixelFormat::RG16;
116 case Tegra::RenderTargetFormat::RG16_SNORM:
117 return PixelFormat::RG16S;
118 case Tegra::RenderTargetFormat::RG8_UNORM:
119 return PixelFormat::RG8U;
120 case Tegra::RenderTargetFormat::RG8_SNORM:
121 return PixelFormat::RG8S;
122 case Tegra::RenderTargetFormat::R16_FLOAT:
123 return PixelFormat::R16F;
124 case Tegra::RenderTargetFormat::R16_UNORM:
125 return PixelFormat::R16U;
126 case Tegra::RenderTargetFormat::R16_SNORM:
127 return PixelFormat::R16S;
128 case Tegra::RenderTargetFormat::R16_UINT:
129 return PixelFormat::R16UI;
130 case Tegra::RenderTargetFormat::R16_SINT:
131 return PixelFormat::R16I;
132 case Tegra::RenderTargetFormat::R32_FLOAT:
133 return PixelFormat::R32F;
134 case Tegra::RenderTargetFormat::R32_UINT:
135 return PixelFormat::R32UI;
136 case Tegra::RenderTargetFormat::RG32_UINT:
137 return PixelFormat::RG32UI;
138 default:
139 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
140 UNREACHABLE();
141 }
142}
143
144PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
145 Tegra::Texture::ComponentType component_type,
146 bool is_srgb) {
147 // TODO(Subv): Properly implement this
148 switch (format) {
149 case Tegra::Texture::TextureFormat::A8R8G8B8:
150 if (is_srgb) {
151 return PixelFormat::RGBA8_SRGB;
152 }
153 switch (component_type) {
154 case Tegra::Texture::ComponentType::UNORM:
155 return PixelFormat::ABGR8U;
156 case Tegra::Texture::ComponentType::SNORM:
157 return PixelFormat::ABGR8S;
158 case Tegra::Texture::ComponentType::UINT:
159 return PixelFormat::ABGR8UI;
160 }
161 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
162 UNREACHABLE();
163 case Tegra::Texture::TextureFormat::B5G6R5:
164 switch (component_type) {
165 case Tegra::Texture::ComponentType::UNORM:
166 return PixelFormat::B5G6R5U;
167 }
168 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
169 UNREACHABLE();
170 case Tegra::Texture::TextureFormat::A2B10G10R10:
171 switch (component_type) {
172 case Tegra::Texture::ComponentType::UNORM:
173 return PixelFormat::A2B10G10R10U;
174 }
175 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
176 UNREACHABLE();
177 case Tegra::Texture::TextureFormat::A1B5G5R5:
178 switch (component_type) {
179 case Tegra::Texture::ComponentType::UNORM:
180 return PixelFormat::A1B5G5R5U;
181 }
182 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
183 UNREACHABLE();
184 case Tegra::Texture::TextureFormat::R8:
185 switch (component_type) {
186 case Tegra::Texture::ComponentType::UNORM:
187 return PixelFormat::R8U;
188 case Tegra::Texture::ComponentType::UINT:
189 return PixelFormat::R8UI;
190 }
191 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
192 UNREACHABLE();
193 case Tegra::Texture::TextureFormat::G8R8:
194 switch (component_type) {
195 case Tegra::Texture::ComponentType::UNORM:
196 return PixelFormat::G8R8U;
197 case Tegra::Texture::ComponentType::SNORM:
198 return PixelFormat::G8R8S;
199 }
200 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
201 UNREACHABLE();
202 case Tegra::Texture::TextureFormat::R16_G16_B16_A16:
203 switch (component_type) {
204 case Tegra::Texture::ComponentType::UNORM:
205 return PixelFormat::RGBA16U;
206 case Tegra::Texture::ComponentType::FLOAT:
207 return PixelFormat::RGBA16F;
208 }
209 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
210 UNREACHABLE();
211 case Tegra::Texture::TextureFormat::BF10GF11RF11:
212 switch (component_type) {
213 case Tegra::Texture::ComponentType::FLOAT:
214 return PixelFormat::R11FG11FB10F;
215 }
216 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
217 UNREACHABLE();
218 case Tegra::Texture::TextureFormat::R32_G32_B32_A32:
219 switch (component_type) {
220 case Tegra::Texture::ComponentType::FLOAT:
221 return PixelFormat::RGBA32F;
222 case Tegra::Texture::ComponentType::UINT:
223 return PixelFormat::RGBA32UI;
224 }
225 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
226 UNREACHABLE();
227 case Tegra::Texture::TextureFormat::R32_G32:
228 switch (component_type) {
229 case Tegra::Texture::ComponentType::FLOAT:
230 return PixelFormat::RG32F;
231 case Tegra::Texture::ComponentType::UINT:
232 return PixelFormat::RG32UI;
233 }
234 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
235 UNREACHABLE();
236 case Tegra::Texture::TextureFormat::R32_G32_B32:
237 switch (component_type) {
238 case Tegra::Texture::ComponentType::FLOAT:
239 return PixelFormat::RGB32F;
240 }
241 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
242 UNREACHABLE();
243 case Tegra::Texture::TextureFormat::R16:
244 switch (component_type) {
245 case Tegra::Texture::ComponentType::FLOAT:
246 return PixelFormat::R16F;
247 case Tegra::Texture::ComponentType::UNORM:
248 return PixelFormat::R16U;
249 case Tegra::Texture::ComponentType::SNORM:
250 return PixelFormat::R16S;
251 case Tegra::Texture::ComponentType::UINT:
252 return PixelFormat::R16UI;
253 case Tegra::Texture::ComponentType::SINT:
254 return PixelFormat::R16I;
255 }
256 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
257 UNREACHABLE();
258 case Tegra::Texture::TextureFormat::R32:
259 switch (component_type) {
260 case Tegra::Texture::ComponentType::FLOAT:
261 return PixelFormat::R32F;
262 case Tegra::Texture::ComponentType::UINT:
263 return PixelFormat::R32UI;
264 }
265 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
266 UNREACHABLE();
267 case Tegra::Texture::TextureFormat::ZF32:
268 return PixelFormat::Z32F;
269 case Tegra::Texture::TextureFormat::Z16:
270 return PixelFormat::Z16;
271 case Tegra::Texture::TextureFormat::Z24S8:
272 return PixelFormat::Z24S8;
273 case Tegra::Texture::TextureFormat::DXT1:
274 return is_srgb ? PixelFormat::DXT1_SRGB : PixelFormat::DXT1;
275 case Tegra::Texture::TextureFormat::DXT23:
276 return is_srgb ? PixelFormat::DXT23_SRGB : PixelFormat::DXT23;
277 case Tegra::Texture::TextureFormat::DXT45:
278 return is_srgb ? PixelFormat::DXT45_SRGB : PixelFormat::DXT45;
279 case Tegra::Texture::TextureFormat::DXN1:
280 return PixelFormat::DXN1;
281 case Tegra::Texture::TextureFormat::DXN2:
282 switch (component_type) {
283 case Tegra::Texture::ComponentType::UNORM:
284 return PixelFormat::DXN2UNORM;
285 case Tegra::Texture::ComponentType::SNORM:
286 return PixelFormat::DXN2SNORM;
287 }
288 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
289 UNREACHABLE();
290 case Tegra::Texture::TextureFormat::BC7U:
291 return is_srgb ? PixelFormat::BC7U_SRGB : PixelFormat::BC7U;
292 case Tegra::Texture::TextureFormat::BC6H_UF16:
293 return PixelFormat::BC6H_UF16;
294 case Tegra::Texture::TextureFormat::BC6H_SF16:
295 return PixelFormat::BC6H_SF16;
296 case Tegra::Texture::TextureFormat::ASTC_2D_4X4:
297 return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4;
298 case Tegra::Texture::TextureFormat::ASTC_2D_5X4:
299 return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4;
300 case Tegra::Texture::TextureFormat::ASTC_2D_8X8:
301 return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8;
302 case Tegra::Texture::TextureFormat::ASTC_2D_8X5:
303 return is_srgb ? PixelFormat::ASTC_2D_8X5_SRGB : PixelFormat::ASTC_2D_8X5;
304 case Tegra::Texture::TextureFormat::R16_G16:
305 switch (component_type) {
306 case Tegra::Texture::ComponentType::FLOAT:
307 return PixelFormat::RG16F;
308 case Tegra::Texture::ComponentType::UNORM:
309 return PixelFormat::RG16;
310 case Tegra::Texture::ComponentType::SNORM:
311 return PixelFormat::RG16S;
312 case Tegra::Texture::ComponentType::UINT:
313 return PixelFormat::RG16UI;
314 case Tegra::Texture::ComponentType::SINT:
315 return PixelFormat::RG16I;
316 }
317 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
318 UNREACHABLE();
319 default:
320 LOG_CRITICAL(HW_GPU, "Unimplemented format={}, component_type={}", static_cast<u32>(format),
321 static_cast<u32>(component_type));
322 UNREACHABLE();
323 }
324}
325
326ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
327 // TODO(Subv): Implement more component types
328 switch (type) {
329 case Tegra::Texture::ComponentType::UNORM:
330 return ComponentType::UNorm;
331 case Tegra::Texture::ComponentType::FLOAT:
332 return ComponentType::Float;
333 case Tegra::Texture::ComponentType::SNORM:
334 return ComponentType::SNorm;
335 case Tegra::Texture::ComponentType::UINT:
336 return ComponentType::UInt;
337 case Tegra::Texture::ComponentType::SINT:
338 return ComponentType::SInt;
339 default:
340 LOG_CRITICAL(HW_GPU, "Unimplemented component type={}", static_cast<u32>(type));
341 UNREACHABLE();
342 }
343}
344
345ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format) {
346 // TODO(Subv): Implement more render targets
347 switch (format) {
348 case Tegra::RenderTargetFormat::RGBA8_UNORM:
349 case Tegra::RenderTargetFormat::RGBA8_SRGB:
350 case Tegra::RenderTargetFormat::BGRA8_UNORM:
351 case Tegra::RenderTargetFormat::BGRA8_SRGB:
352 case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
353 case Tegra::RenderTargetFormat::R8_UNORM:
354 case Tegra::RenderTargetFormat::RG16_UNORM:
355 case Tegra::RenderTargetFormat::R16_UNORM:
356 case Tegra::RenderTargetFormat::B5G6R5_UNORM:
357 case Tegra::RenderTargetFormat::BGR5A1_UNORM:
358 case Tegra::RenderTargetFormat::RG8_UNORM:
359 case Tegra::RenderTargetFormat::RGBA16_UNORM:
360 return ComponentType::UNorm;
361 case Tegra::RenderTargetFormat::RGBA8_SNORM:
362 case Tegra::RenderTargetFormat::RG16_SNORM:
363 case Tegra::RenderTargetFormat::R16_SNORM:
364 case Tegra::RenderTargetFormat::RG8_SNORM:
365 return ComponentType::SNorm;
366 case Tegra::RenderTargetFormat::RGBA16_FLOAT:
367 case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
368 case Tegra::RenderTargetFormat::RGBA32_FLOAT:
369 case Tegra::RenderTargetFormat::RG32_FLOAT:
370 case Tegra::RenderTargetFormat::RG16_FLOAT:
371 case Tegra::RenderTargetFormat::R16_FLOAT:
372 case Tegra::RenderTargetFormat::R32_FLOAT:
373 return ComponentType::Float;
374 case Tegra::RenderTargetFormat::RGBA32_UINT:
375 case Tegra::RenderTargetFormat::RGBA16_UINT:
376 case Tegra::RenderTargetFormat::RG16_UINT:
377 case Tegra::RenderTargetFormat::R8_UINT:
378 case Tegra::RenderTargetFormat::R16_UINT:
379 case Tegra::RenderTargetFormat::RG32_UINT:
380 case Tegra::RenderTargetFormat::R32_UINT:
381 case Tegra::RenderTargetFormat::RGBA8_UINT:
382 return ComponentType::UInt;
383 case Tegra::RenderTargetFormat::RG16_SINT:
384 case Tegra::RenderTargetFormat::R16_SINT:
385 return ComponentType::SInt;
386 default:
387 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
388 UNREACHABLE();
389 }
390}
391
392PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) {
393 switch (format) {
394 case Tegra::FramebufferConfig::PixelFormat::ABGR8:
395 return PixelFormat::ABGR8U;
396 default:
397 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
398 UNREACHABLE();
399 }
400}
401
402ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) {
403 switch (format) {
404 case Tegra::DepthFormat::Z16_UNORM:
405 case Tegra::DepthFormat::S8_Z24_UNORM:
406 case Tegra::DepthFormat::Z24_S8_UNORM:
407 return ComponentType::UNorm;
408 case Tegra::DepthFormat::Z32_FLOAT:
409 case Tegra::DepthFormat::Z32_S8_X24_FLOAT:
410 return ComponentType::Float;
411 default:
412 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
413 UNREACHABLE();
414 }
415}
416
417SurfaceType GetFormatType(PixelFormat pixel_format) {
418 if (static_cast<std::size_t>(pixel_format) <
419 static_cast<std::size_t>(PixelFormat::MaxColorFormat)) {
420 return SurfaceType::ColorTexture;
421 }
422
423 if (static_cast<std::size_t>(pixel_format) <
424 static_cast<std::size_t>(PixelFormat::MaxDepthFormat)) {
425 return SurfaceType::Depth;
426 }
427
428 if (static_cast<std::size_t>(pixel_format) <
429 static_cast<std::size_t>(PixelFormat::MaxDepthStencilFormat)) {
430 return SurfaceType::DepthStencil;
431 }
432
433 // TODO(Subv): Implement the other formats
434 ASSERT(false);
435
436 return SurfaceType::Invalid;
437}
438
439bool IsPixelFormatASTC(PixelFormat format) {
440 switch (format) {
441 case PixelFormat::ASTC_2D_4X4:
442 case PixelFormat::ASTC_2D_5X4:
443 case PixelFormat::ASTC_2D_8X8:
444 case PixelFormat::ASTC_2D_8X5:
445 case PixelFormat::ASTC_2D_4X4_SRGB:
446 case PixelFormat::ASTC_2D_5X4_SRGB:
447 case PixelFormat::ASTC_2D_8X8_SRGB:
448 case PixelFormat::ASTC_2D_8X5_SRGB:
449 return true;
450 default:
451 return false;
452 }
453}
454
455std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
456 switch (format) {
457 case PixelFormat::ASTC_2D_4X4:
458 return {4, 4};
459 case PixelFormat::ASTC_2D_5X4:
460 return {5, 4};
461 case PixelFormat::ASTC_2D_8X8:
462 return {8, 8};
463 case PixelFormat::ASTC_2D_8X5:
464 return {8, 5};
465 case PixelFormat::ASTC_2D_4X4_SRGB:
466 return {4, 4};
467 case PixelFormat::ASTC_2D_5X4_SRGB:
468 return {5, 4};
469 case PixelFormat::ASTC_2D_8X8_SRGB:
470 return {8, 8};
471 case PixelFormat::ASTC_2D_8X5_SRGB:
472 return {8, 5};
473 default:
474 LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format));
475 UNREACHABLE();
476 }
477}
478
479bool IsFormatBCn(PixelFormat format) {
480 switch (format) {
481 case PixelFormat::DXT1:
482 case PixelFormat::DXT23:
483 case PixelFormat::DXT45:
484 case PixelFormat::DXN1:
485 case PixelFormat::DXN2SNORM:
486 case PixelFormat::DXN2UNORM:
487 case PixelFormat::BC7U:
488 case PixelFormat::BC6H_UF16:
489 case PixelFormat::BC6H_SF16:
490 case PixelFormat::DXT1_SRGB:
491 case PixelFormat::DXT23_SRGB:
492 case PixelFormat::DXT45_SRGB:
493 case PixelFormat::BC7U_SRGB:
494 return true;
495 }
496 return false;
497}
498
499} // namespace VideoCore::Surface