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:
Item | CPU | GPU |
---|---|---|
Shader Program | ByteArray (from AGALMiniAssembler ) |
GPU-specific machine code |
Vertex Buffer | Vector.<Number> |
Array of floating point numbers |
Index Buffer | Vector.<uint> |
Array of unsigned integers |
Uncompressed Texture | BitmapData |
2D array of ARGB-format integers |
Compressed Texture | ByteArray (loaded from an ATF file) |
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!
#1 by henke37 on December 10th, 2012 ·
Spoilers: The Flash player will also crash if it runs out of memory. It is just darned hard to do so.
#2 by RTLShadow on December 12th, 2012 ·
I’ve never really understood how the GPU works (moreso didn’t look into it) and this article has really cleared it up for me. Well written and perfect for someone who hasn’t fully understood the subject yet. Good job!
#3 by Moose on May 27th, 2014 ·
Back in the day with the old consoles such as the Sega Mega Drive , if it only had 64KB of VRAM how did it render a frame at full resolution of 320×240?
#4 by jackson on May 27th, 2014 ·
I’m not familiar with Sega Mega Drive programming, but if a whole frame can’t fit in VRAM then there must be an alternate system. For example, system RAM could be fetched and used. Or a tile system. Or part of the frame could be rendered while VRAM is re-filled to render the latter parts of the frame. For example, perhaps you fill one horizontal line, render it, fill the next horizontal line, render it, etc.
#5 by Mridul Gupta on July 9th, 2015 ·
You said that the data needs to be copied from RAM to VRAM so that the GPU could draw 3D objects, my question is what’s the need of it?
Why the data can’t be directly taken from system RAM than VRAM?
#6 by jackson on July 9th, 2015 ·
It’s mainly an optimization. The GPU can normally access VRAM way faster than system RAM because the VRAM is right there on the graphics card and the system RAM is all the way across a system bus (e.g. PCI-E).
#7 by Frank La Fauci on March 22nd, 2016 ·
This articles cleared up a few of my questions, thank you. My first query referred mostly VRAM on gaming computers. I have seen graphic cards with 2, 4 and 8 GB. How much RAM and VRAM do gaming computers need?
#8 by jackson on March 22nd, 2016 ·
It really depends on what kind of games you want to play. The latest games, especially those in VR, need a graphics card like an Nvidia GeForce GTX 970 with 4 GB of VRAM. Older games like World of Warcraft are fine with less than 1 GB.
#9 by shuopei on September 13th, 2017 ·
As a newbie of as3, I am confused about where texture memory locates. When upload texture to VRAM, it seems the RAM of flash process increases, according to the data from Windows Taskmgr. As I understand it, the growth should be on VRAM rather than RAM.
Following is the sample code:
var texture:Texture = context3D.createTexture(256, 256, Context3DTextureFormat.COMPRESSED_ALPHA, false);
var textureAsset:ByteArray = new TextureAsset() as ByteArray;
texture.uploadCompressedTextureFromByteArray(textureAsset, 0); // after this statement, the ram will grow up
#10 by jackson on September 13th, 2017 ·
Flash may keep a copy of the texture in system memory to handle “context loss”, which can happen on Windows. In that case it may use the texture in RAM to restore the texture in VRAM.
#11 by shuopei on September 13th, 2017 ·
Is there any way to get rid of the copy? Since the texture occupy too much RAM in our application.
#12 by jackson on September 13th, 2017 ·
I don’t know of a way, or even if the copy actually exists. It’s more of a theory given the data you’re seeing in Task Manager.
#13 by shuopei on September 13th, 2017 ·
Thanks for the tips. The article is helpful for me!