[2.3] Binding depth buffer to compute job. Topic is solved

Discussion area about developing with Ogre-Next (2.1, 2.2 and beyond)


Post Reply
przemir
Halfling
Posts: 68
Joined: Sun May 11, 2014 7:55 pm
Location: Poland
x 21

[2.3] Binding depth buffer to compute job.

Post by przemir »

Hi,

I try to bind depth buffer used in compositor to compute job (for particle depth collisions) with this code:

Code: Select all

	CompositorNode* node = mCompositorWorkspace->findNode(Ogre::IdString("PostprocessingSampleStdRenderer")); 
	if(node) {
		TextureGpu* tex = node->getDefinedTexture(Ogre::IdString("depthTextureView"));

		DescriptorSetTexture2::TextureSlot texSlot(DescriptorSetTexture2::TextureSlot::makeEmpty());
		texSlot.texture = tex;
		mUpdateParticlesJob->setTexture( 4, texSlot );
	}
But it seems to be an empty texture - I tried to save this texture with:

Code: Select all

	Ogre::Image2 img;
	img.convertFromTexture( tex, 0u, tex->getNumMipmaps() - 1u );
	img.save( path + "depthTextureView" + Ogre::StringConverter::toString(counter2) + "." + ext, 0u, tex->getNumMipmaps() );
And depth texture is all black (standard textures are generated properly).

In compositor node depth texture is declared as follow:

Code: Select all

	texture rt0 target_width target_height PFG_RGBA8_UNORM depth_format PFG_D32_FLOAT_S8X24_UINT depth_texture depth_pool 1
	texture rt1 target_width target_height PFG_RGBA8_UNORM depth_pool 1
	
	... // some other textures using the same depth buffer

	texture depthTextureView target_width target_height PFG_D32_FLOAT_S8X24_UINT depth_pool 1 keep_content
I also tried to get depth texture via Ogre::Window::getDepthBuffer(), but I got exception:

Code: Select all

An exception has occured: OGRE EXCEPTION(1:InvalidStateException): Transitioning texture RenderWindow DepthBuffer from Undefined to a read-only layout. Perhaps you didn't want to set TextureFlags::DiscardableContent / aka keep_content in compositor? in BarrierSolver::resolveTransition
I also tried with SceneManager::getCompositorTextures, but I don't get any textures there. Is this valid only during compositor pass?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.3] Binding depth buffer to compute job.

Post by dark_sylinc »

Hi!

You're using 2.1 methods to access the depth buffer. I think that no longer works, or if it works it's very fragile (despite having the same pool ID, subtle differences in settings can cause the depth buffer to be different, instead of being shared).
See any of these samples:
  • Samples/Media/2.0/scripts/Compositors/Tutorial_ReconstructPosFromDepth.compositor
  • Samples/Media/2.0/scripts/materials/Tutorial_SSAO/SSAO_HS.compositor
  • Samples/Media/2.0/scripts/Compositors/ScreenSpaceReflections.compositor
Which setup an RTV with a colour and depth buffer, and later read from the depth buffer. Using an explicitly-declared RTV is robust because you force Ogre to render using that specific depth buffer.
przemir wrote: Sun May 23, 2021 9:36 am I also tried to get depth texture via Ogre::Window::getDepthBuffer(), but I got exception:

Code: Select all

An exception has occured: OGRE EXCEPTION(1:InvalidStateException): Transitioning texture RenderWindow DepthBuffer from Undefined to a read-only layout. Perhaps you didn't want to set TextureFlags::DiscardableContent / aka keep_content in compositor? in BarrierSolver::resolveTransition
If this is the Vulkan RenderSystem, then downloading data from a RenderWindow isn't yet implemented.
If this is any other RS, the error means the operation was done too late (i.e. must be done before RenderSystem::_update gets called again)
przemir
Halfling
Posts: 68
Joined: Sun May 11, 2014 7:55 pm
Location: Poland
x 21

Re: [2.3] Binding depth buffer to compute job.

Post by przemir »

Thanks. I updated compositor.

1) I declared depthbuffer as this

Code: Select all

texture depthTexture target_width target_height PFG_D32_FLOAT_S8X24_UINT keep_content
If I use this texture in shader will I get only depth information or stencil information as well (I don't need stencil for compute job)? When I exported this texture with Ogre::Image2, the only difference I was able to spot is that image for PFG_D32_FLOAT_S8X24_UINT uses only red colour instead of gray in case of PFG_D32_FLOAT.

2) I found that pass_clear clears whole texture even with stencil check on. Is it intented behaviour?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.3] Binding depth buffer to compute job.

Post by dark_sylinc »

