Page 1 of 1

Regarding UAVs and Ogre 2.1

Posted: Sun Apr 12, 2015 4:52 pm
by dark_sylinc
Jesse, aka. holocronweaver, has already implemented image load/store functionality in GL3+ (but it requires manually calling the C++ function). He was thinking into incorporating this functionality at the material level.

I've been researching into how D3D11 does things (they call them UAVs, Unordered Access Views).

D3D11 equals UAVs to RenderTargets; while OpenGL equals them more like textures.
In fact, the D3D11 API call to bind UAVs must set RenderTargets at the same time. There is no API call to only set UAVs.

This is so for performance improvements: they can check for hazards when setting RTs and UAVs (i.e. make sure you don't bind the same resource as both RT and UAV) while they still use the same hazard checking they do for textures to check that you're not binding a texture at the same time it is bound as an RT/UAV.

If the UAV equals a texture, as in OpenGL; they would have to check textures against textures every time a texture changes, which is O( N! ) complexity; and also a very common operation. Considering past experiences, I'm guessing OpenGL just simply skips the check and lets the hazard happen (which is cool when there are hardware extensions that allow you to read/write from these resources at the same time as long as you abide to certain rules).

So, to comply with both I'm drastically changing Jesse's plan on how UAVs are going to be bound in Ogre (since D3D11 is more restrictive than OGL). You will do them via compositor scripts; or via explicit RenderSystem calls in C++; rather than leaving this to materials.

Since UAVs in D3D11 equals SSBOs + image load/store in OpenGL; I'm requiring OGL 4.3 to support the "UAV" feature (rather than OGL 4.2 to just get image load/store).

In the new system, you will bind the UAV to binding points beforehand, that are kept in a list; which will be set the next time a render target is set.
It will be the user's responsibility to ensure the shader's binding point for each ssbo/imagestore variable is in sync with the binding points you set from C++ or compositor scripts.

This is much more simple, elegant, and easy to implement. Plus, all UAV applications I can think of involve switching RenderTargets or doing postprocessing effects (advanced shadow mapping, Order Independent Transparency, Bokeh depth of field, Forward+, Tiled Deferred Shading), for which moving the interface to the compositor (rather than the material) feels like natural.

I'm just keeping you all in the loop.

Cheers
Matias

Re: Regarding UAVs and Ogre 2.1

Posted: Sun Apr 12, 2015 5:03 pm
by al2950
All over my head I am afriad :oops:.

However without trying to derail this thread, has much thought been given to how API decisions like this may affect Dx12 & Vulkan?

Re: Regarding UAVs and Ogre 2.1

Posted: Sun Apr 12, 2015 6:20 pm
by holocronweaver
dark_sylinc wrote:Plus, all UAV applications I can think of involve switching RenderTargets or doing postprocessing effects
I use image load/store for those things, but I primarily use it in compute shaders which perform 3D grid-based physics simulations. However, since compute shaders are going to be available in the compositor, I think I can port my C++ calls to compositor scripts.

Overall I think your approach will work for most use cases. (I can imagine some exotic algorithms which save geometry / tessellation shader output to textures for all sorts of procedural purposes, but at the moment I have no plans to attempt this.) If I encounter a situation where there is need for material level access, it shouldn't be too hard to add. D3D & GL RS feature parity is nice, but not essential.

Re: Regarding UAVs and Ogre 2.1

Posted: Mon May 11, 2015 2:34 am
by dark_sylinc
New commit: https://bitbucket.org/sinbad/ogre/commi ... 826f65f5db.

The proposed compositor script syntax is somewhere along the following:

Code: Select all

compositor_node PbsMaterialsRenderingNode
{
	in 0 rt_renderwindow

	target rt_renderwindow
	{
                //Sets UAVs by name on given slots.
		pass uav_queue
		{
			starting_slot 1
			uav				0 rt_renderwindow <mrt #> <read> <write> [PF_R32] [<mipmap> #]
			uav				1 rt_mrt 2
			uav_external	2 externalTexture
		}

		pass render_quad
		{
			material material_that_uses_uavs_on_slots_0_and_1
			uses_uav 0 read
			uses_uav 1 read write
		}

		pass render_quad
		{
			material another_material_that_uses_uavs_on_slots_0_and_1
			//Fogetting to set "uses_uav", no memory barrier will placed. Useful if multiple passes are only reading from the resource, but dangerous. Remember to inform!
		}

		pass uav_queue
		{
			uav				1 some_otherUav
			keep_previous_uavs false
		}

		pass render_quad
		{
			material material_that_uses_uav_on_1
			uses_uav 1 write
		}

		pass clear
		{
			colour_value 0.2 0.4 0.6 1
		}

		pass render_scene
		{
			//colour_write off
			overlays	on
			shadows		PbsMaterialsShadowNode
		}
	}
}
The compositor will create the ResourceTransitions & Memory barriers automatically, although in some parts extra information is needed (i.e. UAVs, the pass quads need to specify which UAVs will be used).

Re: Regarding UAVs and Ogre 2.1

Posted: Mon May 11, 2015 5:13 pm
by uelkfr
Bleeding edge is good, but how about mobile compatibility:
https://trello.com/c/c1OBLJRI/40-restore-gles2-support

Re: Regarding UAVs and Ogre 2.1

Posted: Mon May 11, 2015 9:00 pm
by dark_sylinc
I'm afraid that's in the distant future.
GLES2 turned out much more difficult to port to than anticipated; GLES3 is a better match, and honestly Metal & Vulkan are much more 2.1 friendly.

Sadly GLES2 market share can't be ignored (Android users); but due to difficulties, support has been delayed and there's no ETA.