From d6148b194e2d9d48581fc3567af06d546d972ad6 Mon Sep 17 00:00:00 2001 From: Samuliak Date: Sun, 6 Oct 2024 19:26:02 +0200 Subject: [PATCH] check for pixel format support --- .../renderer_metal/maxwell_to_mtl.cpp | 55 ++++++++++++++++++- .../renderer_metal/maxwell_to_mtl.h | 4 +- .../renderer_metal/renderer_metal.cpp | 3 + 3 files changed, 59 insertions(+), 3 deletions(-) diff --git a/src/video_core/renderer_metal/maxwell_to_mtl.cpp b/src/video_core/renderer_metal/maxwell_to_mtl.cpp index 0f3d488009..33376d16aa 100644 --- a/src/video_core/renderer_metal/maxwell_to_mtl.cpp +++ b/src/video_core/renderer_metal/maxwell_to_mtl.cpp @@ -7,7 +7,7 @@ namespace Metal::MaxwellToMTL { // TODO: emulate some formats which don't map directly // TODO: ASTC formats -constexpr std::array FORMAT_TABLE = {{ +std::array FORMAT_TABLE = {{ {MTL::PixelFormatRGBA8Unorm, 4}, // A8B8G8R8_UNORM TODO {MTL::PixelFormatRGBA8Snorm, 4}, // A8B8G8R8_SNORM TODO {MTL::PixelFormatRGBA8Sint, 4}, // A8B8G8R8_SINT TODO @@ -112,7 +112,58 @@ constexpr std::array FORMAT {MTL::PixelFormatDepth32Float_Stencil8, 5}, // D32_FLOAT_S8_UINT }}; -const PixelFormatInfo GetPixelFormatInfo(VideoCore::Surface::PixelFormat pixel_format) { +void CheckForPixelFormatSupport(MTL::Device* device) { + [[maybe_unused]] bool supportsR8Unorm_sRGB = device->supportsFamily(MTL::GPUFamilyApple1); + [[maybe_unused]] bool supportsRG8Unorm_sRGB = device->supportsFamily(MTL::GPUFamilyApple1); + bool supportsPacked16BitFormats = device->supportsFamily(MTL::GPUFamilyApple1); + bool supportsDepth24Unorm_Stencil8 = device->depth24Stencil8PixelFormatSupported(); + + if (!supportsPacked16BitFormats) { + // B5G6R5Unorm + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::R5G6B5_UNORM].pixel_format = + MTL::PixelFormatRGBA8Unorm; + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::R5G6B5_UNORM].bytes_per_block = 4; + + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::B5G6R5_UNORM].pixel_format = + MTL::PixelFormatRGBA8Unorm; + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::B5G6R5_UNORM].bytes_per_block = 4; + + // A1BGR5Unorm + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::A1R5G5B5_UNORM].pixel_format = + MTL::PixelFormatRGBA8Unorm; + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::A1R5G5B5_UNORM].bytes_per_block = 4; + + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM].pixel_format = + MTL::PixelFormatRGBA8Unorm; + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM].bytes_per_block = 4; + + // ABGR4Unorm + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::A4B4G4R4_UNORM].pixel_format = + MTL::PixelFormatRGBA8Unorm; + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::A4B4G4R4_UNORM].bytes_per_block = 4; + + // BGR5A1Unorm + // FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM].pixel_format = + // MTL::PixelFormatRGBA8Unorm; + // FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::A1B5G5R5_UNORM].bytes_per_block = + // 4; + } + + if (!supportsDepth24Unorm_Stencil8) { + // Depth24Unorm_Stencil8 + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::D24_UNORM_S8_UINT].pixel_format = + MTL::PixelFormatDepth32Float_Stencil8; + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::D24_UNORM_S8_UINT].bytes_per_block = + 5; + + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::S8_UINT_D24_UNORM].pixel_format = + MTL::PixelFormatDepth32Float_Stencil8; + FORMAT_TABLE[(size_t)VideoCore::Surface::PixelFormat::S8_UINT_D24_UNORM].bytes_per_block = + 5; + } +} + +const PixelFormatInfo& GetPixelFormatInfo(VideoCore::Surface::PixelFormat pixel_format) { ASSERT(static_cast(pixel_format) < FORMAT_TABLE.size()); return FORMAT_TABLE[static_cast(pixel_format)]; diff --git a/src/video_core/renderer_metal/maxwell_to_mtl.h b/src/video_core/renderer_metal/maxwell_to_mtl.h index 6d80607eaf..d1cd6da51e 100644 --- a/src/video_core/renderer_metal/maxwell_to_mtl.h +++ b/src/video_core/renderer_metal/maxwell_to_mtl.h @@ -20,7 +20,9 @@ struct PixelFormatInfo { bool can_be_render_target = true; }; -const PixelFormatInfo GetPixelFormatInfo(VideoCore::Surface::PixelFormat pixel_format); +void CheckForPixelFormatSupport(MTL::Device* device); + +const PixelFormatInfo& GetPixelFormatInfo(VideoCore::Surface::PixelFormat pixel_format); size_t GetTextureBytesPerRow(VideoCore::Surface::PixelFormat pixel_format, u32 texels_per_row); diff --git a/src/video_core/renderer_metal/renderer_metal.cpp b/src/video_core/renderer_metal/renderer_metal.cpp index e04098bf73..1c27621933 100644 --- a/src/video_core/renderer_metal/renderer_metal.cpp +++ b/src/video_core/renderer_metal/renderer_metal.cpp @@ -19,6 +19,9 @@ RendererMetal::RendererMetal(Core::Frontend::EmuWindow& emu_window, swap_chain(device, command_recorder, static_cast(render_window.GetWindowInfo().render_surface)), rasterizer(gpu_, device_memory, device, command_recorder, swap_chain) { + // Per device info + MaxwellToMTL::CheckForPixelFormatSupport(device.GetDevice()); + CreateBlitPipelineState(); }