Sign in to follow this  
_Tank_

[mdx] What is the right way to lock a texture (FatalExceptionEngineError)

Recommended Posts

Hi all. I have a problem with locking a texture. texture is created with valid device, Usage.Dynamic and Pool.Default The aim: I need to draw some 2-D dynamic data on screen. (Question #0: What is the right way to do that at all) The way i wanted to do that: Data.CopyToTexture(texture) ... sprite.Draw2d(texture...) (Question #0.5: Should i allways create new texture for new drawing cycle) The problem: The main problem is in Data.CopyToTexture(texture) after locking the texture, receiving a pointer, writing few hundred bytes of data to texture, i receive quite suspicious exception The symptoms: FatalExceptionEngineError: The runtime has encountered a fatal error. The address of the error was at 0x7a00d227, on thread 0xa04. The error code is 0xc0000005. This error may be a bug in the CLR or in the unsafe or non-verifiable portions of user code. Common sources of this bug include user marshaling errors for COM-interop or PInvoke, which may corrupt the stack. The code:

texture = new Texture(device, screenSize, screenSize, textureRequirements.NumberMipLevels, Usage.Dynamic, textureRequirements.Format, Pool.Default);

int pitch;

fixed (int* tPtr = &(texture.LockRectangle(IntType, 0, 0, out pitch, 1) as int[])[0])
{
    fixed (Pixel* pixelsPtr = &pixels[0, 0])
    {
        pitch /= 4;

        int index = 0;

        for (int i = 0; i < screenSize; i++)
        {
            int tPtrIndex = i * pitch;

            for (int j = 0; j < screenSize; j++)
            {
                Pixel p = pixelsPtr[index];

                if (p.TotalComponents > 0)
                {
                    tPtr[tPtrIndex] = (p.OveralEnergy / p.TotalComponents) << 8;
                }
                else
                {
                    tPtr[tPtrIndex] = transperentARGB;
                }

                tPtrIndex++;
                index++;
            }
        }
    }
}

texture.UnlockRectangle(0);

Share this post


Link to post
Share on other sites
Quote:
(Question #0: What is the right way to do that at all)


Drawing textures onto a sprite like you're doing now is the most common approach afaik, so you're good to go there.

Quote:
(Question #0.5: Should i allways create new texture for new drawing cycle)


Never! [smile] Creating a new texture every drawing cycle eats up video memory very quickly (or causes unnecessary overhead for creation/disposing). There's typically no need to create a new texture, since you can just update and reuse an existing one. For this, you'll need to create the texture during device resets and dispose of it when the device is lost. Once you got this out of the way, you can just use the texture whenever you want.

Quote:
The problem:
The main problem is in Data.CopyToTexture(texture) after locking the texture, receiving a pointer...


Well, I've never worked with unsafe texture access before, since I basically never needed it. You can just use the array returned from the LockRectangle method directly, like this:

[source lang=csharp]
int[,] data = (int[,])frameTexture.LockRectangle( typeof(int), 0, LockFlags.None, width, height );

for (int v = 0; v < height; v++)
{
for (int u = 0; u < width; u++)
{
// copy image pixel onto texture
data[v,u] = unchecked((int)0xffff0000); // for A8R8G8B8
}
}

// unlock texture
frameTexture.UnlockRectangle(0);



The performance of this approach is usually more than sufficient, so I don't know if you have a specific reason for filling the texture using pointers. If you really want to use the pointers, I'm afraid I can't help you any further because they were the main reason I switched to C# in the first place [wink]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this