Strange OpenXR Behaviour on xrEndFrame

264 Views Asked by At

Firstly: Context is VR with HP Reverb G2, WMR runtime, DX12.

We're seeing some unexplained behaviour across developer machines when working with OpenXR. It looks as thought the OpenXR runtime is changing the way it presents depending on the machine setting for preferred GPU.

More specifically, we noticed that depending on the machines setting for preferred GPU, we are seeing a different method used when XrEndFrame is called. This is a big deal as the different method results in a blank screen being drawn into our current renderTarget!

The difference is that when the preferred device is an Nvidia GPU, xrEndFrame looks like this in PIX (in a graphics queue that is separate to our main render):

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)     

and when it isn't, (i.e. somehow maybe picking up Intel onboard?) it looks like this:

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)     

The latter is clearing the current renderTargetView and drawing a quad over the top that is the dimensions of the headset display.

Yet- we've checked the rendering code and it is definitely not selecting the Intel graphics device. However the second behaviour goes away if we set 'preferred graphics processor' to nvidia gpu in nvidia control panel.

We can also see that the above behaviour is the result of a call to XrEndFrame, and that our rendering code is identical otherwise.

Any clue as to what part of the runtime might be looking at or influenced by this setting?

Unfortunately (fortuitously?) we found we need to work on the rendering code to be able to swap runtimes to say SteamVR, so right now we can't swap out the runtime.

Obviously we have a workaround, which is to set the preferred device. But understanding how/why this issue is occurring would be great.

1

There are 1 best solutions below

0
On BEST ANSWER

So this was finally tracked down to an error on our part. In our case we were using xrGetD3D12GraphicsRequirementsKHR to get the minimum graphics requirements for openxr.

This has an adapterLuid identifier in the structure XrGraphicsRequirementsD3D12KHR which we should have been using to select the GPU in the graphics API, but weren't.