1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2<html xml:lang="en-US" lang="en-US" xmlns="http://www.w3.org/1999/xhtml">
3  <head>
4    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5    <meta http-equiv="Content-Style-Type" content="text/css" />
6    <link rel="stylesheet" href="../../../css/manpage.css" type="text/css" />
7<title>MakeChannel0SubroutineCommand</title>
8  </head>
9  <body>
10<h1><a href="../../../nn/Overview.html">nn</a>::<a href="../../../nn/gr/Overview.html">gr</a>::<a href="../../../nn/gr/CTR/Overview.html">CTR</a>::MakeChannel0SubroutineCommand Function</h1>
11<h2>Syntax</h2>
12    <div class="section">
13      <pre class="definition">
14<a href="../../../nn_types/bit32.html">bit32</a> * MakeChannel0SubroutineCommand(
15     <a href="../../../nn_types/bit32.html">bit32</a> * command,
16     <a href="../../../nn_types/uptr.html">uptr</a> * bufferSizePtr,
17     const <a href="../../../nn_types/uptr.html">uptr</a> commandBufferPtr,
18     const size_t commandBufferSize
19);
20</pre>
21    </div>
22<h2>Arguments</h2>
23    <div class="section">
24      <table class="arguments">
25        <thead>
26          <tr>
27            <td width="15" />
28<th>Name</th>
29<td>Description</td>
30          </tr>
31        </thead>
32        <tr>
33<td>in</td>
34<th><CODE>command</CODE></th>
35<td>The start address for storing the rendering command.</td>
36        </tr>
37        <tr>
38<td>out</td>
39<th><CODE>bufferSizePtr</CODE></th>
40<td>The data address storing the byte size of the command buffer to be executed after control returns from the jump destination.</td>
41        </tr>
42        <tr>
43<td>in</td>
44<th><CODE>commandBufferPtr</CODE></th>
45<td>Address of the jump destination command buffer.</td>
46        </tr>
47        <tr>
48<td>in</td>
49<th><CODE>commandBufferSize</CODE></th>
50<td>Byte size of the jump destination command buffer.</td>
51        </tr> </table>
52    </div>
53<h2>Return Values</h2>
54<div class="section">Returns the address that follows the end of the stored rendering command. </div>
55<h2>Description</h2>
56    <div class="section">
57<p>Adds a command set for jumping to a different command buffer (executed on Channel 0) and then returning control to the original command buffer.</p><!-- write here --><p>
58For convenience, the jump destination command buffer is called a subroutine.
59            </p><p>
60The value found by taking the number of bytes from the point of returning from the subroutine to the next channel kick command or split command (command added using the <CODE>nngxSplitDrawCmdlist</CODE> function or <CODE>nngxFlush3DCommand</CODE> function) and dividing by 8 must be written into <SPAN class="argument">bufferSizePtr</SPAN>.
61            </p><p>
62If the return value of this function is saved for later use, the number of bytes can be calculated based on the difference in the command buffer address immediately after split command is added.
63            </p><p>
64<SPAN class="argument">commandBufferPtr</SPAN> specifies the subroutine address, while <SPAN class="argument">commandbufferSize</SPAN> specifies the subroutine byte size. Both of these values must be a multiple of 16.
65            </p><p>
66Example
67            </p><pre>
68u32* command;
69u32* tmpHead;
70uptr sizeAddr;
71GLint bufSizeFirstKick;    // Stores the size from the start of the command buffer until the first channel kick command
72
73nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast&lt; GLint* &gt;( &command ) );
74const u32* startAddr = command;  // Keep the start address
75
76    ...
77
78// In some cases, we will adjust the size of the command buffer (see below)
79
80command = MakeChannel1SubroutineCommand( command, &sizeAddr, subroutineAddr, subroutineSize );
81// Save the command buffer address immediately after adding the command set for making the jump
82tmpHead = command;
83bufSizeFirstKick = (command - startAddr) * sizeof(u32);
84
85... // Generate the necessary commands
86
87// Advance the pointer to the render command buffer
88nngxMoveCommandbufferPointer( ( command - startAddr ) * sizeof(u32) );
89
90// Stop creating commands and add a split command
91// Specify the size from the start of the command buffer until the first channel kick command
92nngxFlush3DCommandPartially(bufSizeFirstKick);
93
94// Get the command buffer address after adding the split command
95nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast&lt; GLint* &gt;( &command ) );
96
97// Write the value given by taking the number of bytes from returning from the subroutine up to the split command and dividing by 8
98*(reinterpret_cast&lt; u32* &gt;(sizeAddr)) = ((command - tmpHead) * sizeof(u32)) &gt;&gt; 3;
99
100// Flush the cache
101// The nngxFlush3DCommandPartially function does not flush the cache for the command buffer, so:
102// We must perform this for the entire area.
103nngxUpdateBuffer( reinterpret_cast&lt; u32* &gt;(startAddr), (command - startAddr) * sizeof(u32) );
104</pre><br /><p>
105Make sure that the size of the buffer immediately after adding the command generated by this function is a multiple of 16. In some cases, you will need to adjust the size by generating a dummy command beforehand.
106            </p><p>
107The byte size of commands added by this function is 24 bytes.
108            </p><p>
109Also, a Channel 1 kick command must be stored at the end of command buffers specified as a subroutine.
110            </p><p>
111Example: Adjusting the size of the command buffer
112            </p><pre>
113bit32* AddDummyDataForCommandBuffer( bit32* command, const size_t size )
114    {
115// Adjust so that the size of the buffer is a multiple of 16
116if ( size % 16 )
117        {
118int num = (size &gt;&gt; 2) % 4;
119
120for ( int i=4; i&gt;num; --i )
121            {
122*command++ = 0;
123            }
124        }
125
126return command;
127    }
128
129void CreateCommand(void)
130    {
131u32* command;
132nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast&lt; GLint* &gt;( &command ) );
133
134const u32* startAddr = command;  // Keep the start address
135
136... // Create command
137
138// In addition to the existing command buffer contents, the command size added by the <CODE>MakeChannel0SubroutineCommand</CODE> function
139// Assuming 24 bytes, add a dummy command so that the size is a multiple of 16
140command = AddDummyDataForCommandBuffer( command, (command - startAddr) * sizeof(u32) + 24 );
141
142// Adding the kick command makes the size of the command buffer an exact multiple of 16
143command = MakeChannel0SubroutineCommand( command, &sizeAddr, subroutineAddr, subroutineSize );
144
145... // Create command
146    }
147</pre></div>
148<h2>See Also</h2>
149    <div class="section">
150<p class="reference"><a href="../../../nn/gr/CTR/MakeChannel1SubroutineCommand.html"><CODE>nn::gr::CTR::MakeChannel1SubroutineCommand</CODE></a><br /> </p>
151    </div>
152<h2>Revision History</h2>
153    <div class="section">
154      <dl class="history">
155        <dt>2011/10/20</dt>
156<dd>Revised code example, and added code example demonstrating adjustment of command buffer size.
157        </dd>
158        <dt>2011/07/29</dt>
159<dd>Initial version.<br />
160        </dd>
161      </dl>
162    </div>
163  <hr><p>CONFIDENTIAL</p></body>
164</html>