feat: base visionOS bgfx implementation (#3289)

Co-authored-by: mani3xis <mariusz.pas+dev@protonmail.com>

fix: properly set storageMode

cleanup: remove unused variables

fix crash while releasing m_drawable on visionOS

fix: remove unused timing variable

fix: file name cases, cleanup

feat: integrate visionOS into bgfx examples
This commit is contained in:
Oskar Kwaśniewski 2024-06-03 17:14:53 +02:00 committed by GitHub
parent 00fa5ad179
commit 3195593d8d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 110 additions and 30 deletions

View File

@ -68,7 +68,7 @@ void openUrl(const bx::StringView& _url)
#if BX_PLATFORM_WINDOWS #if BX_PLATFORM_WINDOWS
void* result = ShellExecuteA(NULL, NULL, tmp, NULL, NULL, false); void* result = ShellExecuteA(NULL, NULL, tmp, NULL, NULL, false);
BX_UNUSED(result); BX_UNUSED(result);
#elif !BX_PLATFORM_IOS #elif !BX_PLATFORM_IOS && !BX_PLATFORM_VISIONOS
int32_t result = system(tmp); int32_t result = system(tmp);
BX_UNUSED(result); BX_UNUSED(result);
#endif // BX_PLATFORM_* #endif // BX_PLATFORM_*

View File

@ -68,7 +68,7 @@ namespace entry
else else
# endif // ENTRY_CONFIG_USE_WAYLAND # endif // ENTRY_CONFIG_USE_WAYLAND
return (void*)wmi.info.x11.window; return (void*)wmi.info.x11.window;
# elif BX_PLATFORM_OSX || BX_PLATFORM_IOS # elif BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
return wmi.info.cocoa.window; return wmi.info.cocoa.window;
# elif BX_PLATFORM_WINDOWS # elif BX_PLATFORM_WINDOWS
return wmi.info.win.window; return wmi.info.win.window;

View File

@ -34,6 +34,7 @@
|| BX_PLATFORM_LINUX \ || BX_PLATFORM_LINUX \
|| BX_PLATFORM_OSX \ || BX_PLATFORM_OSX \
|| BX_PLATFORM_RPI \ || BX_PLATFORM_RPI \
|| BX_PLATFORM_VISIONOS \
|| BX_PLATFORM_WINDOWS \ || BX_PLATFORM_WINDOWS \
) )
#define BGFX_PLATFORM_SUPPORTS_GLSL (0 \ #define BGFX_PLATFORM_SUPPORTS_GLSL (0 \
@ -44,6 +45,7 @@
#define BGFX_PLATFORM_SUPPORTS_METAL (0 \ #define BGFX_PLATFORM_SUPPORTS_METAL (0 \
|| BX_PLATFORM_IOS \ || BX_PLATFORM_IOS \
|| BX_PLATFORM_OSX \ || BX_PLATFORM_OSX \
|| BX_PLATFORM_VISIONOS \
) )
#define BGFX_PLATFORM_SUPPORTS_NVN (0 \ #define BGFX_PLATFORM_SUPPORTS_NVN (0 \
|| BX_PLATFORM_NX \ || BX_PLATFORM_NX \

View File

