From 5c2e4cc8d66a1a91a54f89bb94e6a6499d7bf075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Kwa=C5=9Bniewski?= Date: Thu, 25 Jul 2024 10:17:47 +0200 Subject: [PATCH] fix: properly set viewports and render targets (#3325) fix: do not use STL --- src/renderer_mtl.h | 11 +++++ src/renderer_mtl.mm | 110 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 115 insertions(+), 6 deletions(-) diff --git a/src/renderer_mtl.h b/src/renderer_mtl.h index 26de5da332..1c26a67a31 100644 --- a/src/renderer_mtl.h +++ b/src/renderer_mtl.h @@ -435,6 +435,11 @@ namespace bgfx { namespace mtl [m_obj setBlendColorRed:_red green:_green blue:_blue alpha:_alpha]; } + void setVertexAmplificationCount(NSUInteger count, MTLVertexAmplificationViewMapping* viewMappings) + { + [m_obj setVertexAmplificationCount:count viewMappings:viewMappings]; + } + void setCullMode(MTLCullMode _cullMode) { [m_obj setCullMode:_cullMode]; @@ -480,6 +485,11 @@ namespace bgfx { namespace mtl [m_obj setViewport:_viewport]; } + void setViewports(MTLViewport _viewport[], NSInteger count) + { + [m_obj setViewports:_viewport count:count]; + } + void setVisibilityResultMode(MTLVisibilityResultMode _mode, NSUInteger _offset) { [m_obj setVisibilityResultMode:_mode offset:_offset]; @@ -1061,6 +1071,7 @@ namespace bgfx { namespace mtl #if BX_PLATFORM_VISIONOS cp_layer_renderer_t m_layerRenderer; + cp_layer_renderer_configuration_t m_layerRendererConfiguration; cp_frame_t m_frame; cp_drawable_t m_drawable; #else diff --git a/src/renderer_mtl.mm b/src/renderer_mtl.mm index c1facd7a3c..dbcec2a299 100644 --- a/src/renderer_mtl.mm +++ b/src/renderer_mtl.mm @@ -611,6 +611,9 @@ bool init(const Init& _init) reset(m_renderPipelineDescriptor); m_renderPipelineDescriptor.colorAttachments[0].pixelFormat = getSwapChainPixelFormat(m_mainFrameBuffer.m_swapChain); +#if BX_PLATFORM_VISIONOS + m_renderPipelineDescriptor.depthAttachmentPixelFormat = cp_layer_renderer_configuration_get_depth_format(m_mainFrameBuffer.m_swapChain->m_layerRendererConfiguration); +#endif m_renderPipelineDescriptor.vertexFunction = m_screenshotBlitProgram.m_vsh->m_function; m_renderPipelineDescriptor.fragmentFunction = m_screenshotBlitProgram.m_fsh->m_function; m_screenshotBlitRenderPipelineState = m_device.newRenderPipelineStateWithDescriptor(m_renderPipelineDescriptor); @@ -1054,7 +1057,8 @@ void updateTextureEnd() override MTLPixelFormat getSwapChainPixelFormat(SwapChainMtl *swapChain) { #if BX_PLATFORM_VISIONOS - return MTLPixelFormatBGRA8Unorm_sRGB; + cp_layer_renderer_configuration_t layerConfiguration = cp_layer_renderer_get_configuration(swapChain->m_layerRenderer); + return cp_layer_renderer_configuration_get_color_format(layerConfiguration); #else return swapChain->m_metalLayer.pixelFormat; #endif @@ -1307,6 +1311,32 @@ void blitSetup(TextVideoMemBlitter& _blitter) override { BX_UNUSED(_blitter); } + +#if BX_PLATFORM_VISIONOS + void calculateViewPorts(MTLViewport (&viewports)[2]) { + const int viewCount = 2; + for (int i = 0; i < viewCount; i++) { + cp_view_t view = cp_drawable_get_view(m_mainFrameBuffer.m_swapChain->m_drawable, i); + cp_view_texture_map_t texture_map = cp_view_get_view_texture_map(view); + viewports[i] = cp_view_texture_map_get_viewport(texture_map); + } + } + + void setVertexAmplification(RenderCommandEncoder& _rce) { + MTLVertexAmplificationViewMapping mapping0; + MTLVertexAmplificationViewMapping mapping1; + + mapping0.renderTargetArrayIndexOffset = 0; + mapping1.renderTargetArrayIndexOffset = 1; + + mapping0.viewportArrayIndexOffset = 1; + mapping1.viewportArrayIndexOffset = 2; + + MTLVertexAmplificationViewMapping mappings[] = { mapping0, mapping1 }; + + _rce.setVertexAmplificationCount(2, mappings); + } +#endif void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override { @@ -1349,11 +1379,20 @@ void blitRender(TextVideoMemBlitter& _blitter, uint32_t _numIndices) override m_renderCommandEncoderFrameBufferHandle = fbh; MTL_RELEASE(renderPassDescriptor); +#if BX_PLATFORM_VISIONOS + if (cp_layer_renderer_configuration_get_layout(m_mainFrameBuffer.m_swapChain->m_layerRendererConfiguration) == cp_layer_renderer_layout_layered) { + MTLViewport viewports[2]; + calculateViewPorts(viewports); + rce.setViewports(viewports, 2); + setVertexAmplification(rce); + } +#else MTLViewport viewport = { 0.0f, 0.0f, (float)width, (float)height, 0.0f, 1.0f }; rce.setViewport(viewport); MTLScissorRect rc = { 0, 0, width, height }; rce.setScissorRect(rc); +#endif rce.setCullMode(MTLCullModeNone); @@ -1444,7 +1483,6 @@ void flip() override 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 @@ -1892,9 +1930,22 @@ void setFrameBuffer(RenderPassDescriptor _renderPassDescriptor, FrameBufferHandl : swapChain->currentDrawableTexture() ; } +#if BX_PLATFORM_VISIONOS + Texture texture = cp_drawable_get_depth_texture(swapChain->m_drawable, 0); + _renderPassDescriptor.depthAttachment.texture = texture; + _renderPassDescriptor.stencilAttachment.texture = swapChain->m_backBufferStencil; + cp_layer_renderer_configuration_t layerConfiguration = cp_layer_renderer_get_configuration(swapChain->m_layerRenderer); + cp_layer_renderer_layout layout = cp_layer_renderer_configuration_get_layout(layerConfiguration); + if (layout == cp_layer_renderer_layout_layered) { + _renderPassDescriptor.renderTargetArrayLength = cp_drawable_get_view_count(swapChain->m_drawable); + } else { + _renderPassDescriptor.renderTargetArrayLength = 1; + } +#else _renderPassDescriptor.depthAttachment.texture = swapChain->m_backBufferDepth; _renderPassDescriptor.stencilAttachment.texture = swapChain->m_backBufferStencil; +#endif } else { @@ -2267,7 +2318,11 @@ void processArguments( : 1 ; pd.colorAttachments[0].pixelFormat = swapChain->currentDrawableTexture().pixelFormat; - pd.depthAttachmentPixelFormat = swapChain->m_backBufferDepth.m_obj.pixelFormat; +#if BX_PLATFORM_VISIONOS + pd.depthAttachmentPixelFormat = cp_layer_renderer_configuration_get_depth_format(swapChain->m_layerRendererConfiguration); +#else + pd.depthAttachmentPixelFormat = swapChain->m_backBufferDepth.m_obj.pixelFormat; +#endif pd.stencilAttachmentPixelFormat = swapChain->m_backBufferStencil.m_obj.pixelFormat; } else @@ -2367,6 +2422,12 @@ void processArguments( pd.vertexFunction = program.m_vsh->m_function; pd.fragmentFunction = program.m_fsh != NULL ? program.m_fsh->m_function : NULL; +#if BX_PLATFORM_VISIONOS + if (cp_layer_renderer_configuration_get_layout(m_mainFrameBuffer.m_swapChain->m_layerRendererConfiguration) == cp_layer_renderer_layout_layered) { + auto properties = cp_layer_renderer_get_properties(m_mainFrameBuffer.m_swapChain->m_layerRenderer); + pd.maxVertexAmplificationCount = cp_layer_renderer_properties_get_view_count(properties); + } +#endif VertexDescriptor vertexDesc = m_vertexDescriptor; reset(vertexDesc); @@ -3347,7 +3408,20 @@ void writeString(bx::WriterI* _writer, const char* _str) void SwapChainMtl::init(void* _nwh) { -#if !BX_PLATFORM_VISIONOS +#if BX_PLATFORM_VISIONOS + { + cp_layer_renderer_t layerRenderer = (cp_layer_renderer_t)_nwh; + m_layerRenderer = layerRenderer; + m_layerRendererConfiguration = cp_layer_renderer_get_configuration(m_layerRenderer); + + if (cp_layer_renderer_configuration_get_layout(m_layerRendererConfiguration) == cp_layer_renderer_layout_dedicated) { + BX_WARN(false, "Dedicated layer renderer layout is not supported."); + } + + retain(m_layerRendererConfiguration); + retain(m_layerRenderer); + } +#else if (m_metalLayer) { release(m_metalLayer); @@ -3521,8 +3595,13 @@ void writeString(bx::WriterI* _writer, const char* _str) release(m_backBufferDepth); } +#if BX_PLATFORM_VISIONOS + if (m_drawable) { + m_backBufferDepth = cp_drawable_get_depth_texture(m_drawable, 0); + } +#else m_backBufferDepth = s_renderMtl->m_device.newTextureWithDescriptor(desc); - +#endif if (NULL != m_backBufferStencil) { release(m_backBufferStencil); @@ -3573,7 +3652,17 @@ void writeString(bx::WriterI* _writer, const char* _str) { #if BX_PLATFORM_VISIONOS m_frame = cp_layer_renderer_query_next_frame(m_layerRenderer); - if (m_frame) { + if (m_frame) + { + cp_frame_timing_t timing = cp_frame_predict_timing(m_frame); + if (timing == nullptr) { return nullptr; } + + cp_frame_start_update(m_frame); + + cp_frame_end_update(m_frame); + + cp_time_wait_until(cp_frame_timing_get_optimal_input_time(timing)); + cp_frame_start_submission(m_frame); m_drawable = cp_frame_query_drawable(m_frame); } #else // BX_PLATFORM_VISIONOS @@ -4394,6 +4483,14 @@ static void setTimestamp(void* _data) rce.setTriangleFillMode(wireframe ? MTLTriangleFillModeLines : MTLTriangleFillModeFill); +#if BX_PLATFORM_VISIONOS + if (cp_layer_renderer_configuration_get_layout(m_mainFrameBuffer.m_swapChain->m_layerRendererConfiguration) == cp_layer_renderer_layout_layered) { + MTLViewport viewports[2]; + calculateViewPorts(viewports); + rce.setViewports(viewports, 1); + setVertexAmplification(rce); + } +#else MTLViewport vp; vp.originX = viewState.m_rect.m_x; vp.originY = viewState.m_rect.m_y; @@ -4411,6 +4508,7 @@ static void setTimestamp(void* _data) }; rce.setScissorRect(sciRect); +#endif if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK) && !clearWithRenderPass) {