summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/video_core/CMakeLists.txt2
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp7
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.cpp170
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer_cache.h789
-rw-r--r--src/video_core/surface.cpp499
-rw-r--r--src/video_core/surface.h385
6 files changed, 954 insertions, 898 deletions
diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt
index c5f7128ec..ddb1a1d69 100644
--- a/src/video_core/CMakeLists.txt
+++ b/src/video_core/CMakeLists.txt
@@ -53,6 +53,8 @@ add_library(video_core STATIC
53 renderer_opengl/renderer_opengl.h 53 renderer_opengl/renderer_opengl.h
54 renderer_opengl/utils.cpp 54 renderer_opengl/utils.cpp
55 renderer_opengl/utils.h 55 renderer_opengl/utils.h
56 surface.cpp
57 surface.h
56 textures/astc.cpp 58 textures/astc.cpp
57 textures/astc.h 59 textures/astc.h
58 textures/decoders.cpp 60 textures/decoders.cpp
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index bf381271e..75e31c6de 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -30,8 +30,8 @@
30namespace OpenGL { 30namespace OpenGL {
31 31
32using Maxwell = Tegra::Engines::Maxwell3D::Regs; 32using Maxwell = Tegra::Engines::Maxwell3D::Regs;
33using PixelFormat = SurfaceParams::PixelFormat; 33using PixelFormat = VideoCore::Surface::PixelFormat;
34using SurfaceType = SurfaceParams::SurfaceType; 34using SurfaceType = VideoCore::Surface::SurfaceType;
35 35
36MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Array Setup", MP_RGB(128, 128, 192)); 36MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Array Setup", MP_RGB(128, 128, 192));
37MICROPROFILE_DEFINE(OpenGL_Shader, "OpenGL", "Shader Setup", MP_RGB(128, 128, 192)); 37MICROPROFILE_DEFINE(OpenGL_Shader, "OpenGL", "Shader Setup", MP_RGB(128, 128, 192));
@@ -703,7 +703,8 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
703 703
704 // Verify that the cached surface is the same size and format as the requested framebuffer 704 // Verify that the cached surface is the same size and format as the requested framebuffer
705 const auto& params{surface->GetSurfaceParams()}; 705 const auto& params{surface->GetSurfaceParams()};
706 const auto& pixel_format{SurfaceParams::PixelFormatFromGPUPixelFormat(config.pixel_format)}; 706 const auto& pixel_format{
707 VideoCore::Surface::PixelFormatFromGPUPixelFormat(config.pixel_format)};
707 ASSERT_MSG(params.width == config.width, "Framebuffer width is different"); 708 ASSERT_MSG(params.width == config.width, "Framebuffer width is different");
708 ASSERT_MSG(params.height == config.height, "Framebuffer height is different"); 709 ASSERT_MSG(params.height == config.height, "Framebuffer height is different");
709 ASSERT_MSG(params.pixel_format == pixel_format, "Framebuffer pixel_format is different"); 710 ASSERT_MSG(params.pixel_format == pixel_format, "Framebuffer pixel_format is different");
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
index 1d43a419d..f194a7687 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.cpp
@@ -17,15 +17,20 @@
17#include "video_core/engines/maxwell_3d.h" 17#include "video_core/engines/maxwell_3d.h"
18#include "video_core/renderer_opengl/gl_rasterizer_cache.h" 18#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
19#include "video_core/renderer_opengl/utils.h" 19#include "video_core/renderer_opengl/utils.h"
20#include "video_core/surface.h"
20#include "video_core/textures/astc.h" 21#include "video_core/textures/astc.h"
21#include "video_core/textures/decoders.h" 22#include "video_core/textures/decoders.h"
22#include "video_core/utils.h" 23#include "video_core/utils.h"
23 24
24namespace OpenGL { 25namespace OpenGL {
25 26
26using SurfaceType = SurfaceParams::SurfaceType; 27using VideoCore::Surface::ComponentTypeFromDepthFormat;
27using PixelFormat = SurfaceParams::PixelFormat; 28using VideoCore::Surface::ComponentTypeFromRenderTarget;
28using ComponentType = SurfaceParams::ComponentType; 29using VideoCore::Surface::ComponentTypeFromTexture;
30using VideoCore::Surface::PixelFormatFromDepthFormat;
31using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
32using VideoCore::Surface::PixelFormatFromTextureFormat;
33using VideoCore::Surface::SurfaceTargetFromTextureType;
29 34
30struct FormatTuple { 35struct FormatTuple {
31 GLint internal_format; 36 GLint internal_format;
@@ -35,46 +40,6 @@ struct FormatTuple {
35 bool compressed; 40 bool compressed;
36}; 41};
37 42
38static bool IsPixelFormatASTC(PixelFormat format) {
39 switch (format) {
40 case PixelFormat::ASTC_2D_4X4:
41 case PixelFormat::ASTC_2D_5X4:
42 case PixelFormat::ASTC_2D_8X8:
43 case PixelFormat::ASTC_2D_8X5:
44 case PixelFormat::ASTC_2D_4X4_SRGB:
45 case PixelFormat::ASTC_2D_5X4_SRGB:
46 case PixelFormat::ASTC_2D_8X8_SRGB:
47 case PixelFormat::ASTC_2D_8X5_SRGB:
48 return true;
49 default:
50 return false;
51 }
52}
53
54static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
55 switch (format) {
56 case PixelFormat::ASTC_2D_4X4:
57 return {4, 4};
58 case PixelFormat::ASTC_2D_5X4:
59 return {5, 4};
60 case PixelFormat::ASTC_2D_8X8:
61 return {8, 8};
62 case PixelFormat::ASTC_2D_8X5:
63 return {8, 5};
64 case PixelFormat::ASTC_2D_4X4_SRGB:
65 return {4, 4};
66 case PixelFormat::ASTC_2D_5X4_SRGB:
67 return {5, 4};
68 case PixelFormat::ASTC_2D_8X8_SRGB:
69 return {8, 8};
70 case PixelFormat::ASTC_2D_8X5_SRGB:
71 return {8, 5};
72 default:
73 LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format));
74 UNREACHABLE();
75 }
76}
77
78void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) { 43void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) {
79 auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()}; 44 auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()};
80 const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr_)}; 45 const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr_)};
@@ -267,7 +232,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
267 return params; 232 return params;
268} 233}
269 234
270static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{ 235static constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{
271 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U 236 {GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U
272 {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S 237 {GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S
273 {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false}, // ABGR8UI 238 {GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, ComponentType::UInt, false}, // ABGR8UI
@@ -355,19 +320,19 @@ static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_form
355 ComponentType::Float, false}, // Z32FS8 320 ComponentType::Float, false}, // Z32FS8
356}}; 321}};
357 322
358static GLenum SurfaceTargetToGL(SurfaceParams::SurfaceTarget target) { 323static GLenum SurfaceTargetToGL(SurfaceTarget target) {
359 switch (target) { 324 switch (target) {
360 case SurfaceParams::SurfaceTarget::Texture1D: 325 case SurfaceTarget::Texture1D:
361 return GL_TEXTURE_1D; 326 return GL_TEXTURE_1D;
362 case SurfaceParams::SurfaceTarget::Texture2D: 327 case SurfaceTarget::Texture2D:
363 return GL_TEXTURE_2D; 328 return GL_TEXTURE_2D;
364 case SurfaceParams::SurfaceTarget::Texture3D: 329 case SurfaceTarget::Texture3D:
365 return GL_TEXTURE_3D; 330 return GL_TEXTURE_3D;
366 case SurfaceParams::SurfaceTarget::Texture1DArray: 331 case SurfaceTarget::Texture1DArray:
367 return GL_TEXTURE_1D_ARRAY; 332 return GL_TEXTURE_1D_ARRAY;
368 case SurfaceParams::SurfaceTarget::Texture2DArray: 333 case SurfaceTarget::Texture2DArray:
369 return GL_TEXTURE_2D_ARRAY; 334 return GL_TEXTURE_2D_ARRAY;
370 case SurfaceParams::SurfaceTarget::TextureCubemap: 335 case SurfaceTarget::TextureCubemap:
371 return GL_TEXTURE_CUBE_MAP; 336 return GL_TEXTURE_CUBE_MAP;
372 } 337 }
373 LOG_CRITICAL(Render_OpenGL, "Unimplemented texture target={}", static_cast<u32>(target)); 338 LOG_CRITICAL(Render_OpenGL, "Unimplemented texture target={}", static_cast<u32>(target));
@@ -392,31 +357,10 @@ MathUtil::Rectangle<u32> SurfaceParams::GetRect(u32 mip_level) const {
392 return {0, actual_height, MipWidth(mip_level), 0}; 357 return {0, actual_height, MipWidth(mip_level), 0};
393} 358}
394 359
395/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
396static bool IsFormatBCn(PixelFormat format) {
397 switch (format) {
398 case PixelFormat::DXT1:
399 case PixelFormat::DXT23:
400 case PixelFormat::DXT45:
401 case PixelFormat::DXN1:
402 case PixelFormat::DXN2SNORM:
403 case PixelFormat::DXN2UNORM:
404 case PixelFormat::BC7U:
405 case PixelFormat::BC6H_UF16:
406 case PixelFormat::BC6H_SF16:
407 case PixelFormat::DXT1_SRGB:
408 case PixelFormat::DXT23_SRGB:
409 case PixelFormat::DXT45_SRGB:
410 case PixelFormat::BC7U_SRGB:
411 return true;
412 }
413 return false;
414}
415
416template <bool morton_to_gl, PixelFormat format> 360template <bool morton_to_gl, PixelFormat format>
417void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 depth, u8* gl_buffer, 361void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 depth, u8* gl_buffer,
418 std::size_t gl_buffer_size, VAddr addr) { 362 std::size_t gl_buffer_size, VAddr addr) {
419 constexpr u32 bytes_per_pixel = SurfaceParams::GetBytesPerPixel(format); 363 constexpr u32 bytes_per_pixel = GetBytesPerPixel(format);
420 364
421 // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual 365 // With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual
422 // pixel values. 366 // pixel values.
@@ -435,7 +379,7 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 d
435} 379}
436 380
437using GLConversionArray = std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr), 381using GLConversionArray = std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr),
438 SurfaceParams::MaxPixelFormat>; 382 VideoCore::Surface::MaxPixelFormat>;
439 383
440static constexpr GLConversionArray morton_to_gl_fns = { 384static constexpr GLConversionArray morton_to_gl_fns = {
441 // clang-format off 385 // clang-format off
@@ -575,7 +519,7 @@ static constexpr GLConversionArray gl_to_morton_fns = {
575void SwizzleFunc(const GLConversionArray& functions, const SurfaceParams& params, 519void SwizzleFunc(const GLConversionArray& functions, const SurfaceParams& params,
576 std::vector<u8>& gl_buffer, u32 mip_level) { 520 std::vector<u8>& gl_buffer, u32 mip_level) {
577 u32 depth = params.MipDepth(mip_level); 521 u32 depth = params.MipDepth(mip_level);
578 if (params.target == SurfaceParams::SurfaceTarget::Texture2D) { 522 if (params.target == SurfaceTarget::Texture2D) {
579 // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented. 523 // TODO(Blinkhawk): Eliminate this condition once all texture types are implemented.
580 depth = 1U; 524 depth = 1U;
581 } 525 }
@@ -622,13 +566,13 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
622 566
623 if (src_params.type == SurfaceType::ColorTexture) { 567 if (src_params.type == SurfaceType::ColorTexture) {
624 switch (src_params.target) { 568 switch (src_params.target) {
625 case SurfaceParams::SurfaceTarget::Texture2D: 569 case SurfaceTarget::Texture2D:
626 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment, 570 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
627 GL_TEXTURE_2D, src_surface->Texture().handle, 0); 571 GL_TEXTURE_2D, src_surface->Texture().handle, 0);
628 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 572 glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
629 0, 0); 573 0, 0);
630 break; 574 break;
631 case SurfaceParams::SurfaceTarget::TextureCubemap: 575 case SurfaceTarget::TextureCubemap:
632 glFramebufferTexture2D( 576 glFramebufferTexture2D(
633 GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment, 577 GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
634 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 578 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face),
@@ -637,12 +581,12 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
637 GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 581 GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
638 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0); 582 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0);
639 break; 583 break;
640 case SurfaceParams::SurfaceTarget::Texture2DArray: 584 case SurfaceTarget::Texture2DArray:
641 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment, 585 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
642 src_surface->Texture().handle, 0, 0); 586 src_surface->Texture().handle, 0, 0);
643 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0); 587 glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
644 break; 588 break;
645 case SurfaceParams::SurfaceTarget::Texture3D: 589 case SurfaceTarget::Texture3D:
646 glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment, 590 glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
647 SurfaceTargetToGL(src_params.target), 591 SurfaceTargetToGL(src_params.target),
648 src_surface->Texture().handle, 0, 0); 592 src_surface->Texture().handle, 0, 0);
@@ -658,13 +602,13 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
658 } 602 }
659 603
660 switch (dst_params.target) { 604 switch (dst_params.target) {
661 case SurfaceParams::SurfaceTarget::Texture2D: 605 case SurfaceTarget::Texture2D:
662 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment, 606 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
663 GL_TEXTURE_2D, dst_surface->Texture().handle, 0); 607 GL_TEXTURE_2D, dst_surface->Texture().handle, 0);
664 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 608 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
665 0, 0); 609 0, 0);
666 break; 610 break;
667 case SurfaceParams::SurfaceTarget::TextureCubemap: 611 case SurfaceTarget::TextureCubemap:
668 glFramebufferTexture2D( 612 glFramebufferTexture2D(
669 GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment, 613 GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
670 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 614 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face),
@@ -673,13 +617,13 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
673 GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 617 GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
674 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0); 618 static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0);
675 break; 619 break;
676 case SurfaceParams::SurfaceTarget::Texture2DArray: 620 case SurfaceTarget::Texture2DArray:
677 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment, 621 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
678 dst_surface->Texture().handle, 0, 0); 622 dst_surface->Texture().handle, 0, 0);
679 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0); 623 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
680 break; 624 break;
681 625
682 case SurfaceParams::SurfaceTarget::Texture3D: 626 case SurfaceTarget::Texture3D:
683 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment, 627 glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
684 SurfaceTargetToGL(dst_params.target), 628 SurfaceTargetToGL(dst_params.target),
685 dst_surface->Texture().handle, 0, 0); 629 dst_surface->Texture().handle, 0, 0);
@@ -800,21 +744,21 @@ static void CopySurface(const Surface& src_surface, const Surface& dst_surface,
800 UNREACHABLE(); 744 UNREACHABLE();
801 } else { 745 } else {
802 switch (dst_params.target) { 746 switch (dst_params.target) {
803 case SurfaceParams::SurfaceTarget::Texture1D: 747 case SurfaceTarget::Texture1D:
804 glTextureSubImage1D(dst_surface->Texture().handle, 0, 0, width, dest_format.format, 748 glTextureSubImage1D(dst_surface->Texture().handle, 0, 0, width, dest_format.format,
805 dest_format.type, nullptr); 749 dest_format.type, nullptr);
806 break; 750 break;
807 case SurfaceParams::SurfaceTarget::Texture2D: 751 case SurfaceTarget::Texture2D:
808 glTextureSubImage2D(dst_surface->Texture().handle, 0, 0, 0, width, height, 752 glTextureSubImage2D(dst_surface->Texture().handle, 0, 0, 0, width, height,
809 dest_format.format, dest_format.type, nullptr); 753 dest_format.format, dest_format.type, nullptr);
810 break; 754 break;
811 case SurfaceParams::SurfaceTarget::Texture3D: 755 case SurfaceTarget::Texture3D:
812 case SurfaceParams::SurfaceTarget::Texture2DArray: 756 case SurfaceTarget::Texture2DArray:
813 glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0, 0, width, height, 757 glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0, 0, width, height,
814 static_cast<GLsizei>(dst_params.depth), dest_format.format, 758 static_cast<GLsizei>(dst_params.depth), dest_format.format,
815 dest_format.type, nullptr); 759 dest_format.type, nullptr);
816 break; 760 break;
817 case SurfaceParams::SurfaceTarget::TextureCubemap: 761 case SurfaceTarget::TextureCubemap:
818 glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0, 762 glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0,
819 static_cast<GLint>(cubemap_face), width, height, 1, 763 static_cast<GLint>(cubemap_face), width, height, 1,
820 dest_format.format, dest_format.type, nullptr); 764 dest_format.format, dest_format.type, nullptr);
@@ -851,17 +795,17 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
851 if (!format_tuple.compressed) { 795 if (!format_tuple.compressed) {
852 // Only pre-create the texture for non-compressed textures. 796 // Only pre-create the texture for non-compressed textures.
853 switch (params.target) { 797 switch (params.target) {
854 case SurfaceParams::SurfaceTarget::Texture1D: 798 case SurfaceTarget::Texture1D:
855 glTexStorage1D(SurfaceTargetToGL(params.target), params.max_mip_level, 799 glTexStorage1D(SurfaceTargetToGL(params.target), params.max_mip_level,
856 format_tuple.internal_format, rect.GetWidth()); 800 format_tuple.internal_format, rect.GetWidth());
857 break; 801 break;
858 case SurfaceParams::SurfaceTarget::Texture2D: 802 case SurfaceTarget::Texture2D:
859 case SurfaceParams::SurfaceTarget::TextureCubemap: 803 case SurfaceTarget::TextureCubemap:
860 glTexStorage2D(SurfaceTargetToGL(params.target), params.max_mip_level, 804 glTexStorage2D(SurfaceTargetToGL(params.target), params.max_mip_level,
861 format_tuple.internal_format, rect.GetWidth(), rect.GetHeight()); 805 format_tuple.internal_format, rect.GetWidth(), rect.GetHeight());
862 break; 806 break;
863 case SurfaceParams::SurfaceTarget::Texture3D: 807 case SurfaceTarget::Texture3D:
864 case SurfaceParams::SurfaceTarget::Texture2DArray: 808 case SurfaceTarget::Texture2DArray:
865 glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level, 809 glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level,
866 format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(), 810 format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(),
867 params.depth); 811 params.depth);
@@ -916,7 +860,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height, bo
916 860
917 S8Z24 s8z24_pixel{}; 861 S8Z24 s8z24_pixel{};
918 Z24S8 z24s8_pixel{}; 862 Z24S8 z24s8_pixel{};
919 constexpr auto bpp{SurfaceParams::GetBytesPerPixel(PixelFormat::S8Z24)}; 863 constexpr auto bpp{GetBytesPerPixel(PixelFormat::S8Z24)};
920 for (std::size_t y = 0; y < height; ++y) { 864 for (std::size_t y = 0; y < height; ++y) {
921 for (std::size_t x = 0; x < width; ++x) { 865 for (std::size_t x = 0; x < width; ++x) {
922 const std::size_t offset{bpp * (y * width + x)}; 866 const std::size_t offset{bpp * (y * width + x)};
@@ -936,7 +880,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height, bo
936} 880}
937 881
938static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) { 882static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) {
939 constexpr auto bpp{SurfaceParams::GetBytesPerPixel(PixelFormat::G8R8U)}; 883 constexpr auto bpp{GetBytesPerPixel(PixelFormat::G8R8U)};
940 for (std::size_t y = 0; y < height; ++y) { 884 for (std::size_t y = 0; y < height; ++y) {
941 for (std::size_t x = 0; x < width; ++x) { 885 for (std::size_t x = 0; x < width; ++x) {
942 const std::size_t offset{bpp * (y * width + x)}; 886 const std::size_t offset{bpp * (y * width + x)};
@@ -1042,7 +986,7 @@ void CachedSurface::FlushGLBuffer() {
1042 986
1043 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); 987 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
1044 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT 988 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT
1045 ASSERT(params.width * SurfaceParams::GetBytesPerPixel(params.pixel_format) % 4 == 0); 989 ASSERT(params.width * GetBytesPerPixel(params.pixel_format) % 4 == 0);
1046 glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(params.width)); 990 glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(params.width));
1047 ASSERT(!tuple.compressed); 991 ASSERT(!tuple.compressed);
1048 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); 992 glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
@@ -1074,7 +1018,7 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
1074 std::size_t buffer_offset = 1018 std::size_t buffer_offset =
1075 static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.MipWidth(mip_map) + 1019 static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.MipWidth(mip_map) +
1076 static_cast<std::size_t>(x0)) * 1020 static_cast<std::size_t>(x0)) *
1077 SurfaceParams::GetBytesPerPixel(params.pixel_format); 1021 GetBytesPerPixel(params.pixel_format);
1078 1022
1079 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type); 1023 const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
1080 const GLuint target_tex = texture.handle; 1024 const GLuint target_tex = texture.handle;
@@ -1090,35 +1034,34 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
1090 cur_state.Apply(); 1034 cur_state.Apply();
1091 1035
1092 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT 1036 // Ensure no bad interactions with GL_UNPACK_ALIGNMENT
1093 ASSERT(params.MipWidth(mip_map) * SurfaceParams::GetBytesPerPixel(params.pixel_format) % 4 == 1037 ASSERT(params.MipWidth(mip_map) * GetBytesPerPixel(params.pixel_format) % 4 == 0);
1094 0);
1095 glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.MipWidth(mip_map))); 1038 glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.MipWidth(mip_map)));
1096 1039
1097 GLsizei image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false)); 1040 GLsizei image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false));
1098 glActiveTexture(GL_TEXTURE0); 1041 glActiveTexture(GL_TEXTURE0);
1099 if (tuple.compressed) { 1042 if (tuple.compressed) {
1100 switch (params.target) { 1043 switch (params.target) {
1101 case SurfaceParams::SurfaceTarget::Texture2D: 1044 case SurfaceTarget::Texture2D:
1102 glCompressedTexImage2D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, 1045 glCompressedTexImage2D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
1103 static_cast<GLsizei>(params.MipWidth(mip_map)), 1046 static_cast<GLsizei>(params.MipWidth(mip_map)),
1104 static_cast<GLsizei>(params.MipHeight(mip_map)), 0, image_size, 1047 static_cast<GLsizei>(params.MipHeight(mip_map)), 0, image_size,
1105 &gl_buffer[mip_map][buffer_offset]); 1048 &gl_buffer[mip_map][buffer_offset]);
1106 break; 1049 break;
1107 case SurfaceParams::SurfaceTarget::Texture3D: 1050 case SurfaceTarget::Texture3D:
1108 glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, 1051 glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
1109 static_cast<GLsizei>(params.MipWidth(mip_map)), 1052 static_cast<GLsizei>(params.MipWidth(mip_map)),
1110 static_cast<GLsizei>(params.MipHeight(mip_map)), 1053 static_cast<GLsizei>(params.MipHeight(mip_map)),
1111 static_cast<GLsizei>(params.MipDepth(mip_map)), 0, image_size, 1054 static_cast<GLsizei>(params.MipDepth(mip_map)), 0, image_size,
1112 &gl_buffer[mip_map][buffer_offset]); 1055 &gl_buffer[mip_map][buffer_offset]);
1113 break; 1056 break;
1114 case SurfaceParams::SurfaceTarget::Texture2DArray: 1057 case SurfaceTarget::Texture2DArray:
1115 glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format, 1058 glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
1116 static_cast<GLsizei>(params.MipWidth(mip_map)), 1059 static_cast<GLsizei>(params.MipWidth(mip_map)),
1117 static_cast<GLsizei>(params.MipHeight(mip_map)), 1060 static_cast<GLsizei>(params.MipHeight(mip_map)),
1118 static_cast<GLsizei>(params.depth), 0, image_size, 1061 static_cast<GLsizei>(params.depth), 0, image_size,
1119 &gl_buffer[mip_map][buffer_offset]); 1062 &gl_buffer[mip_map][buffer_offset]);
1120 break; 1063 break;
1121 case SurfaceParams::SurfaceTarget::TextureCubemap: { 1064 case SurfaceTarget::TextureCubemap: {
1122 GLsizei layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map)); 1065 GLsizei layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map));
1123 for (std::size_t face = 0; face < params.depth; ++face) { 1066 for (std::size_t face = 0; face < params.depth; ++face) {
1124 glCompressedTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), 1067 glCompressedTexImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face),
@@ -1143,30 +1086,30 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
1143 } else { 1086 } else {
1144 1087
1145 switch (params.target) { 1088 switch (params.target) {
1146 case SurfaceParams::SurfaceTarget::Texture1D: 1089 case SurfaceTarget::Texture1D:
1147 glTexSubImage1D(SurfaceTargetToGL(params.target), mip_map, x0, 1090 glTexSubImage1D(SurfaceTargetToGL(params.target), mip_map, x0,
1148 static_cast<GLsizei>(rect.GetWidth()), tuple.format, tuple.type, 1091 static_cast<GLsizei>(rect.GetWidth()), tuple.format, tuple.type,
1149 &gl_buffer[mip_map][buffer_offset]); 1092 &gl_buffer[mip_map][buffer_offset]);
1150 break; 1093 break;
1151 case SurfaceParams::SurfaceTarget::Texture2D: 1094 case SurfaceTarget::Texture2D:
1152 glTexSubImage2D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 1095 glTexSubImage2D(SurfaceTargetToGL(params.target), mip_map, x0, y0,
1153 static_cast<GLsizei>(rect.GetWidth()), 1096 static_cast<GLsizei>(rect.GetWidth()),
1154 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type, 1097 static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
1155 &gl_buffer[mip_map][buffer_offset]); 1098 &gl_buffer[mip_map][buffer_offset]);
1156 break; 1099 break;
1157 case SurfaceParams::SurfaceTarget::Texture3D: 1100 case SurfaceTarget::Texture3D:
1158 glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, 1101 glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0,
1159 static_cast<GLsizei>(rect.GetWidth()), 1102 static_cast<GLsizei>(rect.GetWidth()),
1160 static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map), 1103 static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map),
1161 tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]); 1104 tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
1162 break; 1105 break;
1163 case SurfaceParams::SurfaceTarget::Texture2DArray: 1106 case SurfaceTarget::Texture2DArray:
1164 glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0, 1107 glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0,
1165 static_cast<GLsizei>(rect.GetWidth()), 1108 static_cast<GLsizei>(rect.GetWidth()),
1166 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format, 1109 static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
1167 tuple.type, &gl_buffer[mip_map][buffer_offset]); 1110 tuple.type, &gl_buffer[mip_map][buffer_offset]);
1168 break; 1111 break;
1169 case SurfaceParams::SurfaceTarget::TextureCubemap: { 1112 case SurfaceTarget::TextureCubemap: {
1170 std::size_t start = buffer_offset; 1113 std::size_t start = buffer_offset;
1171 for (std::size_t face = 0; face < params.depth; ++face) { 1114 for (std::size_t face = 0; face < params.depth; ++face) {
1172 glTexSubImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), mip_map, 1115 glTexSubImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), mip_map,
@@ -1341,8 +1284,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
1341 // For compatible surfaces, we can just do fast glCopyImageSubData based copy 1284 // For compatible surfaces, we can just do fast glCopyImageSubData based copy
1342 if (old_params.target == new_params.target && old_params.type == new_params.type && 1285 if (old_params.target == new_params.target && old_params.type == new_params.type &&
1343 old_params.depth == new_params.depth && old_params.depth == 1 && 1286 old_params.depth == new_params.depth && old_params.depth == 1 &&
1344 SurfaceParams::GetFormatBpp(old_params.pixel_format) == 1287 GetFormatBpp(old_params.pixel_format) == GetFormatBpp(new_params.pixel_format)) {
1345 SurfaceParams::GetFormatBpp(new_params.pixel_format)) {
1346 FastCopySurface(old_surface, new_surface); 1288 FastCopySurface(old_surface, new_surface);
1347 return new_surface; 1289 return new_surface;
1348 } 1290 }
@@ -1355,15 +1297,15 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
1355 const bool is_blit{old_params.pixel_format == new_params.pixel_format}; 1297 const bool is_blit{old_params.pixel_format == new_params.pixel_format};
1356 1298
1357 switch (new_params.target) { 1299 switch (new_params.target) {
1358 case SurfaceParams::SurfaceTarget::Texture2D: 1300 case SurfaceTarget::Texture2D:
1359 if (is_blit) { 1301 if (is_blit) {
1360 BlitSurface(old_surface, new_surface, read_framebuffer.handle, draw_framebuffer.handle); 1302 BlitSurface(old_surface, new_surface, read_framebuffer.handle, draw_framebuffer.handle);
1361 } else { 1303 } else {
1362 CopySurface(old_surface, new_surface, copy_pbo.handle); 1304 CopySurface(old_surface, new_surface, copy_pbo.handle);
1363 } 1305 }
1364 break; 1306 break;
1365 case SurfaceParams::SurfaceTarget::TextureCubemap: 1307 case SurfaceTarget::TextureCubemap:
1366 case SurfaceParams::SurfaceTarget::Texture3D: 1308 case SurfaceTarget::Texture3D:
1367 AccurateCopySurface(old_surface, new_surface); 1309 AccurateCopySurface(old_surface, new_surface);
1368 break; 1310 break;
1369 default: 1311 default:
@@ -1373,7 +1315,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
1373 } 1315 }
1374 1316
1375 return new_surface; 1317 return new_surface;
1376} // namespace OpenGL 1318}
1377 1319
1378Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr addr) const { 1320Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr addr) const {
1379 return TryGet(addr); 1321 return TryGet(addr);
diff --git a/src/video_core/renderer_opengl/gl_rasterizer_cache.h b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
index e72f4f2d2..f255f4419 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer_cache.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer_cache.h
@@ -7,6 +7,7 @@
7#include <array> 7#include <array>
8#include <map> 8#include <map>
9#include <memory> 9#include <memory>
10#include <string>
10#include <vector> 11#include <vector>
11 12
12#include "common/alignment.h" 13#include "common/alignment.h"
@@ -18,6 +19,7 @@
18#include "video_core/rasterizer_cache.h" 19#include "video_core/rasterizer_cache.h"
19#include "video_core/renderer_opengl/gl_resource_manager.h" 20#include "video_core/renderer_opengl/gl_resource_manager.h"
20#include "video_core/renderer_opengl/gl_shader_gen.h" 21#include "video_core/renderer_opengl/gl_shader_gen.h"
22#include "video_core/surface.h"
21#include "video_core/textures/decoders.h" 23#include "video_core/textures/decoders.h"
22#include "video_core/textures/texture.h" 24#include "video_core/textures/texture.h"
23 25
@@ -27,135 +29,12 @@ class CachedSurface;
27using Surface = std::shared_ptr<CachedSurface>; 29using Surface = std::shared_ptr<CachedSurface>;
28using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>; 30using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>;
29 31
30struct SurfaceParams { 32using SurfaceTarget = VideoCore::Surface::SurfaceTarget;
31 enum class PixelFormat { 33using SurfaceType = VideoCore::Surface::SurfaceType;
32 ABGR8U = 0, 34using PixelFormat = VideoCore::Surface::PixelFormat;
33 ABGR8S = 1, 35using ComponentType = VideoCore::Surface::ComponentType;
34 ABGR8UI = 2,
35 B5G6R5U = 3,
36 A2B10G10R10U = 4,
37 A1B5G5R5U = 5,
38 R8U = 6,
39 R8UI = 7,
40 RGBA16F = 8,
41 RGBA16U = 9,
42 RGBA16UI = 10,
43 R11FG11FB10F = 11,
44 RGBA32UI = 12,
45 DXT1 = 13,
46 DXT23 = 14,
47 DXT45 = 15,
48 DXN1 = 16, // This is also known as BC4
49 DXN2UNORM = 17,
50 DXN2SNORM = 18,
51 BC7U = 19,
52 BC6H_UF16 = 20,
53 BC6H_SF16 = 21,
54 ASTC_2D_4X4 = 22,
55 G8R8U = 23,
56 G8R8S = 24,
57 BGRA8 = 25,
58 RGBA32F = 26,
59 RG32F = 27,
60 R32F = 28,
61 R16F = 29,
62 R16U = 30,
63 R16S = 31,
64 R16UI = 32,
65 R16I = 33,
66 RG16 = 34,
67 RG16F = 35,
68 RG16UI = 36,
69 RG16I = 37,
70 RG16S = 38,
71 RGB32F = 39,
72 RGBA8_SRGB = 40,
73 RG8U = 41,
74 RG8S = 42,
75 RG32UI = 43,
76 R32UI = 44,
77 ASTC_2D_8X8 = 45,
78 ASTC_2D_8X5 = 46,
79 ASTC_2D_5X4 = 47,
80 BGRA8_SRGB = 48,
81 DXT1_SRGB = 49,
82 DXT23_SRGB = 50,
83 DXT45_SRGB = 51,
84 BC7U_SRGB = 52,
85 ASTC_2D_4X4_SRGB = 53,
86 ASTC_2D_8X8_SRGB = 54,
87 ASTC_2D_8X5_SRGB = 55,
88 ASTC_2D_5X4_SRGB = 56,
89
90 MaxColorFormat,
91
92 // Depth formats
93 Z32F = 57,
94 Z16 = 58,
95
96 MaxDepthFormat,
97
98 // DepthStencil formats
99 Z24S8 = 59,
100 S8Z24 = 60,
101 Z32FS8 = 61,
102
103 MaxDepthStencilFormat,
104
105 Max = MaxDepthStencilFormat,
106 Invalid = 255,
107 };
108
109 static constexpr std::size_t MaxPixelFormat = static_cast<std::size_t>(PixelFormat::Max);
110
111 enum class ComponentType {
112 Invalid = 0,
113 SNorm = 1,
114 UNorm = 2,
115 SInt = 3,
116 UInt = 4,
117 Float = 5,
118 };
119
120 enum class SurfaceType {
121 ColorTexture = 0,
122 Depth = 1,
123 DepthStencil = 2,
124 Fill = 3,
125 Invalid = 4,
126 };
127
128 enum class SurfaceTarget {
129 Texture1D,
130 Texture2D,
131 Texture3D,
132 Texture1DArray,
133 Texture2DArray,
134 TextureCubemap,
135 };
136
137 static SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type) {
138 switch (texture_type) {
139 case Tegra::Texture::TextureType::Texture1D:
140 return SurfaceTarget::Texture1D;
141 case Tegra::Texture::TextureType::Texture2D:
142 case Tegra::Texture::TextureType::Texture2DNoMipmap:
143 return SurfaceTarget::Texture2D;
144 case Tegra::Texture::TextureType::Texture3D:
145 return SurfaceTarget::Texture3D;
146 case Tegra::Texture::TextureType::TextureCubemap:
147 return SurfaceTarget::TextureCubemap;
148 case Tegra::Texture::TextureType::Texture1DArray:
149 return SurfaceTarget::Texture1DArray;
150 case Tegra::Texture::TextureType::Texture2DArray:
151 return SurfaceTarget::Texture2DArray;
152 default:
153 LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", static_cast<u32>(texture_type));
154 UNREACHABLE();
155 return SurfaceTarget::Texture2D;
156 }
157 }
158 36
37struct SurfaceParams {
159 static std::string SurfaceTargetName(SurfaceTarget target) { 38 static std::string SurfaceTargetName(SurfaceTarget target) {
160 switch (target) { 39 switch (target) {
161 case SurfaceTarget::Texture1D: 40 case SurfaceTarget::Texture1D:
@@ -177,660 +56,8 @@ struct SurfaceParams {
177 } 56 }
178 } 57 }
179 58
180 static bool SurfaceTargetIsLayered(SurfaceTarget target) {
181 switch (target) {
182 case SurfaceTarget::Texture1D:
183 case SurfaceTarget::Texture2D:
184 case SurfaceTarget::Texture3D:
185 return false;
186 case SurfaceTarget::Texture1DArray:
187 case SurfaceTarget::Texture2DArray:
188 case SurfaceTarget::TextureCubemap:
189 return true;
190 default:
191 LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
192 UNREACHABLE();
193 return false;
194 }
195 }
196
197 /**
198 * Gets the compression factor for the specified PixelFormat. This applies to just the
199 * "compressed width" and "compressed height", not the overall compression factor of a
200 * compressed image. This is used for maintaining proper surface sizes for compressed
201 * texture formats.
202 */
203 static constexpr u32 GetCompressionFactor(PixelFormat format) {
204 if (format == PixelFormat::Invalid)
205 return 0;
206
207 constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{
208 1, // ABGR8U
209 1, // ABGR8S
210 1, // ABGR8UI
211 1, // B5G6R5U
212 1, // A2B10G10R10U
213 1, // A1B5G5R5U
214 1, // R8U
215 1, // R8UI
216 1, // RGBA16F
217 1, // RGBA16U
218 1, // RGBA16UI
219 1, // R11FG11FB10F
220 1, // RGBA32UI
221 4, // DXT1
222 4, // DXT23
223 4, // DXT45
224 4, // DXN1
225 4, // DXN2UNORM
226 4, // DXN2SNORM
227 4, // BC7U
228 4, // BC6H_UF16
229 4, // BC6H_SF16
230 4, // ASTC_2D_4X4
231 1, // G8R8U
232 1, // G8R8S
233 1, // BGRA8
234 1, // RGBA32F
235 1, // RG32F
236 1, // R32F
237 1, // R16F
238 1, // R16U
239 1, // R16S
240 1, // R16UI
241 1, // R16I
242 1, // RG16
243 1, // RG16F
244 1, // RG16UI
245 1, // RG16I
246 1, // RG16S
247 1, // RGB32F
248 1, // RGBA8_SRGB
249 1, // RG8U
250 1, // RG8S
251 1, // RG32UI
252 1, // R32UI
253 4, // ASTC_2D_8X8
254 4, // ASTC_2D_8X5
255 4, // ASTC_2D_5X4
256 1, // BGRA8_SRGB
257 4, // DXT1_SRGB
258 4, // DXT23_SRGB
259 4, // DXT45_SRGB
260 4, // BC7U_SRGB
261 4, // ASTC_2D_4X4_SRGB
262 4, // ASTC_2D_8X8_SRGB
263 4, // ASTC_2D_8X5_SRGB
264 4, // ASTC_2D_5X4_SRGB
265 1, // Z32F
266 1, // Z16
267 1, // Z24S8
268 1, // S8Z24
269 1, // Z32FS8
270 }};
271
272 ASSERT(static_cast<std::size_t>(format) < compression_factor_table.size());
273 return compression_factor_table[static_cast<std::size_t>(format)];
274 }
275
276 static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
277 if (format == PixelFormat::Invalid)
278 return 0;
279 constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
280 1, // ABGR8U
281 1, // ABGR8S
282 1, // ABGR8UI
283 1, // B5G6R5U
284 1, // A2B10G10R10U
285 1, // A1B5G5R5U
286 1, // R8U
287 1, // R8UI
288 1, // RGBA16F
289 1, // RGBA16U
290 1, // RGBA16UI
291 1, // R11FG11FB10F
292 1, // RGBA32UI
293 4, // DXT1
294 4, // DXT23
295 4, // DXT45
296 4, // DXN1
297 4, // DXN2UNORM
298 4, // DXN2SNORM
299 4, // BC7U
300 4, // BC6H_UF16
301 4, // BC6H_SF16
302 4, // ASTC_2D_4X4
303 1, // G8R8U
304 1, // G8R8S
305 1, // BGRA8
306 1, // RGBA32F
307 1, // RG32F
308 1, // R32F
309 1, // R16F
310 1, // R16U
311 1, // R16S
312 1, // R16UI
313 1, // R16I
314 1, // RG16
315 1, // RG16F
316 1, // RG16UI
317 1, // RG16I
318 1, // RG16S
319 1, // RGB32F
320 1, // RGBA8_SRGB
321 1, // RG8U
322 1, // RG8S
323 1, // RG32UI
324 1, // R32UI
325 8, // ASTC_2D_8X8
326 5, // ASTC_2D_8X5
327 4, // ASTC_2D_5X4
328 1, // BGRA8_SRGB
329 4, // DXT1_SRGB
330 4, // DXT23_SRGB
331 4, // DXT45_SRGB
332 4, // BC7U_SRGB
333 4, // ASTC_2D_4X4_SRGB
334 8, // ASTC_2D_8X8_SRGB
335 5, // ASTC_2D_8X5_SRGB
336 4, // ASTC_2D_5X4_SRGB
337 1, // Z32F
338 1, // Z16
339 1, // Z24S8
340 1, // S8Z24
341 1, // Z32FS8
342 }};
343 ASSERT(static_cast<std::size_t>(format) < block_height_table.size());
344 return block_height_table[static_cast<std::size_t>(format)];
345 }
346
347 static constexpr u32 GetFormatBpp(PixelFormat format) {
348 if (format == PixelFormat::Invalid)
349 return 0;
350
351 constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
352 32, // ABGR8U
353 32, // ABGR8S
354 32, // ABGR8UI
355 16, // B5G6R5U
356 32, // A2B10G10R10U
357 16, // A1B5G5R5U
358 8, // R8U
359 8, // R8UI
360 64, // RGBA16F
361 64, // RGBA16U
362 64, // RGBA16UI
363 32, // R11FG11FB10F
364 128, // RGBA32UI
365 64, // DXT1
366 128, // DXT23
367 128, // DXT45
368 64, // DXN1
369 128, // DXN2UNORM
370 128, // DXN2SNORM
371 128, // BC7U
372 128, // BC6H_UF16
373 128, // BC6H_SF16
374 32, // ASTC_2D_4X4
375 16, // G8R8U
376 16, // G8R8S
377 32, // BGRA8
378 128, // RGBA32F
379 64, // RG32F
380 32, // R32F
381 16, // R16F
382 16, // R16U
383 16, // R16S
384 16, // R16UI
385 16, // R16I
386 32, // RG16
387 32, // RG16F
388 32, // RG16UI
389 32, // RG16I
390 32, // RG16S
391 96, // RGB32F
392 32, // RGBA8_SRGB
393 16, // RG8U
394 16, // RG8S
395 64, // RG32UI
396 32, // R32UI
397 16, // ASTC_2D_8X8
398 16, // ASTC_2D_8X5
399 32, // ASTC_2D_5X4
400 32, // BGRA8_SRGB
401 64, // DXT1_SRGB
402 128, // DXT23_SRGB
403 128, // DXT45_SRGB
404 128, // BC7U
405 32, // ASTC_2D_4X4_SRGB
406 16, // ASTC_2D_8X8_SRGB
407 16, // ASTC_2D_8X5_SRGB
408 32, // ASTC_2D_5X4_SRGB
409 32, // Z32F
410 16, // Z16
411 32, // Z24S8
412 32, // S8Z24
413 64, // Z32FS8
414 }};
415
416 ASSERT(static_cast<std::size_t>(format) < bpp_table.size());
417 return bpp_table[static_cast<std::size_t>(format)];
418 }
419
420 u32 GetFormatBpp() const { 59 u32 GetFormatBpp() const {
421 return GetFormatBpp(pixel_format); 60 return VideoCore::Surface::GetFormatBpp(pixel_format);
422 }
423
424 static PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
425 switch (format) {
426 case Tegra::DepthFormat::S8_Z24_UNORM:
427 return PixelFormat::S8Z24;
428 case Tegra::DepthFormat::Z24_S8_UNORM:
429 return PixelFormat::Z24S8;
430 case Tegra::DepthFormat::Z32_FLOAT:
431 return PixelFormat::Z32F;
432 case Tegra::DepthFormat::Z16_UNORM:
433 return PixelFormat::Z16;
434 case Tegra::DepthFormat::Z32_S8_X24_FLOAT:
435 return PixelFormat::Z32FS8;
436 default:
437 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
438 UNREACHABLE();
439 }
440 }
441
442 static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
443 switch (format) {
444 // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the
445 // gamma.
446 case Tegra::RenderTargetFormat::RGBA8_SRGB:
447 return PixelFormat::RGBA8_SRGB;
448 case Tegra::RenderTargetFormat::RGBA8_UNORM:
449 return PixelFormat::ABGR8U;
450 case Tegra::RenderTargetFormat::RGBA8_SNORM:
451 return PixelFormat::ABGR8S;
452 case Tegra::RenderTargetFormat::RGBA8_UINT:
453 return PixelFormat::ABGR8UI;
454 case Tegra::RenderTargetFormat::BGRA8_SRGB:
455 return PixelFormat::BGRA8_SRGB;
456 case Tegra::RenderTargetFormat::BGRA8_UNORM:
457 return PixelFormat::BGRA8;
458 case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
459 return PixelFormat::A2B10G10R10U;
460 case Tegra::RenderTargetFormat::RGBA16_FLOAT:
461 return PixelFormat::RGBA16F;
462 case Tegra::RenderTargetFormat::RGBA16_UNORM:
463 return PixelFormat::RGBA16U;
464 case Tegra::RenderTargetFormat::RGBA16_UINT:
465 return PixelFormat::RGBA16UI;
466 case Tegra::RenderTargetFormat::RGBA32_FLOAT:
467 return PixelFormat::RGBA32F;
468 case Tegra::RenderTargetFormat::RG32_FLOAT:
469 return PixelFormat::RG32F;
470 case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
471 return PixelFormat::R11FG11FB10F;
472 case Tegra::RenderTargetFormat::B5G6R5_UNORM:
473 return PixelFormat::B5G6R5U;
474 case Tegra::RenderTargetFormat::BGR5A1_UNORM:
475 return PixelFormat::A1B5G5R5U;
476 case Tegra::RenderTargetFormat::RGBA32_UINT:
477 return PixelFormat::RGBA32UI;
478 case Tegra::RenderTargetFormat::R8_UNORM:
479 return PixelFormat::R8U;
480 case Tegra::RenderTargetFormat::R8_UINT:
481 return PixelFormat::R8UI;
482 case Tegra::RenderTargetFormat::RG16_FLOAT:
483 return PixelFormat::RG16F;
484 case Tegra::RenderTargetFormat::RG16_UINT:
485 return PixelFormat::RG16UI;
486 case Tegra::RenderTargetFormat::RG16_SINT:
487 return PixelFormat::RG16I;
488 case Tegra::RenderTargetFormat::RG16_UNORM:
489 return PixelFormat::RG16;
490 case Tegra::RenderTargetFormat::RG16_SNORM:
491 return PixelFormat::RG16S;
492 case Tegra::RenderTargetFormat::RG8_UNORM:
493 return PixelFormat::RG8U;
494 case Tegra::RenderTargetFormat::RG8_SNORM:
495 return PixelFormat::RG8S;
496 case Tegra::RenderTargetFormat::R16_FLOAT:
497 return PixelFormat::R16F;
498 case Tegra::RenderTargetFormat::R16_UNORM:
499 return PixelFormat::R16U;
500 case Tegra::RenderTargetFormat::R16_SNORM:
501 return PixelFormat::R16S;
502 case Tegra::RenderTargetFormat::R16_UINT:
503 return PixelFormat::R16UI;
504 case Tegra::RenderTargetFormat::R16_SINT:
505 return PixelFormat::R16I;
506 case Tegra::RenderTargetFormat::R32_FLOAT:
507 return PixelFormat::R32F;
508 case Tegra::RenderTargetFormat::R32_UINT:
509 return PixelFormat::R32UI;
510 case Tegra::RenderTargetFormat::RG32_UINT:
511 return PixelFormat::RG32UI;
512 default:
513 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
514 UNREACHABLE();
515 }
516 }
517
518 static PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
519 Tegra::Texture::ComponentType component_type,
520 bool is_srgb) {
521 // TODO(Subv): Properly implement this
522 switch (format) {
523 case Tegra::Texture::TextureFormat::A8R8G8B8:
524 if (is_srgb) {
525 return PixelFormat::RGBA8_SRGB;
526 }
527 switch (component_type) {
528 case Tegra::Texture::ComponentType::UNORM:
529 return PixelFormat::ABGR8U;
530 case Tegra::Texture::ComponentType::SNORM:
531 return PixelFormat::ABGR8S;
532 case Tegra::Texture::ComponentType::UINT:
533 return PixelFormat::ABGR8UI;
534 }
535 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
536 static_cast<u32>(component_type));
537 UNREACHABLE();
538 case Tegra::Texture::TextureFormat::B5G6R5:
539 switch (component_type) {
540 case Tegra::Texture::ComponentType::UNORM:
541 return PixelFormat::B5G6R5U;
542 }
543 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
544 static_cast<u32>(component_type));
545 UNREACHABLE();
546 case Tegra::Texture::TextureFormat::A2B10G10R10:
547 switch (component_type) {
548 case Tegra::Texture::ComponentType::UNORM:
549 return PixelFormat::A2B10G10R10U;
550 }
551 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
552 static_cast<u32>(component_type));
553 UNREACHABLE();
554 case Tegra::Texture::TextureFormat::A1B5G5R5:
555 switch (component_type) {
556 case Tegra::Texture::ComponentType::UNORM:
557 return PixelFormat::A1B5G5R5U;
558 }
559 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
560 static_cast<u32>(component_type));
561 UNREACHABLE();
562 case Tegra::Texture::TextureFormat::R8:
563 switch (component_type) {
564 case Tegra::Texture::ComponentType::UNORM:
565 return PixelFormat::R8U;
566 case Tegra::Texture::ComponentType::UINT:
567 return PixelFormat::R8UI;
568 }
569 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
570 static_cast<u32>(component_type));
571 UNREACHABLE();
572 case Tegra::Texture::TextureFormat::G8R8:
573 switch (component_type) {
574 case Tegra::Texture::ComponentType::UNORM:
575 return PixelFormat::G8R8U;
576 case Tegra::Texture::ComponentType::SNORM:
577 return PixelFormat::G8R8S;
578 }
579 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
580 static_cast<u32>(component_type));
581 UNREACHABLE();
582 case Tegra::Texture::TextureFormat::R16_G16_B16_A16:
583 switch (component_type) {
584 case Tegra::Texture::ComponentType::UNORM:
585 return PixelFormat::RGBA16U;
586 case Tegra::Texture::ComponentType::FLOAT:
587 return PixelFormat::RGBA16F;
588 }
589 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
590 static_cast<u32>(component_type));
591 UNREACHABLE();
592 case Tegra::Texture::TextureFormat::BF10GF11RF11:
593 switch (component_type) {
594 case Tegra::Texture::ComponentType::FLOAT:
595 return PixelFormat::R11FG11FB10F;
596 }
597 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
598 static_cast<u32>(component_type));
599 UNREACHABLE();
600 case Tegra::Texture::TextureFormat::R32_G32_B32_A32:
601 switch (component_type) {
602 case Tegra::Texture::ComponentType::FLOAT:
603 return PixelFormat::RGBA32F;
604 case Tegra::Texture::ComponentType::UINT:
605 return PixelFormat::RGBA32UI;
606 }
607 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
608 static_cast<u32>(component_type));
609 UNREACHABLE();
610 case Tegra::Texture::TextureFormat::R32_G32:
611 switch (component_type) {
612 case Tegra::Texture::ComponentType::FLOAT:
613 return PixelFormat::RG32F;
614 case Tegra::Texture::ComponentType::UINT:
615 return PixelFormat::RG32UI;
616 }
617 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
618 static_cast<u32>(component_type));
619 UNREACHABLE();
620 case Tegra::Texture::TextureFormat::R32_G32_B32:
621 switch (component_type) {
622 case Tegra::Texture::ComponentType::FLOAT:
623 return PixelFormat::RGB32F;
624 }
625 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
626 static_cast<u32>(component_type));
627 UNREACHABLE();
628 case Tegra::Texture::TextureFormat::R16:
629 switch (component_type) {
630 case Tegra::Texture::ComponentType::FLOAT:
631 return PixelFormat::R16F;
632 case Tegra::Texture::ComponentType::UNORM:
633 return PixelFormat::R16U;
634 case Tegra::Texture::ComponentType::SNORM:
635 return PixelFormat::R16S;
636 case Tegra::Texture::ComponentType::UINT:
637 return PixelFormat::R16UI;
638 case Tegra::Texture::ComponentType::SINT:
639 return PixelFormat::R16I;
640 }
641 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
642 static_cast<u32>(component_type));
643 UNREACHABLE();
644 case Tegra::Texture::TextureFormat::R32:
645 switch (component_type) {
646 case Tegra::Texture::ComponentType::FLOAT:
647 return PixelFormat::R32F;
648 case Tegra::Texture::ComponentType::UINT:
649 return PixelFormat::R32UI;
650 }
651 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
652 static_cast<u32>(component_type));
653 UNREACHABLE();
654 case Tegra::Texture::TextureFormat::ZF32:
655 return PixelFormat::Z32F;
656 case Tegra::Texture::TextureFormat::Z16:
657 return PixelFormat::Z16;
658 case Tegra::Texture::TextureFormat::Z24S8:
659 return PixelFormat::Z24S8;
660 case Tegra::Texture::TextureFormat::DXT1:
661 return is_srgb ? PixelFormat::DXT1_SRGB : PixelFormat::DXT1;
662 case Tegra::Texture::TextureFormat::DXT23:
663 return is_srgb ? PixelFormat::DXT23_SRGB : PixelFormat::DXT23;
664 case Tegra::Texture::TextureFormat::DXT45:
665 return is_srgb ? PixelFormat::DXT45_SRGB : PixelFormat::DXT45;
666 case Tegra::Texture::TextureFormat::DXN1:
667 return PixelFormat::DXN1;
668 case Tegra::Texture::TextureFormat::DXN2:
669 switch (component_type) {
670 case Tegra::Texture::ComponentType::UNORM:
671 return PixelFormat::DXN2UNORM;
672 case Tegra::Texture::ComponentType::SNORM:
673 return PixelFormat::DXN2SNORM;
674 }
675 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
676 static_cast<u32>(component_type));
677 UNREACHABLE();
678 case Tegra::Texture::TextureFormat::BC7U:
679 return is_srgb ? PixelFormat::BC7U_SRGB : PixelFormat::BC7U;
680 case Tegra::Texture::TextureFormat::BC6H_UF16:
681 return PixelFormat::BC6H_UF16;
682 case Tegra::Texture::TextureFormat::BC6H_SF16:
683 return PixelFormat::BC6H_SF16;
684 case Tegra::Texture::TextureFormat::ASTC_2D_4X4:
685 return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4;
686 case Tegra::Texture::TextureFormat::ASTC_2D_5X4:
687 return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4;
688 case Tegra::Texture::TextureFormat::ASTC_2D_8X8:
689 return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8;
690 case Tegra::Texture::TextureFormat::ASTC_2D_8X5:
691 return is_srgb ? PixelFormat::ASTC_2D_8X5_SRGB : PixelFormat::ASTC_2D_8X5;
692 case Tegra::Texture::TextureFormat::R16_G16:
693 switch (component_type) {
694 case Tegra::Texture::ComponentType::FLOAT:
695 return PixelFormat::RG16F;
696 case Tegra::Texture::ComponentType::UNORM:
697 return PixelFormat::RG16;
698 case Tegra::Texture::ComponentType::SNORM:
699 return PixelFormat::RG16S;
700 case Tegra::Texture::ComponentType::UINT:
701 return PixelFormat::RG16UI;
702 case Tegra::Texture::ComponentType::SINT:
703 return PixelFormat::RG16I;
704 }
705 LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
706 static_cast<u32>(component_type));
707 UNREACHABLE();
708 default:
709 LOG_CRITICAL(HW_GPU, "Unimplemented format={}, component_type={}",
710 static_cast<u32>(format), static_cast<u32>(component_type));
711 UNREACHABLE();
712 }
713 }
714
715 static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
716 // TODO(Subv): Implement more component types
717 switch (type) {
718 case Tegra::Texture::ComponentType::UNORM:
719 return ComponentType::UNorm;
720 case Tegra::Texture::ComponentType::FLOAT:
721 return ComponentType::Float;
722 case Tegra::Texture::ComponentType::SNORM:
723 return ComponentType::SNorm;
724 case Tegra::Texture::ComponentType::UINT:
725 return ComponentType::UInt;
726 case Tegra::Texture::ComponentType::SINT:
727 return ComponentType::SInt;
728 default:
729 LOG_CRITICAL(HW_GPU, "Unimplemented component type={}", static_cast<u32>(type));
730 UNREACHABLE();
731 }
732 }
733
734 static ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format) {
735 // TODO(Subv): Implement more render targets
736 switch (format) {
737 case Tegra::RenderTargetFormat::RGBA8_UNORM:
738 case Tegra::RenderTargetFormat::RGBA8_SRGB:
739 case Tegra::RenderTargetFormat::BGRA8_UNORM:
740 case Tegra::RenderTargetFormat::BGRA8_SRGB:
741 case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
742 case Tegra::RenderTargetFormat::R8_UNORM:
743 case Tegra::RenderTargetFormat::RG16_UNORM:
744 case Tegra::RenderTargetFormat::R16_UNORM:
745 case Tegra::RenderTargetFormat::B5G6R5_UNORM:
746 case Tegra::RenderTargetFormat::BGR5A1_UNORM:
747 case Tegra::RenderTargetFormat::RG8_UNORM:
748 case Tegra::RenderTargetFormat::RGBA16_UNORM:
749 return ComponentType::UNorm;
750 case Tegra::RenderTargetFormat::RGBA8_SNORM:
751 case Tegra::RenderTargetFormat::RG16_SNORM:
752 case Tegra::RenderTargetFormat::R16_SNORM:
753 case Tegra::RenderTargetFormat::RG8_SNORM:
754 return ComponentType::SNorm;
755 case Tegra::RenderTargetFormat::RGBA16_FLOAT:
756 case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
757 case Tegra::RenderTargetFormat::RGBA32_FLOAT:
758 case Tegra::RenderTargetFormat::RG32_FLOAT:
759 case Tegra::RenderTargetFormat::RG16_FLOAT:
760 case Tegra::RenderTargetFormat::R16_FLOAT:
761 case Tegra::RenderTargetFormat::R32_FLOAT:
762 return ComponentType::Float;
763 case Tegra::RenderTargetFormat::RGBA32_UINT:
764 case Tegra::RenderTargetFormat::RGBA16_UINT:
765 case Tegra::RenderTargetFormat::RG16_UINT:
766 case Tegra::RenderTargetFormat::R8_UINT:
767 case Tegra::RenderTargetFormat::R16_UINT:
768 case Tegra::RenderTargetFormat::RG32_UINT:
769 case Tegra::RenderTargetFormat::R32_UINT:
770 case Tegra::RenderTargetFormat::RGBA8_UINT:
771 return ComponentType::UInt;
772 case Tegra::RenderTargetFormat::RG16_SINT:
773 case Tegra::RenderTargetFormat::R16_SINT:
774 return ComponentType::SInt;
775 default:
776 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
777 UNREACHABLE();
778 }
779 }
780
781 static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) {
782 switch (format) {
783 case Tegra::FramebufferConfig::PixelFormat::ABGR8:
784 return PixelFormat::ABGR8U;
785 default:
786 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
787 UNREACHABLE();
788 }
789 }
790
791 static ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) {
792 switch (format) {
793 case Tegra::DepthFormat::Z16_UNORM:
794 case Tegra::DepthFormat::S8_Z24_UNORM:
795 case Tegra::DepthFormat::Z24_S8_UNORM:
796 return ComponentType::UNorm;
797 case Tegra::DepthFormat::Z32_FLOAT:
798 case Tegra::DepthFormat::Z32_S8_X24_FLOAT:
799 return ComponentType::Float;
800 default:
801 LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
802 UNREACHABLE();
803 }
804 }
805
806 static SurfaceType GetFormatType(PixelFormat pixel_format) {
807 if (static_cast<std::size_t>(pixel_format) <
808 static_cast<std::size_t>(PixelFormat::MaxColorFormat)) {
809 return SurfaceType::ColorTexture;
810 }
811
812 if (static_cast<std::size_t>(pixel_format) <
813 static_cast<std::size_t>(PixelFormat::MaxDepthFormat)) {
814 return SurfaceType::Depth;
815 }
816
817 if (static_cast<std::size_t>(pixel_format) <
818 static_cast<std::size_t>(PixelFormat::MaxDepthStencilFormat)) {
819 return SurfaceType::DepthStencil;
820 }
821
822 // TODO(Subv): Implement the other formats
823 ASSERT(false);
824
825 return SurfaceType::Invalid;
826 }
827
828 /// Returns the sizer in bytes of the specified pixel format
829 static constexpr u32 GetBytesPerPixel(PixelFormat pixel_format) {
830 if (pixel_format == SurfaceParams::PixelFormat::Invalid) {
831 return 0;
832 }
833 return GetFormatBpp(pixel_format) / CHAR_BIT;
834 } 61 }
835 62
836 /// Returns the rectangle corresponding to this surface 63 /// Returns the rectangle corresponding to this surface
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
diff --git a/src/video_core/surface.h b/src/video_core/surface.h
new file mode 100644
index 000000000..3232e437f
--- /dev/null
+++ b/src/video_core/surface.h
@@ -0,0 +1,385 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <climits>
8#include <utility>
9#include "common/assert.h"
10#include "common/common_types.h"
11#include "common/logging/log.h"
12#include "video_core/gpu.h"
13#include "video_core/textures/texture.h"
14
15namespace VideoCore::Surface {
16
17enum class PixelFormat {
18 ABGR8U = 0,
19 ABGR8S = 1,
20 ABGR8UI = 2,
21 B5G6R5U = 3,
22 A2B10G10R10U = 4,
23 A1B5G5R5U = 5,
24 R8U = 6,
25 R8UI = 7,
26 RGBA16F = 8,
27 RGBA16U = 9,
28 RGBA16UI = 10,
29 R11FG11FB10F = 11,
30 RGBA32UI = 12,
31 DXT1 = 13,
32 DXT23 = 14,
33 DXT45 = 15,
34 DXN1 = 16, // This is also known as BC4
35 DXN2UNORM = 17,
36 DXN2SNORM = 18,
37 BC7U = 19,
38 BC6H_UF16 = 20,
39 BC6H_SF16 = 21,
40 ASTC_2D_4X4 = 22,
41 G8R8U = 23,
42 G8R8S = 24,
43 BGRA8 = 25,
44 RGBA32F = 26,
45 RG32F = 27,
46 R32F = 28,
47 R16F = 29,
48 R16U = 30,
49 R16S = 31,
50 R16UI = 32,
51 R16I = 33,
52 RG16 = 34,
53 RG16F = 35,
54 RG16UI = 36,
55 RG16I = 37,
56 RG16S = 38,
57 RGB32F = 39,
58 RGBA8_SRGB = 40,
59 RG8U = 41,
60 RG8S = 42,
61 RG32UI = 43,
62 R32UI = 44,
63 ASTC_2D_8X8 = 45,
64 ASTC_2D_8X5 = 46,
65 ASTC_2D_5X4 = 47,
66 BGRA8_SRGB = 48,
67 DXT1_SRGB = 49,
68 DXT23_SRGB = 50,
69 DXT45_SRGB = 51,
70 BC7U_SRGB = 52,
71 ASTC_2D_4X4_SRGB = 53,
72 ASTC_2D_8X8_SRGB = 54,
73 ASTC_2D_8X5_SRGB = 55,
74 ASTC_2D_5X4_SRGB = 56,
75
76 MaxColorFormat,
77
78 // Depth formats
79 Z32F = 57,
80 Z16 = 58,
81
82 MaxDepthFormat,
83
84 // DepthStencil formats
85 Z24S8 = 59,
86 S8Z24 = 60,
87 Z32FS8 = 61,
88
89 MaxDepthStencilFormat,
90
91 Max = MaxDepthStencilFormat,
92 Invalid = 255,
93};
94
95static constexpr std::size_t MaxPixelFormat = static_cast<std::size_t>(PixelFormat::Max);
96
97enum class ComponentType {
98 Invalid = 0,
99 SNorm = 1,
100 UNorm = 2,
101 SInt = 3,
102 UInt = 4,
103 Float = 5,
104};
105
106enum class SurfaceType {
107 ColorTexture = 0,
108 Depth = 1,
109 DepthStencil = 2,
110 Fill = 3,
111 Invalid = 4,
112};
113
114enum class SurfaceTarget {
115 Texture1D,
116 Texture2D,
117 Texture3D,
118 Texture1DArray,
119 Texture2DArray,
120 TextureCubemap,
121};
122
123/**
124 * Gets the compression factor for the specified PixelFormat. This applies to just the
125 * "compressed width" and "compressed height", not the overall compression factor of a
126 * compressed image. This is used for maintaining proper surface sizes for compressed
127 * texture formats.
128 */
129static constexpr u32 GetCompressionFactor(PixelFormat format) {
130 if (format == PixelFormat::Invalid)
131 return 0;
132
133 constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{
134 1, // ABGR8U
135 1, // ABGR8S
136 1, // ABGR8UI
137 1, // B5G6R5U
138 1, // A2B10G10R10U
139 1, // A1B5G5R5U
140 1, // R8U
141 1, // R8UI
142 1, // RGBA16F
143 1, // RGBA16U
144 1, // RGBA16UI
145 1, // R11FG11FB10F
146 1, // RGBA32UI
147 4, // DXT1
148 4, // DXT23
149 4, // DXT45
150 4, // DXN1
151 4, // DXN2UNORM
152 4, // DXN2SNORM
153 4, // BC7U
154 4, // BC6H_UF16
155 4, // BC6H_SF16
156 4, // ASTC_2D_4X4
157 1, // G8R8U
158 1, // G8R8S
159 1, // BGRA8
160 1, // RGBA32F
161 1, // RG32F
162 1, // R32F
163 1, // R16F
164 1, // R16U
165 1, // R16S
166 1, // R16UI
167 1, // R16I
168 1, // RG16
169 1, // RG16F
170 1, // RG16UI
171 1, // RG16I
172 1, // RG16S
173 1, // RGB32F
174 1, // RGBA8_SRGB
175 1, // RG8U
176 1, // RG8S
177 1, // RG32UI
178 1, // R32UI
179 4, // ASTC_2D_8X8
180 4, // ASTC_2D_8X5
181 4, // ASTC_2D_5X4
182 1, // BGRA8_SRGB
183 4, // DXT1_SRGB
184 4, // DXT23_SRGB
185 4, // DXT45_SRGB
186 4, // BC7U_SRGB
187 4, // ASTC_2D_4X4_SRGB
188 4, // ASTC_2D_8X8_SRGB
189 4, // ASTC_2D_8X5_SRGB
190 4, // ASTC_2D_5X4_SRGB
191 1, // Z32F
192 1, // Z16
193 1, // Z24S8
194 1, // S8Z24
195 1, // Z32FS8
196 }};
197
198 ASSERT(static_cast<std::size_t>(format) < compression_factor_table.size());
199 return compression_factor_table[static_cast<std::size_t>(format)];
200}
201
202static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
203 if (format == PixelFormat::Invalid)
204 return 0;
205
206 constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
207 1, // ABGR8U
208 1, // ABGR8S
209 1, // ABGR8UI
210 1, // B5G6R5U
211 1, // A2B10G10R10U
212 1, // A1B5G5R5U
213 1, // R8U
214 1, // R8UI
215 1, // RGBA16F
216 1, // RGBA16U
217 1, // RGBA16UI
218 1, // R11FG11FB10F
219 1, // RGBA32UI
220 4, // DXT1
221 4, // DXT23
222 4, // DXT45
223 4, // DXN1
224 4, // DXN2UNORM
225 4, // DXN2SNORM
226 4, // BC7U
227 4, // BC6H_UF16
228 4, // BC6H_SF16
229 4, // ASTC_2D_4X4
230 1, // G8R8U
231 1, // G8R8S
232 1, // BGRA8
233 1, // RGBA32F
234 1, // RG32F
235 1, // R32F
236 1, // R16F
237 1, // R16U
238 1, // R16S
239 1, // R16UI
240 1, // R16I
241 1, // RG16
242 1, // RG16F
243 1, // RG16UI
244 1, // RG16I
245 1, // RG16S
246 1, // RGB32F
247 1, // RGBA8_SRGB
248 1, // RG8U
249 1, // RG8S
250 1, // RG32UI
251 1, // R32UI
252 8, // ASTC_2D_8X8
253 5, // ASTC_2D_8X5
254 4, // ASTC_2D_5X4
255 1, // BGRA8_SRGB
256 4, // DXT1_SRGB
257 4, // DXT23_SRGB
258 4, // DXT45_SRGB
259 4, // BC7U_SRGB
260 4, // ASTC_2D_4X4_SRGB
261 8, // ASTC_2D_8X8_SRGB
262 5, // ASTC_2D_8X5_SRGB
263 4, // ASTC_2D_5X4_SRGB
264 1, // Z32F
265 1, // Z16
266 1, // Z24S8
267 1, // S8Z24
268 1, // Z32FS8
269 }};
270
271 ASSERT(static_cast<std::size_t>(format) < block_height_table.size());
272 return block_height_table[static_cast<std::size_t>(format)];
273}
274
275static constexpr u32 GetFormatBpp(PixelFormat format) {
276 if (format == PixelFormat::Invalid)
277 return 0;
278
279 constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
280 32, // ABGR8U
281 32, // ABGR8S
282 32, // ABGR8UI
283 16, // B5G6R5U
284 32, // A2B10G10R10U
285 16, // A1B5G5R5U
286 8, // R8U
287 8, // R8UI
288 64, // RGBA16F
289 64, // RGBA16U
290 64, // RGBA16UI
291 32, // R11FG11FB10F
292 128, // RGBA32UI
293 64, // DXT1
294 128, // DXT23
295 128, // DXT45
296 64, // DXN1
297 128, // DXN2UNORM
298 128, // DXN2SNORM
299 128, // BC7U
300 128, // BC6H_UF16
301 128, // BC6H_SF16
302 32, // ASTC_2D_4X4
303 16, // G8R8U
304 16, // G8R8S
305 32, // BGRA8
306 128, // RGBA32F
307 64, // RG32F
308 32, // R32F
309 16, // R16F
310 16, // R16U
311 16, // R16S
312 16, // R16UI
313 16, // R16I
314 32, // RG16
315 32, // RG16F
316 32, // RG16UI
317 32, // RG16I
318 32, // RG16S
319 96, // RGB32F
320 32, // RGBA8_SRGB
321 16, // RG8U
322 16, // RG8S
323 64, // RG32UI
324 32, // R32UI
325 16, // ASTC_2D_8X8
326 16, // ASTC_2D_8X5
327 32, // ASTC_2D_5X4
328 32, // BGRA8_SRGB
329 64, // DXT1_SRGB
330 128, // DXT23_SRGB
331 128, // DXT45_SRGB
332 128, // BC7U
333 32, // ASTC_2D_4X4_SRGB
334 16, // ASTC_2D_8X8_SRGB
335 16, // ASTC_2D_8X5_SRGB
336 32, // ASTC_2D_5X4_SRGB
337 32, // Z32F
338 16, // Z16
339 32, // Z24S8
340 32, // S8Z24
341 64, // Z32FS8
342 }};
343
344 ASSERT(static_cast<std::size_t>(format) < bpp_table.size());
345 return bpp_table[static_cast<std::size_t>(format)];
346}
347
348/// Returns the sizer in bytes of the specified pixel format
349static constexpr u32 GetBytesPerPixel(PixelFormat pixel_format) {
350 if (pixel_format == PixelFormat::Invalid) {
351 return 0;
352 }
353 return GetFormatBpp(pixel_format) / CHAR_BIT;
354}
355
356SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type);
357
358bool SurfaceTargetIsLayered(SurfaceTarget target);
359
360PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format);
361
362PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format);
363
364PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
365 Tegra::Texture::ComponentType component_type,
366 bool is_srgb);
367
368ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type);
369
370ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format);
371
372PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format);
373
374ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format);
375
376SurfaceType GetFormatType(PixelFormat pixel_format);
377
378bool IsPixelFormatASTC(PixelFormat format);
379
380std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
381
382/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
383bool IsFormatBCn(PixelFormat format);
384
385} // namespace VideoCore::Surface