xrEndFrame 上奇怪的 OpenXR 行为
Strange OpenXR Behaviour on xrEndFrame
首先:上下文是使用 HP Reverb G2、WMR 运行时、DX12 的 VR。
在使用 OpenXR 时,我们在开发人员机器上看到了一些无法解释的行为。看起来 OpenXR 运行时正在根据首选 GPU 的机器设置改变它的呈现方式。
更具体地说,我们注意到根据首选 GPU 的机器设置,我们看到在调用 XrEndFrame
时使用了不同的方法。这是一个大问题,因为不同的方法会导致空白屏幕被绘制到我们当前的 renderTarget!
不同之处在于,当首选设备是 Nvidia GPU 时,xrEndFrame 在 PIX 中看起来像这样(在独立于我们的主渲染的图形队列中):
Index Global ID Name EOP to EOP Duration (ns) Execution Start Time (ns)
2 8063 Signal(pFence:obj#20, Value:62)
3 8064 Wait(pFence:obj#36, Value:31)
5 8065 CopyTextureRegion(pDst:{pResource:obj#4083, Type:D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, SubresourceIndex:0}, DstX:0, DstY:0, DstZ:0, pSrc:{pResource:obj#4084, Type:D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, SubresourceIndex:0}, pSrcBox:{left:0, top:0, front:0, right:2088, bottom:2036, back:1})
6 8066 CopyTextureRegion(pDst:{pResource:obj#4083, Type:D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, SubresourceIndex:1}, DstX:0, DstY:0, DstZ:0, pSrc:{pResource:obj#4085, Type:D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, SubresourceIndex:0}, pSrcBox:{left:0, top:0, front:0, right:2088, bottom:2036, back:1})
8 8067 Signal(pFence:obj#20, Value:63)
9 8068 Signal(pFence:obj#21, Value:31)
如果不是,(即可能以某种方式搭载英特尔?)它看起来像这样:
Index Global ID Name EOP to EOP Duration (ns) Execution Start Time (ns)
0 8064 Wait(pFence:obj#45, Value:21)
2 8065 ClearRenderTargetView(RenderTargetView:res#4008, ColorRGBA:{Element:0, Element:0, Element:0, Element:0}, NumRects:0, pRects:nullptr)
15 8066 DrawIndexedInstanced(IndexCountPerInstance:4, InstanceCount:2, StartIndexLocation:0, BaseVertexLocation:0, StartInstanceLocation:0)
17 8067 Signal(pFence:obj#22, Value:23)
18 8068 Signal(pFence:obj#23, Value:21)
后者正在清除当前的 renderTargetView 并在顶部绘制一个四边形,这是耳机显示器的尺寸。
然而-我们检查了渲染代码,它肯定没有选择英特尔图形设备。但是,如果我们在 nvidia 控制面板中将 'preferred graphics processor' 设置为 nvidia gpu,第二种行为就会消失。
我们还可以看到上述行为是调用 XrEndFrame
的结果,并且我们的渲染代码在其他方面是相同的。
关于运行时的哪一部分可能正在查看或受此设置影响的任何线索?
不幸的是(幸运的是?)我们发现我们需要处理渲染代码才能交换运行时说 SteamVR,所以现在我们不能交换运行时。
显然我们有一个解决方法,就是设置首选设备。但是了解 how/why 这个问题的发生会很棒。
所以这最终被追踪到是我们的错误。
在我们的例子中,我们使用 xrGetD3D12GraphicsRequirementsKHR
来获得 openxr 的最低图形要求。
这在结构 XrGraphicsRequirementsD3D12KHR
中有一个 adapterLuid
标识符,我们本应将其用于 select 图形 API 中的 GPU,但没有。
首先:上下文是使用 HP Reverb G2、WMR 运行时、DX12 的 VR。
在使用 OpenXR 时,我们在开发人员机器上看到了一些无法解释的行为。看起来 OpenXR 运行时正在根据首选 GPU 的机器设置改变它的呈现方式。
更具体地说,我们注意到根据首选 GPU 的机器设置,我们看到在调用 XrEndFrame
时使用了不同的方法。这是一个大问题,因为不同的方法会导致空白屏幕被绘制到我们当前的 renderTarget!
不同之处在于,当首选设备是 Nvidia GPU 时,xrEndFrame 在 PIX 中看起来像这样(在独立于我们的主渲染的图形队列中):
Index Global ID Name EOP to EOP Duration (ns) Execution Start Time (ns)
2 8063 Signal(pFence:obj#20, Value:62)
3 8064 Wait(pFence:obj#36, Value:31)
5 8065 CopyTextureRegion(pDst:{pResource:obj#4083, Type:D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, SubresourceIndex:0}, DstX:0, DstY:0, DstZ:0, pSrc:{pResource:obj#4084, Type:D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, SubresourceIndex:0}, pSrcBox:{left:0, top:0, front:0, right:2088, bottom:2036, back:1})
6 8066 CopyTextureRegion(pDst:{pResource:obj#4083, Type:D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, SubresourceIndex:1}, DstX:0, DstY:0, DstZ:0, pSrc:{pResource:obj#4085, Type:D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX, SubresourceIndex:0}, pSrcBox:{left:0, top:0, front:0, right:2088, bottom:2036, back:1})
8 8067 Signal(pFence:obj#20, Value:63)
9 8068 Signal(pFence:obj#21, Value:31)
如果不是,(即可能以某种方式搭载英特尔?)它看起来像这样:
Index Global ID Name EOP to EOP Duration (ns) Execution Start Time (ns)
0 8064 Wait(pFence:obj#45, Value:21)
2 8065 ClearRenderTargetView(RenderTargetView:res#4008, ColorRGBA:{Element:0, Element:0, Element:0, Element:0}, NumRects:0, pRects:nullptr)
15 8066 DrawIndexedInstanced(IndexCountPerInstance:4, InstanceCount:2, StartIndexLocation:0, BaseVertexLocation:0, StartInstanceLocation:0)
17 8067 Signal(pFence:obj#22, Value:23)
18 8068 Signal(pFence:obj#23, Value:21)
后者正在清除当前的 renderTargetView 并在顶部绘制一个四边形,这是耳机显示器的尺寸。
然而-我们检查了渲染代码,它肯定没有选择英特尔图形设备。但是,如果我们在 nvidia 控制面板中将 'preferred graphics processor' 设置为 nvidia gpu,第二种行为就会消失。
我们还可以看到上述行为是调用 XrEndFrame
的结果,并且我们的渲染代码在其他方面是相同的。
关于运行时的哪一部分可能正在查看或受此设置影响的任何线索?
不幸的是(幸运的是?)我们发现我们需要处理渲染代码才能交换运行时说 SteamVR,所以现在我们不能交换运行时。
显然我们有一个解决方法,就是设置首选设备。但是了解 how/why 这个问题的发生会很棒。
所以这最终被追踪到是我们的错误。
在我们的例子中,我们使用 xrGetD3D12GraphicsRequirementsKHR
来获得 openxr 的最低图形要求。
这在结构 XrGraphicsRequirementsD3D12KHR
中有一个 adapterLuid
标识符,我们本应将其用于 select 图形 API 中的 GPU,但没有。