System RAM and VRAM Explained
I’ve mentioned the concept of VRAM (video memory) in a few articles, but I still find constant confusion among readers of this site as well as coworkers and colleagues in day-to-day work with
Stage3D. Today’s article will hopefully clear up the differences, dispel some myths, and help you make the best use of both of them.
First, let’s start at the hardware level. Virtually every computer has dedicated hardware to draw graphics and it is usually called a video card, graphics card, or GPU. I’ll just call it the GPU. Every computer also has a main processor for general purpose computing (including AS3) that is known as the CPU.
Stage3D may not be able to make use of the computer’s GPU. In that case the CPU will pull double-duty and draw all of the graphics.
Both the CPU and GPU have their own pool of temporary memory: RAM. These pools of RAM may in fact be the same, but that is a hardware detail that your
Stage3D app will probably be unaware of. These two logical pools of RAM are called “system RAM” (or just “RAM”) for the CPU and “VRAM” for the GPU. The v is for video. Of these two, VRAM is much simpler than system RAM because it only holds four kinds of data:
- Shader Programs: Little programs that run on the video card to calculate vertex positions and pixel colors. You probably won’t have many of these and they are very small (bytes to KB)
- Vertex Buffers: Arrays of floating point data that vertex shaders use as input. This scales in size with the complexity of your 3D scene and will probably be medium size (KB to MB)
- Index Buffers: Arrays of unsigned integers that specify how vertex buffers are linked together to form the triangles that make up the 3D scene. This also scales with the complexity of your 3D scene and will probably be small (KB)
- Textures: Bitmap image data that fragment shaders use as input. This will often be very large (many MB)
VRAM is simple, but it is often quite small. It’s not uncommon to find that VRAM is only 50 MB (a decent budget for iPad 1) but a high-end gaming PC may have 1 GB or even more.
In contrast, system RAM is usually quite a bit larger than VRAM. Even low-end smartphones have 512 MB these days and high-end ones have at least 1-2 GB. Desktop and laptop PCs have had at least 1 GB for many years and you can now find them with 8-32 GB. This is good because system RAM is expected to hold everything else: all of your AS3 code and objects.
The only thing system RAM can’t do is serve as the pool of memory that the GPU uses while it renders your 3D scene. For that, you must “upload” (i.e. copy) data from system RAM to VRAM. This means that your graphics data will temporarily be in both places: system RAM and VRAM. However, once the upload is done you may choose to get rid of the copy in system RAM.
Once you start writing shader code (probably in AGAL) you will find that your programming environment is very limited. It probably won’t come as much of a surprise to you then that the data you upload to the GPU must also be in a very limited format. The following table shows you the conversion:
||GPU-specific machine code|
||Array of floating point numbers|
||Array of unsigned integers|
||2D array of ARGB-format integers|
||Algorithm-specific array of compressed texture data (e.g. PVRTC)|
Textures are the most complex of these because of the possibility of compression. When you don’t use compression the data is just a big block of ARGB pixels on both sides. When you do use compression, you’re introducing ATF into the picture.
To simplify the introduction article, ATF is a format that can contain more than one copy of your texture, each copy compressed with a different algorithm for use on specific GPUs. This means that one ATF can work on many different types of GPUs, but muddies the water when we’re talking about what is in RAM and what is in VRAM.
When you tell Flash to upload your ATF to VRAM it will choose the copy of your texture that was compressed with the appropriate algorithm and upload only that copy of the texture. This means that in RAM you may have an ATF-formatted
ByteArray with DXT1, ETC1, and PVRTC textures but when you upload it to an iPad 2 the GPU will only be sent the PVRTC texture.
Further, it’s very important to remember that these compressed textures are not uncompressed by the GPU when it receives them. In fact, it never fully uncompresses them. As the GPU renders your 3D scene it will, on-the-fly, selectively decompress only the parts of the texture that contain the pixels your fragment shader wants to read from. So your compressed texture stays compressed and your VRAM usage stays low.
One final note on the subject of garbage collection. In AS3 you never need to explicitly release memory that you’re not using anymore. All you have to do is make sure you don’t have any references to an object and Flash will free up the memory that object was using. On the GPU side this is not the case. You must create and dispose of your GPU resources: shader programs, vertex buffers, index buffers, and textures. The
Stage3D API makes this as easy as it can but you still have to remember to do it. If you don’t ever dispose of your GPU resources and just keep creating more, you’ll use more and more VRAM until you run out and bad things happen. The operating system may decide to immediately terminate your app (e.g. iOS) or perhaps everything will just start running really slowly (e.g. Windows).
Any more questions about RAM or VRAM? Post a comment and I’ll do my best to answer!