From 7356ab1de6ab7336da426b9176daafb3ebb503f5 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sun, 6 Nov 2022 15:19:08 +0100 Subject: GPU: Implement additional render target formats. --- src/video_core/engines/sw_blitter/converter.cpp | 106 ++++++++++++++++++++++- src/video_core/gpu.h | 14 +-- src/video_core/renderer_opengl/maxwell_to_gl.h | 1 + src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 1 + src/video_core/surface.cpp | 10 ++- src/video_core/surface.h | 4 + src/video_core/texture_cache/formatter.h | 2 + 7 files changed, 126 insertions(+), 12 deletions(-) (limited to 'src/video_core') diff --git a/src/video_core/engines/sw_blitter/converter.cpp b/src/video_core/engines/sw_blitter/converter.cpp index 408d87944..37c5eff69 100644 --- a/src/video_core/engines/sw_blitter/converter.cpp +++ b/src/video_core/engines/sw_blitter/converter.cpp @@ -133,13 +133,13 @@ constexpr std::array RGB_TO_SRGB_LUT = { } // namespace -struct R32B32G32A32_FLOATTraits { +struct R32G32B32A32_FLOATTraits { static constexpr size_t num_components = 4; static constexpr std::array component_types = { ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; static constexpr std::array component_sizes = {32, 32, 32, 32}; static constexpr std::array component_swizzle = { - Swizzle::R, Swizzle::B, Swizzle::G, Swizzle::A}; + Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; }; struct R32G32B32A32_SINTTraits { @@ -160,6 +160,33 @@ struct R32G32B32A32_UINTTraits { Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::A}; }; +struct R32G32B32X32_FLOATTraits { + static constexpr size_t num_components = 4; + static constexpr std::array component_types = { + ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT, ComponentType::FLOAT}; + static constexpr std::array component_sizes = {32, 32, 32, 32}; + static constexpr std::array component_swizzle = { + Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::None}; +}; + +struct R32G32B32X32_SINTTraits { + static constexpr size_t num_components = 4; + static constexpr std::array component_types = { + ComponentType::SINT, ComponentType::SINT, ComponentType::SINT, ComponentType::SINT}; + static constexpr std::array component_sizes = {32, 32, 32, 32}; + static constexpr std::array component_swizzle = { + Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::None}; +}; + +struct R32G32B32X32_UINTTraits { + static constexpr size_t num_components = 4; + static constexpr std::array component_types = { + ComponentType::UINT, ComponentType::UINT, ComponentType::UINT, ComponentType::UINT}; + static constexpr std::array component_sizes = {32, 32, 32, 32}; + static constexpr std::array component_swizzle = { + Swizzle::R, Swizzle::G, Swizzle::B, Swizzle::None}; +}; + struct R16G16B16A16_UNORMTraits { static constexpr size_t num_components = 4; static constexpr std::array component_types = { @@ -277,6 +304,15 @@ struct A2B10G10R10_UINTTraits { Swizzle::A, Swizzle::B, Swizzle::G, Swizzle::R}; }; +struct A2R10G10B10_UNORMTraits { + static constexpr size_t num_components = 4; + static constexpr std::array component_types = { + ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; + static constexpr std::array component_sizes = {2, 10, 10, 10}; + static constexpr std::array component_swizzle = { + Swizzle::A, Swizzle::R, Swizzle::G, Swizzle::B}; +}; + struct A8B8G8R8_UNORMTraits { static constexpr size_t num_components = 4; static constexpr std::array component_types = { @@ -544,6 +580,33 @@ struct R8_UINTTraits { static constexpr std::array component_swizzle = {Swizzle::R}; }; +struct X1R5G5B5_UNORMTraits { + static constexpr size_t num_components = 4; + static constexpr std::array component_types = { + ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; + static constexpr std::array component_sizes = {1, 5, 5, 5}; + static constexpr std::array component_swizzle = { + Swizzle::None, Swizzle::R, Swizzle::G, Swizzle::B}; +}; + +struct X8B8G8R8_UNORMTraits { + static constexpr size_t num_components = 4; + static constexpr std::array component_types = { + ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM, ComponentType::UNORM}; + static constexpr std::array component_sizes = {8, 8, 8, 8}; + static constexpr std::array component_swizzle = { + Swizzle::None, Swizzle::B, Swizzle::G, Swizzle::R}; +}; + +struct X8B8G8R8_SRGBTraits { + static constexpr size_t num_components = 4; + static constexpr std::array component_types = { + ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB, ComponentType::SRGB}; + static constexpr std::array component_sizes = {8, 8, 8, 8}; + static constexpr std::array component_swizzle = { + Swizzle::None, Swizzle::B, Swizzle::G, Swizzle::R}; +}; + template class ConverterImpl : public Converter { private: @@ -884,9 +947,9 @@ public: Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) { switch (format) { - case RenderTargetFormat::R32B32G32A32_FLOAT: + case RenderTargetFormat::R32G32B32A32_FLOAT: return impl->converters_cache - .emplace(format, std::make_unique>()) + .emplace(format, std::make_unique>()) .first->second.get(); break; case RenderTargetFormat::R32G32B32A32_SINT: @@ -899,6 +962,21 @@ Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) { .emplace(format, std::make_unique>()) .first->second.get(); break; + case RenderTargetFormat::R32G32B32X32_FLOAT: + return impl->converters_cache + .emplace(format, std::make_unique>()) + .first->second.get(); + break; + case RenderTargetFormat::R32G32B32X32_SINT: + return impl->converters_cache + .emplace(format, std::make_unique>()) + .first->second.get(); + break; + case RenderTargetFormat::R32G32B32X32_UINT: + return impl->converters_cache + .emplace(format, std::make_unique>()) + .first->second.get(); + break; case RenderTargetFormat::R16G16B16A16_UNORM: return impl->converters_cache .emplace(format, std::make_unique>()) @@ -964,6 +1042,11 @@ Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) { .emplace(format, std::make_unique>()) .first->second.get(); break; + case RenderTargetFormat::A2R10G10B10_UNORM: + return impl->converters_cache + .emplace(format, std::make_unique>()) + .first->second.get(); + break; case RenderTargetFormat::A8B8G8R8_UNORM: return impl->converters_cache .emplace(format, std::make_unique>()) @@ -1119,6 +1202,21 @@ Converter* ConverterFactory::BuildConverter(RenderTargetFormat format) { .emplace(format, std::make_unique>()) .first->second.get(); break; + case RenderTargetFormat::X1R5G5B5_UNORM: + return impl->converters_cache + .emplace(format, std::make_unique>()) + .first->second.get(); + break; + case RenderTargetFormat::X8B8G8R8_UNORM: + return impl->converters_cache + .emplace(format, std::make_unique>()) + .first->second.get(); + break; + case RenderTargetFormat::X8B8G8R8_SRGB: + return impl->converters_cache + .emplace(format, std::make_unique>()) + .first->second.get(); + break; default: { UNIMPLEMENTED_MSG("This format {} converter is not implemented", format); return impl->converters_cache.emplace(format, std::make_unique()) diff --git a/src/video_core/gpu.h b/src/video_core/gpu.h index 87ebf2054..8a871593a 100644 --- a/src/video_core/gpu.h +++ b/src/video_core/gpu.h @@ -27,12 +27,12 @@ struct CommandList; // TODO: Implement the commented ones enum class RenderTargetFormat : u32 { NONE = 0x0, - R32B32G32A32_FLOAT = 0xC0, + R32G32B32A32_FLOAT = 0xC0, R32G32B32A32_SINT = 0xC1, R32G32B32A32_UINT = 0xC2, - // R32G32B32X32_FLOAT = 0xC3, - // R32G32B32X32_SINT = 0xC4, - // R32G32B32X32_UINT = 0xC5, + R32G32B32X32_FLOAT = 0xC3, + R32G32B32X32_SINT = 0xC4, + R32G32B32X32_UINT = 0xC5, R16G16B16A16_UNORM = 0xC6, R16G16B16A16_SNORM = 0xC7, R16G16B16A16_SINT = 0xC8, @@ -56,7 +56,7 @@ enum class RenderTargetFormat : u32 { R16G16_SINT = 0xDC, R16G16_UINT = 0xDD, R16G16_FLOAT = 0xDE, - // A2R10G10B10_UNORM = 0xDF, + A2R10G10B10_UNORM = 0xDF, B10G11R11_FLOAT = 0xE0, R32_SINT = 0xE3, R32_UINT = 0xE4, @@ -79,11 +79,11 @@ enum class RenderTargetFormat : u32 { R8_SINT = 0xF5, R8_UINT = 0xF6, - /* - A8_UNORM = 0xF7, + // A8_UNORM = 0xF7, X1R5G5B5_UNORM = 0xF8, X8B8G8R8_UNORM = 0xF9, X8B8G8R8_SRGB = 0xFA, + /* Z1R5G5B5_UNORM = 0xFB, O1R5G5B5_UNORM = 0xFC, Z8R8G8B8_UNORM = 0xFD, diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index e14f9b2db..ef1190e1f 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -28,6 +28,7 @@ constexpr std::array FORMAT_TAB {GL_RGB5_A1, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1R5G5B5_UNORM {GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10_UNORM {GL_RGB10_A2UI, GL_RGBA_INTEGER, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2B10G10R10_UINT + {GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_2_10_10_10_REV}, // A2R10G10B10_UNORM {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV}, // A1B5G5R5_UNORM {GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1}, // A5B5G5R1_UNORM {GL_R8, GL_RED, GL_UNSIGNED_BYTE}, // R8_UNORM diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 5c156087b..1da53f203 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -125,6 +125,7 @@ struct FormatTuple { {VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1R5G5B5_UNORM {VK_FORMAT_A2B10G10R10_UNORM_PACK32, Attachable | Storage}, // A2B10G10R10_UNORM {VK_FORMAT_A2B10G10R10_UINT_PACK32, Attachable | Storage}, // A2B10G10R10_UINT + {VK_FORMAT_A2R10G10B10_UNORM_PACK32, Attachable | Storage}, // A2R10G10B10_UNORM {VK_FORMAT_A1R5G5B5_UNORM_PACK16, Attachable}, // A1B5G5R5_UNORM (flipped with swizzle) {VK_FORMAT_R5G5B5A1_UNORM_PACK16}, // A5B5G5R1_UNORM (specially swizzled) {VK_FORMAT_R8_UNORM, Attachable | Storage}, // R8_UNORM diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp index 80a7d908f..b618e1a25 100644 --- a/src/video_core/surface.cpp +++ b/src/video_core/surface.cpp @@ -93,11 +93,14 @@ PixelFormat PixelFormatFromDepthFormat(Tegra::DepthFormat format) { PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) { switch (format) { - case Tegra::RenderTargetFormat::R32B32G32A32_FLOAT: + case Tegra::RenderTargetFormat::R32G32B32A32_FLOAT: + case Tegra::RenderTargetFormat::R32G32B32X32_FLOAT: return PixelFormat::R32G32B32A32_FLOAT; case Tegra::RenderTargetFormat::R32G32B32A32_SINT: + case Tegra::RenderTargetFormat::R32G32B32X32_SINT: return PixelFormat::R32G32B32A32_SINT; case Tegra::RenderTargetFormat::R32G32B32A32_UINT: + case Tegra::RenderTargetFormat::R32G32B32X32_UINT: return PixelFormat::R32G32B32A32_UINT; case Tegra::RenderTargetFormat::R16G16B16A16_UNORM: return PixelFormat::R16G16B16A16_UNORM; @@ -127,9 +130,13 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) return PixelFormat::A2B10G10R10_UNORM; case Tegra::RenderTargetFormat::A2B10G10R10_UINT: return PixelFormat::A2B10G10R10_UINT; + case Tegra::RenderTargetFormat::A2R10G10B10_UNORM: + return PixelFormat::A2R10G10B10_UNORM; case Tegra::RenderTargetFormat::A8B8G8R8_UNORM: + case Tegra::RenderTargetFormat::X8B8G8R8_UNORM: return PixelFormat::A8B8G8R8_UNORM; case Tegra::RenderTargetFormat::A8B8G8R8_SRGB: + case Tegra::RenderTargetFormat::X8B8G8R8_SRGB: return PixelFormat::A8B8G8R8_SRGB; case Tegra::RenderTargetFormat::A8B8G8R8_SNORM: return PixelFormat::A8B8G8R8_SNORM; @@ -158,6 +165,7 @@ PixelFormat PixelFormatFromRenderTargetFormat(Tegra::RenderTargetFormat format) case Tegra::RenderTargetFormat::R5G6B5_UNORM: return PixelFormat::R5G6B5_UNORM; case Tegra::RenderTargetFormat::A1R5G5B5_UNORM: + case Tegra::RenderTargetFormat::X1R5G5B5_UNORM: return PixelFormat::A1R5G5B5_UNORM; case Tegra::RenderTargetFormat::R8G8_UNORM: return PixelFormat::R8G8_UNORM; diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 57ca7f597..44b79af20 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -23,6 +23,7 @@ enum class PixelFormat { A1R5G5B5_UNORM, A2B10G10R10_UNORM, A2B10G10R10_UINT, + A2R10G10B10_UNORM, A1B5G5R5_UNORM, A5B5G5R1_UNORM, R8_UNORM, @@ -159,6 +160,7 @@ constexpr std::array BLOCK_WIDTH_TABLE = {{ 1, // A1R5G5B5_UNORM 1, // A2B10G10R10_UNORM 1, // A2B10G10R10_UINT + 1, // A2R10G10B10_UNORM 1, // A1B5G5R5_UNORM 1, // A5B5G5R1_UNORM 1, // R8_UNORM @@ -264,6 +266,7 @@ constexpr std::array BLOCK_HEIGHT_TABLE = {{ 1, // A1R5G5B5_UNORM 1, // A2B10G10R10_UNORM 1, // A2B10G10R10_UINT + 1, // A2R10G10B10_UNORM 1, // A1B5G5R5_UNORM 1, // A5B5G5R1_UNORM 1, // R8_UNORM @@ -369,6 +372,7 @@ constexpr std::array BITS_PER_BLOCK_TABLE = {{ 16, // A1R5G5B5_UNORM 32, // A2B10G10R10_UNORM 32, // A2B10G10R10_UINT + 32, // A2R10G10B10_UNORM 16, // A1B5G5R5_UNORM 16, // A5B5G5R1_UNORM 8, // R8_UNORM diff --git a/src/video_core/texture_cache/formatter.h b/src/video_core/texture_cache/formatter.h index acc854715..f1f0a057b 100644 --- a/src/video_core/texture_cache/formatter.h +++ b/src/video_core/texture_cache/formatter.h @@ -35,6 +35,8 @@ struct fmt::formatter : fmt::formatter