Closed 9MW closed 4 months ago
Note that your code for 24-bit is incorrect. You are reading as if 24-bit depth was packed into 32-bit leaving each byte unused, which may not be the case.
How do you copy your depth texture to your staging texture?
Note that your code for 24-bit is incorrect. You are reading as if 24-bit depth was packed into 32-bit leaving each byte unused, which may not be the case.
How do you copy your depth texture to your staging texture?
I stopped use TEX_FORMAT_D24_UNORM_S8_UINT after found this format is not supported to copy back to RAM. Copied by
math::v4f cursorZ;
const float ClearColor[] = { 0.350f, 0.350f, 0.350f, 1.0f };
auto& m_pSwapChain = this->p_rt->m_pSwapChain;
auto pRTV = m_pSwapChain->GetCurrentBackBufferRTV();
auto pDSV = m_pSwapChain->GetDepthBufferDSV();
auto df = pDSV->GetTexture()->GetDesc();
auto& pContext = this->p_rt->m_pImmediateContext;
auto pdepthtex = pDSV->GetTexture();
pContext->SetRenderTargets(0, nullptr, nullptr, RESOURCE_STATE_TRANSITION_MODE_NONE);
auto& m_UploadCompleteFence = _editmem.get<1>().m_UploadCompleteFence;
auto& cam = Camera::Main();
inputmanager& ipt = *p_ipt;
cursorZ.head<2>() = ipt.mouseinfo.operator pj2::mousestate::f2 & ();
editmemCounters& memedit = _editmem.get<1>();
cursorZ = cursorZ.cwiseMax(math::v4f::Ones()*4);
cursorZ[0] = std::min((UINT32)cursorZ[0], cam.m_ProjAttribs.Width);
cursorZ[1] = std::min((UINT32)cursorZ[1], cam.m_ProjAttribs.Height);
//pContext->UnmapTextureSubresource(pStagingTexture, StartDstMip + mip, StartDstSlice + slice);
Box SrcBox;
SrcBox.MaxX = cursorZ[0];
SrcBox.MinX = std::max(0u, SrcBox.MaxX - 3);
SrcBox.MaxY = cursorZ[1];
SrcBox.MinY = std::max(0u, SrcBox.MaxY - 3);
CopyTextureAttribs CopyAttribs(pdepthtex, RESOURCE_STATE_TRANSITION_MODE_TRANSITION,
memedit.pStagingTexture, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
CopyAttribs.pSrcBox = &SrcBox;
pContext->CopyTexture(CopyAttribs);
pContext->EnqueueSignal(m_UploadCompleteFence, ++_editmem.get<1>().m_UploadCompleteFenceValue);
const StateTransitionDesc Barrier{ pdepthtex, RESOURCE_STATE_COPY_SOURCE, RESOURCE_STATE_DEPTH_WRITE };
pContext->TransitionResourceStates(1, &Barrier);
pContext->SetRenderTargets(1, &pRTV, pDSV, RESOURCE_STATE_TRANSITION_MODE_TRANSITION);
You may consider using GPUCompletionAwaitQueue
Here is the code that does what you need.
Thanks you reply, I'll try it.
inline void CvtDepth(edtmem& edtm, span<float> num) {
constexpr int Mip = 0;
auto& UploadBuffDesc = edtm.get<1>().UploadBuffDesc;
const Uint32 Width = UploadBuffDesc.Width >> Mip;
const Uint32 Height = UploadBuffDesc.Height >> Mip;
auto& MappedData = edtm.get<1>().MappedData;
constexpr uint xs = 0x00FFFFFF;
auto pRGBAData = reinterpret_cast<float*>(MappedData.pData);
{
for (Uint32 y = 0, cnt = 0; y < Height; ++y)
{
auto pRGBA = pRGBAData + MappedData.Stride * y;
for (Uint32 x = 0; x < Width; ++x)
{
// depth bits
num[cnt++] = static_cast<float>(pRGBA[x]);
}
}
}
}
inputmanager& ipt = *p_ipt;
auto pdepthtex = rt_.m_pDepthDSV->GetTexture();
auto& m_UploadCompleteFence = _editmem.get<1>().m_UploadCompleteFence;
m_UploadCompleteFence->Wait(_editmem.get<1>().m_UploadCompleteFenceValue);
math::v4f cursorZ, zero4 = {};
inputmanager::updateParam uppara;
auto& worldPos = std::get<0>(uppara);
cursorZ.head<2>() = ipt.mouseinfo.operator pj2::mousestate::f2 & ();
editmemCounters& memedit = _editmem.get<1>();
cursorZ = cursorZ.cwiseMax(zero4);
cursorZ[0] = std::min((UINT32)cursorZ[0], cam.m_ProjAttribs.Width);
cursorZ[1] = std::min((UINT32)cursorZ[1], cam.m_ProjAttribs.Height);
pContext->UnmapTextureSubresource(memedit.pStagingTexture, 0,0);
pContext->MapTextureSubresource(memedit.pStagingTexture, 0, 0,
MAP_READ,
MAP_FLAG_DO_NOT_WAIT | MAP_FLAG_DISCARD | MAP_FLAG_NO_OVERWRITE, nullptr, memedit.MappedData);
auto& UploadBuffDesc = _editmem.get<1>().UploadBuffDesc;
UploadBuffDesc.Width = 1;
UploadBuffDesc.Height = 1;
assert(rt_.DepthBufferFormat != TEX_FORMAT_D24_UNORM_S8_UINT);
std::array<float, 16> depthNorm;
CvtDepth(_editmem, span(depthNorm.data(), 1));
cursorZ[2] = depthNorm[0];
const math::Matrix4f& inverse_projection_matrix = cam.m_ProjMatrix.inverse();
const math::Matrix4f& inverse_View_matrix = cam.m_ViewMatrix.matrix().inverse();
getRays(cursorZ, inverse_projection_matrix, worldPos, cam);
worldPos = inverse_View_matrix * worldPos;
freeUIVec = worldPos;
ipt.update(uppara);
here is update function to read depth before call the CopyTexture Code posted previously
Did you run this in Debug? Do you get any messages in the console?
This is incorrect:
cursorZ[0] = std::min((UINT32)cursorZ[0], cam.m_ProjAttribs.Width);
cursorZ[1] = std::min((UINT32)cursorZ[1], cam.m_ProjAttribs.Height);
It should be
cursorZ[0] = std::min((UINT32)cursorZ[0], cam.m_ProjAttribs.Width - 1);
cursorZ[1] = std::min((UINT32)cursorZ[1], cam.m_ProjAttribs.Height - 1);
I suggest you look at the code I sent and do the same way.
I suggest you look at the code I sent and do the same way.
Appreciate you reply, I'll take a look.
solved by remove UnmapTextureSubresource and MapTextureSubresource call in update function. MapTextureSubresource once at init function would be enough. Maybe I need UnmapTextureSubresource before release, haven't try that
You read the data between MapTextureSubresource
and UnmapTextureSubresource
. In you snippet, you unmap right before mapping again, which does not make a lot of sense.
Once again, take a look at the code that I sent.
version : diligent 2.4 backend : vulkan GPU : rx5700xt OS: windows11 I want use depth to get world position from point of screen on CPU side here.
statge texture code
depth format is TEX_FORMAT_D32_FLOAT copy code is `
` the depth value read out is .06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06533402e+09 1.06533440e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06533478e+09 1.06533395e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06533440e+09 1.06533510e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06533498e+09 1.06533382e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09 1.06535322e+09
"1.06534010e+09" is the default read out after I called ClearDepthStencil funtion
notice that there are variations for depth read out that is due to I'm reading different point of depth texture, though such change of value should be right based my observation. I want know why is depth value not within range of [0,1]?