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>MakeChannel1SubroutineCommand</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>::MakeChannel1SubroutineCommand Function</h1> 11<h2>Syntax</h2> 12 <div class="section"> 13 <pre class="definition"> 14<a href="../../../nn_types/bit32.html">bit32</a> * MakeChannel1SubroutineCommand( 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 1) 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 32 bytes. 108 </p><p> 109Also, a Channel 0 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 MakeChannel1SubroutineCommand function 139 // Assuming 32 bytes, add a dummy command so that the size is a multiple of 16 140 command = AddDummyDataForCommandBuffer( command, (command - startAddr) * sizeof(u32) + 32 ); 141 142 // Adding the kick command makes the size of the command buffer an exact multiple of 16 143 command = MakeChannel1SubroutineCommand( 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/MakeChannel0SubroutineCommand.html"><CODE>nn::gr::CTR::MakeChannel0SubroutineCommand</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