فهرست منبع

fix: properly set viewports and render targets (#3325)

fix: do not use STL
Oskar Kwaśniewski 1 سال پیش
والد
کامیت
b4df15f848
2فایلهای تغییر یافته به همراه106 افزوده شده و 4 حذف شده
  1. 11 0
      src/renderer_mtl.h
  2. 95 4
      src/renderer_mtl.mm

+ 11 - 0
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

+ 95 - 4
src/renderer_mtl.mm

@@ -604,6 +604,9 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 
 			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);
@@ -1043,7 +1046,8 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 		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 // BX_PLATFORM_VISIONOS
@@ -1296,6 +1300,32 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 		{
 			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
 		{
@@ -1338,11 +1368,20 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 				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);
 
@@ -1433,7 +1472,6 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 					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
@@ -1881,9 +1919,22 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 						: 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
 			{
@@ -2256,7 +2307,11 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 						: 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
@@ -2356,6 +2411,12 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 
 				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);
@@ -3341,6 +3402,13 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 		{
 			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
@@ -3515,8 +3583,13 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 			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);
@@ -3569,6 +3642,15 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 			m_frame = cp_layer_renderer_query_next_frame(m_layerRenderer);
 			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
@@ -4392,6 +4474,14 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 
 						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;
@@ -4409,6 +4499,7 @@ BX_STATIC_ASSERT(BX_COUNTOF(s_accessNames) == Access::Count, "Invalid s_accessNa
 						};
 						rce.setScissorRect(sciRect);
 
+#endif
 						if (BGFX_CLEAR_NONE != (clr.m_flags & BGFX_CLEAR_MASK)
 							&& !clearWithRenderPass)
 						{