@ -12,7 +12,7 @@
#include "topology.h" #include "topology.h"
#if BX_PLATFORM_OSX || BX_PLATFORM_IOS #if BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
# include <objc/message.h> # include <objc/message.h>
#elif BX_PLATFORM_WINDOWS #elif BX_PLATFORM_WINDOWS
# ifndef WIN32_LEAN_AND_MEAN # ifndef WIN32_LEAN_AND_MEAN
@ -2413,7 +2413,7 @@ namespace bgfx
} }
} }
#if BX_PLATFORM_OSX || BX_PLATFORM_IOS #if BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
struct NSAutoreleasePoolScope struct NSAutoreleasePoolScope
{ {
NSAutoreleasePoolScope() NSAutoreleasePoolScope()
@ -2437,7 +2437,7 @@ namespace bgfx
{ {
BGFX_PROFILER_SCOPE("bgfx::renderFrame", 0xff2040ff); BGFX_PROFILER_SCOPE("bgfx::renderFrame", 0xff2040ff);
#if BX_PLATFORM_OSX || BX_PLATFORM_IOS #if BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
NSAutoreleasePoolScope pool; NSAutoreleasePoolScope pool;
#endif // BX_PLATFORM_OSX #endif // BX_PLATFORM_OSX
@ -2635,11 +2635,11 @@ namespace bgfx
{ d3d11::rendererCreate, d3d11::rendererDestroy, BGFX_RENDERER_DIRECT3D11_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D11 }, // Direct3D11 { d3d11::rendererCreate, d3d11::rendererDestroy, BGFX_RENDERER_DIRECT3D11_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D11 }, // Direct3D11
{ d3d12::rendererCreate, d3d12::rendererDestroy, BGFX_RENDERER_DIRECT3D12_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D12 }, // Direct3D12 { d3d12::rendererCreate, d3d12::rendererDestroy, BGFX_RENDERER_DIRECT3D12_NAME, !!BGFX_CONFIG_RENDERER_DIRECT3D12 }, // Direct3D12
{ gnm::rendererCreate, gnm::rendererDestroy, BGFX_RENDERER_GNM_NAME, !!BGFX_CONFIG_RENDERER_GNM }, // GNM { gnm::rendererCreate, gnm::rendererDestroy, BGFX_RENDERER_GNM_NAME, !!BGFX_CONFIG_RENDERER_GNM }, // GNM
#if BX_PLATFORM_OSX || BX_PLATFORM_IOS #if BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
{ mtl::rendererCreate, mtl::rendererDestroy, BGFX_RENDERER_METAL_NAME, !!BGFX_CONFIG_RENDERER_METAL }, // Metal { mtl::rendererCreate, mtl::rendererDestroy, BGFX_RENDERER_METAL_NAME, !!BGFX_CONFIG_RENDERER_METAL }, // Metal
#else #else
{ noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, false }, // Noop { noop::rendererCreate, noop::rendererDestroy, BGFX_RENDERER_NOOP_NAME, false }, // Noop
#endif // BX_PLATFORM_OSX || BX_PLATFORM_IOS #endif // BX_PLATFORM_OSX || BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
{ nvn::rendererCreate, nvn::rendererDestroy, BGFX_RENDERER_NVN_NAME, !!BGFX_CONFIG_RENDERER_NVN }, // NVN { nvn::rendererCreate, nvn::rendererDestroy, BGFX_RENDERER_NVN_NAME, !!BGFX_CONFIG_RENDERER_NVN }, // NVN
{ gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGLES }, // OpenGLES { gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGLES }, // OpenGLES
{ gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGL }, // OpenGL { gl::rendererCreate, gl::rendererDestroy, BGFX_RENDERER_OPENGL_NAME, !!BGFX_CONFIG_RENDERER_OPENGL }, // OpenGL
@ -2737,7 +2737,7 @@ namespace bgfx
score += RendererType::Metal == renderer ? 20 : 0; score += RendererType::Metal == renderer ? 20 : 0;
score += RendererType::Vulkan == renderer ? 10 : 0; score += RendererType::Vulkan == renderer ? 10 : 0;
} }
else if (BX_ENABLED(BX_PLATFORM_IOS) ) else if (BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS))
{ {
score += RendererType::Metal == renderer ? 20 : 0; score += RendererType::Metal == renderer ? 20 : 0;
} }

View File

@ -63,6 +63,7 @@
# define BGFX_CONFIG_RENDERER_METAL (0 \ # define BGFX_CONFIG_RENDERER_METAL (0 \
|| BX_PLATFORM_IOS \ || BX_PLATFORM_IOS \
|| BX_PLATFORM_OSX \ || BX_PLATFORM_OSX \
|| BX_PLATFORM_VISIONOS \
? 1 : 0) ? 1 : 0)
# endif // BGFX_CONFIG_RENDERER_METAL # endif // BGFX_CONFIG_RENDERER_METAL

View File

