crjc wrote: ↑Tue Oct 20, 2020 11:11 am
I have it all working but in the interest of performance I'd like to use those methods you've mentioned - But how would I get an instance of
MTLRenderPassDescriptor that I can pass to
ImGui_ImplMetal_NewFrame without using
performLoadActions?
I took a look at Imgui's Metal code, they don't really need the MTLRenderPassDescriptor (that confused me for a while), they just need some of the information inside MTLRenderPassDescriptor to construct their PSOs.
Fortunately! After looking at what performLoadActions is doing, it doesn't actually set anything to the current state (unlike the other backends). It just fills passDesc.
Your code is correct! There is nothing to be done, and in your case don't call setRenderPassDescToCurrent nor executeRenderPassDescriptorDelayedActions; this way rendering the UI will continue after your regular rendering.
Unless you do Imgui at the end after postprocessing, in which case you should call:
Code: Select all
setRenderPassDescToCurrent();
RenderSystem *renderSystem = sceneManager->getDestinationRenderSystem();
renderSystem->executeRenderPassDescriptorDelayedActions();
MTLRenderPassDescriptor *passDesc = [MTLRenderPassDescriptor renderPassDescriptor];
MetalRenderPassDescriptor *ogreMetalRenderPass =
static_cast<MetalRenderPassDescriptor *>( renderSystem->getCurrentPassDescriptor() );
renderPassDesc->performLoadActions( passDesc, false );
TL;DR: If it works for you (i.e. no validation complains) avoid calling setRenderPassDescToCurrent & executeRenderPassDescriptorDelayedActions();
If you get problems, then do call them.
Edit: To elaborate on this: Ogre passes have load & store actions per pass. For best performance, one should avoid closing a render encoder and opening a new one as much as possible (e.g. like submitting 2 products in the same package instead of submitting 2 packages)
Ogre's setRenderPassDescToCurrent & executeRenderPassDescriptorDelayedActions try their best to merge passes as much as possible if the user specified actions are compatible. But sometimes this breaks in subtle ways because the load/store actions the user requested are incompatible; and the only way to debug this is with RenderDoc (Vulkan backend) or XCode Graphics Debugger (Metal backend).
One easy way to always force passes being merged is by not calling setRenderPassDescToCurrent & executeRenderPassDescriptorDelayedActions at all; thus the render pass desc from the previous compositor pass gets reused. This may be undesirable however, if the previous pass was rendering to a completely unrelated render target to the one we will be rendering now (which is very rare for an UI rendering pass).
A side problem I now have: If I use SetSky, it completely breaks my ImGui setup, looks like ImGui is getting the sky's cube map by mistake, any suggestions on how to fix this?
That's odd. Imgui should set their own textures, overwriting whatever state we set; this implies there may be a bug in Imgui.
Unless you somehow issued Ogre calls in the middle of Imgui calls.
Anyway, the quick solution would be to tell Ogre to unset the texture at that slot:
Code: Select all
renderSystem->_setTexture( 0, nullptr, false );
But there may be something deeper going on since Imgui's code should be preventing this from happening at all.