I am coding an application that uses the camera using Unity and the Hololens. It works ok. Then I changed something (explained later) and I got the following errors after a crash:
d3d11: failed to create staging 2D texture w=896 h=504 d3dfmt=87 [887a0005]
d3d11: failed to lock buffer 1104C69C of size 4194304 [0x8007000E].
DrawBuffers() got a range of indices but no index buffer (Filename: C:\buildslave\unity\build\Runtime/GfxDevice/d3d11/DrawBuffersD3D11.cpp Line: 137)
I have searched for these errors and there are no solutions applicable. I hope I could get some insights on this.
What I was doing and what I changed
Basically the program acquired a frame from the camera in a array of bytes byte[] _latestImage;
Originally this image is applied to a Texture as in
_videoTexture.LoadRawTextureData(_latestImage);
_videoTexture.wrapMode = TextureWrapMode.Clamp;
_videoTexture.Apply();
_videoPanelUIRenderer.sharedMaterial.SetTexture("_MainTex", _videoTexture);
where _videoTexture
is a Texture2D and _videoPanelUIRenderer
is a Renderer.
This works right. Then I processed the array _latestImage to convert it to Grey inside a function ProcessSync
. This also works right with the only problem: Since the array is being processed (into Grey) but also is being updated automatically by the camera, when applying into a texture, it flickers, sometimes grey, and sometimes in color. But other than that, no crash.
So my next step was to Clone that array at the start of the processing function so that I can process this new array and apply it to a texture without the interference of new data coming from the camera.
so I did:
void ProcessSync(byte[] rawimage, Matrix4x4 cTwMatrix, Matrix4x4 pMatrix)
{
int rr, gg, bb;
int p = 0;
int yval;
byte[] image=(byte[])rawimage.Clone();//<--THIS is the only change
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{ //...some processing here
}
//Then apply it to the texture like indicated above
}
When I apply this, the application works fine, and I can see that I am getting the grey image...but after some time it crashes with the message above.
My image is 896x504 so I guess
d3d11: failed to create staging 2D texture w=896 h=504 d3dfmt=87 [887a0005]
means that somehow the Texture2D failed to be created but why? My texture is only created once when the video mode is being initialized so I don't understand why this happens.
I guess the error could be related with me cloning the image. Can anyone help me here?
As @Equalsk mentioned in comment, there might be chances that the original array is being reused (considering that Array is a reference type). One thing you can do is to create a copy of array before passing in the ProcessSync()
leaving no chance of the original pointer being used in the method.
One more thing I would suggest : Method should have single responsibility (return the processed array). The resulting byte[]
should be then applied to texture.
byte[] ProcessSync(byte[] image, Matrix4x4 cTwMatrix, Matrix4x4 pMatrix)
{
int rr, gg, bb;
int p = 0;
int yval;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++)
{ //...some processing here
}
return image;
}
Then use it as following:
var image = ProcessSync(_latestImage.ToArray(),_cTwCatrix, _pMatrix);
_videoTexture.LoadRawTextureData(image);
_videoTexture.wrapMode = TextureWrapMode.Clamp;
_videoTexture.Apply();
_videoPanelUIRenderer.sharedMaterial.SetTexture("_MainTex", _videoTexture);
NOTE: ToArray()
is extension from System.Linq
which creates a copy. You can use other ways to copy the array if you prefer.
Hope this helps :)
User contributions licensed under CC BY-SA 3.0