diff options
| -rw-r--r-- | src/video_core/renderer_opengl/gl_texture_cache.cpp | 26 | ||||
| -rw-r--r-- | src/video_core/renderer_opengl/maxwell_to_gl.h | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/maxwell_to_vk.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_texture_cache.cpp | 49 | ||||
| -rw-r--r-- | src/video_core/surface.h | 8 | ||||
| -rw-r--r-- | src/video_core/texture_cache/format_lookup_table.cpp | 6 | ||||
| -rw-r--r-- | src/video_core/texture_cache/formatter.h | 4 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 12 | 
8 files changed, 102 insertions, 7 deletions
| diff --git a/src/video_core/renderer_opengl/gl_texture_cache.cpp b/src/video_core/renderer_opengl/gl_texture_cache.cpp index d12076358..f8c6e5c7e 100644 --- a/src/video_core/renderer_opengl/gl_texture_cache.cpp +++ b/src/video_core/renderer_opengl/gl_texture_cache.cpp @@ -182,6 +182,26 @@ GLenum AttachmentType(PixelFormat format) {      }  } +GLint ConvertA5B5G5R1_UNORM(SwizzleSource source) { +    switch (source) { +    case SwizzleSource::Zero: +        return GL_ZERO; +    case SwizzleSource::R: +        return GL_ALPHA; +    case SwizzleSource::G: +        return GL_BLUE; +    case SwizzleSource::B: +        return GL_GREEN; +    case SwizzleSource::A: +        return GL_RED; +    case SwizzleSource::OneInt: +    case SwizzleSource::OneFloat: +        return GL_ONE; +    } +    UNREACHABLE_MSG("Invalid swizzle source={}", source); +    return GL_NONE; +} +  void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4> swizzle) {      switch (format) {      case PixelFormat::D24_UNORM_S8_UINT: @@ -192,6 +212,12 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4                              TextureMode(format, swizzle[0] == SwizzleSource::R));          std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed);          break; +    case PixelFormat::A5B5G5R1_UNORM: { +        std::array<GLint, 4> gl_swizzle; +        std::ranges::transform(swizzle, gl_swizzle.begin(), ConvertA5B5G5R1_UNORM); +        glTextureParameteriv(handle, GL_TEXTURE_SWIZZLE_RGBA, gl_swizzle.data()); +        return; +    }      default:          break;      } diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h index db5bf1d30..03adf3d4c 100644 --- a/src/video_core/renderer_opengl/maxwell_to_gl.h +++ b/src/video_core/renderer_opengl/maxwell_to_gl.h @@ -30,6 +30,7 @@ constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> FORMAT_TAB      {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_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      {GL_R8_SNORM, GL_RED, GL_BYTE},                                   // R8_SNORM      {GL_R8I, GL_RED_INTEGER, GL_BYTE},                                // R8_SINT @@ -87,6 +88,7 @@ constexpr std::array<FormatTuple, VideoCore::Surface::MaxPixelFormat> FORMAT_TAB      {GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT},                         // BC3_SRGB      {GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM},                            // BC7_SRGB      {GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV},               // A4B4G4R4_UNORM +    {GL_R8, GL_RED, GL_UNSIGNED_BYTE},                                // R4G4_UNORM      {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR},                        // ASTC_2D_4X4_SRGB      {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR},                        // ASTC_2D_8X8_SRGB      {GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR},                        // ASTC_2D_8X5_SRGB diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp index 1c136c410..a2c6d0e6c 100644 --- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp +++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp @@ -127,6 +127,7 @@ struct FormatTuple {      {VK_FORMAT_A2B10G10R10_UNORM_PACK32, Attachable | Storage}, // A2B10G10R10_UNORM      {VK_FORMAT_A2B10G10R10_UINT_PACK32, Attachable | Storage},  // A2B10G10R10_UINT      {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      {VK_FORMAT_R8_SNORM, Attachable | Storage},            // R8_SNORM      {VK_FORMAT_R8_SINT, Attachable | Storage},             // R8_SINT @@ -184,6 +185,7 @@ struct FormatTuple {      {VK_FORMAT_BC3_SRGB_BLOCK},                                // BC3_SRGB      {VK_FORMAT_BC7_SRGB_BLOCK},                                // BC7_SRGB      {VK_FORMAT_R4G4B4A4_UNORM_PACK16, Attachable},             // A4B4G4R4_UNORM +    {VK_FORMAT_R4G4_UNORM_PACK8},                              // R4G4_UNORM      {VK_FORMAT_ASTC_4x4_SRGB_BLOCK},                           // ASTC_2D_4X4_SRGB      {VK_FORMAT_ASTC_8x8_SRGB_BLOCK},                           // ASTC_2D_8X8_SRGB      {VK_FORMAT_ASTC_8x5_SRGB_BLOCK},                           // ASTC_2D_8X5_SRGB diff --git a/src/video_core/renderer_vulkan/vk_texture_cache.cpp b/src/video_core/renderer_vulkan/vk_texture_cache.cpp index 2c2ccc7c6..49691ce0c 100644 --- a/src/video_core/renderer_vulkan/vk_texture_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_texture_cache.cpp @@ -438,6 +438,32 @@ constexpr VkBorderColor ConvertBorderColor(const std::array<float, 4>& color) {      }  } +[[nodiscard]] SwizzleSource SwapGreenRed(SwizzleSource value) { +    switch (value) { +    case SwizzleSource::R: +        return SwizzleSource::G; +    case SwizzleSource::G: +        return SwizzleSource::R; +    default: +        return value; +    } +} + +[[nodiscard]] SwizzleSource SwapSpecial(SwizzleSource value) { +    switch (value) { +    case SwizzleSource::A: +        return SwizzleSource::R; +    case SwizzleSource::R: +        return SwizzleSource::A; +    case SwizzleSource::G: +        return SwizzleSource::B; +    case SwizzleSource::B: +        return SwizzleSource::G; +    default: +        return value; +    } +} +  void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage image,                         VkImageAspectFlags aspect_mask, bool is_initialized,                         std::span<const VkBufferImageCopy> copies) { @@ -554,14 +580,25 @@ void CopyBufferToImage(vk::CommandBuffer cmdbuf, VkBuffer src_buffer, VkImage im      };  } -[[nodiscard]] bool IsFormatFlipped(PixelFormat format, bool emulate_bgr565) { +void TryTransformSwizzleIfNeeded(PixelFormat format, std::array<SwizzleSource, 4>& swizzle, +                                 bool emulate_bgr565) {      switch (format) {      case PixelFormat::A1B5G5R5_UNORM: -        return true; +        std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed); +        break;      case PixelFormat::B5G6R5_UNORM: -        return emulate_bgr565; +        if (emulate_bgr565) { +            std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed); +        } +        break; +    case PixelFormat::A5B5G5R1_UNORM: +        std::ranges::transform(swizzle, swizzle.begin(), SwapSpecial); +        break; +    case PixelFormat::R4G4_UNORM: +        std::ranges::transform(swizzle, swizzle.begin(), SwapGreenRed); +        break;      default: -        return false; +        break;      }  } @@ -1496,9 +1533,7 @@ ImageView::ImageView(TextureCacheRuntime& runtime, const VideoCommon::ImageViewI      };      if (!info.IsRenderTarget()) {          swizzle = info.Swizzle(); -        if (IsFormatFlipped(format, device->MustEmulateBGR565())) { -            std::ranges::transform(swizzle, swizzle.begin(), SwapBlueRed); -        } +        TryTransformSwizzleIfNeeded(format, swizzle, device->MustEmulateBGR565());          if ((aspect_mask & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0) {              std::ranges::transform(swizzle, swizzle.begin(), ConvertGreenRed);          } diff --git a/src/video_core/surface.h b/src/video_core/surface.h index 5704cf16a..86fea61ae 100644 --- a/src/video_core/surface.h +++ b/src/video_core/surface.h @@ -25,6 +25,7 @@ enum class PixelFormat {      A2B10G10R10_UNORM,      A2B10G10R10_UINT,      A1B5G5R5_UNORM, +    A5B5G5R1_UNORM,      R8_UNORM,      R8_SNORM,      R8_SINT, @@ -82,6 +83,7 @@ enum class PixelFormat {      BC3_SRGB,      BC7_SRGB,      A4B4G4R4_UNORM, +    R4G4_UNORM,      ASTC_2D_4X4_SRGB,      ASTC_2D_8X8_SRGB,      ASTC_2D_8X5_SRGB, @@ -156,6 +158,7 @@ constexpr std::array<u32, MaxPixelFormat> BLOCK_WIDTH_TABLE = {{      1,  // A2B10G10R10_UNORM      1,  // A2B10G10R10_UINT      1,  // A1B5G5R5_UNORM +    1,  // A5B5G5R1_UNORM      1,  // R8_UNORM      1,  // R8_SNORM      1,  // R8_SINT @@ -213,6 +216,7 @@ constexpr std::array<u32, MaxPixelFormat> BLOCK_WIDTH_TABLE = {{      4,  // BC3_SRGB      4,  // BC7_SRGB      1,  // A4B4G4R4_UNORM +    1,  // R4G4_UNORM      4,  // ASTC_2D_4X4_SRGB      8,  // ASTC_2D_8X8_SRGB      8,  // ASTC_2D_8X5_SRGB @@ -256,6 +260,7 @@ constexpr std::array<u32, MaxPixelFormat> BLOCK_HEIGHT_TABLE = {{      1,  // A2B10G10R10_UNORM      1,  // A2B10G10R10_UINT      1,  // A1B5G5R5_UNORM +    1,  // A5B5G5R1_UNORM      1,  // R8_UNORM      1,  // R8_SNORM      1,  // R8_SINT @@ -313,6 +318,7 @@ constexpr std::array<u32, MaxPixelFormat> BLOCK_HEIGHT_TABLE = {{      4,  // BC3_SRGB      4,  // BC7_SRGB      1,  // A4B4G4R4_UNORM +    1,  // R4G4_UNORM      4,  // ASTC_2D_4X4_SRGB      8,  // ASTC_2D_8X8_SRGB      5,  // ASTC_2D_8X5_SRGB @@ -356,6 +362,7 @@ constexpr std::array<u32, MaxPixelFormat> BITS_PER_BLOCK_TABLE = {{      32,  // A2B10G10R10_UNORM      32,  // A2B10G10R10_UINT      16,  // A1B5G5R5_UNORM +    16,  // A5B5G5R1_UNORM      8,   // R8_UNORM      8,   // R8_SNORM      8,   // R8_SINT @@ -413,6 +420,7 @@ constexpr std::array<u32, MaxPixelFormat> BITS_PER_BLOCK_TABLE = {{      128, // BC3_SRGB      128, // BC7_UNORM      16,  // A4B4G4R4_UNORM +    8,   // R4G4_UNORM      128, // ASTC_2D_4X4_SRGB      128, // ASTC_2D_8X8_SRGB      128, // ASTC_2D_8X5_SRGB diff --git a/src/video_core/texture_cache/format_lookup_table.cpp b/src/video_core/texture_cache/format_lookup_table.cpp index afa807d5d..20e64a7c2 100644 --- a/src/video_core/texture_cache/format_lookup_table.cpp +++ b/src/video_core/texture_cache/format_lookup_table.cpp @@ -63,6 +63,10 @@ PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red,          return PixelFormat::A1B5G5R5_UNORM;      case Hash(TextureFormat::A4B4G4R4, UNORM):          return PixelFormat::A4B4G4R4_UNORM; +    case Hash(TextureFormat::G4R4, UNORM): +        return PixelFormat::R4G4_UNORM; +    case Hash(TextureFormat::A5B5G5R1, UNORM): +        return PixelFormat::A5B5G5R1_UNORM;      case Hash(TextureFormat::R8, UNORM):          return PixelFormat::R8_UNORM;      case Hash(TextureFormat::R8, SNORM): @@ -143,6 +147,8 @@ PixelFormat PixelFormatFromTextureInfo(TextureFormat format, ComponentType red,          return PixelFormat::S8_UINT_D24_UNORM;      case Hash(TextureFormat::R8G24, UINT, UNORM, UNORM, UNORM, LINEAR):          return PixelFormat::S8_UINT_D24_UNORM; +    case Hash(TextureFormat::D24S8, UNORM, UINT, UINT, UINT, LINEAR): +        return PixelFormat::D24_UNORM_S8_UINT;      case Hash(TextureFormat::D32S8, FLOAT, UINT, UNORM, UNORM, LINEAR):          return PixelFormat::D32_FLOAT_S8_UINT;      case Hash(TextureFormat::BC1_RGBA, UNORM, LINEAR): diff --git a/src/video_core/texture_cache/formatter.h b/src/video_core/texture_cache/formatter.h index b2c81057b..6f5afc5a9 100644 --- a/src/video_core/texture_cache/formatter.h +++ b/src/video_core/texture_cache/formatter.h @@ -38,6 +38,8 @@ struct fmt::formatter<VideoCore::Surface::PixelFormat> : fmt::formatter<fmt::str                  return "A2B10G10R10_UINT";              case PixelFormat::A1B5G5R5_UNORM:                  return "A1B5G5R5_UNORM"; +            case PixelFormat::A5B5G5R1_UNORM: +                return "A5B5G5R1_UNORM";              case PixelFormat::R8_UNORM:                  return "R8_UNORM";              case PixelFormat::R8_SNORM: @@ -152,6 +154,8 @@ struct fmt::formatter<VideoCore::Surface::PixelFormat> : fmt::formatter<fmt::str                  return "BC7_SRGB";              case PixelFormat::A4B4G4R4_UNORM:                  return "A4B4G4R4_UNORM"; +            case PixelFormat::R4G4_UNORM: +                return "R4G4_UNORM";              case PixelFormat::ASTC_2D_4X4_SRGB:                  return "ASTC_2D_4X4_SRGB";              case PixelFormat::ASTC_2D_8X8_SRGB: diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index f3a05ada9..bd05a1f84 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -45,6 +45,12 @@ constexpr std::array B5G6R5_UNORM_PACK16{      VK_FORMAT_R5G6B5_UNORM_PACK16,      VK_FORMAT_UNDEFINED,  }; + +constexpr std::array R4G4_UNORM_PACK8{ +    VK_FORMAT_R8_UNORM, +    VK_FORMAT_UNDEFINED, +}; +  } // namespace Alternatives  enum class NvidiaArchitecture { @@ -95,6 +101,8 @@ constexpr const VkFormat* GetFormatAlternatives(VkFormat format) {          return Alternatives::DEPTH16_UNORM_STENCIL8_UINT.data();      case VK_FORMAT_B5G6R5_UNORM_PACK16:          return Alternatives::B5G6R5_UNORM_PACK16.data(); +    case VK_FORMAT_R4G4_UNORM_PACK8: +        return Alternatives::R4G4_UNORM_PACK8.data();      default:          return nullptr;      } @@ -122,6 +130,8 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica          VK_FORMAT_A8B8G8R8_SRGB_PACK32,          VK_FORMAT_R5G6B5_UNORM_PACK16,          VK_FORMAT_B5G6R5_UNORM_PACK16, +        VK_FORMAT_R5G5B5A1_UNORM_PACK16, +        VK_FORMAT_B5G5R5A1_UNORM_PACK16,          VK_FORMAT_A2B10G10R10_UNORM_PACK32,          VK_FORMAT_A2B10G10R10_UINT_PACK32,          VK_FORMAT_A1R5G5B5_UNORM_PACK16, @@ -160,7 +170,9 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica          VK_FORMAT_R16G16B16A16_SFLOAT,          VK_FORMAT_B8G8R8A8_UNORM,          VK_FORMAT_B8G8R8A8_SRGB, +        VK_FORMAT_R4G4_UNORM_PACK8,          VK_FORMAT_R4G4B4A4_UNORM_PACK16, +        VK_FORMAT_B4G4R4A4_UNORM_PACK16,          VK_FORMAT_D32_SFLOAT,          VK_FORMAT_D16_UNORM,          VK_FORMAT_S8_UINT, | 