@ -14,10 +14,14 @@
#import <Metal/Metal.h> #import <Metal/Metal.h>
#import <MetalKit/MetalKit.h> #import <MetalKit/MetalKit.h>
#if BX_PLATFORM_IOS #if BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
# import <UIKit/UIKit.h> # import <UIKit/UIKit.h>
#endif // BX_PLATFORM_* #endif // BX_PLATFORM_*
#if BX_PLATFORM_VISIONOS
#import <CompositorServices/CompositorServices.h>
#endif
#define BGFX_MTL_PROFILER_BEGIN(_view, _abgr) \ #define BGFX_MTL_PROFILER_BEGIN(_view, _abgr) \
BX_MACRO_BLOCK_BEGIN \ BX_MACRO_BLOCK_BEGIN \
BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \ BGFX_PROFILER_BEGIN(s_viewName[view], _abgr); \
@ -38,7 +42,7 @@ namespace bgfx { namespace mtl
//runtime os check //runtime os check
inline bool iOSVersionEqualOrGreater(const char* _version) inline bool iOSVersionEqualOrGreater(const char* _version)
{ {
#if BX_PLATFORM_IOS #if BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending); return ([[[UIDevice currentDevice] systemVersion] compare:@(_version) options:NSNumericSearch] != NSOrderedAscending);
#else #else
BX_UNUSED(_version); BX_UNUSED(_version);
@ -386,7 +390,7 @@ namespace bgfx { namespace mtl
bool supportsTextureSampleCount(int sampleCount) bool supportsTextureSampleCount(int sampleCount)
{ {
if (BX_ENABLED(BX_PLATFORM_IOS) && !iOSVersionEqualOrGreater("9.0.0") ) if (BX_ENABLED(BX_PLATFORM_VISIONOS) || (BX_ENABLED(BX_PLATFORM_IOS) && !iOSVersionEqualOrGreater("9.0.0")) )
return sampleCount == 1 || sampleCount == 2 || sampleCount == 4; return sampleCount == 1 || sampleCount == 2 || sampleCount == 4;
else else
return [m_obj supportsTextureSampleCount:sampleCount]; return [m_obj supportsTextureSampleCount:sampleCount];
@ -394,11 +398,11 @@ namespace bgfx { namespace mtl
bool depth24Stencil8PixelFormatSupported() bool depth24Stencil8PixelFormatSupported()
{ {
#if BX_PLATFORM_IOS #if BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
return false; return false;
#else #else
return m_obj.depth24Stencil8PixelFormatSupported; return m_obj.depth24Stencil8PixelFormatSupported;
#endif // BX_PLATFORM_IOS #endif // BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS
} }
MTL_CLASS_END MTL_CLASS_END
@ -1032,7 +1036,12 @@ namespace bgfx { namespace mtl
struct SwapChainMtl struct SwapChainMtl
{ {
SwapChainMtl() SwapChainMtl()
#if BX_PLATFORM_VISIONOS
: m_layerRenderer(NULL)
, m_frame(NULL)
#else
: m_metalLayer(nil) : m_metalLayer(nil)
#endif
, m_drawable(nil) , m_drawable(nil)
, m_drawableTexture(nil) , m_drawableTexture(nil)
, m_backBufferColorMsaa() , m_backBufferColorMsaa()
@ -1049,8 +1058,15 @@ namespace bgfx { namespace mtl
id <MTLTexture> currentDrawableTexture(); id <MTLTexture> currentDrawableTexture();
#if BX_PLATFORM_VISIONOS
cp_layer_renderer_t m_layerRenderer;
cp_frame_t m_frame;
cp_drawable_t m_drawable;
#else
CAMetalLayer* m_metalLayer; CAMetalLayer* m_metalLayer;
id <CAMetalDrawable> m_drawable; id <CAMetalDrawable> m_drawable;
#endif
id <MTLTexture> m_drawableTexture; id <MTLTexture> m_drawableTexture;
Texture m_backBufferColorMsaa; Texture m_backBufferColorMsaa;
Texture m_backBufferDepth; Texture m_backBufferDepth;

View File

@ -247,7 +247,7 @@ namespace bgfx { namespace mtl
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATC { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATC
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATCE { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATCE
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATCI { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ATCI
#if BX_PLATFORM_IOS && !TARGET_OS_MACCATALYST #if (BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS) && !TARGET_OS_MACCATALYST
{ MTLPixelFormatASTC_4x4_LDR, MTLPixelFormatASTC_4x4_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC4x4 { MTLPixelFormatASTC_4x4_LDR, MTLPixelFormatASTC_4x4_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC4x4
{ MTLPixelFormatASTC_5x4_LDR, MTLPixelFormatASTC_5x4_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC5x4 { MTLPixelFormatASTC_5x4_LDR, MTLPixelFormatASTC_5x4_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC5x4
{ MTLPixelFormatASTC_5x5_LDR, MTLPixelFormatASTC_5x5_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC5x5 { MTLPixelFormatASTC_5x5_LDR, MTLPixelFormatASTC_5x5_sRGB, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC5x5
@ -277,7 +277,7 @@ namespace bgfx { namespace mtl
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC10x10 { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC10x10
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC12x10 { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC12x10
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC12x12 { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // ASTC12x12
#endif // BX_PLATFORM_IOS && !TARGET_OS_MACCATALYST #endif // (BX_PLATFORM_IOS || BX_PLATFORM_VISIONOS) && !TARGET_OS_MACCATALYST
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // Unknown { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // Unknown
{ MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // R1 { MTLPixelFormatInvalid, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // R1
{ MTLPixelFormatA8Unorm, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // A8 { MTLPixelFormatA8Unorm, MTLPixelFormatInvalid, MTLReadWriteTextureTierNone, { $R, $G, $B, $A }, false }, // A8
@ -524,7 +524,11 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
); );
m_numWindows = 1; m_numWindows = 1;
#if BX_PLATFORM_VISIONOS
if (NULL == m_mainFrameBuffer.m_swapChain->m_layerRenderer)
#else // BX_PLATFORM_VISIONOS
if (NULL == m_mainFrameBuffer.m_swapChain->m_metalLayer) if (NULL == m_mainFrameBuffer.m_swapChain->m_metalLayer)
#endif // BX_PLATFORM_VISIONOS
{ {
release(m_device); release(m_device);
return false; return false;
@ -588,7 +592,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
m_screenshotBlitProgram.create(&m_screenshotBlitProgramVsh, &m_screenshotBlitProgramFsh); m_screenshotBlitProgram.create(&m_screenshotBlitProgramVsh, &m_screenshotBlitProgramFsh);
reset(m_renderPipelineDescriptor); reset(m_renderPipelineDescriptor);
m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat; m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain);
m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function; m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function;
m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function; m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function;
m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor); m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor);
@ -784,7 +788,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
g_caps.formats[TextureFormat::RGBA32I] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); g_caps.formats[TextureFormat::RGBA32I] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA);
g_caps.formats[TextureFormat::RGBA32U] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA); g_caps.formats[TextureFormat::RGBA32U] &= ~(BGFX_CAPS_FORMAT_TEXTURE_FRAMEBUFFER_MSAA);
if (BX_ENABLED(BX_PLATFORM_IOS) ) if (BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS))
{ {
s_textureFormat[TextureFormat::D24S8].m_fmt = MTLPixelFormatDepth32Float_Stencil8; s_textureFormat[TextureFormat::D24S8].m_fmt = MTLPixelFormatDepth32Float_Stencil8;
@ -1025,6 +1029,14 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
{ {
} }
MTLPixelFormat getSwapChainPixelFormat(SwapChainMtl *swapChain) {
#if BX_PLATFORM_VISIONOS
return MTLPixelFormatBGRA8Unorm_sRGB;
#else
return swapChain->m_metalLayer.pixelFormat;
#endif
}
void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override void readTexture(TextureHandle _handle, void* _data, uint8_t _mip) override
{ {
const TextureMtl& texture = m_textures[_handle.idx]; const TextureMtl& texture = m_textures[_handle.idx];
@ -1408,8 +1420,14 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
if (NULL != frameBuffer.m_swapChain->m_drawable) if (NULL != frameBuffer.m_swapChain->m_drawable)
{ {
#if BX_PLATFORM_VISIONOS
cp_frame_start_submission(frameBuffer.m_swapChain->m_frame);
cp_drawable_encode_present(frameBuffer.m_swapChain->m_drawable, m_commandBuffer);
cp_frame_end_submission(frameBuffer.m_swapChain->m_frame);
#else // BX_PLATFORM_VISIONOS
m_commandBuffer.presentDrawable(frameBuffer.m_swapChain->m_drawable); m_commandBuffer.presentDrawable(frameBuffer.m_swapChain->m_drawable);
MTL_RELEASE(frameBuffer.m_swapChain->m_drawable); MTL_RELEASE(frameBuffer.m_swapChain->m_drawable);
#endif // BX_PLATFORM_VISIONOS
} }
} }
} }
@ -1435,8 +1453,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
|| m_resolution.height != _resolution.height || m_resolution.height != _resolution.height
|| (m_resolution.reset&maskFlags) != (_resolution.reset&maskFlags) ) || (m_resolution.reset&maskFlags) != (_resolution.reset&maskFlags) )
{ {
MTLPixelFormat prevMetalLayerPixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat; MTLPixelFormat prevMetalLayerPixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain);
m_resolution = _resolution; m_resolution = _resolution;
if (m_resolution.reset & BGFX_RESET_INTERNAL_FORCE if (m_resolution.reset & BGFX_RESET_INTERNAL_FORCE
@ -1458,12 +1475,13 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
m_textVideoMem.resize(false, _resolution.width, _resolution.height); m_textVideoMem.resize(false, _resolution.width, _resolution.height);
m_textVideoMem.clear(); m_textVideoMem.clear();
if (prevMetalLayerPixelFormat != m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat)
if (prevMetalLayerPixelFormat != getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain))
{ {
MTL_RELEASE(m_screenshotBlitRenderPipelineState) MTL_RELEASE(m_screenshotBlitRenderPipelineState)
reset(m_renderPipelineDescriptor); reset(m_renderPipelineDescriptor);
m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat; m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain);
m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function; m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function;
m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function; m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function;
m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor); m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor);
@ -3005,7 +3023,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
|| writeOnly || writeOnly
|| bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) ) || bimg::isDepth(bimg::TextureFormat::Enum(m_textureFormat) )
? 2 /* MTLStorageModePrivate */ ? 2 /* MTLStorageModePrivate */
: (BX_ENABLED(BX_PLATFORM_IOS) : (BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS)
? 0 /* MTLStorageModeShared */ ? 0 /* MTLStorageModeShared */
: 1 /* MTLStorageModeManaged */ : 1 /* MTLStorageModeManaged */
) ); ) );
@ -3198,7 +3216,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) if (s_renderMtl->m_hasCPUCacheModesAndStorageModes)
{ {
desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; desc.cpuCacheMode = MTLCPUCacheModeDefaultCache;
desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS)
? (MTLStorageMode)0 // MTLStorageModeShared ? (MTLStorageMode)0 // MTLStorageModeShared
: (MTLStorageMode)1 // MTLStorageModeManaged : (MTLStorageMode)1 // MTLStorageModeManaged
; ;
@ -3286,8 +3304,12 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
SwapChainMtl::~SwapChainMtl() SwapChainMtl::~SwapChainMtl()
{ {
#if BX_PLATFORM_VISIONOS
MTL_RELEASE(m_layerRenderer);
#else // BX_PLATFORM_VISIONOS
MTL_RELEASE(m_metalLayer); MTL_RELEASE(m_metalLayer);
MTL_RELEASE(m_drawable); MTL_RELEASE(m_drawable);
#endif // BX_PLATFORM_VISIONOS
MTL_RELEASE(m_drawableTexture); MTL_RELEASE(m_drawableTexture);
MTL_RELEASE(m_backBufferDepth); MTL_RELEASE(m_backBufferDepth);
@ -3302,6 +3324,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
void SwapChainMtl::init(void* _nwh) void SwapChainMtl::init(void* _nwh)
{ {
#if !BX_PLATFORM_VISIONOS
if (m_metalLayer) if (m_metalLayer)
{ {
release(m_metalLayer); release(m_metalLayer);
@ -3402,8 +3425,15 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
m_metalLayer.device = s_renderMtl->m_device; m_metalLayer.device = s_renderMtl->m_device;
m_metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; m_metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
m_metalLayer.magnificationFilter = kCAFilterNearest; m_metalLayer.magnificationFilter = kCAFilterNearest;
m_nwh = _nwh;
retain(m_metalLayer); retain(m_metalLayer);
#else // BX_PLATFORM_VISIONOS
{
cp_layer_renderer_t layerRenderer = (cp_layer_renderer_t)_nwh;
m_layerRenderer = layerRenderer;
retain(m_layerRenderer);
}
#endif // BX_PLATFORM_VISIONOS
m_nwh = _nwh;
} }
void SwapChainMtl::resize(FrameBufferMtl &_frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags, uint32_t _maximumDrawableCount) void SwapChainMtl::resize(FrameBufferMtl &_frameBuffer, uint32_t _width, uint32_t _height, uint32_t _flags, uint32_t _maximumDrawableCount)
@ -3428,11 +3458,13 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
# endif // __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300 # endif // __MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
#endif // BX_PLATFORM_OSX #endif // BX_PLATFORM_OSX
#if !BX_PLATFORM_VISIONOS
m_metalLayer.drawableSize = CGSizeMake(_width, _height); m_metalLayer.drawableSize = CGSizeMake(_width, _height);
m_metalLayer.pixelFormat = (_flags & BGFX_RESET_SRGB_BACKBUFFER) m_metalLayer.pixelFormat = (_flags & BGFX_RESET_SRGB_BACKBUFFER)
? MTLPixelFormatBGRA8Unorm_sRGB ? MTLPixelFormatBGRA8Unorm_sRGB
: MTLPixelFormatBGRA8Unorm : MTLPixelFormatBGRA8Unorm
; ;
#endif // BX_PLATFORM_VISIONOS
TextureDescriptor desc = s_renderMtl->m_textureDescriptor; TextureDescriptor desc = s_renderMtl->m_textureDescriptor;
@ -3492,14 +3524,20 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
if (sampleCount > 1) if (sampleCount > 1)
{ {
#if BX_PLATFORM_VISIONOS
desc.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
#else
desc.pixelFormat = m_metalLayer.pixelFormat; desc.pixelFormat = m_metalLayer.pixelFormat;
#endif
m_backBufferColorMsaa = s_renderMtl->m_device.newTextureWithDescriptor(desc); m_backBufferColorMsaa = s_renderMtl->m_device.newTextureWithDescriptor(desc);
} }
bx::HashMurmur2A murmur; bx::HashMurmur2A murmur;
murmur.begin(); murmur.begin();
murmur.add(1); murmur.add(1);
#if !BX_PLATFORM_VISIONOS
murmur.add( (uint32_t)m_metalLayer.pixelFormat); murmur.add( (uint32_t)m_metalLayer.pixelFormat);
#endif // BX_PLATFORM_VISIONOS
murmur.add( (uint32_t)m_backBufferDepth.pixelFormat() ); murmur.add( (uint32_t)m_backBufferDepth.pixelFormat() );
murmur.add( (uint32_t)m_backBufferStencil.pixelFormat() ); murmur.add( (uint32_t)m_backBufferStencil.pixelFormat() );
murmur.add( (uint32_t)sampleCount); murmur.add( (uint32_t)sampleCount);
@ -3510,20 +3548,35 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
{ {
if (NULL == m_drawableTexture) if (NULL == m_drawableTexture)
{ {
#if BX_PLATFORM_VISIONOS
m_frame = cp_layer_renderer_query_next_frame(m_layerRenderer);
if (m_frame) {
m_drawable = cp_frame_query_drawable(m_frame);
}
#else // BX_PLATFORM_VISIONOS
m_drawable = m_metalLayer.nextDrawable; m_drawable = m_metalLayer.nextDrawable;
#endif // BX_PLATFORM_VISIONOS
if (m_drawable != NULL) if (m_drawable != NULL)
{ {
#if BX_PLATFORM_VISIONOS
m_drawableTexture = cp_drawable_get_color_texture(m_drawable, 0);
#else // BX_PLATFORM_VISIONOS
m_drawableTexture = m_drawable.texture; m_drawableTexture = m_drawable.texture;
retain(m_drawableTexture);
retain(m_drawable); // keep alive to be useable at 'flip' retain(m_drawable); // keep alive to be useable at 'flip'
#endif // BX_PLATFORM_VISIONOS
retain(m_drawableTexture);
} }
else else
{ {
TextureDescriptor desc = s_renderMtl->m_textureDescriptor; TextureDescriptor desc = s_renderMtl->m_textureDescriptor;
desc.textureType = MTLTextureType2D; desc.textureType = MTLTextureType2D;
#if !BX_PLATFORM_VISIONOS
desc.pixelFormat = m_metalLayer.pixelFormat; desc.pixelFormat = m_metalLayer.pixelFormat;
desc.width = m_metalLayer.drawableSize.width; desc.width = m_metalLayer.drawableSize.width;
desc.height = m_metalLayer.drawableSize.height; desc.height = m_metalLayer.drawableSize.height;
#else // BX_PLATFORM_VISIONOS
desc.pixelFormat = MTLPixelFormatBGRA8Unorm_sRGB;
#endif // BX_PLATFORM_VISIONOS
desc.depth = 1; desc.depth = 1;
desc.mipmapLevelCount = 1; desc.mipmapLevelCount = 1;
desc.sampleCount = 1; desc.sampleCount = 1;
@ -3532,7 +3585,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) if (s_renderMtl->m_hasCPUCacheModesAndStorageModes)
{ {
desc.cpuCacheMode = MTLCPUCacheModeDefaultCache; desc.cpuCacheMode = MTLCPUCacheModeDefaultCache;
desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) desc.storageMode = BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS)
? (MTLStorageMode)0 // MTLStorageModeShared ? (MTLStorageMode)0 // MTLStorageModeShared
: (MTLStorageMode)1 // MTLStorageModeManaged : (MTLStorageMode)1 // MTLStorageModeManaged
; ;
@ -3998,7 +4051,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
if (NULL == m_screenshotTarget) if (NULL == m_screenshotTarget)
{ {
m_textureDescriptor.textureType = MTLTextureType2D; m_textureDescriptor.textureType = MTLTextureType2D;
m_textureDescriptor.pixelFormat = m_mainFrameBuffer.m_swapChain->m_metalLayer.pixelFormat; m_textureDescriptor.pixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain);
m_textureDescriptor.width = m_resolution.width; m_textureDescriptor.width = m_resolution.width;
m_textureDescriptor.height = m_resolution.height; m_textureDescriptor.height = m_resolution.height;
m_textureDescriptor.depth = 1; m_textureDescriptor.depth = 1;
@ -4009,7 +4062,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
if (s_renderMtl->m_hasCPUCacheModesAndStorageModes) if (s_renderMtl->m_hasCPUCacheModesAndStorageModes)
{ {
m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache; m_textureDescriptor.cpuCacheMode = MTLCPUCacheModeDefaultCache;
m_textureDescriptor.storageMode = BX_ENABLED(BX_PLATFORM_IOS) m_textureDescriptor.storageMode = BX_ENABLED(BX_PLATFORM_IOS) || BX_ENABLED(BX_PLATFORM_VISIONOS)
? (MTLStorageMode)0 // MTLStorageModeShared ? (MTLStorageMode)0 // MTLStorageModeShared
: (MTLStorageMode)1 // MTLStorageModeManaged : (MTLStorageMode)1 // MTLStorageModeManaged
; ;

View File

@ -1163,6 +1163,7 @@ namespace bgfx
preprocessor.setDefaultDefine("BX_PLATFORM_ANDROID"); preprocessor.setDefaultDefine("BX_PLATFORM_ANDROID");
preprocessor.setDefaultDefine("BX_PLATFORM_EMSCRIPTEN"); preprocessor.setDefaultDefine("BX_PLATFORM_EMSCRIPTEN");
preprocessor.setDefaultDefine("BX_PLATFORM_IOS"); preprocessor.setDefaultDefine("BX_PLATFORM_IOS");
preprocessor.setDefaultDefine("BX_PLATFORM_VISIONOS");
preprocessor.setDefaultDefine("BX_PLATFORM_LINUX"); preprocessor.setDefaultDefine("BX_PLATFORM_LINUX");
preprocessor.setDefaultDefine("BX_PLATFORM_OSX"); preprocessor.setDefaultDefine("BX_PLATFORM_OSX");
preprocessor.setDefaultDefine("BX_PLATFORM_PS4"); preprocessor.setDefaultDefine("BX_PLATFORM_PS4");
@ -1228,12 +1229,19 @@ namespace bgfx
preprocessor.setDefine(glslDefine); preprocessor.setDefine(glslDefine);
} }
} }
else if (0 == bx::strCmpI(platform, "ios") || (0 == bx::strCmpI(platform, "osx")) ) else if (
0 == bx::strCmpI(platform, "ios") ||
0 == bx::strCmpI(platform, "osx") ||
0 == bx::strCmpI(platform, "visionos")
)
{ {
if (0 == bx::strCmpI(platform, "osx")) if (0 == bx::strCmpI(platform, "osx"))
{ {
preprocessor.setDefine("BX_PLATFORM_OSX=1"); preprocessor.setDefine("BX_PLATFORM_OSX=1");
} }
else if (0 == bx::strCmpI(platform, "visionos")) {
preprocessor.setDefine("BX_PLATFORM_VISIONOS=1");
}
else else
{ {
preprocessor.setDefine("BX_PLATFORM_IOS=1"); preprocessor.setDefine("BX_PLATFORM_IOS=1");