summaryrefslogtreecommitdiffstats
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
renderer_opengl/renderer_opengl.h
renderer_opengl/utils.cpp
renderer_opengl/utils.h
+ surface.cpp
+ surface.h
textures/astc.cpp
textures/astc.h
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 @@
namespace OpenGL {
using Maxwell = Tegra::Engines::Maxwell3D::Regs;
-using PixelFormat = SurfaceParams::PixelFormat;
-using SurfaceType = SurfaceParams::SurfaceType;
+using PixelFormat = VideoCore::Surface::PixelFormat;
+using SurfaceType = VideoCore::Surface::SurfaceType;
MICROPROFILE_DEFINE(OpenGL_VAO, "OpenGL", "Vertex Array Setup", MP_RGB(128, 128, 192));
MICROPROFILE_DEFINE(OpenGL_Shader, "OpenGL", "Shader Setup", MP_RGB(128, 128, 192));
@@ -703,7 +703,8 @@ bool RasterizerOpenGL::AccelerateDisplay(const Tegra::FramebufferConfig& config,
// Verify that the cached surface is the same size and format as the requested framebuffer
const auto& params{surface->GetSurfaceParams()};
- const auto& pixel_format{SurfaceParams::PixelFormatFromGPUPixelFormat(config.pixel_format)};
+ const auto& pixel_format{
+ VideoCore::Surface::PixelFormatFromGPUPixelFormat(config.pixel_format)};
ASSERT_MSG(params.width == config.width, "Framebuffer width is different");
ASSERT_MSG(params.height == config.height, "Framebuffer height is different");
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 @@
#include "video_core/engines/maxwell_3d.h"
#include "video_core/renderer_opengl/gl_rasterizer_cache.h"
#include "video_core/renderer_opengl/utils.h"
+#include "video_core/surface.h"
#include "video_core/textures/astc.h"
#include "video_core/textures/decoders.h"
#include "video_core/utils.h"
namespace OpenGL {
-using SurfaceType = SurfaceParams::SurfaceType;
-using PixelFormat = SurfaceParams::PixelFormat;
-using ComponentType = SurfaceParams::ComponentType;
+using VideoCore::Surface::ComponentTypeFromDepthFormat;
+using VideoCore::Surface::ComponentTypeFromRenderTarget;
+using VideoCore::Surface::ComponentTypeFromTexture;
+using VideoCore::Surface::PixelFormatFromDepthFormat;
+using VideoCore::Surface::PixelFormatFromRenderTargetFormat;
+using VideoCore::Surface::PixelFormatFromTextureFormat;
+using VideoCore::Surface::SurfaceTargetFromTextureType;
struct FormatTuple {
GLint internal_format;
@@ -35,46 +40,6 @@ struct FormatTuple {
bool compressed;
};
-static bool IsPixelFormatASTC(PixelFormat format) {
- switch (format) {
- case PixelFormat::ASTC_2D_4X4:
- case PixelFormat::ASTC_2D_5X4:
- case PixelFormat::ASTC_2D_8X8:
- case PixelFormat::ASTC_2D_8X5:
- case PixelFormat::ASTC_2D_4X4_SRGB:
- case PixelFormat::ASTC_2D_5X4_SRGB:
- case PixelFormat::ASTC_2D_8X8_SRGB:
- case PixelFormat::ASTC_2D_8X5_SRGB:
- return true;
- default:
- return false;
- }
-}
-
-static std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
- switch (format) {
- case PixelFormat::ASTC_2D_4X4:
- return {4, 4};
- case PixelFormat::ASTC_2D_5X4:
- return {5, 4};
- case PixelFormat::ASTC_2D_8X8:
- return {8, 8};
- case PixelFormat::ASTC_2D_8X5:
- return {8, 5};
- case PixelFormat::ASTC_2D_4X4_SRGB:
- return {4, 4};
- case PixelFormat::ASTC_2D_5X4_SRGB:
- return {5, 4};
- case PixelFormat::ASTC_2D_8X8_SRGB:
- return {8, 8};
- case PixelFormat::ASTC_2D_8X5_SRGB:
- return {8, 5};
- default:
- LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format));
- UNREACHABLE();
- }
-}
-
void SurfaceParams::InitCacheParameters(Tegra::GPUVAddr gpu_addr_) {
auto& memory_manager{Core::System::GetInstance().GPU().MemoryManager()};
const auto cpu_addr{memory_manager.GpuToCpuAddress(gpu_addr_)};
@@ -267,7 +232,7 @@ std::size_t SurfaceParams::InnerMemorySize(bool force_gl, bool layer_only,
return params;
}
-static constexpr std::array<FormatTuple, SurfaceParams::MaxPixelFormat> tex_format_tuples = {{
+static constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> tex_format_tuples = {{
{GL_RGBA8, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, ComponentType::UNorm, false}, // ABGR8U
{GL_RGBA8, GL_RGBA, GL_BYTE, ComponentType::SNorm, false}, // ABGR8S
{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
ComponentType::Float, false}, // Z32FS8
}};
-static GLenum SurfaceTargetToGL(SurfaceParams::SurfaceTarget target) {
+static GLenum SurfaceTargetToGL(SurfaceTarget target) {
switch (target) {
- case SurfaceParams::SurfaceTarget::Texture1D:
+ case SurfaceTarget::Texture1D:
return GL_TEXTURE_1D;
- case SurfaceParams::SurfaceTarget::Texture2D:
+ case SurfaceTarget::Texture2D:
return GL_TEXTURE_2D;
- case SurfaceParams::SurfaceTarget::Texture3D:
+ case SurfaceTarget::Texture3D:
return GL_TEXTURE_3D;
- case SurfaceParams::SurfaceTarget::Texture1DArray:
+ case SurfaceTarget::Texture1DArray:
return GL_TEXTURE_1D_ARRAY;
- case SurfaceParams::SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::Texture2DArray:
return GL_TEXTURE_2D_ARRAY;
- case SurfaceParams::SurfaceTarget::TextureCubemap:
+ case SurfaceTarget::TextureCubemap:
return GL_TEXTURE_CUBE_MAP;
}
LOG_CRITICAL(Render_OpenGL, "Unimplemented texture target={}", static_cast<u32>(target));
@@ -392,31 +357,10 @@ MathUtil::Rectangle<u32> SurfaceParams::GetRect(u32 mip_level) const {
return {0, actual_height, MipWidth(mip_level), 0};
}
-/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
-static bool IsFormatBCn(PixelFormat format) {
- switch (format) {
- case PixelFormat::DXT1:
- case PixelFormat::DXT23:
- case PixelFormat::DXT45:
- case PixelFormat::DXN1:
- case PixelFormat::DXN2SNORM:
- case PixelFormat::DXN2UNORM:
- case PixelFormat::BC7U:
- case PixelFormat::BC6H_UF16:
- case PixelFormat::BC6H_SF16:
- case PixelFormat::DXT1_SRGB:
- case PixelFormat::DXT23_SRGB:
- case PixelFormat::DXT45_SRGB:
- case PixelFormat::BC7U_SRGB:
- return true;
- }
- return false;
-}
-
template <bool morton_to_gl, PixelFormat format>
void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 depth, u8* gl_buffer,
std::size_t gl_buffer_size, VAddr addr) {
- constexpr u32 bytes_per_pixel = SurfaceParams::GetBytesPerPixel(format);
+ constexpr u32 bytes_per_pixel = GetBytesPerPixel(format);
// With the BCn formats (DXT and DXN), each 4x4 tile is swizzled instead of just individual
// pixel values.
@@ -435,7 +379,7 @@ void MortonCopy(u32 stride, u32 block_height, u32 height, u32 block_depth, u32 d
}
using GLConversionArray = std::array<void (*)(u32, u32, u32, u32, u32, u8*, std::size_t, VAddr),
- SurfaceParams::MaxPixelFormat>;
+ VideoCore::Surface::MaxPixelFormat>;
static constexpr GLConversionArray morton_to_gl_fns = {
// clang-format off
@@ -575,7 +519,7 @@ static constexpr GLConversionArray gl_to_morton_fns = {
void SwizzleFunc(const GLConversionArray& functions, const SurfaceParams& params,
std::vector<u8>& gl_buffer, u32 mip_level) {
u32 depth = params.MipDepth(mip_level);
- if (params.target == SurfaceParams::SurfaceTarget::Texture2D) {
+ if (params.target == SurfaceTarget::Texture2D) {
// TODO(Blinkhawk): Eliminate this condition once all texture types are implemented.
depth = 1U;
}
@@ -622,13 +566,13 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
if (src_params.type == SurfaceType::ColorTexture) {
switch (src_params.target) {
- case SurfaceParams::SurfaceTarget::Texture2D:
+ case SurfaceTarget::Texture2D:
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
GL_TEXTURE_2D, src_surface->Texture().handle, 0);
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
0, 0);
break;
- case SurfaceParams::SurfaceTarget::TextureCubemap:
+ case SurfaceTarget::TextureCubemap:
glFramebufferTexture2D(
GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
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,
GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0);
break;
- case SurfaceParams::SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::Texture2DArray:
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
src_surface->Texture().handle, 0, 0);
glFramebufferTextureLayer(GL_READ_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
break;
- case SurfaceParams::SurfaceTarget::Texture3D:
+ case SurfaceTarget::Texture3D:
glFramebufferTexture3D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + src_attachment,
SurfaceTargetToGL(src_params.target),
src_surface->Texture().handle, 0, 0);
@@ -658,13 +602,13 @@ static bool BlitSurface(const Surface& src_surface, const Surface& dst_surface,
}
switch (dst_params.target) {
- case SurfaceParams::SurfaceTarget::Texture2D:
+ case SurfaceTarget::Texture2D:
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
GL_TEXTURE_2D, dst_surface->Texture().handle, 0);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D,
0, 0);
break;
- case SurfaceParams::SurfaceTarget::TextureCubemap:
+ case SurfaceTarget::TextureCubemap:
glFramebufferTexture2D(
GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
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,
GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cubemap_face), 0, 0);
break;
- case SurfaceParams::SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::Texture2DArray:
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
dst_surface->Texture().handle, 0, 0);
glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 0, 0, 0);
break;
- case SurfaceParams::SurfaceTarget::Texture3D:
+ case SurfaceTarget::Texture3D:
glFramebufferTexture3D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + dst_attachment,
SurfaceTargetToGL(dst_params.target),
dst_surface->Texture().handle, 0, 0);
@@ -800,21 +744,21 @@ static void CopySurface(const Surface& src_surface, const Surface& dst_surface,
UNREACHABLE();
} else {
switch (dst_params.target) {
- case SurfaceParams::SurfaceTarget::Texture1D:
+ case SurfaceTarget::Texture1D:
glTextureSubImage1D(dst_surface->Texture().handle, 0, 0, width, dest_format.format,
dest_format.type, nullptr);
break;
- case SurfaceParams::SurfaceTarget::Texture2D:
+ case SurfaceTarget::Texture2D:
glTextureSubImage2D(dst_surface->Texture().handle, 0, 0, 0, width, height,
dest_format.format, dest_format.type, nullptr);
break;
- case SurfaceParams::SurfaceTarget::Texture3D:
- case SurfaceParams::SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::Texture3D:
+ case SurfaceTarget::Texture2DArray:
glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0, 0, width, height,
static_cast<GLsizei>(dst_params.depth), dest_format.format,
dest_format.type, nullptr);
break;
- case SurfaceParams::SurfaceTarget::TextureCubemap:
+ case SurfaceTarget::TextureCubemap:
glTextureSubImage3D(dst_surface->Texture().handle, 0, 0, 0,
static_cast<GLint>(cubemap_face), width, height, 1,
dest_format.format, dest_format.type, nullptr);
@@ -851,17 +795,17 @@ CachedSurface::CachedSurface(const SurfaceParams& params)
if (!format_tuple.compressed) {
// Only pre-create the texture for non-compressed textures.
switch (params.target) {
- case SurfaceParams::SurfaceTarget::Texture1D:
+ case SurfaceTarget::Texture1D:
glTexStorage1D(SurfaceTargetToGL(params.target), params.max_mip_level,
format_tuple.internal_format, rect.GetWidth());
break;
- case SurfaceParams::SurfaceTarget::Texture2D:
- case SurfaceParams::SurfaceTarget::TextureCubemap:
+ case SurfaceTarget::Texture2D:
+ case SurfaceTarget::TextureCubemap:
glTexStorage2D(SurfaceTargetToGL(params.target), params.max_mip_level,
format_tuple.internal_format, rect.GetWidth(), rect.GetHeight());
break;
- case SurfaceParams::SurfaceTarget::Texture3D:
- case SurfaceParams::SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::Texture3D:
+ case SurfaceTarget::Texture2DArray:
glTexStorage3D(SurfaceTargetToGL(params.target), params.max_mip_level,
format_tuple.internal_format, rect.GetWidth(), rect.GetHeight(),
params.depth);
@@ -916,7 +860,7 @@ static void ConvertS8Z24ToZ24S8(std::vector<u8>& data, u32 width, u32 height, bo
S8Z24 s8z24_pixel{};
Z24S8 z24s8_pixel{};
- constexpr auto bpp{SurfaceParams::GetBytesPerPixel(PixelFormat::S8Z24)};
+ constexpr auto bpp{GetBytesPerPixel(PixelFormat::S8Z24)};
for (std::size_t y = 0; y < height; ++y) {
for (std::size_t x = 0; x < width; ++x) {
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
}
static void ConvertG8R8ToR8G8(std::vector<u8>& data, u32 width, u32 height) {
- constexpr auto bpp{SurfaceParams::GetBytesPerPixel(PixelFormat::G8R8U)};
+ constexpr auto bpp{GetBytesPerPixel(PixelFormat::G8R8U)};
for (std::size_t y = 0; y < height; ++y) {
for (std::size_t x = 0; x < width; ++x) {
const std::size_t offset{bpp * (y * width + x)};
@@ -1042,7 +986,7 @@ void CachedSurface::FlushGLBuffer() {
const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
// Ensure no bad interactions with GL_UNPACK_ALIGNMENT
- ASSERT(params.width * SurfaceParams::GetBytesPerPixel(params.pixel_format) % 4 == 0);
+ ASSERT(params.width * GetBytesPerPixel(params.pixel_format) % 4 == 0);
glPixelStorei(GL_PACK_ROW_LENGTH, static_cast<GLint>(params.width));
ASSERT(!tuple.compressed);
glBindBuffer(GL_PIXEL_PACK_BUFFER, 0);
@@ -1074,7 +1018,7 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
std::size_t buffer_offset =
static_cast<std::size_t>(static_cast<std::size_t>(y0) * params.MipWidth(mip_map) +
static_cast<std::size_t>(x0)) *
- SurfaceParams::GetBytesPerPixel(params.pixel_format);
+ GetBytesPerPixel(params.pixel_format);
const FormatTuple& tuple = GetFormatTuple(params.pixel_format, params.component_type);
const GLuint target_tex = texture.handle;
@@ -1090,35 +1034,34 @@ void CachedSurface::UploadGLMipmapTexture(u32 mip_map, GLuint read_fb_handle,
cur_state.Apply();
// Ensure no bad interactions with GL_UNPACK_ALIGNMENT
- ASSERT(params.MipWidth(mip_map) * SurfaceParams::GetBytesPerPixel(params.pixel_format) % 4 ==
- 0);
+ ASSERT(params.MipWidth(mip_map) * GetBytesPerPixel(params.pixel_format) % 4 == 0);
glPixelStorei(GL_UNPACK_ROW_LENGTH, static_cast<GLint>(params.MipWidth(mip_map)));
GLsizei image_size = static_cast<GLsizei>(params.GetMipmapSizeGL(mip_map, false));
glActiveTexture(GL_TEXTURE0);
if (tuple.compressed) {
switch (params.target) {
- case SurfaceParams::SurfaceTarget::Texture2D:
+ case SurfaceTarget::Texture2D:
glCompressedTexImage2D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
static_cast<GLsizei>(params.MipWidth(mip_map)),
static_cast<GLsizei>(params.MipHeight(mip_map)), 0, image_size,
&gl_buffer[mip_map][buffer_offset]);
break;
- case SurfaceParams::SurfaceTarget::Texture3D:
+ case SurfaceTarget::Texture3D:
glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
static_cast<GLsizei>(params.MipWidth(mip_map)),
static_cast<GLsizei>(params.MipHeight(mip_map)),
static_cast<GLsizei>(params.MipDepth(mip_map)), 0, image_size,
&gl_buffer[mip_map][buffer_offset]);
break;
- case SurfaceParams::SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::Texture2DArray:
glCompressedTexImage3D(SurfaceTargetToGL(params.target), mip_map, tuple.internal_format,
static_cast<GLsizei>(params.MipWidth(mip_map)),
static_cast<GLsizei>(params.MipHeight(mip_map)),
static_cast<GLsizei>(params.depth), 0, image_size,
&gl_buffer[mip_map][buffer_offset]);
break;
- case SurfaceParams::SurfaceTarget::TextureCubemap: {
+ case SurfaceTarget::TextureCubemap: {
GLsizei layer_size = static_cast<GLsizei>(params.LayerSizeGL(mip_map));
for (std::size_t face = 0; face < params.depth; ++face) {
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,
} else {
switch (params.target) {
- case SurfaceParams::SurfaceTarget::Texture1D:
+ case SurfaceTarget::Texture1D:
glTexSubImage1D(SurfaceTargetToGL(params.target), mip_map, x0,
static_cast<GLsizei>(rect.GetWidth()), tuple.format, tuple.type,
&gl_buffer[mip_map][buffer_offset]);
break;
- case SurfaceParams::SurfaceTarget::Texture2D:
+ case SurfaceTarget::Texture2D:
glTexSubImage2D(SurfaceTargetToGL(params.target), mip_map, x0, y0,
static_cast<GLsizei>(rect.GetWidth()),
static_cast<GLsizei>(rect.GetHeight()), tuple.format, tuple.type,
&gl_buffer[mip_map][buffer_offset]);
break;
- case SurfaceParams::SurfaceTarget::Texture3D:
+ case SurfaceTarget::Texture3D:
glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0,
static_cast<GLsizei>(rect.GetWidth()),
static_cast<GLsizei>(rect.GetHeight()), params.MipDepth(mip_map),
tuple.format, tuple.type, &gl_buffer[mip_map][buffer_offset]);
break;
- case SurfaceParams::SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::Texture2DArray:
glTexSubImage3D(SurfaceTargetToGL(params.target), mip_map, x0, y0, 0,
static_cast<GLsizei>(rect.GetWidth()),
static_cast<GLsizei>(rect.GetHeight()), params.depth, tuple.format,
tuple.type, &gl_buffer[mip_map][buffer_offset]);
break;
- case SurfaceParams::SurfaceTarget::TextureCubemap: {
+ case SurfaceTarget::TextureCubemap: {
std::size_t start = buffer_offset;
for (std::size_t face = 0; face < params.depth; ++face) {
glTexSubImage2D(static_cast<GLenum>(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face), mip_map,
@@ -1341,8 +1284,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
// For compatible surfaces, we can just do fast glCopyImageSubData based copy
if (old_params.target == new_params.target && old_params.type == new_params.type &&
old_params.depth == new_params.depth && old_params.depth == 1 &&
- SurfaceParams::GetFormatBpp(old_params.pixel_format) ==
- SurfaceParams::GetFormatBpp(new_params.pixel_format)) {
+ GetFormatBpp(old_params.pixel_format) == GetFormatBpp(new_params.pixel_format)) {
FastCopySurface(old_surface, new_surface);
return new_surface;
}
@@ -1355,15 +1297,15 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
const bool is_blit{old_params.pixel_format == new_params.pixel_format};
switch (new_params.target) {
- case SurfaceParams::SurfaceTarget::Texture2D:
+ case SurfaceTarget::Texture2D:
if (is_blit) {
BlitSurface(old_surface, new_surface, read_framebuffer.handle, draw_framebuffer.handle);
} else {
CopySurface(old_surface, new_surface, copy_pbo.handle);
}
break;
- case SurfaceParams::SurfaceTarget::TextureCubemap:
- case SurfaceParams::SurfaceTarget::Texture3D:
+ case SurfaceTarget::TextureCubemap:
+ case SurfaceTarget::Texture3D:
AccurateCopySurface(old_surface, new_surface);
break;
default:
@@ -1373,7 +1315,7 @@ Surface RasterizerCacheOpenGL::RecreateSurface(const Surface& old_surface,
}
return new_surface;
-} // namespace OpenGL
+}
Surface RasterizerCacheOpenGL::TryFindFramebufferSurface(VAddr addr) const {
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 @@
#include <array>
#include <map>
#include <memory>
+#include <string>
#include <vector>
#include "common/alignment.h"
@@ -18,6 +19,7 @@
#include "video_core/rasterizer_cache.h"
#include "video_core/renderer_opengl/gl_resource_manager.h"
#include "video_core/renderer_opengl/gl_shader_gen.h"
+#include "video_core/surface.h"
#include "video_core/textures/decoders.h"
#include "video_core/textures/texture.h"
@@ -27,135 +29,12 @@ class CachedSurface;
using Surface = std::shared_ptr<CachedSurface>;
using SurfaceSurfaceRect_Tuple = std::tuple<Surface, Surface, MathUtil::Rectangle<u32>>;
-struct SurfaceParams {
- enum class PixelFormat {
- ABGR8U = 0,
- ABGR8S = 1,
- ABGR8UI = 2,
- B5G6R5U = 3,
- A2B10G10R10U = 4,
- A1B5G5R5U = 5,
- R8U = 6,
- R8UI = 7,
- RGBA16F = 8,
- RGBA16U = 9,
- RGBA16UI = 10,
- R11FG11FB10F = 11,
- RGBA32UI = 12,
- DXT1 = 13,
- DXT23 = 14,
- DXT45 = 15,
- DXN1 = 16, // This is also known as BC4
- DXN2UNORM = 17,
- DXN2SNORM = 18,
- BC7U = 19,
- BC6H_UF16 = 20,
- BC6H_SF16 = 21,
- ASTC_2D_4X4 = 22,
- G8R8U = 23,
- G8R8S = 24,
- BGRA8 = 25,
- RGBA32F = 26,
- RG32F = 27,
- R32F = 28,
- R16F = 29,
- R16U = 30,
- R16S = 31,
- R16UI = 32,
- R16I = 33,
- RG16 = 34,
- RG16F = 35,
- RG16UI = 36,
- RG16I = 37,
- RG16S = 38,
- RGB32F = 39,
- RGBA8_SRGB = 40,
- RG8U = 41,
- RG8S = 42,
- RG32UI = 43,
- R32UI = 44,
- ASTC_2D_8X8 = 45,
- ASTC_2D_8X5 = 46,
- ASTC_2D_5X4 = 47,
- BGRA8_SRGB = 48,
- DXT1_SRGB = 49,
- DXT23_SRGB = 50,
- DXT45_SRGB = 51,
- BC7U_SRGB = 52,
- ASTC_2D_4X4_SRGB = 53,
- ASTC_2D_8X8_SRGB = 54,
- ASTC_2D_8X5_SRGB = 55,
- ASTC_2D_5X4_SRGB = 56,
-
- MaxColorFormat,
-
- // Depth formats
- Z32F = 57,
- Z16 = 58,
-
- MaxDepthFormat,
-
- // DepthStencil formats
- Z24S8 = 59,
- S8Z24 = 60,
- Z32FS8 = 61,
-
- MaxDepthStencilFormat,
-
- Max = MaxDepthStencilFormat,
- Invalid = 255,
- };
-
- static constexpr std::size_t MaxPixelFormat = static_cast<std::size_t>(PixelFormat::Max);
-
- enum class ComponentType {
- Invalid = 0,
- SNorm = 1,
- UNorm = 2,
- SInt = 3,
- UInt = 4,
- Float = 5,
- };
-
- enum class SurfaceType {
- ColorTexture = 0,
- Depth = 1,
- DepthStencil = 2,
- Fill = 3,
- Invalid = 4,
- };
-
- enum class SurfaceTarget {
- Texture1D,
- Texture2D,
- Texture3D,
- Texture1DArray,
- Texture2DArray,
- TextureCubemap,
- };
-
- static SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type) {
- switch (texture_type) {
- case Tegra::Texture::TextureType::Texture1D:
- return SurfaceTarget::Texture1D;
- case Tegra::Texture::TextureType::Texture2D:
- case Tegra::Texture::TextureType::Texture2DNoMipmap:
- return SurfaceTarget::Texture2D;
- case Tegra::Texture::TextureType::Texture3D:
- return SurfaceTarget::Texture3D;
- case Tegra::Texture::TextureType::TextureCubemap:
- return SurfaceTarget::TextureCubemap;
- case Tegra::Texture::TextureType::Texture1DArray:
- return SurfaceTarget::Texture1DArray;
- case Tegra::Texture::TextureType::Texture2DArray:
- return SurfaceTarget::Texture2DArray;
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", static_cast<u32>(texture_type));
- UNREACHABLE();
- return SurfaceTarget::Texture2D;
- }
- }
+using SurfaceTarget = VideoCore::Surface::SurfaceTarget;
+using SurfaceType = VideoCore::Surface::SurfaceType;
+using PixelFormat = VideoCore::Surface::PixelFormat;
+using ComponentType = VideoCore::Surface::ComponentType;
+struct SurfaceParams {
static std::string SurfaceTargetName(SurfaceTarget target) {
switch (target) {
case SurfaceTarget::Texture1D:
@@ -177,660 +56,8 @@ struct SurfaceParams {
}
}
- static bool SurfaceTargetIsLayered(SurfaceTarget target) {
- switch (target) {
- case SurfaceTarget::Texture1D:
- case SurfaceTarget::Texture2D:
- case SurfaceTarget::Texture3D:
- return false;
- case SurfaceTarget::Texture1DArray:
- case SurfaceTarget::Texture2DArray:
- case SurfaceTarget::TextureCubemap:
- return true;
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
- UNREACHABLE();
- return false;
- }
- }
-
- /**
- * Gets the compression factor for the specified PixelFormat. This applies to just the
- * "compressed width" and "compressed height", not the overall compression factor of a
- * compressed image. This is used for maintaining proper surface sizes for compressed
- * texture formats.
- */
- static constexpr u32 GetCompressionFactor(PixelFormat format) {
- if (format == PixelFormat::Invalid)
- return 0;
-
- constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{
- 1, // ABGR8U
- 1, // ABGR8S
- 1, // ABGR8UI
- 1, // B5G6R5U
- 1, // A2B10G10R10U
- 1, // A1B5G5R5U
- 1, // R8U
- 1, // R8UI
- 1, // RGBA16F
- 1, // RGBA16U
- 1, // RGBA16UI
- 1, // R11FG11FB10F
- 1, // RGBA32UI
- 4, // DXT1
- 4, // DXT23
- 4, // DXT45
- 4, // DXN1
- 4, // DXN2UNORM
- 4, // DXN2SNORM
- 4, // BC7U
- 4, // BC6H_UF16
- 4, // BC6H_SF16
- 4, // ASTC_2D_4X4
- 1, // G8R8U
- 1, // G8R8S
- 1, // BGRA8
- 1, // RGBA32F
- 1, // RG32F
- 1, // R32F
- 1, // R16F
- 1, // R16U
- 1, // R16S
- 1, // R16UI
- 1, // R16I
- 1, // RG16
- 1, // RG16F
- 1, // RG16UI
- 1, // RG16I
- 1, // RG16S
- 1, // RGB32F
- 1, // RGBA8_SRGB
- 1, // RG8U
- 1, // RG8S
- 1, // RG32UI
- 1, // R32UI
- 4, // ASTC_2D_8X8
- 4, // ASTC_2D_8X5
- 4, // ASTC_2D_5X4
- 1, // BGRA8_SRGB
- 4, // DXT1_SRGB
- 4, // DXT23_SRGB
- 4, // DXT45_SRGB
- 4, // BC7U_SRGB
- 4, // ASTC_2D_4X4_SRGB
- 4, // ASTC_2D_8X8_SRGB
- 4, // ASTC_2D_8X5_SRGB
- 4, // ASTC_2D_5X4_SRGB
- 1, // Z32F
- 1, // Z16
- 1, // Z24S8
- 1, // S8Z24
- 1, // Z32FS8
- }};
-
- ASSERT(static_cast<std::size_t>(format) < compression_factor_table.size());
- return compression_factor_table[static_cast<std::size_t>(format)];
- }
-
- static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
- if (format == PixelFormat::Invalid)
- return 0;
- constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
- 1, // ABGR8U
- 1, // ABGR8S
- 1, // ABGR8UI
- 1, // B5G6R5U
- 1, // A2B10G10R10U
- 1, // A1B5G5R5U
- 1, // R8U
- 1, // R8UI
- 1, // RGBA16F
- 1, // RGBA16U
- 1, // RGBA16UI
- 1, // R11FG11FB10F
- 1, // RGBA32UI
- 4, // DXT1
- 4, // DXT23
- 4, // DXT45
- 4, // DXN1
- 4, // DXN2UNORM
- 4, // DXN2SNORM
- 4, // BC7U
- 4, // BC6H_UF16
- 4, // BC6H_SF16
- 4, // ASTC_2D_4X4
- 1, // G8R8U
- 1, // G8R8S
- 1, // BGRA8
- 1, // RGBA32F
- 1, // RG32F
- 1, // R32F
- 1, // R16F
- 1, // R16U
- 1, // R16S
- 1, // R16UI
- 1, // R16I
- 1, // RG16
- 1, // RG16F
- 1, // RG16UI
- 1, // RG16I
- 1, // RG16S
- 1, // RGB32F
- 1, // RGBA8_SRGB
- 1, // RG8U
- 1, // RG8S
- 1, // RG32UI
- 1, // R32UI
- 8, // ASTC_2D_8X8
- 5, // ASTC_2D_8X5
- 4, // ASTC_2D_5X4
- 1, // BGRA8_SRGB
- 4, // DXT1_SRGB
- 4, // DXT23_SRGB
- 4, // DXT45_SRGB
- 4, // BC7U_SRGB
- 4, // ASTC_2D_4X4_SRGB
- 8, // ASTC_2D_8X8_SRGB
- 5, // ASTC_2D_8X5_SRGB
- 4, // ASTC_2D_5X4_SRGB
- 1, // Z32F
- 1, // Z16
- 1, // Z24S8
- 1, // S8Z24
- 1, // Z32FS8
- }};
- ASSERT(static_cast<std::size_t>(format) < block_height_table.size());
- return block_height_table[static_cast<std::size_t>(format)];
- }
-
- static constexpr u32 GetFormatBpp(PixelFormat format) {
- if (format == PixelFormat::Invalid)
- return 0;
-
- constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
- 32, // ABGR8U
- 32, // ABGR8S
- 32, // ABGR8UI
- 16, // B5G6R5U
- 32, // A2B10G10R10U
- 16, // A1B5G5R5U
- 8, // R8U
- 8, // R8UI
- 64, // RGBA16F
- 64, // RGBA16U
- 64, // RGBA16UI
- 32, // R11FG11FB10F
- 128, // RGBA32UI
- 64, // DXT1
- 128, // DXT23
- 128, // DXT45
- 64, // DXN1
- 128, // DXN2UNORM
- 128, // DXN2SNORM
- 128, // BC7U
- 128, // BC6H_UF16
- 128, // BC6H_SF16
- 32, // ASTC_2D_4X4
- 16, // G8R8U
- 16, // G8R8S
- 32, // BGRA8
- 128, // RGBA32F
- 64, // RG32F
- 32, // R32F
- 16, // R16F
- 16, // R16U
- 16, // R16S
- 16, // R16UI
- 16, // R16I
- 32, // RG16
- 32, // RG16F
- 32, // RG16UI
- 32, // RG16I
- 32, // RG16S
- 96, // RGB32F
- 32, // RGBA8_SRGB
- 16, // RG8U
- 16, // RG8S
- 64, // RG32UI
- 32, // R32UI
- 16, // ASTC_2D_8X8
- 16, // ASTC_2D_8X5
- 32, // ASTC_2D_5X4
- 32, // BGRA8_SRGB
- 64, // DXT1_SRGB
- 128, // DXT23_SRGB
- 128, // DXT45_SRGB
- 128, // BC7U
- 32, // ASTC_2D_4X4_SRGB
- 16, // ASTC_2D_8X8_SRGB
- 16, // ASTC_2D_8X5_SRGB
- 32, // ASTC_2D_5X4_SRGB
- 32, // Z32F
- 16, // Z16
- 32, // Z24S8
- 32, // S8Z24
- 64, // Z32FS8
- }};
-
- ASSERT(static_cast<std::size_t>(format) < bpp_table.size());
- return bpp_table[static_cast<std::size_t>(format)];
- }
-
u32 GetFormatBpp() const {
- return GetFormatBpp(pixel_format);
- }
-
- static PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
- switch (format) {
- case Tegra::DepthFormat::S8_Z24_UNORM:
- return PixelFormat::S8Z24;
- case Tegra::DepthFormat::Z24_S8_UNORM:
- return PixelFormat::Z24S8;
- case Tegra::DepthFormat::Z32_FLOAT:
- return PixelFormat::Z32F;
- case Tegra::DepthFormat::Z16_UNORM:
- return PixelFormat::Z16;
- case Tegra::DepthFormat::Z32_S8_X24_FLOAT:
- return PixelFormat::Z32FS8;
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
- UNREACHABLE();
- }
- }
-
- static PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
- switch (format) {
- // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the
- // gamma.
- case Tegra::RenderTargetFormat::RGBA8_SRGB:
- return PixelFormat::RGBA8_SRGB;
- case Tegra::RenderTargetFormat::RGBA8_UNORM:
- return PixelFormat::ABGR8U;
- case Tegra::RenderTargetFormat::RGBA8_SNORM:
- return PixelFormat::ABGR8S;
- case Tegra::RenderTargetFormat::RGBA8_UINT:
- return PixelFormat::ABGR8UI;
- case Tegra::RenderTargetFormat::BGRA8_SRGB:
- return PixelFormat::BGRA8_SRGB;
- case Tegra::RenderTargetFormat::BGRA8_UNORM:
- return PixelFormat::BGRA8;
- case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
- return PixelFormat::A2B10G10R10U;
- case Tegra::RenderTargetFormat::RGBA16_FLOAT:
- return PixelFormat::RGBA16F;
- case Tegra::RenderTargetFormat::RGBA16_UNORM:
- return PixelFormat::RGBA16U;
- case Tegra::RenderTargetFormat::RGBA16_UINT:
- return PixelFormat::RGBA16UI;
- case Tegra::RenderTargetFormat::RGBA32_FLOAT:
- return PixelFormat::RGBA32F;
- case Tegra::RenderTargetFormat::RG32_FLOAT:
- return PixelFormat::RG32F;
- case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
- return PixelFormat::R11FG11FB10F;
- case Tegra::RenderTargetFormat::B5G6R5_UNORM:
- return PixelFormat::B5G6R5U;
- case Tegra::RenderTargetFormat::BGR5A1_UNORM:
- return PixelFormat::A1B5G5R5U;
- case Tegra::RenderTargetFormat::RGBA32_UINT:
- return PixelFormat::RGBA32UI;
- case Tegra::RenderTargetFormat::R8_UNORM:
- return PixelFormat::R8U;
- case Tegra::RenderTargetFormat::R8_UINT:
- return PixelFormat::R8UI;
- case Tegra::RenderTargetFormat::RG16_FLOAT:
- return PixelFormat::RG16F;
- case Tegra::RenderTargetFormat::RG16_UINT:
- return PixelFormat::RG16UI;
- case Tegra::RenderTargetFormat::RG16_SINT:
- return PixelFormat::RG16I;
- case Tegra::RenderTargetFormat::RG16_UNORM:
- return PixelFormat::RG16;
- case Tegra::RenderTargetFormat::RG16_SNORM:
- return PixelFormat::RG16S;
- case Tegra::RenderTargetFormat::RG8_UNORM:
- return PixelFormat::RG8U;
- case Tegra::RenderTargetFormat::RG8_SNORM:
- return PixelFormat::RG8S;
- case Tegra::RenderTargetFormat::R16_FLOAT:
- return PixelFormat::R16F;
- case Tegra::RenderTargetFormat::R16_UNORM:
- return PixelFormat::R16U;
- case Tegra::RenderTargetFormat::R16_SNORM:
- return PixelFormat::R16S;
- case Tegra::RenderTargetFormat::R16_UINT:
- return PixelFormat::R16UI;
- case Tegra::RenderTargetFormat::R16_SINT:
- return PixelFormat::R16I;
- case Tegra::RenderTargetFormat::R32_FLOAT:
- return PixelFormat::R32F;
- case Tegra::RenderTargetFormat::R32_UINT:
- return PixelFormat::R32UI;
- case Tegra::RenderTargetFormat::RG32_UINT:
- return PixelFormat::RG32UI;
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
- UNREACHABLE();
- }
- }
-
- static PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
- Tegra::Texture::ComponentType component_type,
- bool is_srgb) {
- // TODO(Subv): Properly implement this
- switch (format) {
- case Tegra::Texture::TextureFormat::A8R8G8B8:
- if (is_srgb) {
- return PixelFormat::RGBA8_SRGB;
- }
- switch (component_type) {
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::ABGR8U;
- case Tegra::Texture::ComponentType::SNORM:
- return PixelFormat::ABGR8S;
- case Tegra::Texture::ComponentType::UINT:
- return PixelFormat::ABGR8UI;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::B5G6R5:
- switch (component_type) {
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::B5G6R5U;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::A2B10G10R10:
- switch (component_type) {
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::A2B10G10R10U;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::A1B5G5R5:
- switch (component_type) {
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::A1B5G5R5U;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::R8:
- switch (component_type) {
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::R8U;
- case Tegra::Texture::ComponentType::UINT:
- return PixelFormat::R8UI;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::G8R8:
- switch (component_type) {
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::G8R8U;
- case Tegra::Texture::ComponentType::SNORM:
- return PixelFormat::G8R8S;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::R16_G16_B16_A16:
- switch (component_type) {
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::RGBA16U;
- case Tegra::Texture::ComponentType::FLOAT:
- return PixelFormat::RGBA16F;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::BF10GF11RF11:
- switch (component_type) {
- case Tegra::Texture::ComponentType::FLOAT:
- return PixelFormat::R11FG11FB10F;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::R32_G32_B32_A32:
- switch (component_type) {
- case Tegra::Texture::ComponentType::FLOAT:
- return PixelFormat::RGBA32F;
- case Tegra::Texture::ComponentType::UINT:
- return PixelFormat::RGBA32UI;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::R32_G32:
- switch (component_type) {
- case Tegra::Texture::ComponentType::FLOAT:
- return PixelFormat::RG32F;
- case Tegra::Texture::ComponentType::UINT:
- return PixelFormat::RG32UI;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::R32_G32_B32:
- switch (component_type) {
- case Tegra::Texture::ComponentType::FLOAT:
- return PixelFormat::RGB32F;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::R16:
- switch (component_type) {
- case Tegra::Texture::ComponentType::FLOAT:
- return PixelFormat::R16F;
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::R16U;
- case Tegra::Texture::ComponentType::SNORM:
- return PixelFormat::R16S;
- case Tegra::Texture::ComponentType::UINT:
- return PixelFormat::R16UI;
- case Tegra::Texture::ComponentType::SINT:
- return PixelFormat::R16I;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::R32:
- switch (component_type) {
- case Tegra::Texture::ComponentType::FLOAT:
- return PixelFormat::R32F;
- case Tegra::Texture::ComponentType::UINT:
- return PixelFormat::R32UI;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::ZF32:
- return PixelFormat::Z32F;
- case Tegra::Texture::TextureFormat::Z16:
- return PixelFormat::Z16;
- case Tegra::Texture::TextureFormat::Z24S8:
- return PixelFormat::Z24S8;
- case Tegra::Texture::TextureFormat::DXT1:
- return is_srgb ? PixelFormat::DXT1_SRGB : PixelFormat::DXT1;
- case Tegra::Texture::TextureFormat::DXT23:
- return is_srgb ? PixelFormat::DXT23_SRGB : PixelFormat::DXT23;
- case Tegra::Texture::TextureFormat::DXT45:
- return is_srgb ? PixelFormat::DXT45_SRGB : PixelFormat::DXT45;
- case Tegra::Texture::TextureFormat::DXN1:
- return PixelFormat::DXN1;
- case Tegra::Texture::TextureFormat::DXN2:
- switch (component_type) {
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::DXN2UNORM;
- case Tegra::Texture::ComponentType::SNORM:
- return PixelFormat::DXN2SNORM;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- case Tegra::Texture::TextureFormat::BC7U:
- return is_srgb ? PixelFormat::BC7U_SRGB : PixelFormat::BC7U;
- case Tegra::Texture::TextureFormat::BC6H_UF16:
- return PixelFormat::BC6H_UF16;
- case Tegra::Texture::TextureFormat::BC6H_SF16:
- return PixelFormat::BC6H_SF16;
- case Tegra::Texture::TextureFormat::ASTC_2D_4X4:
- return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4;
- case Tegra::Texture::TextureFormat::ASTC_2D_5X4:
- return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4;
- case Tegra::Texture::TextureFormat::ASTC_2D_8X8:
- return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8;
- case Tegra::Texture::TextureFormat::ASTC_2D_8X5:
- return is_srgb ? PixelFormat::ASTC_2D_8X5_SRGB : PixelFormat::ASTC_2D_8X5;
- case Tegra::Texture::TextureFormat::R16_G16:
- switch (component_type) {
- case Tegra::Texture::ComponentType::FLOAT:
- return PixelFormat::RG16F;
- case Tegra::Texture::ComponentType::UNORM:
- return PixelFormat::RG16;
- case Tegra::Texture::ComponentType::SNORM:
- return PixelFormat::RG16S;
- case Tegra::Texture::ComponentType::UINT:
- return PixelFormat::RG16UI;
- case Tegra::Texture::ComponentType::SINT:
- return PixelFormat::RG16I;
- }
- LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}",
- static_cast<u32>(component_type));
- UNREACHABLE();
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented format={}, component_type={}",
- static_cast<u32>(format), static_cast<u32>(component_type));
- UNREACHABLE();
- }
- }
-
- static ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
- // TODO(Subv): Implement more component types
- switch (type) {
- case Tegra::Texture::ComponentType::UNORM:
- return ComponentType::UNorm;
- case Tegra::Texture::ComponentType::FLOAT:
- return ComponentType::Float;
- case Tegra::Texture::ComponentType::SNORM:
- return ComponentType::SNorm;
- case Tegra::Texture::ComponentType::UINT:
- return ComponentType::UInt;
- case Tegra::Texture::ComponentType::SINT:
- return ComponentType::SInt;
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented component type={}", static_cast<u32>(type));
- UNREACHABLE();
- }
- }
-
- static ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format) {
- // TODO(Subv): Implement more render targets
- switch (format) {
- case Tegra::RenderTargetFormat::RGBA8_UNORM:
- case Tegra::RenderTargetFormat::RGBA8_SRGB:
- case Tegra::RenderTargetFormat::BGRA8_UNORM:
- case Tegra::RenderTargetFormat::BGRA8_SRGB:
- case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
- case Tegra::RenderTargetFormat::R8_UNORM:
- case Tegra::RenderTargetFormat::RG16_UNORM:
- case Tegra::RenderTargetFormat::R16_UNORM:
- case Tegra::RenderTargetFormat::B5G6R5_UNORM:
- case Tegra::RenderTargetFormat::BGR5A1_UNORM:
- case Tegra::RenderTargetFormat::RG8_UNORM:
- case Tegra::RenderTargetFormat::RGBA16_UNORM:
- return ComponentType::UNorm;
- case Tegra::RenderTargetFormat::RGBA8_SNORM:
- case Tegra::RenderTargetFormat::RG16_SNORM:
- case Tegra::RenderTargetFormat::R16_SNORM:
- case Tegra::RenderTargetFormat::RG8_SNORM:
- return ComponentType::SNorm;
- case Tegra::RenderTargetFormat::RGBA16_FLOAT:
- case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
- case Tegra::RenderTargetFormat::RGBA32_FLOAT:
- case Tegra::RenderTargetFormat::RG32_FLOAT:
- case Tegra::RenderTargetFormat::RG16_FLOAT:
- case Tegra::RenderTargetFormat::R16_FLOAT:
- case Tegra::RenderTargetFormat::R32_FLOAT:
- return ComponentType::Float;
- case Tegra::RenderTargetFormat::RGBA32_UINT:
- case Tegra::RenderTargetFormat::RGBA16_UINT:
- case Tegra::RenderTargetFormat::RG16_UINT:
- case Tegra::RenderTargetFormat::R8_UINT:
- case Tegra::RenderTargetFormat::R16_UINT:
- case Tegra::RenderTargetFormat::RG32_UINT:
- case Tegra::RenderTargetFormat::R32_UINT:
- case Tegra::RenderTargetFormat::RGBA8_UINT:
- return ComponentType::UInt;
- case Tegra::RenderTargetFormat::RG16_SINT:
- case Tegra::RenderTargetFormat::R16_SINT:
- return ComponentType::SInt;
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
- UNREACHABLE();
- }
- }
-
- static PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) {
- switch (format) {
- case Tegra::FramebufferConfig::PixelFormat::ABGR8:
- return PixelFormat::ABGR8U;
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
- UNREACHABLE();
- }
- }
-
- static ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) {
- switch (format) {
- case Tegra::DepthFormat::Z16_UNORM:
- case Tegra::DepthFormat::S8_Z24_UNORM:
- case Tegra::DepthFormat::Z24_S8_UNORM:
- return ComponentType::UNorm;
- case Tegra::DepthFormat::Z32_FLOAT:
- case Tegra::DepthFormat::Z32_S8_X24_FLOAT:
- return ComponentType::Float;
- default:
- LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
- UNREACHABLE();
- }
- }
-
- static SurfaceType GetFormatType(PixelFormat pixel_format) {
- if (static_cast<std::size_t>(pixel_format) <
- static_cast<std::size_t>(PixelFormat::MaxColorFormat)) {
- return SurfaceType::ColorTexture;
- }
-
- if (static_cast<std::size_t>(pixel_format) <
- static_cast<std::size_t>(PixelFormat::MaxDepthFormat)) {
- return SurfaceType::Depth;
- }
-
- if (static_cast<std::size_t>(pixel_format) <
- static_cast<std::size_t>(PixelFormat::MaxDepthStencilFormat)) {
- return SurfaceType::DepthStencil;
- }
-
- // TODO(Subv): Implement the other formats
- ASSERT(false);
-
- return SurfaceType::Invalid;
- }
-
- /// Returns the sizer in bytes of the specified pixel format
- static constexpr u32 GetBytesPerPixel(PixelFormat pixel_format) {
- if (pixel_format == SurfaceParams::PixelFormat::Invalid) {
- return 0;
- }
- return GetFormatBpp(pixel_format) / CHAR_BIT;
+ return VideoCore::Surface::GetFormatBpp(pixel_format);
}
/// 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 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "common/common_types.h"
+#include "common/math_util.h"
+#include "video_core/surface.h"
+
+namespace VideoCore::Surface {
+
+SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type) {
+ switch (texture_type) {
+ case Tegra::Texture::TextureType::Texture1D:
+ return SurfaceTarget::Texture1D;
+ case Tegra::Texture::TextureType::Texture2D:
+ case Tegra::Texture::TextureType::Texture2DNoMipmap:
+ return SurfaceTarget::Texture2D;
+ case Tegra::Texture::TextureType::Texture3D:
+ return SurfaceTarget::Texture3D;
+ case Tegra::Texture::TextureType::TextureCubemap:
+ return SurfaceTarget::TextureCubemap;
+ case Tegra::Texture::TextureType::Texture1DArray:
+ return SurfaceTarget::Texture1DArray;
+ case Tegra::Texture::TextureType::Texture2DArray:
+ return SurfaceTarget::Texture2DArray;
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented texture_type={}", static_cast<u32>(texture_type));
+ UNREACHABLE();
+ return SurfaceTarget::Texture2D;
+ }
+}
+
+bool SurfaceTargetIsLayered(SurfaceTarget target) {
+ switch (target) {
+ case SurfaceTarget::Texture1D:
+ case SurfaceTarget::Texture2D:
+ case SurfaceTarget::Texture3D:
+ return false;
+ case SurfaceTarget::Texture1DArray:
+ case SurfaceTarget::Texture2DArray:
+ case SurfaceTarget::TextureCubemap:
+ return true;
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented surface_target={}", static_cast<u32>(target));
+ UNREACHABLE();
+ return false;
+ }
+}
+
+PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) {
+ switch (format) {
+ case Tegra::DepthFormat::S8_Z24_UNORM:
+ return PixelFormat::S8Z24;
+ case Tegra::DepthFormat::Z24_S8_UNORM:
+ return PixelFormat::Z24S8;
+ case Tegra::DepthFormat::Z32_FLOAT:
+ return PixelFormat::Z32F;
+ case Tegra::DepthFormat::Z16_UNORM:
+ return PixelFormat::Z16;
+ case Tegra::DepthFormat::Z32_S8_X24_FLOAT:
+ return PixelFormat::Z32FS8;
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
+ UNREACHABLE();
+ }
+}
+
+PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) {
+ switch (format) {
+ // TODO (Hexagon12): Converting SRGBA to RGBA is a hack and doesn't completely correct the
+ // gamma.
+ case Tegra::RenderTargetFormat::RGBA8_SRGB:
+ return PixelFormat::RGBA8_SRGB;
+ case Tegra::RenderTargetFormat::RGBA8_UNORM:
+ return PixelFormat::ABGR8U;
+ case Tegra::RenderTargetFormat::RGBA8_SNORM:
+ return PixelFormat::ABGR8S;
+ case Tegra::RenderTargetFormat::RGBA8_UINT:
+ return PixelFormat::ABGR8UI;
+ case Tegra::RenderTargetFormat::BGRA8_SRGB:
+ return PixelFormat::BGRA8_SRGB;
+ case Tegra::RenderTargetFormat::BGRA8_UNORM:
+ return PixelFormat::BGRA8;
+ case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
+ return PixelFormat::A2B10G10R10U;
+ case Tegra::RenderTargetFormat::RGBA16_FLOAT:
+ return PixelFormat::RGBA16F;
+ case Tegra::RenderTargetFormat::RGBA16_UNORM:
+ return PixelFormat::RGBA16U;
+ case Tegra::RenderTargetFormat::RGBA16_UINT:
+ return PixelFormat::RGBA16UI;
+ case Tegra::RenderTargetFormat::RGBA32_FLOAT:
+ return PixelFormat::RGBA32F;
+ case Tegra::RenderTargetFormat::RG32_FLOAT:
+ return PixelFormat::RG32F;
+ case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
+ return PixelFormat::R11FG11FB10F;
+ case Tegra::RenderTargetFormat::B5G6R5_UNORM:
+ return PixelFormat::B5G6R5U;
+ case Tegra::RenderTargetFormat::BGR5A1_UNORM:
+ return PixelFormat::A1B5G5R5U;
+ case Tegra::RenderTargetFormat::RGBA32_UINT:
+ return PixelFormat::RGBA32UI;
+ case Tegra::RenderTargetFormat::R8_UNORM:
+ return PixelFormat::R8U;
+ case Tegra::RenderTargetFormat::R8_UINT:
+ return PixelFormat::R8UI;
+ case Tegra::RenderTargetFormat::RG16_FLOAT:
+ return PixelFormat::RG16F;
+ case Tegra::RenderTargetFormat::RG16_UINT:
+ return PixelFormat::RG16UI;
+ case Tegra::RenderTargetFormat::RG16_SINT:
+ return PixelFormat::RG16I;
+ case Tegra::RenderTargetFormat::RG16_UNORM:
+ return PixelFormat::RG16;
+ case Tegra::RenderTargetFormat::RG16_SNORM:
+ return PixelFormat::RG16S;
+ case Tegra::RenderTargetFormat::RG8_UNORM:
+ return PixelFormat::RG8U;
+ case Tegra::RenderTargetFormat::RG8_SNORM:
+ return PixelFormat::RG8S;
+ case Tegra::RenderTargetFormat::R16_FLOAT:
+ return PixelFormat::R16F;
+ case Tegra::RenderTargetFormat::R16_UNORM:
+ return PixelFormat::R16U;
+ case Tegra::RenderTargetFormat::R16_SNORM:
+ return PixelFormat::R16S;
+ case Tegra::RenderTargetFormat::R16_UINT:
+ return PixelFormat::R16UI;
+ case Tegra::RenderTargetFormat::R16_SINT:
+ return PixelFormat::R16I;
+ case Tegra::RenderTargetFormat::R32_FLOAT:
+ return PixelFormat::R32F;
+ case Tegra::RenderTargetFormat::R32_UINT:
+ return PixelFormat::R32UI;
+ case Tegra::RenderTargetFormat::RG32_UINT:
+ return PixelFormat::RG32UI;
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
+ UNREACHABLE();
+ }
+}
+
+PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
+ Tegra::Texture::ComponentType component_type,
+ bool is_srgb) {
+ // TODO(Subv): Properly implement this
+ switch (format) {
+ case Tegra::Texture::TextureFormat::A8R8G8B8:
+ if (is_srgb) {
+ return PixelFormat::RGBA8_SRGB;
+ }
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::ABGR8U;
+ case Tegra::Texture::ComponentType::SNORM:
+ return PixelFormat::ABGR8S;
+ case Tegra::Texture::ComponentType::UINT:
+ return PixelFormat::ABGR8UI;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::B5G6R5:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::B5G6R5U;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::A2B10G10R10:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::A2B10G10R10U;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::A1B5G5R5:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::A1B5G5R5U;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::R8:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::R8U;
+ case Tegra::Texture::ComponentType::UINT:
+ return PixelFormat::R8UI;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::G8R8:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::G8R8U;
+ case Tegra::Texture::ComponentType::SNORM:
+ return PixelFormat::G8R8S;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::R16_G16_B16_A16:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::RGBA16U;
+ case Tegra::Texture::ComponentType::FLOAT:
+ return PixelFormat::RGBA16F;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::BF10GF11RF11:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::FLOAT:
+ return PixelFormat::R11FG11FB10F;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::R32_G32_B32_A32:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::FLOAT:
+ return PixelFormat::RGBA32F;
+ case Tegra::Texture::ComponentType::UINT:
+ return PixelFormat::RGBA32UI;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::R32_G32:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::FLOAT:
+ return PixelFormat::RG32F;
+ case Tegra::Texture::ComponentType::UINT:
+ return PixelFormat::RG32UI;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::R32_G32_B32:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::FLOAT:
+ return PixelFormat::RGB32F;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::R16:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::FLOAT:
+ return PixelFormat::R16F;
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::R16U;
+ case Tegra::Texture::ComponentType::SNORM:
+ return PixelFormat::R16S;
+ case Tegra::Texture::ComponentType::UINT:
+ return PixelFormat::R16UI;
+ case Tegra::Texture::ComponentType::SINT:
+ return PixelFormat::R16I;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::R32:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::FLOAT:
+ return PixelFormat::R32F;
+ case Tegra::Texture::ComponentType::UINT:
+ return PixelFormat::R32UI;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::ZF32:
+ return PixelFormat::Z32F;
+ case Tegra::Texture::TextureFormat::Z16:
+ return PixelFormat::Z16;
+ case Tegra::Texture::TextureFormat::Z24S8:
+ return PixelFormat::Z24S8;
+ case Tegra::Texture::TextureFormat::DXT1:
+ return is_srgb ? PixelFormat::DXT1_SRGB : PixelFormat::DXT1;
+ case Tegra::Texture::TextureFormat::DXT23:
+ return is_srgb ? PixelFormat::DXT23_SRGB : PixelFormat::DXT23;
+ case Tegra::Texture::TextureFormat::DXT45:
+ return is_srgb ? PixelFormat::DXT45_SRGB : PixelFormat::DXT45;
+ case Tegra::Texture::TextureFormat::DXN1:
+ return PixelFormat::DXN1;
+ case Tegra::Texture::TextureFormat::DXN2:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::DXN2UNORM;
+ case Tegra::Texture::ComponentType::SNORM:
+ return PixelFormat::DXN2SNORM;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ case Tegra::Texture::TextureFormat::BC7U:
+ return is_srgb ? PixelFormat::BC7U_SRGB : PixelFormat::BC7U;
+ case Tegra::Texture::TextureFormat::BC6H_UF16:
+ return PixelFormat::BC6H_UF16;
+ case Tegra::Texture::TextureFormat::BC6H_SF16:
+ return PixelFormat::BC6H_SF16;
+ case Tegra::Texture::TextureFormat::ASTC_2D_4X4:
+ return is_srgb ? PixelFormat::ASTC_2D_4X4_SRGB : PixelFormat::ASTC_2D_4X4;
+ case Tegra::Texture::TextureFormat::ASTC_2D_5X4:
+ return is_srgb ? PixelFormat::ASTC_2D_5X4_SRGB : PixelFormat::ASTC_2D_5X4;
+ case Tegra::Texture::TextureFormat::ASTC_2D_8X8:
+ return is_srgb ? PixelFormat::ASTC_2D_8X8_SRGB : PixelFormat::ASTC_2D_8X8;
+ case Tegra::Texture::TextureFormat::ASTC_2D_8X5:
+ return is_srgb ? PixelFormat::ASTC_2D_8X5_SRGB : PixelFormat::ASTC_2D_8X5;
+ case Tegra::Texture::TextureFormat::R16_G16:
+ switch (component_type) {
+ case Tegra::Texture::ComponentType::FLOAT:
+ return PixelFormat::RG16F;
+ case Tegra::Texture::ComponentType::UNORM:
+ return PixelFormat::RG16;
+ case Tegra::Texture::ComponentType::SNORM:
+ return PixelFormat::RG16S;
+ case Tegra::Texture::ComponentType::UINT:
+ return PixelFormat::RG16UI;
+ case Tegra::Texture::ComponentType::SINT:
+ return PixelFormat::RG16I;
+ }
+ LOG_CRITICAL(HW_GPU, "Unimplemented component_type={}", static_cast<u32>(component_type));
+ UNREACHABLE();
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented format={}, component_type={}", static_cast<u32>(format),
+ static_cast<u32>(component_type));
+ UNREACHABLE();
+ }
+}
+
+ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type) {
+ // TODO(Subv): Implement more component types
+ switch (type) {
+ case Tegra::Texture::ComponentType::UNORM:
+ return ComponentType::UNorm;
+ case Tegra::Texture::ComponentType::FLOAT:
+ return ComponentType::Float;
+ case Tegra::Texture::ComponentType::SNORM:
+ return ComponentType::SNorm;
+ case Tegra::Texture::ComponentType::UINT:
+ return ComponentType::UInt;
+ case Tegra::Texture::ComponentType::SINT:
+ return ComponentType::SInt;
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented component type={}", static_cast<u32>(type));
+ UNREACHABLE();
+ }
+}
+
+ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format) {
+ // TODO(Subv): Implement more render targets
+ switch (format) {
+ case Tegra::RenderTargetFormat::RGBA8_UNORM:
+ case Tegra::RenderTargetFormat::RGBA8_SRGB:
+ case Tegra::RenderTargetFormat::BGRA8_UNORM:
+ case Tegra::RenderTargetFormat::BGRA8_SRGB:
+ case Tegra::RenderTargetFormat::RGB10_A2_UNORM:
+ case Tegra::RenderTargetFormat::R8_UNORM:
+ case Tegra::RenderTargetFormat::RG16_UNORM:
+ case Tegra::RenderTargetFormat::R16_UNORM:
+ case Tegra::RenderTargetFormat::B5G6R5_UNORM:
+ case Tegra::RenderTargetFormat::BGR5A1_UNORM:
+ case Tegra::RenderTargetFormat::RG8_UNORM:
+ case Tegra::RenderTargetFormat::RGBA16_UNORM:
+ return ComponentType::UNorm;
+ case Tegra::RenderTargetFormat::RGBA8_SNORM:
+ case Tegra::RenderTargetFormat::RG16_SNORM:
+ case Tegra::RenderTargetFormat::R16_SNORM:
+ case Tegra::RenderTargetFormat::RG8_SNORM:
+ return ComponentType::SNorm;
+ case Tegra::RenderTargetFormat::RGBA16_FLOAT:
+ case Tegra::RenderTargetFormat::R11G11B10_FLOAT:
+ case Tegra::RenderTargetFormat::RGBA32_FLOAT:
+ case Tegra::RenderTargetFormat::RG32_FLOAT:
+ case Tegra::RenderTargetFormat::RG16_FLOAT:
+ case Tegra::RenderTargetFormat::R16_FLOAT:
+ case Tegra::RenderTargetFormat::R32_FLOAT:
+ return ComponentType::Float;
+ case Tegra::RenderTargetFormat::RGBA32_UINT:
+ case Tegra::RenderTargetFormat::RGBA16_UINT:
+ case Tegra::RenderTargetFormat::RG16_UINT:
+ case Tegra::RenderTargetFormat::R8_UINT:
+ case Tegra::RenderTargetFormat::R16_UINT:
+ case Tegra::RenderTargetFormat::RG32_UINT:
+ case Tegra::RenderTargetFormat::R32_UINT:
+ case Tegra::RenderTargetFormat::RGBA8_UINT:
+ return ComponentType::UInt;
+ case Tegra::RenderTargetFormat::RG16_SINT:
+ case Tegra::RenderTargetFormat::R16_SINT:
+ return ComponentType::SInt;
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
+ UNREACHABLE();
+ }
+}
+
+PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format) {
+ switch (format) {
+ case Tegra::FramebufferConfig::PixelFormat::ABGR8:
+ return PixelFormat::ABGR8U;
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
+ UNREACHABLE();
+ }
+}
+
+ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format) {
+ switch (format) {
+ case Tegra::DepthFormat::Z16_UNORM:
+ case Tegra::DepthFormat::S8_Z24_UNORM:
+ case Tegra::DepthFormat::Z24_S8_UNORM:
+ return ComponentType::UNorm;
+ case Tegra::DepthFormat::Z32_FLOAT:
+ case Tegra::DepthFormat::Z32_S8_X24_FLOAT:
+ return ComponentType::Float;
+ default:
+ LOG_CRITICAL(HW_GPU, "Unimplemented format={}", static_cast<u32>(format));
+ UNREACHABLE();
+ }
+}
+
+SurfaceType GetFormatType(PixelFormat pixel_format) {
+ if (static_cast<std::size_t>(pixel_format) <
+ static_cast<std::size_t>(PixelFormat::MaxColorFormat)) {
+ return SurfaceType::ColorTexture;
+ }
+
+ if (static_cast<std::size_t>(pixel_format) <
+ static_cast<std::size_t>(PixelFormat::MaxDepthFormat)) {
+ return SurfaceType::Depth;
+ }
+
+ if (static_cast<std::size_t>(pixel_format) <
+ static_cast<std::size_t>(PixelFormat::MaxDepthStencilFormat)) {
+ return SurfaceType::DepthStencil;
+ }
+
+ // TODO(Subv): Implement the other formats
+ ASSERT(false);
+
+ return SurfaceType::Invalid;
+}
+
+bool IsPixelFormatASTC(PixelFormat format) {
+ switch (format) {
+ case PixelFormat::ASTC_2D_4X4:
+ case PixelFormat::ASTC_2D_5X4:
+ case PixelFormat::ASTC_2D_8X8:
+ case PixelFormat::ASTC_2D_8X5:
+ case PixelFormat::ASTC_2D_4X4_SRGB:
+ case PixelFormat::ASTC_2D_5X4_SRGB:
+ case PixelFormat::ASTC_2D_8X8_SRGB:
+ case PixelFormat::ASTC_2D_8X5_SRGB:
+ return true;
+ default:
+ return false;
+ }
+}
+
+std::pair<u32, u32> GetASTCBlockSize(PixelFormat format) {
+ switch (format) {
+ case PixelFormat::ASTC_2D_4X4:
+ return {4, 4};
+ case PixelFormat::ASTC_2D_5X4:
+ return {5, 4};
+ case PixelFormat::ASTC_2D_8X8:
+ return {8, 8};
+ case PixelFormat::ASTC_2D_8X5:
+ return {8, 5};
+ case PixelFormat::ASTC_2D_4X4_SRGB:
+ return {4, 4};
+ case PixelFormat::ASTC_2D_5X4_SRGB:
+ return {5, 4};
+ case PixelFormat::ASTC_2D_8X8_SRGB:
+ return {8, 8};
+ case PixelFormat::ASTC_2D_8X5_SRGB:
+ return {8, 5};
+ default:
+ LOG_CRITICAL(HW_GPU, "Unhandled format: {}", static_cast<u32>(format));
+ UNREACHABLE();
+ }
+}
+
+bool IsFormatBCn(PixelFormat format) {
+ switch (format) {
+ case PixelFormat::DXT1:
+ case PixelFormat::DXT23:
+ case PixelFormat::DXT45:
+ case PixelFormat::DXN1:
+ case PixelFormat::DXN2SNORM:
+ case PixelFormat::DXN2UNORM:
+ case PixelFormat::BC7U:
+ case PixelFormat::BC6H_UF16:
+ case PixelFormat::BC6H_SF16:
+ case PixelFormat::DXT1_SRGB:
+ case PixelFormat::DXT23_SRGB:
+ case PixelFormat::DXT45_SRGB:
+ case PixelFormat::BC7U_SRGB:
+ return true;
+ }
+ return false;
+}
+
+} // 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 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <climits>
+#include <utility>
+#include "common/assert.h"
+#include "common/common_types.h"
+#include "common/logging/log.h"
+#include "video_core/gpu.h"
+#include "video_core/textures/texture.h"
+
+namespace VideoCore::Surface {
+
+enum class PixelFormat {
+ ABGR8U = 0,
+ ABGR8S = 1,
+ ABGR8UI = 2,
+ B5G6R5U = 3,
+ A2B10G10R10U = 4,
+ A1B5G5R5U = 5,
+ R8U = 6,
+ R8UI = 7,
+ RGBA16F = 8,
+ RGBA16U = 9,
+ RGBA16UI = 10,
+ R11FG11FB10F = 11,
+ RGBA32UI = 12,
+ DXT1 = 13,
+ DXT23 = 14,
+ DXT45 = 15,
+ DXN1 = 16, // This is also known as BC4
+ DXN2UNORM = 17,
+ DXN2SNORM = 18,
+ BC7U = 19,
+ BC6H_UF16 = 20,
+ BC6H_SF16 = 21,
+ ASTC_2D_4X4 = 22,
+ G8R8U = 23,
+ G8R8S = 24,
+ BGRA8 = 25,
+ RGBA32F = 26,
+ RG32F = 27,
+ R32F = 28,
+ R16F = 29,
+ R16U = 30,
+ R16S = 31,
+ R16UI = 32,
+ R16I = 33,
+ RG16 = 34,
+ RG16F = 35,
+ RG16UI = 36,
+ RG16I = 37,
+ RG16S = 38,
+ RGB32F = 39,
+ RGBA8_SRGB = 40,
+ RG8U = 41,
+ RG8S = 42,
+ RG32UI = 43,
+ R32UI = 44,
+ ASTC_2D_8X8 = 45,
+ ASTC_2D_8X5 = 46,
+ ASTC_2D_5X4 = 47,
+ BGRA8_SRGB = 48,
+ DXT1_SRGB = 49,
+ DXT23_SRGB = 50,
+ DXT45_SRGB = 51,
+ BC7U_SRGB = 52,
+ ASTC_2D_4X4_SRGB = 53,
+ ASTC_2D_8X8_SRGB = 54,
+ ASTC_2D_8X5_SRGB = 55,
+ ASTC_2D_5X4_SRGB = 56,
+
+ MaxColorFormat,
+
+ // Depth formats
+ Z32F = 57,
+ Z16 = 58,
+
+ MaxDepthFormat,
+
+ // DepthStencil formats
+ Z24S8 = 59,
+ S8Z24 = 60,
+ Z32FS8 = 61,
+
+ MaxDepthStencilFormat,
+
+ Max = MaxDepthStencilFormat,
+ Invalid = 255,
+};
+
+static constexpr std::size_t MaxPixelFormat = static_cast<std::size_t>(PixelFormat::Max);
+
+enum class ComponentType {
+ Invalid = 0,
+ SNorm = 1,
+ UNorm = 2,
+ SInt = 3,
+ UInt = 4,
+ Float = 5,
+};
+
+enum class SurfaceType {
+ ColorTexture = 0,
+ Depth = 1,
+ DepthStencil = 2,
+ Fill = 3,
+ Invalid = 4,
+};
+
+enum class SurfaceTarget {
+ Texture1D,
+ Texture2D,
+ Texture3D,
+ Texture1DArray,
+ Texture2DArray,
+ TextureCubemap,
+};
+
+/**
+ * Gets the compression factor for the specified PixelFormat. This applies to just the
+ * "compressed width" and "compressed height", not the overall compression factor of a
+ * compressed image. This is used for maintaining proper surface sizes for compressed
+ * texture formats.
+ */
+static constexpr u32 GetCompressionFactor(PixelFormat format) {
+ if (format == PixelFormat::Invalid)
+ return 0;
+
+ constexpr std::array<u32, MaxPixelFormat> compression_factor_table = {{
+ 1, // ABGR8U
+ 1, // ABGR8S
+ 1, // ABGR8UI
+ 1, // B5G6R5U
+ 1, // A2B10G10R10U
+ 1, // A1B5G5R5U
+ 1, // R8U
+ 1, // R8UI
+ 1, // RGBA16F
+ 1, // RGBA16U
+ 1, // RGBA16UI
+ 1, // R11FG11FB10F
+ 1, // RGBA32UI
+ 4, // DXT1
+ 4, // DXT23
+ 4, // DXT45
+ 4, // DXN1
+ 4, // DXN2UNORM
+ 4, // DXN2SNORM
+ 4, // BC7U
+ 4, // BC6H_UF16
+ 4, // BC6H_SF16
+ 4, // ASTC_2D_4X4
+ 1, // G8R8U
+ 1, // G8R8S
+ 1, // BGRA8
+ 1, // RGBA32F
+ 1, // RG32F
+ 1, // R32F
+ 1, // R16F
+ 1, // R16U
+ 1, // R16S
+ 1, // R16UI
+ 1, // R16I
+ 1, // RG16
+ 1, // RG16F
+ 1, // RG16UI
+ 1, // RG16I
+ 1, // RG16S
+ 1, // RGB32F
+ 1, // RGBA8_SRGB
+ 1, // RG8U
+ 1, // RG8S
+ 1, // RG32UI
+ 1, // R32UI
+ 4, // ASTC_2D_8X8
+ 4, // ASTC_2D_8X5
+ 4, // ASTC_2D_5X4
+ 1, // BGRA8_SRGB
+ 4, // DXT1_SRGB
+ 4, // DXT23_SRGB
+ 4, // DXT45_SRGB
+ 4, // BC7U_SRGB
+ 4, // ASTC_2D_4X4_SRGB
+ 4, // ASTC_2D_8X8_SRGB
+ 4, // ASTC_2D_8X5_SRGB
+ 4, // ASTC_2D_5X4_SRGB
+ 1, // Z32F
+ 1, // Z16
+ 1, // Z24S8
+ 1, // S8Z24
+ 1, // Z32FS8
+ }};
+
+ ASSERT(static_cast<std::size_t>(format) < compression_factor_table.size());
+ return compression_factor_table[static_cast<std::size_t>(format)];
+}
+
+static constexpr u32 GetDefaultBlockHeight(PixelFormat format) {
+ if (format == PixelFormat::Invalid)
+ return 0;
+
+ constexpr std::array<u32, MaxPixelFormat> block_height_table = {{
+ 1, // ABGR8U
+ 1, // ABGR8S
+ 1, // ABGR8UI
+ 1, // B5G6R5U
+ 1, // A2B10G10R10U
+ 1, // A1B5G5R5U
+ 1, // R8U
+ 1, // R8UI
+ 1, // RGBA16F
+ 1, // RGBA16U
+ 1, // RGBA16UI
+ 1, // R11FG11FB10F
+ 1, // RGBA32UI
+ 4, // DXT1
+ 4, // DXT23
+ 4, // DXT45
+ 4, // DXN1
+ 4, // DXN2UNORM
+ 4, // DXN2SNORM
+ 4, // BC7U
+ 4, // BC6H_UF16
+ 4, // BC6H_SF16
+ 4, // ASTC_2D_4X4
+ 1, // G8R8U
+ 1, // G8R8S
+ 1, // BGRA8
+ 1, // RGBA32F
+ 1, // RG32F
+ 1, // R32F
+ 1, // R16F
+ 1, // R16U
+ 1, // R16S
+ 1, // R16UI
+ 1, // R16I
+ 1, // RG16
+ 1, // RG16F
+ 1, // RG16UI
+ 1, // RG16I
+ 1, // RG16S
+ 1, // RGB32F
+ 1, // RGBA8_SRGB
+ 1, // RG8U
+ 1, // RG8S
+ 1, // RG32UI
+ 1, // R32UI
+ 8, // ASTC_2D_8X8
+ 5, // ASTC_2D_8X5
+ 4, // ASTC_2D_5X4
+ 1, // BGRA8_SRGB
+ 4, // DXT1_SRGB
+ 4, // DXT23_SRGB
+ 4, // DXT45_SRGB
+ 4, // BC7U_SRGB
+ 4, // ASTC_2D_4X4_SRGB
+ 8, // ASTC_2D_8X8_SRGB
+ 5, // ASTC_2D_8X5_SRGB
+ 4, // ASTC_2D_5X4_SRGB
+ 1, // Z32F
+ 1, // Z16
+ 1, // Z24S8
+ 1, // S8Z24
+ 1, // Z32FS8
+ }};
+
+ ASSERT(static_cast<std::size_t>(format) < block_height_table.size());
+ return block_height_table[static_cast<std::size_t>(format)];
+}
+
+static constexpr u32 GetFormatBpp(PixelFormat format) {
+ if (format == PixelFormat::Invalid)
+ return 0;
+
+ constexpr std::array<u32, MaxPixelFormat> bpp_table = {{
+ 32, // ABGR8U
+ 32, // ABGR8S
+ 32, // ABGR8UI
+ 16, // B5G6R5U
+ 32, // A2B10G10R10U
+ 16, // A1B5G5R5U
+ 8, // R8U
+ 8, // R8UI
+ 64, // RGBA16F
+ 64, // RGBA16U
+ 64, // RGBA16UI
+ 32, // R11FG11FB10F
+ 128, // RGBA32UI
+ 64, // DXT1
+ 128, // DXT23
+ 128, // DXT45
+ 64, // DXN1
+ 128, // DXN2UNORM
+ 128, // DXN2SNORM
+ 128, // BC7U
+ 128, // BC6H_UF16
+ 128, // BC6H_SF16
+ 32, // ASTC_2D_4X4
+ 16, // G8R8U
+ 16, // G8R8S
+ 32, // BGRA8
+ 128, // RGBA32F
+ 64, // RG32F
+ 32, // R32F
+ 16, // R16F
+ 16, // R16U
+ 16, // R16S
+ 16, // R16UI
+ 16, // R16I
+ 32, // RG16
+ 32, // RG16F
+ 32, // RG16UI
+ 32, // RG16I
+ 32, // RG16S
+ 96, // RGB32F
+ 32, // RGBA8_SRGB
+ 16, // RG8U
+ 16, // RG8S
+ 64, // RG32UI
+ 32, // R32UI
+ 16, // ASTC_2D_8X8
+ 16, // ASTC_2D_8X5
+ 32, // ASTC_2D_5X4
+ 32, // BGRA8_SRGB
+ 64, // DXT1_SRGB
+ 128, // DXT23_SRGB
+ 128, // DXT45_SRGB
+ 128, // BC7U
+ 32, // ASTC_2D_4X4_SRGB
+ 16, // ASTC_2D_8X8_SRGB
+ 16, // ASTC_2D_8X5_SRGB
+ 32, // ASTC_2D_5X4_SRGB
+ 32, // Z32F
+ 16, // Z16
+ 32, // Z24S8
+ 32, // S8Z24
+ 64, // Z32FS8
+ }};
+
+ ASSERT(static_cast<std::size_t>(format) < bpp_table.size());
+ return bpp_table[static_cast<std::size_t>(format)];
+}
+
+/// Returns the sizer in bytes of the specified pixel format
+static constexpr u32 GetBytesPerPixel(PixelFormat pixel_format) {
+ if (pixel_format == PixelFormat::Invalid) {
+ return 0;
+ }
+ return GetFormatBpp(pixel_format) / CHAR_BIT;
+}
+
+SurfaceTarget SurfaceTargetFromTextureType(Tegra::Texture::TextureType texture_type);
+
+bool SurfaceTargetIsLayered(SurfaceTarget target);
+
+PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format);
+
+PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format);
+
+PixelFormat PixelFormatFromTextureFormat(Tegra::Texture::TextureFormat format,
+ Tegra::Texture::ComponentType component_type,
+ bool is_srgb);
+
+ComponentType ComponentTypeFromTexture(Tegra::Texture::ComponentType type);
+
+ComponentType ComponentTypeFromRenderTarget(Tegra::RenderTargetFormat format);
+
+PixelFormat PixelFormatFromGPUPixelFormat(Tegra::FramebufferConfig::PixelFormat format);
+
+ComponentType ComponentTypeFromDepthFormat(Tegra::DepthFormat format);
+
+SurfaceType GetFormatType(PixelFormat pixel_format);
+
+bool IsPixelFormatASTC(PixelFormat format);
+
+std::pair<u32, u32> GetASTCBlockSize(PixelFormat format);
+
+/// Returns true if the specified PixelFormat is a BCn format, e.g. DXT or DXN
+bool IsFormatBCn(PixelFormat format);
+
+} // namespace VideoCore::Surface