2
\$\begingroup\$

I figured that the best way to ship 2D art for multiple resolutions is to instruct my artist to create the fullscreen background images sized for the highest resolution and then scale them down during the loading stage.

To scale them, during load, I setup a render target sized to the current resolution, SpriteBatch.Draw the assets scaled to the current resolution and then use that render target throughout the game. The render target serves as a SpriteSheet throughout the game. I only do this once (in LoadContent) and not every frame.

My question is whether or not there is a memory/performance penalty for using render targets instead of whatever the ContentManager would've set the textures as. Is there a meaningful way to measure this? Or is there a better way of doing this altogether?

\$\endgroup\$
  • \$\begingroup\$ Since you only do this once i would not worry about it, premature optimization is a bad habit anyway. However if you are drawing the fullscreen background image every frame i would suggest creating a couple of sizes and pick the best one. \$\endgroup\$ – Madmenyo Mar 3 '14 at 16:15
  • \$\begingroup\$ You "figured" it was the best way, but what exactly is wrong with just rendering normally? (i.e. not using a render target). If you truly have a performance issue, your question should be more about that, but I suspect you haven't really got a good reason for doing this. \$\endgroup\$ – craftworkgames Mar 4 '14 at 3:51
  • \$\begingroup\$ @craftworkgames I might be wrong here, but consider this scenario: I have 1920x1080 background, that I need to render on a 1280x720 resolution. I load the 1920x1080 image and then instruct to SpriteBatch to draw it with 1280x720 bounds every single frame. What happens in the background? How much memory/VRAM is the larger-than-screen-resolution image consuming? How many CPU/GPU cycles are wasted to scale the image down each frame? \$\endgroup\$ – RecursiveCall Mar 4 '14 at 15:20
  • \$\begingroup\$ @RecursiveCall You're probably not wrong but until you can actually see / measure the problem you have no real way of knowing it needs fixing. You could in fact create a new problem, or make the existing problem worse and not know it. You might also waste time creating code that may only save you a tiny amount of memory / cycles and in the end not actually make your game any better. Wouldn't you rather spend that time doing something else? I'm not saying don't do it, but you should at least measure it first. Also, read this en.wikipedia.org/wiki/Program_optimization#When_to_optimize \$\endgroup\$ – craftworkgames Mar 5 '14 at 0:59
  • \$\begingroup\$ @craftworkgames Hence my second question in the OP. :) \$\endgroup\$ – RecursiveCall Mar 5 '14 at 3:46
1
\$\begingroup\$

There won't be an appreciable memory pressure differential using a render target texture to hold your resized images versus what the content manager would have loaded them as: it would just load them as textures, which is basically the same data.

Your alternative approach (load them at native resolution and allow the GPU to scale them down during rendering) will also work. It will consume more memory, of course, since you have larger-resolution textures loaded. It will take some non-appreciable amount of time for the GPU to downsample the textures on render, but it won't be a concern. The bigger issue is the extra memory the full-resolution images would consume.

I'd stick with your initial approach until profiling deems it necessary to adjust it.

\$\endgroup\$
  • 1
    \$\begingroup\$ My only issue with this is that all render target data is lost if the device is reset. I however, do not know enough about what sort of events cause a reset to know if that would be an issue. Since its only on load he can copy the data into a regular Texture2D which could be cached preventing the need for the scaling on susequent loads. stackoverflow.com/questions/17603919/… \$\endgroup\$ – ClassicThunder May 14 '14 at 15:27
  • \$\begingroup\$ Yea, I forgot about the device reset scenario; copying to more persistent storage is a good idea. \$\endgroup\$ – user1430 May 14 '14 at 15:36
  • 1
    \$\begingroup\$ Don't forget that rendertargets are generally uncompressed ARGB textures, 32+ bpp depending on the format. If you were using an 8bpc texture anyway, then this isn't a net gain in texture size. But if you were using a S3TC/DDS-style compressed texture then you might be able to make more efficient use of texture memory and bandwidth, if either is a limiting factor in your application. \$\endgroup\$ – DMGregory May 14 '14 at 16:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.