App Hub
Sort Discussions: Previous Discussion Next Discussion
Page 1 of 1 (10 posts)

Texture2D.GetData Performance

Last post 7/23/2008 4:55 PM by BShields. 9 replies.
  • 5/6/2007 1:22 PM

    Texture2D.GetData Performance

    Hello (again),

    I've been trying to use the GetData method on Texture2D to get some results from both the BackBuffer / a RenderTarget but with limited success. The example on the MSDN shows how to return the single pixel from the texture back to an array for the benefit of determining what colour the pixel was, but even this seems to be running incredibly slowly.

    I've timed the GetData to call it about 50ms, which is an eternity to do 1 pixel, the funny thing is that 1280x720 pixels also takes the same amount of time.

    I've zipped up the code/project I'm using, it outputs the time taken to execute the GetData call every time it happens, and on my 6800GT (PCI-Express) it takes 50ms on average, ideally it should take barely any time at all, especially for one pixel.

    This is a texture that has just been written to by the pixel shaders, resolving it takes no time at all. PIX shows:

    968 <0x05F19388> IDirect3DTexture9::GetSurfaceLevel(0, 0x0016EDA8 --> 0x05EA3ED8) 4391765713   
    969 <0x05EA3ED8> IDirect3DSurface9::GetDesc(0x0016ED78) 5616729500

    Basically a massive time taken between call 968 and 969, 1.2 billion (ticks?).

    Anyone with any ideas?

    ajmiles

    PS I'll have to upload the zip file later, the university is having some connectivity issues so hosting the file may happen in an hour or two.

  • 5/6/2007 2:21 PM In reply to

    Re: Texture2D.GetData Performance

    The delay you have is the time it takes your computer to copy the texture info from the GPU's ram to your CPU's ram.  This is aso why 1 pixel of thousands of pixels are about the same amount of time. 
  • 5/6/2007 3:21 PM In reply to

    Re: Texture2D.GetData Performance

    There must be ways of getting results back from the GPU in a hurry? If the latency involved in getting so much as a single pixel back is 50ms how on earth do people like Havok do lots of fancy physics computation on the GPU?

    ajmiles

  • 5/6/2007 3:36 PM In reply to

    Re: Texture2D.GetData Performance

    The delay is not reading back the pixel: it is waiting for the pixel data to be available.

    The GPU and CPU run asynchronously. When you say "I already drew this pixel", that's not really true. All that happened is the CPU wrote a command into a buffer telling the GPU to draw this pixel at some later time, whenever it gets around to it.

    When you try to read that pixel back onto the CPU, a lot of work must happen:
    • The CPU must flush the command buffer
    • The CPU must stall until the GPU is done processing all the outstanding work
    • Then the GPU must stall the entire (usually very deep) rendering pipeline to make sure this work is complete
    • It must signal the CPU, which wakes up and reads back the data
    Forcing a synchronisation between the two processors, by reading back data from the GPU to the CPU, is a terrible thing for performance. Pretty much the worst thing you can do, in fact! Most games are architected to avoid the need to ever do such things.

    What specifically are you trying to achieve here?
  • 5/6/2007 3:41 PM In reply to

    Re: Texture2D.GetData Performance

    I really just want to be able to set things up so I can do any manner of general computation on the GPU inbetween drawing frames for the user, so in keeping a steady 60fps, be able to use the GPU for other things. Currently though getting the results back from the GPU is proving next to impossible without impacting heavily on the frame rate of the actual 'game' itself.

    It doesn't really matter what the computation in the pixel shader is right now, just finding a sane way of getting the results back to main memory.

    ajmiles

  • 5/6/2007 4:01 PM In reply to

    Re: Texture2D.GetData Performance

    That's the problem: there isn't really any sane way of doing this. At best, you can read back data a frame late. That is less likely to stall since the GPU will already be done rendering by the time the CPU wants the information, but is also less useful since the data isn't available when you really wanted it!

    The GPU normally runs about a frame behind the CPU, so if you think about it, it's fundamentally impossible to read back data without causing a stall time of roughly one frame.
  • 5/7/2007 11:55 PM In reply to

    Re: Texture2D.GetData Performance

    Is my scenario worth to call Texture2D.GetData?

    The screen shows a background and a board, I want to make part of the board shows the background as well, and adds postprocess effect on that area, so I render the background on a RenderTarget, get the render result as texture from it , and set the texture to the board while render the board.
  • 5/8/2007 12:07 PM In reply to

    Re: Texture2D.GetData Performance

    That sounds like you are just drawing onto a rendertarget, resolving it, and then using the resulting texture in some subsequent rendering, right?

    That is exactly how rendertargets are designed to be used, and does not require any readback of data from GPU to CPU. There should be no need to call GetData here.
  • 7/23/2008 5:05 AM In reply to

    Re: Texture2D.GetData Performance

    Is the texture that's returned from the RenderTarget a reference or a value? 

    I'm drawing to the same render target multiple times.  After each draw, I'm doing a "GetTexture" and then clearing the graphics device.  However, it looks like the last pull from the render target is what is being kept in all my Texture2D variables that I did a "GetTexture" with earlier.

    I might be doing something else wrong, but I think it's pretty straight forward.

    Thanks

  • 7/23/2008 4:55 PM In reply to

    Re: Texture2D.GetData Performance

    If you have to use GetData, use it as infrequently as you can ;)

    I've got an RTS where the fog of war was implemented rather horribly... but it was too much trouble to remake it. When I needed to prevent the player from creating things in the unexplored regions of the map, my solution was to either replace the FoW, or use GetData on one of the textures being used by the FoW. Using GetData only when the player tries to make something out of sight of their other units and buildings means it gets called very infrequently, and only once, when it is called at all. No noticeable lag from using it in my game :)


Page 1 of 1 (10 posts) Previous Discussion Next Discussion