XNA Texture2D.GetData too Slow!!!

I’m trying to convert a game I was developing a while ago from XNA to Monogame. The game used a bitmap as a minimap which was also read to determine which sprites to place in the cells of the main screen. It worked brilliantly in XNA (VS 2010 Exp) and allowed the user to scroll around the minimap really fast with the main screen being updated “instantly”. However as soon as I moved to Monogame it can take up to 4.5 secs for each screen refresh, i.e. unusable.

Color[] retrievedColour = new Color[1];
_mapTexture.GetData(0, new Rectangle(x, y, 1, 1), retrievedColour, 0, 1);
switch (retrievedColour[0].GetHashCode())
{

}

Any suggestions as to what I can do instead?
Cheers

I guess you’re doing a lot of these? I’m not sure why the performance difference is so huge, but in general GetData is a slow operation. If the map is static you’ll be a lot better off calling GetData once for the entire texture, storing a copy in an array and looking up the colors in there.

2 Likes

I remember this one :slight_smile:

This thread.

or this

We need to put this in big letters in the documentation. Don’t call GetData() every frame. Avoid it entirely if possible. GPUs are designed for data to go into them, not back the other way.

Your map data should be stored in memory as a 2D array. Your main screen view and your minimap will then be generated from this 2D array. This way the CPU has quick read/write access to the map data and the GPU is doing what it does best, reading data and displaying it.

1 Like

Of course you all are right about not doing GetData() calls…
But that code should have been slow in XNA as well, shoudn’t it? Why was it fast then?
As far as I remember from using both XNA and MonoGame there is no major difference in the performance of that part of the library…
So @CaptCodor maybe you’ve changed those lines a bit since the XNA-days, or maybe you’re not calling GetData as often as your snippet suggests and we need to see more code…

1 Like

There was another recent discussion about GetData() being many times slower on textures that are not a multiple of 32 in width. Also, one major difference between XNA and MonoGame is that XNA was based on DirectX 9 on PC whereas MonoGame uses DirectX 11. Different requirements, different caveats, different restrictions.

2 Likes

Oh. I remember that. Thank you for the insight.

I did this in my last game for per-pixel collision detection… Very easy, since you can check any pixel coordinate AS an address in the array…

Collision detection becomes a look-up, rather than some complex operation.

But how big can such an array be without issues?

Take a look at this readme.md here https://github.com/UnterrainerInformatik/perPixelCollision for more detailed information.
Especially the paragraph “Warning” :slight_smile:
Maybe there’s some new information in there for you; Although I doubt it…