XNA Creators Club Online
Page 1 of 1 (5 items)
Sort Posts: Previous Next

Texture2D.GetData() on the 360

Last post 6/26/2009 6:09 PM by jwatte. 4 replies.
  • 6/26/2009 4:06 AM

    Texture2D.GetData() on the 360

    Hi, I expect this gets asked now and then but a quick search didn't bring up any recent answers that spelt it out.

    Does the 360 support this method (specifically using the rect version for grabbing a pixel of texture data)?  Ok, it runs and grabs the data accurately but it would seem that it can't do it in a timely manner.  I first expected the 360 to have the advantage with the unified memory so was quite surprised when 6 calls of

    temp_Rect = new Rectangle((int)Position.X, (int)Position.Y, 1, 1); 
    windRedGreen.GetData<Color>(0, temp_Rect, temp_Col, 0, 1); 

    each Update() cause very noticeable framerate issues.  I then quickly got to the point where I could no longer get a Draw() out of the box when this was increased to around 20 calls (roughly).  Of course this was a bit of a shocker as a low end PC I develop on was happily running several hundred between Draw()s without showing any sign of slowdown from that part of the code (unlike the shaders, which are causing some framerate issues).

    I was planning on using this texture lookup to grab displacement data rather than calculating it from the base information (which takes a bit of maths to do but obviously on the 360 turns out to be many orders of magnitude faster) and was just wondering if this is a 'not really implemented in a workable state' Method on the 360 version of XNA but still probably a fine plan on the average PC or if something weird is going on.  I've seen some examples of collision code using Texture2D.GetData() for transparency checks in 2D games but from what I'm seeing that wouldn't be a practical solution on the 360 for anything but a very sparse game.
  • 6/26/2009 8:49 AM In reply to

    Re: Texture2D.GetData() on the 360

    I don't know if this will help at all with your situation. In my current project, I'm using per-pixel detection on a tiled map that is drawn from tile sheets. What I've done is to use one GetData() call when the tilesheet image is first loaded and kept the colour data in memory. When I check for a collision at a certain Vector2, I first get the tile number from map[x,y], then check the colour data for the corresponding tile using the pre-initialised colordata array, rather than doing a new GetData each time.

    Gareth Williams - MCTS .Net 2 Web Applications - Team Mango - My Blog - Gravsheep - Dysnomia (In Peer Review)
  • 6/26/2009 12:32 PM In reply to

    Re: Texture2D.GetData() on the 360

    Yep, that's my current implementation, using a bit of extra memory to duplicate the same data but in array format rather than a texture.  I just find it a bit weird that I can grab Color data from a texture 10k times per frame on a lower end PC (ATi 2400 graphics card) without issue but the 360 hits a brick wall before getting or even a hundredth of that value.

    Testing the use of this Vector2 array alternative has shown a faster way on the PC too so I guess the 360 has shown me the error of my ways and pushed my particle limit higher (even if I haven't got a use for them yet).
  • 6/26/2009 5:16 PM In reply to

    Re: Texture2D.GetData() on the 360

    Reading data back from GPU resources such as textures is slow on most platforms. You'll find this takes a long time on many PC cards, too. Not a good thing to be doing every frame. It's better to store a separate copy of any data your CPU needs to access, which can be in a form that is optimized for CPU usage.

    There are many reasons why CPU readbacks of GPU resources are slow:

    • Data may be in an entirely different memory subsystem, so needs to travel over a slow bus
    • Data may be in a different address space (kernel vs. user on Xbox) so needs to be copied across the supervisor boundary
    • GPU data is typically stored in non-cached memory pages, which are very slow for the CPU to access
    • GPU textures are stored in swizzled format for cache friendly rendering, and need to be unswizzled for CPU use

    So, GetData and SetData are quite complex operations.
    XNA Framework Developer - blog - homepage
  • 6/26/2009 6:09 PM In reply to

    Re: Texture2D.GetData() on the 360

    You'll find this takes a long time on many PC cards, too

    Not when using MANAGED textures. Which I believe XNA does on PC. MANAGED texture Lock() for READONLY shouldn't even need a memcpy(), although I believe that it actually does one in many cases (for de-swizzling perhaps?).

    However, there should be no reason to call GetData() more than once per texture. Call it when you load the texture, and stash the resulting data in the Tag (or some other convenient location). Then when you need to look at the pixels, simply look at the data you've already gotten.
    Jon Watte, Direct3D MVP
    Tweets, occasionally
    kW X-port 3ds Max .X exporter
    kW Animation source code
Page 1 of 1 (5 items) Previous Next