przemir wrote: Wed May 26, 2021 12:29 am 2) I found that pass_clear clears whole texture even with stencil check on. Is it intented behaviour?
Due to API oddities in certain platforms pass clear will always clear the whole content (not just a subregion) of the whole texture (PFG_D32_FLOAT_S8X24_UINT means depth and stencil are combined as one therefore you can't clear them separately)

We have the code for having separate depth and stencil but platform support is very scarce. Only iOS supports it properly.

Edit: What happens if you set?

Code: Select all

pass clear
{
   load
   {
        stencil load
   }
}
That should work.

Alternative this syntax should work (but only for pass clear, previous syntax works for all types of passes):

Code: Select all

pass clear
{
   // default is: buffers colour depth stencil
   buffers colour depth
}
przemir
Halfling
Posts: 68
Joined: Sun May 11, 2014 7:55 pm
Location: Poland
x 21

Re: [2.3] Binding depth buffer to compute job.

Post by przemir »

dark_sylinc wrote: Wed May 26, 2021 12:38 am What happens if you set?

Code: Select all

pass clear
{
   load
   {
        stencil load
   }
}
Well I am not sure if this is answer for 1) or 2) but I assume the second one (although it also show me idea how to get depth buffer only from PFG_D32_FLOAT_S8X24_UINT ).

If I render texture with this pass, the texture it is all black (or all red if set also colour 1 1 1 1). Similarly for the second snippet. But I already solved this with this code (after stencil pass):

Code: Select all

pass render_quad
{
	material Postprocess/FillColour/White
}
where Postprocess/FillColour/White is my custom material which sets colour to 1 1 1 1

3) Also about

Code: Select all

pass clear
{
   load
   {
        stencil load
   }
}
I still not really get load and store syntax in compositor (documentation didn't mention about it as well).

4)
dark_sylinc wrote: Wed May 26, 2021 12:38 am PFG_D32_FLOAT_S8X24_UINT means depth and stencil are combined as one therefore you can't clear them separately
but what about reading depth from it from shader (eventually copying and converting it to depth buffer only)?
User avatar
dark_sylinc
OGRE Team Member
OGRE Team Member
Posts: 5296
Joined: Sat Jul 21, 2007 4:55 pm
Location: Buenos Aires, Argentina
x 1278
Contact:

Re: [2.3] Binding depth buffer to compute job.

Post by dark_sylinc »

przemir wrote: Wed May 26, 2021 9:25 am I still not really get load and store syntax in compositor (documentation didn't mention about it as well).
I noticed the compositor page of our docs don't mention it at all. That's our bad.

Check the 2.2 changes pages which goes in depth about load/store actions.

About the compositor script syntax, almost all passes can have the following:

Code: Select all

pass ...
{
  load
  {
     colour load | clear | clear_on_tilers | dont_care
     depth load | clear | clear_on_tilers | dont_care
     stencil load | clear | clear_on_tilers | dont_care
  }
  store
  {
     colour dont_care | store | resolve | store_and_resolve | store_or_resolve
     depth dont_care | store | resolve | store_and_resolve | store_or_resolve
     stencil dont_care | store | resolve | store_and_resolve | store_or_resolve
  }
}
As the 2.2 changes page explains, it is usually now better to avoid "pass clear" and use a 'clear' load action in pass_scene.
In some cases using a clear pass is unavoidable or may get better performance in select cases (TBDR section explains how it works).

The "pass clear" pass is just a pass that performs a clear on all load actions, and immediately performs a store.
przemir wrote: Wed May 26, 2021 9:25 am PFG_D32_FLOAT_S8X24_UINT means depth and stencil are combined as one therefore you can't clear them separately
but what about reading depth from it from shader (eventually copying and converting it to depth buffer only)?
I'm not sure I understand what you mean. By default if you bind a PFG_D32_FLOAT_S8X24_UINT texture to a shader, you get the depth part and access it via a texture<float> sampler.

Accessing the raw stencil part from the shader is quite difficult (but possible) but Ogre didn't implement this functionality.
przemir
Halfling
Posts: 68
Joined: Sun May 11, 2014 7:55 pm
Location: Poland
x 21

Re: [2.3] Binding depth buffer to compute job.

Post by przemir »

Thanks a lot for explanation.
dark_sylinc wrote: Wed May 26, 2021 8:45 pm
przemir wrote: Wed May 26, 2021 9:25 am PFG_D32_FLOAT_S8X24_UINT means depth and stencil are combined as one therefore you can't clear them separately
but what about reading depth from it from shader (eventually copying and converting it to depth buffer only)?
I'm not sure I understand what you mean. By default if you bind a PFG_D32_FLOAT_S8X24_UINT texture to a shader, you get the depth part and access it via a texture<float> sampler.
Thats all I wanted to know. I simply though that in PFG_D32_FLOAT_S8X24_UINT format each pixel's float will have both depth and stencil encoded and I will have to somehow extract it inside shader. I see now that it is not the case.
Post Reply