OIT Sorted Pixels is failing when using Bindless

This is observed in Engine Versions 5.7 and 5.8 with and without nanite translucency

Steps to reproduce:

  1. Ensure OIT is enabled in the project and SortedPixels is enabled
  2. Make sure bindless is enabled for your platform at the rhi level and in the platform specific .ini’s
  3. Create a test scene
  4. Place a mesh into the scene, sphere/cube etc. anything works
  5. Create a test material that supports a translucent model, normal / thin translucent, anything works
  6. Enable two sided on that test material, OR have multiple meshes overlapping in the scene with the same translucent material applied
  7. Apply the material to the test object placed in step 1
  8. Observe flickering artefacts like the provided screenshot
  9. For deeper observations look into a renderdoc capture:
    1. Observe inconsistent sample counts on the UAV used in the OIT shader across the material/objects
    2. look at the DXC generated and see the ROV attribute isn’t present at all in the shader
    3. Do a non-bindless enabled capture of the same scene and see the ROV enabled texture in the DXC

OIT depends on the SampleData and SampleCount textures, the latter having the Raster-Order-View attribute

With Bindless enabled the ROV attribute isnt preserved when retrieving the UAV’s in the OIT shaders

Behind the scenes it’s calling into GetUAVFromHeap for bindless functionality and doing casting based on provided type

This access pattern not preserving the attribute means that OIT sorted pixels doesnt function correctly with bindless enabled

Sorted Triangles still works, though this still means Sorted Pixels is failing

Because the OIT implementation isnt through atomics and the attempted implementation for that was avoided/commented out due to GPU hangs (and from testing still causes hangs) there isnt a viable solution for per-pixel OIT with bindless within the engine that works

Is this something planned to be fixed?

Will this change behaviour of OIT if fixed?

[Attachment Removed]

Steps to Reproduce
This is observed in Engine Versions 5.7 and 5.8 with and without nanite translucency

Steps to reproduce:

  1. Ensure OIT is enabled in the project and SortedPixels is enabled
  2. Make sure bindless is enabled for your platform at the rhi level and in the platform specific .ini’s
  3. Create a test scene
  4. Place a mesh into the scene, sphere/cube etc. anything works
  5. Create a test material that supports a translucent model, normal / thin translucent, anything works
  6. Enable two sided on that test material, OR have multiple meshes overlapping in the scene with the same translucent material applied
  7. Apply the material to the test object placed in step 1
  8. Observe flickering artefacts like the provided screenshot
  9. For deeper observations look into a renderdoc capture:
    1. Observe inconsistent sample counts on the UAV used in the OIT shader across the material/objects
    2. look at the DXC generated and see the ROV attribute isn’t present at all in the shader
    3. Do a non-bindless enabled capture of the same scene and see the ROV enabled texture in the DXC

OIT depends on the SampleData and SampleCount textures, the latter having the Raster-Order-View attribute

With Bindless enabled the ROV attribute isnt preserved when retrieving the UAV’s in the OIT shaders

Behind the scenes it’s calling into GetUAVFromHeap for bindless functionality and doing casting based on provided type

This access pattern not preserving the attribute means that OIT sorted pixels doesnt function correctly with bindless enabled

Sorted Triangles still works, though this still means Sorted Pixels is failing

Because the OIT implementation isnt through atomics and the attempted implementation for that was avoided/commented out due to GPU hangs (and from testing still causes hangs) there isnt a viable solution for per-pixel OIT with bindless within the engine that works

Is this something planned to be fixed?

Will this change behaviour of OIT if fixed?

[Attachment Removed]

Hi,

Thank you for reporting this. This is indeed a bug, but it does not seem trivial to fix.

As you mentioned, when using bindless, the ROV attribute isn’t preserved, causing the shader to not flag the shader as using ROV, which cause the resources to fallback on a regular UAV (which thus races write). We could potentially fix that I guess. The main issue seems to be Microsoft’s SM6.6 Dynamic Resources spec simply doesn’t list ROV as a supported dynamic-resource usage, and so I’m not sure drivers guarantee it. So it’s likely undefined-behavior territory across vendors.

I start to think we might need to resort to static binding in this case, but the issue is that the current bindless code does not allow mix of bindless/nonbindless which would have allowed to statically declared this ROV resources and solve that.

I will consult with the RHI team, what are the possibility there.

/Charles.

[Attachment Removed]

So chatting with the team, the mix of bindless and static binding seems to be the route to follow. There is no actual ETA on this front, but it looks like this work won’t happen this year due to other priroties.

/Charles.

[Attachment Removed]