Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird behavior with 3D texture UAV #1351

Closed
darksylinc opened this issue Apr 15, 2019 · 5 comments
Closed

Weird behavior with 3D texture UAV #1351

darksylinc opened this issue Apr 15, 2019 · 5 comments
Labels
Bug A crash, misbehaviour, or other problem Unresolved Waiting for a fix or implementation

Comments

@darksylinc
Copy link
Contributor

darksylinc commented Apr 15, 2019

Description

NOTE: I am porting our voxelizer compute shader from GL3+ to D3D11 so there's a high chance I'm doing things wrong. However this looks like a RenderDoc bug.

When opening the attached file, there is a really weird behaviour going on that looks like a RenderDoc bug:

File: Voxelizer.rdc.7z.zip

Steps to repro:

  1. Open Voxelizer.rdc
  2. Open 3D Texture 1065 through the Texture List
  3. Notice that it is full black at all slices, no matter at which API call (btw I'm 80% certain this is wrong, it shouldn't be black)
  4. Now close 3D Texture 1065
  5. Now open Compute Pass Crash when changing between mesh preview tabs with no capture loaded #1 and go to the last dispatch call, the only one with Dispatch( 32, 32, 1 )
  6. Go to the "Outputs tab", and open CS RW 2[0] voxelAlbedoTex.
  7. This will open 3D Texture 1065
  8. There is white content on slice 0 (huh??? wasn't it black???). This is the expected result btw.
  9. If I close it and now open 3D Texture 1065 via the Texture List, it will appear just fine (no longer black)

This is how it looks (btw it's the expected output):
ExpectedOutput

Opening it via Outputs tab shows the expected output; but opening it via Texture List.
At the beginning of the frame, the texture already should have the same output (because I was running the exact compute shader every frame), so it should have never been black.

Btw voxelNormalTex does not look as expected but that may be my wrong doing I have still debugging to do

Environment

  • RenderDoc build: 2019-04-13 nightly build.
  • Operating System: Windows 10
  • API: D3D11
@darksylinc
Copy link
Contributor Author

Just for reference, this is the output from the GL version.

Note that D3D11 needs to do manual packing of formats while GL has native typed UAV loads:
VoxelizerGL.rdc.7z.zip

And this is the output from D3D11 when using native typed UAV loads (needs D3D11.3 and Windows 10):
VoxelizerD3D11.3.rdc.7z.zip

Note that both GL & D3D11.3 versions behave correctly in RenderDoc, but not the D3D11.1 one

@baldurk baldurk added Bug A crash, misbehaviour, or other problem Unresolved Waiting for a fix or implementation labels Apr 15, 2019
@baldurk
Copy link
Owner

baldurk commented Apr 22, 2019

As far as I can tell this is behaving as expected, though there's an important bit of information which is kind of easy to miss.

In the 'working' cases of GL and D3D11.3, the texture is natively UNORM so when you write 1.0 to any texel it shows up clearly. In the D3D11.0 case the texture is natively TYPELESS and so without any better information it's interpreted as UNORM. However when it's written it's written as packed UINT which means a value of 1 is written - 0.03 in UNorm terms.

So the data is always there, it's just incredibly dark when viewed as UNORM so you need to use the range control to see it show up. When you select the dispatch and view it through the bindings, the UINT type hint is applied and the texture is re-interpreted as UINTs at which point it shows up correctly.

This is all as is expected, though of course you need to know that a TYPELESS texture will be interpreted as UNORM and not as UINT with all else being equal. I've changed the status bar so it will explicitly say "Viewed as UNorm" if it doesn't have anything better - previously it would only show that when explicitly cast by a view.

@darksylinc
Copy link
Contributor Author

darksylinc commented Apr 22, 2019

I don't think I understand.
I am indeed expecting the texture to be shown as UNORM (not UINT) and the data doesn't have a 1 to be interpreted as 0.03, it has 0xFFFFFFFFF so I'd expect white 1.0f, and clicking the pixel RenderDoc says the texture contents are (0, 0, 0, 0), which is wrong.

But after selecting the dispatch call and reopening the texture, it looks as expected from there onwards; and pixel clicking shows the correct value too.

@baldurk
Copy link
Owner

baldurk commented Apr 22, 2019

Maybe I'm seeing something different to you then. When I load the capture and open Texture 1065 it looks like this:

image

As of the next nightly build the status bar will be amended like this:

image

If I adjust the range I can see data:

image

And pick any of those pixels as unorm values, e.g. in slice 0 most of the top row:

image

This is all without changing events, so effectively at the end of the frame. Selecting the start of the frame also gives the same results. Selecting anywhere in EIDs 27 - 52 shows completely black, because the texture is cleared in EID 27's dispatch.

Then if you select the EID 68 that writes to it, and open the texture via the bound thumbnails, the status bar updates to uint interpretation:

image

This shows the 1 values that were written as UINT into the texture in that dispatch. If you open the texture as a buffer you can similarly see that the data is 1, and not 255 in each component.

I looked at the compute shader and while I didn't dive down into it, it seems like maybe you are mistaken based on a bug in packUnorm4x8:

uint packUnorm4x8( float4 v )
{
	uint retVal;
	retVal  = uint( round( saturate( v.x * 255.0f ) ) );
	retVal |= uint( round( saturate( v.y * 255.0f ) ) ) << 8u;
	retVal |= uint( round( saturate( v.z * 255.0f ) ) ) << 16u;
	retVal |= uint( round( saturate( v.w * 255.0f ) ) ) << 24u;

	return retVal;
}

The multiply by 255 happens before the saturate, so an input of float4(1.0, 1.0, 1.0, 1.0) will come out with uint values 1, 1, 1, 1 before being bitpacked. Moving the multiply out does cause 255 to be written out into the texture, and when viewed as UINT it shows up as expected:

image

Then the UNORM values get displayed as pure white even without the UINT typecast:

image

But unless I edit the shader to fix that multiply, I don't ever see 255 when interpreted as UINT or 1.0 as UNORM, and RenderDoc's display is consistent with the underlying data.

Do you actually see signs of 0xFFFFFFFF being written anywhere or was that an assumption based on how you thought the shader should work? Please check to see what you actually get, and if it differs from what I've listed above let me know, but I'm still not sure there's any actual bug here.

@darksylinc
Copy link
Contributor Author

Gaaaahhh!

You're right in all accounts.

I keep forgetting GL vs D3D11 flip the texture, so I was mouse picking the wrong pixels and see the whole bottom black.

Now I see what you mean. There is no RenderDoc bug, there's only my saturation bug. Thanks for spotting it btw.!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug A crash, misbehaviour, or other problem Unresolved Waiting for a fix or implementation
Projects
None yet
Development

No branches or pull requests

2 participants