bkaradzic / bgfx

Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.
https://bkaradzic.github.io/bgfx/overview.html
BSD 2-Clause "Simplified" License
15.15k stars 1.95k forks source link

updateTexture2D fail on D3D12 when using Texture Arrays #2736

Open SergioRZMasson opened 2 years ago

SergioRZMasson commented 2 years ago

Using bgfx::updateTexture2D on a texture array using D3D12 renderer will result in a crash during TextureD3D12::update with the following error:

D3D12 ERROR: ID3D12CommandList::CopyTextureRegion: The source box extends past, at least, one the edges of the source subresource. pSrcBox right is 256, bottom is 98, and back is 2. But, the source subresource only has 256 width, 98 height, and 1 depth. [ RESOURCE_MANIPULATION ERROR #871: COPYTEXTUREREGION_SRCREGIONOUTOFBOUNDS]

To Reproduce Steps to reproduce the behavior:

  1. Clone repro https://github.com/SergioRZMasson/bgfx/tree/2D-texture-array-D3D12-bug
  2. Run example-00-helloworld with --d3d12 args

Expected behavior On all other platforms the textures array gets updated properly when using bgfx::updateTexture2D.

SergioRZMasson commented 2 years ago

After doing some testing, I beliave the problem is that for D3D12 layer should not be used as _z for updating a texture2D Array.

I did some changes by replacing line 5108 on renderer_d3d12.cpp with:

const uint32_t subres = _mip + (_side * m_numMips) + (_z * m_numMips);

and also line 5122:

D3D12_BOX box;
box.left   = 0;
box.top    = 0;
box.right  = box.left + _rect.m_width;
box.bottom = box.top  + _rect.m_height;
box.front  = 0;
box.back   = _depth;

This fixes the behaviour for texture2D arrays since they elements in the array should be considered subresources and handled by index in D3D12. However, this will break Texture3D since _z will have a different usage for them.