7. Relationship Between the GD and GX Libraries

This chapter explains which nngx() functions are called by functions in this library, and when you need to pay particular attention to nngx() functions.

7.1. Internal Use of nngx Functions

Some of the functions in the GD library call nngx() functions. As long as no errors have occurred, the functions in the following table call nngx() functions when the condition in the Condition column is met. However, the same function may call different nngx() functions depending on the condition.

If "Always" is given as a condition, the corresponding nngx() functions are always called unless an error has occurred.

Table 7-1. GD Functions That Call nngx Functions
GD Function Conditions nngx Functions
System::
StartRecordingPackets
Always nngxStartCmdlistSave
System::
StopRecordingPackets
Always

nngxSplitDrawCmdlist

nngxStopCmdlistSave

nngxExportCmdlist

System::ReplayPackets Always nngxImportCmdlist
System::
Execute3DCommandList
Always nngxSplitDrawCmdlist
Resource::
CreateTexture2DResource
There is initial data, and data is copied to a region allocated in VRAM. nngxAddVramDmaCommand
There is initial data, and data is copied to a region allocated in device memory. nngxUpdateBuffer
There is initial data, and mipmaps are generated automatically. nngxFilterBlockImage
Memory::GenerateMipMaps Always nngxFilterBlockImage
Rendering dependency nngxSplitDrawCmdlist
Resource::
CreateVertexBufferResource
There is initial data, and data is copied to a region allocated in VRAM. nngxAddVramDmaCommand
There is initial data, and data is copied to a region allocated in device memory. nngxUpdateBuffer
Memory::
CopyTextureSubResource
Always nngxAddBlockImageCopyCommand
Rendering dependency nngxSplitDrawCmdlist
Memory::
CopyVertexBufferSubResource
Always nngxAddBlockImageCopyCommand
Memory::
CopyTexture2DResource
BlockToLinear
Always nngxAddB2LTransferCommand
Rendering dependency nngxSplitDrawCmdlist
Memory::
CopyTexture2DResource
LinearToBlock
Always nngxAddL2BTransferCommand
Rendering dependency nngxSplitDrawCmdlist
Memory::ClearTargets Always nngxAddMemoryFillCommand
Rendering dependency nngxSplitDrawCmdlist
Memory::
ClearTexture2DResource
Always nngxAddMemoryFillCommand
Rendering dependency nngxSplitDrawCmdlist
Resource::
UnmapTexture2DResource
A mapping that involves writing to resources in device memory nngxUpdateBuffer
Resource::
UnmapVertexBufferResource
A mapping that involves writing to resources in device memory nngxUpdateBuffer

7.2. Interaction With nngx Functions

This section explains when you need to pay particular attention to nngx() functions while using the GD library.

7.2.1. Creating Textures With Initial Data in VRAM

When you create a resource in VRAM using initial data, a DMA transfer command request is added to the command request queue. This command transfers the initial data from main memory to VRAM. Because the GD library does not manage command request execution, applications must confirm that the DMA transfer has completed before releasing the initial data.

As shown in the following sample code, you can call the nngxWaitCmdlistDone() function to wait for all of the command requests to complete. However, if the command list is double-buffered, the DMA transfer command request is not executed until the next frame after it was added to the current command request queue.

Code 7-1. Creating Textures With Initial Data in VRAM
nn::gd::Texture2DResource* texture2DResource = 0;
nn::gd::Texture2DResourceDescription Text2DResDesc =
{
    width, height, 1, nn::gd::Resource::NATIVE_FORMAT_RGB_888,
    nn::gd::Memory::LAYOUT_BLOCK_8, nn::gd::Memory::VRAMA
};
nn::gd::Resource::CreateTexture2DResource(
        &Text2DResDesc, data, GD_TRUE, &texture2DResource);

// We need to confirm that the DMA transfer has completed before releasing the resource, which is created in VRAM.
nngxWaitCmdlistDone();

free(data); 

7.2.2. Accessing Rendered Results

The CPU cannot directly access data in VRAM. If you want to access the contents of the color buffer, depth (stencil) buffer, and textures to directly overwrite something you have already rendered, you must take the following steps.

  • Allocate a temporary resource in device memory.
  • Copy the resource in VRAM to your temporary resource (transfer data from VRAM).
  • Overwrite the temporary resource.
  • Write the content of the temporary resource back to the resource in VRAM (transfer data to VRAM).

Command requests transfer data to and from VRAM. You must wait for the command requests to complete before you overwrite the resource or deallocate the temporary resource.

This procedure can be expressed by the following code.

Code 7-2. Accessing Rendered Results
// Allocate a temporary resource in device memory (FCRAM).
nn::gd::Texture2DResource* tmpResource= 0;
nn::gd::Texture2DResourceDescription tmpResourceDesc =
{
    s_RenderTextureWidth, s_RenderTextureHeight, 1,
    nn::gd::Resource::NATIVE_FORMAT_RGBA_8888,
    nn::gd::Memory::LAYOUT_BLOCK_8,
    nn::gd::Memory::FCRAM
};
res = nn::gd::Resource::CreateTexture2DResource(
        &tmpResourceDesc, 0, GD_FALSE, &tmpResource);

// Copy the resource in VRAM to the temporary resource.
nn::gd::Memory::Rect memRect(0, 0, -1, -1);
res = nn::gd::Memory::CopyTextureSubResource(
        s_texture2DResource_ColorBuffer, 0, memRect, tmpResource, 0, 0, 0);
// Map the resource to access it.
u8* data;
nn::gd::Resource::MapTexture2DResource(
        tmpResource, 0, nn::gd::Resource::MAP_READ_WRITE, (void**)&data);
// You must wait for the command request to complete before accessing data.
nngxWaitCmdlistDone();

// Write to the mapped resource here.
for (int y=0; y<s_RenderTextureHeight*s_RenderTextureWidth>>1; y++)
{
    data[k+] = 255; data[k] = 255; data[k] = 255; data[k+] = 255;
}

// Change to a temporary resource is finalized on unmapping.
nn::gd::Resource::UnmapTexture2DResource(tmpResource);

// Copy the temporary resource to the resource in VRAM.
nn::gd::Memory::CopyTextureSubResource(
        tmpResource, 0, memRect, s_texture2DResource_ColorBuffer, 0, 0, 0); 

CONFIDENTIAL