Search code examples
shaderdirectxhlsl

Reading/writing off the end of a buffer


What happens when you read and write off the end of a buffer in a hlsl shader?

In my experience it seems that writing of the end is a no-op, and reading always returns zero.

Is this undefined behaviour? Should I do it, expecting the above results?

Does it matter whether the resource is untyped or typed?

RWBuffer<uint> // typed
RWStructuredBuffer<uint> // untyped

Solution

  • https://computergraphics.stackexchange.com/questions/13082/does-rwstructuredbuffer-have-built-in-overflow-protection-in-hlsl

    Using D3D11 you should be safe: Direct3D guarantees to return zero for any resource that is accessed out of bounds. Similarly, out of bounds writes should be ignored. That said this guarantee does not exist for D3D12 (iirc), since its the clients responsibility to manage descriptors and resource there anyway.

    https://github.com/Microsoft/DirectX-Graphics-Samples/issues/144

    Are you using a root descriptor or a descriptor table in your root signature? D3D12 introduces a complication with regard to root signatures. If the buffer is described by a normal descriptor in a descriptor table, you should get D3D11 behavior (return 0), but if you use a root descriptor, you get undefined behavior on out of bounds, since the root descriptor does not capture bounds information.

    Jesse goes into some additional detail in this gamedev.net post

    https://www.gamedev.net/forums/topic/677978-hlsl-reading-outside-array-safe/

    that should work as long as you're using descriptors from a table. Root descriptors don't contain size information, so out-of-bounds access can cause a page fault/crash.