Describe the bug
Using bgfx::blit between two 2D texture arrays results in blitting only the first layer (using the blit overload that allows to set _depth to 2).
To Reproduce
Create two 2D Texture Array with at least 2 layers
Observe that second layer is not blitted (verified in RenderDoc for D3D11 and Vulkan)
Expected behavior
blit should honor the z and depth parameters or assert invalid parameter combinations.
Screenshots
NA
Additional context
I came up with a simple fix which works fine for my use case (porting Visual Pinball X, a large open source pinball simulator, to BGFX): https://github.com/bkaradzic/bgfx/compare/master...vbousquet:bgfx:fix_texarray_blit
Note that this fix was only tested for D3D11 and Vulkan with limited test case (BGFX examples do not use this feature, Visual Pinball X has a single use case when rendering for VR or anaglyph stereo)
This fix was made after some search and diving into the bgfx D3D11, OpenGL and Vulkan renderer source. It is based on the understanding I got from this which is the following (and may be wrong):
D3D11 renderer rely on CopySubresourceRegion which allows to copy only one layer at a time. So either depth should be asserted for value above 1 or multiple calls should be performed.
Describe the bug Using
bgfx::blit
between two 2D texture arrays results in blitting only the first layer (using the blit overload that allows to set_depth
to 2).To Reproduce
bgfx::blit(viewId, destTex, 0, 0, 0, 0, srcTex, 0, 0, 0, 0, width, height, 2);
Expected behavior blit should honor the z and depth parameters or assert invalid parameter combinations.
Screenshots NA
Additional context I came up with a simple fix which works fine for my use case (porting Visual Pinball X, a large open source pinball simulator, to BGFX): https://github.com/bkaradzic/bgfx/compare/master...vbousquet:bgfx:fix_texarray_blit Note that this fix was only tested for D3D11 and Vulkan with limited test case (BGFX examples do not use this feature, Visual Pinball X has a single use case when rendering for VR or anaglyph stereo)
This fix was made after some search and diving into the bgfx D3D11, OpenGL and Vulkan renderer source. It is based on the understanding I got from this which is the following (and may be wrong):
_dstZ
,_srcZ
,_depth
are used as z for 3D texture, side for cubemap, and as layer index for texture array. I may be completely wrong on that as this is not stated in the API doc (only cubemap and 3D) but the code seems to show this intent, at least it is what it does. For Vk: https://github.com/bkaradzic/bgfx/blob/00fa5ad179f5aa13c1e44d0bcbccdc535aba2d00/src/renderer_vk.cpp#L8108 for OpenGl: https://github.com/bkaradzic/bgfx/blob/00fa5ad179f5aa13c1e44d0bcbccdc535aba2d00/src/renderer_gl.cpp#L7394 for D3D11: https://github.com/bkaradzic/bgfx/blob/00fa5ad179f5aa13c1e44d0bcbccdc535aba2d00/src/renderer_d3d11.cpp#L5556blit
calls are validated against 6 sides of cubemaps (no support for cubemap array) or 3D texture depth but not number of layers of texture array leading to always consideringdepth
as 0. This is the reason only the first layer is blitted: https://github.com/bkaradzic/bgfx/blob/00fa5ad179f5aa13c1e44d0bcbccdc535aba2d00/src/bgfx.cpp#L4025CopySubresourceRegion
which allows to copy only one layer at a time. So eitherdepth
should be asserted for value above 1 or multiple calls should be performed.