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><CODE><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</CODE> 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>Parameters</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>command</th>
35<td>The start address for storing the rendering command.</td>
36        </tr>
37        <tr>
38<td>out</td>
39<th>bufferSizePtr</th>
40<td>The data address storing the byte size of the command buffer to execute after control returns from the jump destination.</td>
41        </tr>
42        <tr>
43<td>in</td>
44<th>commandBufferPtr</th>
45<td>Address of the jump destination command buffer.</td>
46        </tr>
47        <tr>
48<td>in</td>
49<th>commandBufferSize</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 (the 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 the 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>
68    u32* command;
69    u32* tmpHead;
70    uptr sizeAddr;
71    GLint bufSizeFirstKick;    // Stores the size from the start of the command buffer until the first channel kick command
72
73    nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast< GLint* >( &command ) );
74    const 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
80    command = MakeChannel1SubroutineCommand( command, &sizeAddr, subroutineAddr, subroutineSize );
81    // Save the command buffer address immediately after adding the command set for making the jump
82    tmpHead = command;
83    bufSizeFirstKick = (command - startAddr) * sizeof(u32);
84
85    ... // Generate the necessary commands
86
87    // Advance the pointer to the render command buffer
88    nngxMoveCommandbufferPointer( ( 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
92    nngxFlush3DCommandPartially(bufSizeFirstKick);
93
94    // Get the command buffer address after adding the split command
95    nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast< GLint* >( &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< u32* >(sizeAddr)) = ((command - tmpHead) * sizeof(u32)) >> 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.
103    nngxUpdateBuffer( reinterpret_cast< u32* >(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 must 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>
113    bit32* AddDummyDataForCommandBuffer( bit32* command, const size_t size )
114    {
115        // Adjust so that the size of the buffer is a multiple of 16
116        if ( size % 16 )
117        {
118            int num = (size >> 2) % 4;
119
120            for ( int i=4; i>num; --i )
121            {
122                *command++ = 0;
123            }
124        }
125
126        return command;
127    }
128
129    void CreateCommand(void)
130    {
131        u32* command;
132        nngxGetCmdlistParameteri( NN_GX_CMDLIST_CURRENT_BUFADDR, reinterpret_cast< GLint* >( &command ) );
133
134        const 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
140        command = 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
143        command = 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 the code example, and added a code example demonstrating adjustment of the 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>
165