When loading large scenes, we were having rare random crashes with DX11 (no crashes on Metal iOS). Recently we made a debug scene with deterministic texture loading sequence to reproduce the crash so I'm able to take a look. The final cause is: after getStreaming() returns a mapped region of a staging texture, when copying source image to that mapped region, we got write access violation.
The mapped region is a 1x1 TextureBox (it's the lowest mip of an 512x512 texture) at the edge of the staging texture (the whole staging texture is 512x512 and the mapped region is x=y=511, width=height=1) which does not look good.
I simply enforced all free boxes to be at least 2x2, then there was no crash any more! I'm not sure about the REAL cause of the crash, but anyway the following patch fixes my problem (note that the line numbers don't match because I've added some logging codes elsewhere)
Code: Select all
.../Direct3D11/src/OgreD3D11StagingTexture.cpp | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/RenderSystems/Direct3D11/src/OgreD3D11StagingTexture.cpp b/RenderSystems/Direct3D11/src/OgreD3D11StagingTexture.cpp
index 1edf14d..038ed0b 100644
--- a/RenderSystems/Direct3D11/src/OgreD3D11StagingTexture.cpp
+++ b/RenderSystems/Direct3D11/src/OgreD3D11StagingTexture.cpp
@@ -273,9 +273,15 @@ namespace Ogre
newRecord[2].y += newRecord[2].height;
const size_t idx = record - mFreeBoxes[slice].begin();
- mFreeBoxes[slice].push_back( newRecord[0] );
- mFreeBoxes[slice].push_back( newRecord[1] );
- mFreeBoxes[slice].push_back( newRecord[2] );
+ if (newRecord[0].width > 1 && newRecord[0].height > 1) {
+ mFreeBoxes[slice].push_back(newRecord[0]);
+ }
+ if (newRecord[1].width > 1 && newRecord[1].height > 1) {
+ mFreeBoxes[slice].push_back(newRecord[1]);
+ }
+ if (newRecord[2].width > 1 && newRecord[2].height > 1) {
+ mFreeBoxes[slice].push_back(newRecord[2]);
+ }
record = mFreeBoxes[slice].begin() + idx;
}
@@ -312,7 +318,7 @@ namespace Ogre
StagingBox newRecord = originalRecord;
newRecord.x = consumedBox.x + consumedBox.width;
newRecord.width = originalRecord.width - consumedBox.width;
- if( newRecord.width > 0 )
+ if( newRecord.width > 1 && newRecord.height > 1 )
mFreeBoxes[slice].push_back( newRecord );
}
//-----------------------------------------------------------------------------------
@@ -360,7 +366,7 @@ namespace Ogre
newRecord.width = consumedBox.x;
newRecord.y = consumedBox.y;
newRecord.height = consumedBox.height;
- if( newRecord.width > 0 )
+ if( newRecord.width > 1 && newRecord.height > 1 )
mFreeBoxes[slice].push_back( newRecord );
// New slice #2
@@ -369,14 +375,14 @@ namespace Ogre
newRecord.width = originalRecord.width - newRecord.x;
newRecord.y = consumedBox.y;
newRecord.height = consumedBox.height;
- if( newRecord.width > 0 )
+ if( newRecord.width > 1 && newRecord.height > 1 )
mFreeBoxes[slice].push_back( newRecord );
// New slice #3
newRecord = originalRecord;
newRecord.y = consumedBox.y + consumedBox.height;
newRecord.height = originalRecord.height - newRecord.y;
- if( newRecord.height > 0 )
+ if( newRecord.width > 1 && newRecord.height > 1 )
mFreeBoxes[slice].push_back( newRecord );
}
//-----------------------------------------------------------------------------------