locked
Why does my App keep getting an out of memory exception error on my Surface RT when drawing a DirectX VirtualSurfaceImageSource?

    Question

  • On my Windows 8 Development PC this works great by the way!

    On my Surface RT not so much.  I have set everything up to draw to a large VirtualSurfaceImageSource (like 5000 x 5000 sized) so that I can display high dpi images on my app when zoomed in through DirectX.  It works with low res VSISs but when I put the size to 5000 x 5000 I get an Out of Memory Error.   It works fine on my PC only does it on the surface.  The app is only using about 50 MB of RAM too. 

    Why is this happening, please Help??!!!

    The exact error that I get is "Not enough storage is available to complete this operation."  during the BeginDraw() method when the updateRect is set too a size larger than 2000 x 2000 roughly.

    Now one interesting point is that if I only update a 2000 x 2000 it works but much larger than that and it gets the error.

    Thanks in Advance!


    SB Software Developer

    Thursday, November 08, 2012 4:56 AM

Answers

  • It sounds like you're running into the limits on texture sizes for the video card. This isn't a Windows RT vs. Windows 8 issue so much as a difference in DirectX feature levels. You will get similar behavior on some Windows 8 systems as well.

    See Developing for different Direct3D feature levels and Direct3D feature levels

    --Rob

    • Marked as answer by Sacha Bwin Wednesday, November 14, 2012 12:20 AM
    Thursday, November 08, 2012 6:08 AM
    Owner
  • I guess you'll have to get advice from a Microsoft expert who understands what VSIS actually does. From what you've written and other posts I've seen, it sounds like VSIS is simply creating a gigantic texture and asking you to fill it in, which will always fail.

    If I were you, I'd toss VSIS and implement my own tile renderer to a regular SIS or SwapChainBackgroundPanel. You have to break up your huge input imagery into texture tiles anyway, so render directly from them. Use power-of-two sized texture tiles (<= 2048 pixels) when possible for best performance.

    I'd also create half and quarter resolution tiled images for when your users are zoomed out. Of course, generating those resampled images will be slow on poor-performing CPUs like ARM. You might want to investigate rendering them to textures with the GPU.

    • Marked as answer by Sacha Bwin Wednesday, November 14, 2012 12:21 AM
    Friday, November 09, 2012 4:47 AM

All replies

  • It sounds like you're running into the limits on texture sizes for the video card. This isn't a Windows RT vs. Windows 8 issue so much as a difference in DirectX feature levels. You will get similar behavior on some Windows 8 systems as well.

    See Developing for different Direct3D feature levels and Direct3D feature levels

    --Rob

    • Marked as answer by Sacha Bwin Wednesday, November 14, 2012 12:20 AM
    Thursday, November 08, 2012 6:08 AM
    Owner
  • Something's wrong here. The whole point of a virtual image source is to eliminate problems like this by breaking up the large image into tiles for you, then call you to update those tiles as needed (e.g. when they become visible). Is VSIS calling you back with an update rect that's 5000x5000? If so, it's pointless and you'd be better off handling the tiling yourself.

    Note, I've never used VSIS so I haven't seen how it behaves in actual usage.

    Thursday, November 08, 2012 9:07 PM
  • Yeah I would think so.  I even wrote my own code to do the tiling at 1000 x 1000 tiles on each call to BeginDraw() and it still did the same thing after a few calls.  I am lost here as I just learned C++ and DirectX a few weeks ago, although I do have 29 years of programming experience.  I have already successfully been using it and it works great on the development PC.  Now I am calling the entire image to be updated in the end as I need the final output to be 300dpi or 600dpi.

    SB Software Developer

    Thursday, November 08, 2012 11:37 PM
  • max texture size is up to graphics card. I remembered that DirectX 9 class is less than 4Kx4K. DirectX 10 class is 4Kx4K, DirectX 11 class is 8Kx8K.  

    Charlie Chang L

    Friday, November 09, 2012 4:08 AM
  • I guess you'll have to get advice from a Microsoft expert who understands what VSIS actually does. From what you've written and other posts I've seen, it sounds like VSIS is simply creating a gigantic texture and asking you to fill it in, which will always fail.

    If I were you, I'd toss VSIS and implement my own tile renderer to a regular SIS or SwapChainBackgroundPanel. You have to break up your huge input imagery into texture tiles anyway, so render directly from them. Use power-of-two sized texture tiles (<= 2048 pixels) when possible for best performance.

    I'd also create half and quarter resolution tiled images for when your users are zoomed out. Of course, generating those resampled images will be slow on poor-performing CPUs like ARM. You might want to investigate rendering them to textures with the GPU.

    • Marked as answer by Sacha Bwin Wednesday, November 14, 2012 12:21 AM
    Friday, November 09, 2012 4:47 AM
  • Thanks!

    SB Software Developer

    Wednesday, November 14, 2012 12:21 AM
  • Thanks!
    So yes it was the texture size limit.  Had no idea as I just learned DirectX (finally) a few weeks ago.  Thought it would be unlimited. I am reengineering the visual output in my app now. 

    Kinda bummed on how my app performed on Surface RT because of the way I originally designed my app, I would have released my app in October if it wasn't for this.  But it will just be better and faster now, Awesome!!!


    SB Software Developer


    • Edited by Sacha Bwin Wednesday, November 14, 2012 12:33 AM
    Wednesday, November 14, 2012 12:27 AM
  • You wouldn't happen to know how to combine multiple SISs to a bitmap, would you? 

    SB Software Developer

    Wednesday, November 14, 2012 12:50 AM
  • You wouldn't happen to know how to combine multiple SISs to a bitmap, would you? 

    SB Software Developer


    No, but I think that you're looking at the problem backwards. You should have one SIS and it should be the size (in pixels) of the rectangle control its attached to. On Surface RT it will be no larger than the screen size, which is something like 1366x768. The exact size depends on whether you have more XAML controls in your UI. When the user zooms in/out and pans around, you determine which parts of your source image are visible and blast the visible source tile textures to the SIS. That's it (assuming I understand what you're trying to accomplish).
    Wednesday, November 14, 2012 4:22 PM