Corrects a problem with the D3D11 texture lock/unlock mechanism

This commit is contained in:
rextimmy 2018-04-21 18:19:17 +10:00
parent bc1b506205
commit 96c71a4d5d
2 changed files with 55 additions and 57 deletions

View file

@ -65,59 +65,56 @@ GFXLockedRect *GFXD3D11TextureObject::lock(U32 mipLevel /*= 0*/, RectI *inRect /
{ {
AssertFatal( !mLocked, "GFXD3D11TextureObject::lock - The texture is already locked!" ); AssertFatal( !mLocked, "GFXD3D11TextureObject::lock - The texture is already locked!" );
D3D11_MAPPED_SUBRESOURCE mapInfo; if( !mStagingTex ||
mStagingTex->getWidth() != getWidth() ||
if( mProfile->isRenderTarget() ) mStagingTex->getHeight() != getHeight() )
{ {
//AssertFatal( 0, "GFXD3D11TextureObject::lock - Need to handle mapping render targets" ); mStagingTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemTextureProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
if( !mLockTex || }
mLockTex->getWidth() != getWidth() ||
mLockTex->getHeight() != getHeight() )
{
mLockTex.set( getWidth(), getHeight(), mFormat, &GFXSystemMemTextureProfile, avar("%s() - mLockTex (line %d)", __FUNCTION__, __LINE__) );
}
PROFILE_START(GFXD3D11TextureObject_lockRT); ID3D11DeviceContext* pContext = D3D11DEVICECONTEXT;
D3D11_MAPPED_SUBRESOURCE mapInfo;
U32 offset = 0;
mLockedSubresource = D3D11CalcSubresource(mipLevel, 0, getMipLevels());
GFXD3D11TextureObject* pD3DStagingTex = (GFXD3D11TextureObject*)&(*mStagingTex);
GFXD3D11Device* dev = D3D11; //map staging texture
HRESULT hr = pContext->Map(pD3DStagingTex->get2DTex(), mLockedSubresource, D3D11_MAP_READ, 0, &mapInfo);
GFXD3D11TextureObject* to = (GFXD3D11TextureObject*) &(*mLockTex); if (FAILED(hr))
dev->getDeviceContext()->CopyResource(to->get2DTex(), mD3DTexture); AssertFatal(false, "GFXD3D11TextureObject:lock - failed to map render target resource!");
mLockedSubresource = D3D11CalcSubresource(0, 0, 1); const U32 width = mTextureSize.x >> mipLevel;
HRESULT hr = dev->getDeviceContext()->Map(to->get2DTex(), mLockedSubresource, D3D11_MAP_READ, 0, &mapInfo); const U32 height = mTextureSize.y >> mipLevel;
if (FAILED(hr))
AssertFatal(false, "GFXD3D11TextureObject:lock- failed to map render target resource!");
mLocked = true; //calculate locked box region and offset
if (inRect)
{
if ((inRect->point.x + inRect->extent.x > width) || (inRect->point.y + inRect->extent.y > height))
AssertFatal(false, "GFXD3D11TextureObject::lock - Rectangle too big!");
mLockBox.top = inRect->point.y;
mLockBox.left = inRect->point.x;
mLockBox.bottom = inRect->point.y + inRect->extent.y;
mLockBox.right = inRect->point.x + inRect->extent.x;
mLockBox.back = 1;
mLockBox.front = 0;
PROFILE_END(); //calculate offset
offset = inRect->point.x * getFormatByteSize() + inRect->point.y * mapInfo.RowPitch;
} }
else else
{ {
RECT r; mLockBox.top = 0;
mLockBox.left = 0;
if(inRect) mLockBox.bottom = height;
{ mLockBox.right = width;
r.top = inRect->point.y; mLockBox.back = 1;
r.left = inRect->point.x; mLockBox.front = 0;
r.bottom = inRect->point.y + inRect->extent.y;
r.right = inRect->point.x + inRect->extent.x;
}
mLockedSubresource = D3D11CalcSubresource(mipLevel, 0, getMipLevels());
HRESULT hr = D3D11DEVICECONTEXT->Map(mD3DTexture, mLockedSubresource, D3D11_MAP_WRITE_DISCARD, 0, &mapInfo);
if ( FAILED(hr) )
AssertFatal(false, "GFXD3D11TextureObject::lock - Failed to map subresource.");
mLocked = true;
} }
mLockRect.pBits = static_cast<U8*>(mapInfo.pData); mLocked = true;
mLockRect.pBits = static_cast<U8*>(mapInfo.pData) + offset;
mLockRect.Pitch = mapInfo.RowPitch; mLockRect.Pitch = mapInfo.RowPitch;
return (GFXLockedRect*)&mLockRect; return (GFXLockedRect*)&mLockRect;
@ -127,22 +124,22 @@ void GFXD3D11TextureObject::unlock(U32 mipLevel)
{ {
AssertFatal( mLocked, "GFXD3D11TextureObject::unlock - Attempting to unlock a surface that has not been locked" ); AssertFatal( mLocked, "GFXD3D11TextureObject::unlock - Attempting to unlock a surface that has not been locked" );
if( mProfile->isRenderTarget() ) //profile in the unlock function because all the heavy lifting is done here
{ PROFILE_START(GFXD3D11TextureObject_lockRT);
//AssertFatal( 0, "GFXD3D11TextureObject::unlock - Need to handle mapping render targets" );
GFXD3D11TextureObject* to = (GFXD3D11TextureObject*)&(*mLockTex); ID3D11DeviceContext* pContext = D3D11DEVICECONTEXT;
GFXD3D11TextureObject* pD3DStagingTex = (GFXD3D11TextureObject*)&(*mStagingTex);
D3D11->getDeviceContext()->Unmap(to->get2DTex(), mLockedSubresource); ID3D11Texture2D *pStagingTex = pD3DStagingTex->get2DTex();
mLockedSubresource = 0; //unmap staging texture
mLocked = false; pContext->Unmap(pStagingTex, mLockedSubresource);
} //copy lock box region from the staging texture to our regular texture
else pContext->CopySubresourceRegion(mD3DTexture, mLockedSubresource, mLockBox.left, mLockBox.top, 0, pStagingTex, mLockedSubresource, &mLockBox);
{
D3D11DEVICECONTEXT->Unmap(get2DTex(), mLockedSubresource); PROFILE_END();
mLockedSubresource = 0;
mLocked = false; mLockedSubresource = 0;
} mLocked = false;
} }
void GFXD3D11TextureObject::release() void GFXD3D11TextureObject::release()

View file

@ -31,8 +31,9 @@ class GFXD3D11TextureObject : public GFXTextureObject
{ {
protected: protected:
static U32 mTexCount; static U32 mTexCount;
GFXTexHandle mLockTex; GFXTexHandle mStagingTex;
DXGI_MAPPED_RECT mLockRect; DXGI_MAPPED_RECT mLockRect;
D3D11_BOX mLockBox;
bool mLocked; bool mLocked;
U32 mLockedSubresource; U32 mLockedSubresource;