Vertex buffers and texture images can be located not just in VRAM but also in regions allocated in main memory. "Main memory" in this case refers more specifically to "device memory," which is the portion of main memory where the operating system guarantees the integrity of the addresses accessed by peripheral devices. When specifying graphics data such as vertex buffers and textures in main memory, if you do not use the GL library to create copies of the data in main memory, you must store the data in device memory.
The alignment of addresses differs depending on buffer type (in other words, depending on the purpose of the memory region). For more information, see the Differences in Alignment Between Buffer Types table in 3.2.1.1. Allocator of the 3DS Programming Manual: Basic Graphics. For more information about device memory, see the 3DS Programming Manual: System.
The GPU can directly reference data located in main memory, but it works differently depending on the settings specified when that region was allocated. Also, the access speed of main memory is slower than VRAM, so data location can have an effect on performance. For example, if you allocated memory for vertex buffers in both VRAM and main memory, the access speed for the buffers in VRAM would decrease to match the access speed for the buffers in main memory.
Pass a bitwise OR of certain specific flag values in the target
parameter of the glTexImage2D
, glCompressedTexImage2D
, glCopyTexImage2D
, and glBufferData()
functions to configure the GPU access targets and whether to create a copy in main memory when the memory region is allocated.
Flag | Access Target |
---|---|
NN_GX_MEM_VRAMA |
GPU accesses VRAM-A. |
NN_GX_MEM_VRAMB |
GPU accesses VRAM-B. |
NN_GX_MEM_FCRAM |
GPU accesses main memory. |
Flag | Copy Creation |
---|---|
GL_COPY_FCRAM_DMP |
Create copy in main memory. |
GL_NO_COPY_FCRAM_DMP |
Do not create copy in main memory. |
These flags produce the following four setting combinations.
- Access Main Memory and Create a Copy in Main Memory
- Access Main Memory and Do Not Create a Copy in Main Memory
- Access VRAM-A (or B) and Create a Copy in Main Memory
- Access VRAM-A (or B) and Do Not Create a Copy in Main Memory
Combination (1) is the default for the glTexImage2D()
, glCompressedTexImage2D()
, and glBufferData()
functions.
For just the glTexImage2D()
function, passing NULL
in the pixels
parameter sets VRAM-B as the access target for combination (4).
The arguments to the glCopyTexImage2D()
function can only specify the GPU access target. The function allocates a region in the specified memory, and then transfers the color buffer contents via DMA. NN_GX_MEM_FCRAM
(access main memory) is the default.
The glBufferSubData()
function inherits the configured GPU access target and copy creation flags from the glBufferData()
function.
3.1. Access Main Memory and Create a Copy in Main Memory
This setting combination applies when you specify the bitwise OR of NN_GX_MEM_FCRAM
and GL_COPY_FCRAM_DMP
during a function call.
The function carries out the following operations.
- The function allocates a memory region in main memory.
- The CPU copies data to the allocated region.
- The GPU directly accesses main memory (the region to which the data was copied).
The region storing the data can be released immediately after the function completes (this is immediately after data is copied by the CPU). If NULL
is specified as the data address, a region is allocated but data is not copied.
3.2. Access Main Memory and Do Not Create a Copy in Main Memory
This setting combination applies when you specify the bitwise OR of NN_GX_MEM_FCRAM
and GL_NO_COPY_FCRAM_DMP
during a function call.
The function carries out the following operations.
- The GPU directly accesses main memory (the region allocated by the application).
The region storing the data cannot be released until rendering completes. A GL_INVALID_OPERATION
error occurs when NULL
was specified as the data address and when textures were loaded that are not in PICA native format.
With this setting combination, the application manages the memory for the vertex buffer allocated by the glBufferData()
function, so the glBufferSubData()
function does not update the data of the partial regions but instead only handles cache flushing of the partial regions. Updating the partial regions is the responsibility of the application. A GL_INVALID_VALUE
error occurs if the value passed in the glBufferSubData()
function's data
parameter is not a sum of offset
and the source buffer address specified in the glBufferData()
function.
When using the GPU to render data updated dynamically by the CPU and located in main memory, but without calling any GL function, you must call the nngxUpdateBufferLight()
function.
3.3. Access VRAM-A (or B) and Create a Copy in Main Memory
This setting combination applies when you specify the bitwise OR of NN_GX_MEM_VRAMA
(or NN_GX_MEM_VRAMB
) and GL_COPY_FCRAM_DMP
during a function call.
The function carries out the following operations.
- The function allocates memory regions in both main memory and VRAM.
- The CPU copies data to the allocated region.
- Data is sent via DMA transfer from main memory (the copy region) to VRAM.
- The GPU accesses VRAM.
The region storing the data can be released immediately after the function completes (this is immediately after data is copied by the CPU). A GL_INVALID_OPERATION
error occurs when NULL
was specified as the data address.
3.4. Access VRAM-A (or B) and Do Not Create a Copy in Main Memory
This setting combination applies when you specify the bitwise OR of NN_GX_MEM_VRAMA
(or NN_GX_MEM_VRAMB
) and GL_NO_COPY_FCRAM_DMP
during a function call.
The function carries out the following operations.
- The function allocates a memory region in VRAM.
- Data is sent via DMA transfer from main memory (the region allocated by the application) to VRAM.
- The GPU accesses VRAM.
The region storing the data cannot be released until the DMA-transfer copy operation completes (that is, until completion of the DMA transfer command request is confirmed). If NULL
is specified as the data address, a region is allocated but no DMA transfer is performed. A GL_INVALID_OPERATION
error occurs when textures were loaded that are not in PICA native format.
When you call the glBufferSubData()
function on vertex buffers loaded with this setting combination, the application must guarantee the content of the memory region specified in data
until the DMA transfer completes.
3.5. Effectively Using VRAM
VRAM-A and VRAM-B are accessed using separate channels. If a buffer is sometimes loaded and written at the same time, we recommend allocating that buffer in both VRAMs and using the buffer in one VRAM for loading and the other for writing.
The following combinations can cause competing access.
Combinations That Cause Competing Access | When It Occurs |
---|---|
Color buffer and depth (stencil) buffer | Throughout rendering |
Color buffer and display buffer | When the nngxTransferRenderImage() function runs |
Vertex buffer and index buffer | When the glDrawElements() function runs |
We strongly recommend allocating both the color buffer and depth (stencil) buffer in separate VRAM banks because these buffers are accessed throughout rendering.