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    <style type="text/css">
8      <!--
9      span.static_style
10      {
11        font-size			: 8pt;
12        color				: white;
13        font-weight			: bold;
14        background			: #44f;
15        border-left			: solid 1px #aaf;
16        border-top			: solid 1px #aaf;
17        border-right		: solid 1px #00c;
18        border-bottom		: solid 1px #00c;
19        padding-left		: 2px;
20        padding-right		: 2px;
21      }
22
23      span.virtual_style
24      {
25        font-size			 : 8pt;
26        color				 : white;
27        font-weight			: bold;
28        background			: #0a0;
29        border-left			: solid 1px #0f0;
30        border-top			: solid 1px #0f0;
31        border-right		: solid 1px #060;
32        border-bottom		: solid 1px #060;
33        padding-left		: 2px;
34        padding-right		: 2px;
35      }
36
37      span.protected_style
38      {
39        font-size			 : 8pt;
40        color				 : white;
41        font-weight			: bold;
42        background			: #444;
43        border-left			: solid 1px #ccc;
44        border-top			: solid 1px #ccc;
45        border-right		: solid 1px #222;
46        border-bottom		: solid 1px #222;
47        padding-left		: 2px;
48        padding-right		: 2px;
49      }
50      table.table, table.table td, table.table th
51      {
52        border-collapse: collapse;
53        background-color: white;
54      }
55
56      table.table
57      {
58        width: auto;
59        margin: 1em;
60        position	: static;
61        font-family	: Arial;
62      }
63
64      table.table td, table.table th
65      {
66        padding: 0.2em;
67      }
68
69      table.table td.number, table.table th.number
70      {
71        text-align: right;
72      }
73
74      table.table tbody tr th
75      {
76        text-align: left;
77        font-weight: normal;
78        width: auto;
79      }
80
81      table.table thead tr th,
82      table.table tbody tr th.category
83      {
84        padding: 0 0.2em;
85      }
86
87      table.table caption
88      {
89        font-weight: bold;
90        padding: 0.4em;
91      }
92      table.table th
93      {
94        font-weight			: bold;
95        background			: #acf;
96      }
97        -->
98    </style>
99    <title>Command-Buffer Jumps</title>
100  </head>
101  <body>
102    <h1>Command-Buffer Jumps</h1>
103
104    <div class="section">
105      <p>
106        <ul>
107          <li><a href="#about">Overview</a></li>
108          <li><a href="#feature">Features of Command-Buffer Jumps</a></li>
109            <ul>
110              <li><a href="#feature_merit">Benefits</a></li>
111              <li><a href="#feature_notice">Drawbacks</a></li>
112            </ul>
113          <li><a href="#api">Functions that Support Command-Buffer Jumps</a></li>
114            <ul>
115              <li><a href="#api_nngx">Only the <CODE>nngx</CODE> API</a></li>
116              <li><a href="#api_gr">GR library and <CODE>nngx</CODE> API</a></li>
117              <li><a href="#api_gd">GD library</a></li>
118              <li><a href="#api_direct">Directly generating 3D commands</a></li>
119            </ul>
120          <li><a href="#complement">Supplemental Information</a></li>
121            <ul>
122              <li><a href="#comp_buflocation">Placement of command buffers</a></li>
123              <li><a href="#comp_cpucacheflush">Flushing CPU cache when inserting split commands (when using  <CODE>nngx</CODE> API functions)</a></li>
124              <li><a href="#comp_cmdlist">Execution status of command list</a></li>
125            </ul>
126          <li><a href="#log">Revision History</a></li>
127        </ul>
128      </p>
129    </div>
130
131    <h2><a name="about">Overview</a></h2>
132    <div class="section">
133      <p>
134          You can use command buffer addresses and sizes and kick commands to make execution jump to command buffers at different addresses.
135      </p>
136      <p>
137          The libraries provided by the SDK have API functions not only for normal, unidirectional command-buffer jumps, but also for jumping to command buffers in different locations in the form of subroutines that execute and then jump back to resume execution of subsequent commands in the original command buffer.
138      </p>
139    </div>
140    <!-- 概要 -->
141
142    <h2><a name="feature">Features of Command-Buffer Jumps</a></h2>
143    <div class="section">
144      <p>
145          There are both benefits and drawbacks to the use of command-buffer jumps, and these are both considered below.
146      </p>
147      <h3><a name="feature_merit">Benefits</a></h3>
148      <div class="section">
149        <p>
150          <ul>
151            <li>Enables the reuse of command buffers without adding and duplicating command requests, thereby reducing the load on the CPU.</li>
152            <li>Destination commands can be referenced directly from the GPU without copying to the current command buffer, so you can optimize the size of buffer assigned to the command list.</li>
153          </ul>
154        </p>
155      </div>
156      <h3><a name="feature_notice">Drawbacks</a></h3>
157      <div class="section">
158        <p>
159          <ul>
160            <li>The application must not only create the destination command buffers but also place them and perform all other related tasks.</li>
161            <li>When you execute a lot of jumping it becomes difficult to track the causes of rendering-related bugs.</li>
162            <li>The jumping process itself places a higher load on the GPU, so heavy use of command-buffer jumps can have an overall negative impact.</li>
163          </ul>
164        </p>
165      </div>
166    </div>
167    <!-- コマンドバッファジャンプの特徴 -->
168
169    <h2><a name="api">Functions That Support Command-Buffer Jumps</a></h2>
170    <div class="section">
171      <h3><a name="api_nngx">Only the <CODE>nngx</CODE> API</a></h3>
172      <div class="section">
173      <p>
174          There is the <CODE><a href="../nn_gx/nngxAddJumpCommand.html">nngxAddJumpCommand</a></CODE> function for unidirectional jumps,  and the <CODE><a href="../nn_gx/nngxAddSubroutineCommand.html">nngxAddSubroutineCommand</a></CODE> function for performing command-buffer jumps as subroutines.
175      </p>
176      <p>
177          The <CODE>nngx</CODE> API functions operate internally and automatically to adjust the byte alignment and size.<br /> The subroutine made for the command-buffer jump must add a Channel 1 kick command to the end of the command buffer. (For this, you can use the <CODE>nn::gr::MakeChannelKickCommand</CODE> function, which is described later.)
178      </p>
179      <p>
180          If you are going to add 3D rendering command requests (to add split commands) including a jump, use the following functions:
181          <ul>
182            <li><CODE><a href="../nn_gx/nngxFlush3DCommand.html">nngxFlush3DCommand</a></CODE> function.  (The <CODE><a href="../nn_gx/nngxSplitDrawCmdlist.html">nngxSplitDrawCmdlist</a> </CODE> function is also fine, but not recommended.)</li>
183            <li><CODE><a href="../nn_gx/nngxFlush3DCommandNoCacheFlush.html">nngxFlush3DCommandNoCacheFlush</a></CODE> function.</li>
184          </ul>
185          If using this later function, you need to explicitly flush the CPU cache for the command buffer.<br /> <font color="red">The <a href="../nn_gx/nngxFlush3DCommandPartially.html">nngxFlush3DCommandPartially</a> function does not perform this flush internally.</font>
186      </p>
187      </div>
188
189      <h3><a name="api_gr">GR Library and <CODE>nngx</CODE> API</a></h3>
190      <div class="section">
191      <p>
192          For unidirectional jumps there is the <CODE><a href="../nn/gr/CTR/MakeChannel0JumpCommand.html">nn::gr::MakeChannel0JumpCommand</a></CODE> function and the <CODE> <a href="../nn/gr/CTR/MakeChannel1JumpCommand.html">nn::gr::MakeChannel1JumpCommand</a></CODE> function.  For subroutines, there is the <CODE><a href="../nn/gr/CTR/MakeChannel0SubroutineCommand.html">nn::gr::MakeChannel0SubroutineCommand</a></CODE> function and the <CODE><a href="../nn/gr/CTR/MakeChannel1SubroutineCommand.html">nn::gr::MakeChannel1SubroutineCommand</a></CODE> function.<br /> In addition, the <CODE><a href="../nn/gr/CTR/MakeChannelKickCommand.html">nn::gr::MakeChannelKickCommand</a></CODE> function is supported for adding the kick command itself.
193      </p>
194      <p>
195          The GR library does not take the command buffer size and alignment into consideration when adding jump-related commands.<br /> You will need to make adjustments based on the size of commands added by the API functions.<br />Alternatively, you can select the channels to use and the commands to add. Also, the <a href="../nn/gr/CTR/CommandBufferJumpHelper/Overview.html"><CODE>nn::gr::CommandBufferJumpHelper</CODE></a> class helps you to adjust command sizes and create kick commands, but does not allow you to select channels.
196      </p>
197      <p>
198          <table>
199            <tr>
200              <th>API</th>
201              <th>Size (in bytes) of command being added</th>
202            </tr>
203            <tr>
204              <td><a href="../nn/gr/CTR/MakeChannelKickCommand.html"><CODE>MakeChannelKickCommand</CODE></a></td>
205              <td>8</td>
206            </tr>
207            <tr>
208              <td><a href="../nn/gr/CTR/MakeChannel0SubroutineCommand.html"><CODE>MakeChannel0SubroutineCommand</CODE></a></td>
209              <td>24</td>
210            </tr>
211            <tr>
212              <td><a href="../nn/gr/CTR/MakeChannel1SubroutineCommand.html"><CODE>MakeChannel1SubroutineCommand</CODE></a></td>
213              <td>32</td>
214            </tr>
215            <tr>
216              <td><a href="../nn/gr/CTR/MakeChannel0JumpCommand.html"><CODE>MakeChannel0JumpCommand</CODE></a></td>
217              <td>24</td>
218            </tr>
219            <tr>
220              <td><a href="../nn/gr/CTR/MakeChannel1JumpCommand.html"><CODE>MakeChannel1JumpCommand</CODE></a></td>
221              <td>24</td>
222            </tr>
223          </table>
224      </p>
225      <p>
226           To add a split command you must use the <CODE><a href="../nn_gx/nngxFlush3DCommandPartially.html">nngxFlush3DCommandPartially</a></CODE> function.<br /> For the argument, specify the size from the start of the command buffer to the (first) kick command.<br /> If you are using the GR library, you need to explicitly flush the CPU cache for the command buffer.<br /> <font color="red">The <a href="../nn_gx/nngxFlush3DCommandPartially.html">nngxFlush3DCommandPartially</a> function does not perform this flush internally.</font>
227      </p>
228      </div>
229
230      <h3><a name="api_gd">GD Library</a></h3>
231      <div class="section">
232      <p>
233         If you use the GD library, you do not need to make direct calls to the <CODE>nngx</CODE> functions for command-buffer jumping. The library acts internally to call the necessary functions.
234      </p>
235      <p>
236          Specify RECORD_3D_COMMAND_BUFFER_FOR_JUMP for the <SPAN class="argument">usage</SPAN> parameter of the <CODE><a href="../nn/gd/CTR/System/StartRecordingPackets.html">nn::gd::System::StartRecordingPackets</a></CODE> function and create the 3D command buffer you want as a subroutine. After the necessary commands are created, call the <CODE><a href="../nn/gd/CTR/System/StopRecordingPackets.html">nn::gd::System::StopRecordingPackets</a></CODE> function. The jump command is added internally when you specify the saved RecordedPacketId to the <CODE><a href="../nn/gd/CTR/System/ReplayPackets.html">nn::gd::System::ReplayPackets</a></CODE> function.
237      </p>
238      </div>
239
240      <h3><a name="api_direct">Directly Generating 3D Commands</a></h3>
241      <div class="section">
242      <p>
243          You can also jump by directly creating commands to send to the GPU. Use registers 0x238 to 0x23d. For details, see the documentation.
244      </p>
245      <p>
246          However, there is really no benefit to creating your own commands, so we recommend normally using one of the other methods.
247      </p>
248      </div>
249    </div>
250    <!-- コマンドバッファジャンプをサポートする API -->
251
252    <h2><a name="complement">Supplemental Information</a></h2>
253    <div class="section">
254      <p>
255        Following is supplemental information regarding precautions to take when implementing command-buffer jumps as well as ways to boost efficiency.
256      </p>
257
258      <h3><a name="comp_buflocation">Placement of Command Buffers</a></h3>
259      <div class="section">
260      <p>
261        Access to command buffers from the GPU is faster when the subroutines of commands are stored in VRAM rather than in main memory. So if access to command buffers in main memory becomes a bottleneck, you can expect an overall boost in processing speed by saving to VRAM.
262      </p>
263      <p>
264        To place commands in VRAM, use the <CODE><a href="../nn_gx/nngxAddVramDmaCommand.html">nngxAddVramDmaCommand</a></CODE> function or the <CODE><a href="../nn_gx/nngxAddVramDmaCommandNoCacheFlush.html">nngxAddVramDmaCommandNoCacheFlush</a></CODE> function.
265      </p>
266      </div>
267
268      <h3><a name="comp_cpucacheflush">Flushing the CPU Cache When Inserting Split Commands (When Using  <CODE>nngx</CODE> API Functions)</a></h3>
269      <div class="section">
270      <p>
271        If you implement a subroutine using the <CODE>nngx</CODE> API functions, calling the <CODE>nngxFlush3DCommand</CODE> function when adding a split command increases the load on the CPU because the CPU cache is flushed each time it is called.
272      </p>
273      <p>
274        For this reason, it is more efficient to keep the 3D rendering command requests all together without splitting if they include a subroutine call.<br /> If you need to have 3D rendering command requests containing multiple subroutines, what you can do is use the <CODE>nngxFlush3DCommandNoCacheFlush</CODE> function when adding the split command and then later call the <CODE><a href="../nn/gx/CTR/UpdateBuffer.html">nn::gx::UpdateBuffer</a></CODE> function for the entire required region so all flush operations are done together.
275      </p>
276      </div>
277
278      <h3><a name="comp_cmdlist">Execution Status of the Command List</a></h3>
279      <div class="section">
280      <p>
281        If there are no unexecuted command requests in the command list called by the <CODE><a href="../nn_gx/nngxRunCmdlist.html">nngxRunCmdlist</a></CODE> function, that command list enters the &quot;waiting to run&quot; state.<br /> In this state, if a new command request is added to the list, that request begins to run. During command request processing, the command list is in the &quot;running&quot; state.
282      </p>
283      <p>
284        When the command list is in the running state, some <CODE>nngx</CODE> API functions will generate an error and interrupt the processing.<br /> You need to particularly be careful with the above-mentioned <CODE><a href="../nn_gx/nngxFlush3DCommandPartially.html">nngxFlush3DCommandPartially</a></CODE> function.
285      </p>
286      <p>
287        For implementations similar to the one given as an example below, depending on the timing, the intended commands may not be generated and the GPU may hang.
288      </p>
289
290        <h4>Example of a bad implementation (using one command list)</h4>
291        <div class="section">
292        <p>
293<pre>
294// Bad implementation
295// One command list is used while it remains in the &quot;waiting to run&quot; state
296
297Draw()
298{
299    // Add a command request to clear the render buffer ... (A)
300    nngxAddMemoryFillCommand(...);
301
302    // Create some rendering command (assume the GR library is internally applying the jump)
303    DrawObjects();
304    // Add a split command (add a 3D rendering command request)... (B)
305    nngxFlush3DCommandPartially(buffersize);
306    // Flush CPU cache for the command buffer
307    nngxUpdateBuffer(...);
308
309    // Add a command request to transfer data to the display buffer ... (C)
310    nngxTransferRenderImage(...);
311
312    // Wait for execution to complete
313    nngxWaitCmdlistDone();
314    // Swap buffers
315    Swap();
316    // Clear command list
317    nngxClearCmdlist();
318}
319</pre>
320        If the command list is in the &quot;waiting to run&quot; state, it transitions to the &quot;running&quot; state when the command list is added (A). <br /> If (B) takes place before command request (A) completes, the <CODE><a href="../nn_gx/nngxFlush3DCommandPartially.html">nngxFlush3DCommandPartially</a></CODE> function generates the error GL_ERROR_80AD_DMP.<br /> The split command is not generated when the error occurs in (B), but when the <CODE><a href="../nn_gx/nngxTransferRenderImage.html">nngxTransferRenderImage</a></CODE> function is called in (C), a split command is added if there is any unprocessed command buffer, and a 3D rendering command request created.<br /> Because the execution size is not the size that was intended from the settings (the size from the start to the first kick command), the correct render result is not obtained and, in some cases, the GPU may hang.
321        </p>
322        <p>
323        There are several possible workarounds.
324        <ul>
325          <li>Duplicate the command list.</li>
326          <li>Immediately before step (B), add the <CODE><a href="../nn_gx/nngxWaitCmdlistDone.html">nngxWaitCmdlistDone</a></CODE> function to wait for the command list to finish running.</li>
327        </ul>
328        </p>
329        </div>
330      </div>
331    </div>
332    <!-- 補足 -->
333
334    <h2><a name="log">Revision History</a></h2>
335    <div class="section">
336      <dl class="history">
337        <dt>2012/06/26</dt>
338<dd>Added a note about the <CODE>nn::gr::CommandBufferJumpHelper</CODE> class.<br /></dd>
339        <dt>2012/02/17</dt>
340        <dd>Added a table of contents and information about the GD library.<br /></dd>
341        <dt>2012/02/08</dt>
342        <dd>Initial version.<br /></dd>
343      </dl>
344    </div>
345  <hr><p>CONFIDENTIAL</p></body>
346</html>