1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_ActivateCommand.cpp
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc.  All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law.  They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Revision: 27125 $
14  *---------------------------------------------------------------------------*/
15 
16 #include "precompiled.h"
17 
18 #include <nw/os/os_Memory.h>
19 #include <nw/gfx/gfx_ActivateCommand.h>
20 #include <nw/gfx/gfx_DisplayList.h>
21 #include <nw/gfx/res/gfx_ResVertex.h>
22 #include <nw/gfx/res/gfx_ResShape.h>
23 #include <nw/gfx/gfx_ShaderBinaryInfo.h>
24 
25 namespace nw
26 {
27 namespace gfx
28 {
29 nw::os::IAllocator* CommandCacheManager::s_Allocator = NULL;
30 namespace internal
31 {
32 
33 namespace {
34 
35 // 全ロードアレイをクリアし、固定頂点属性を設定する。
36 const u32 CLEAR_VERTEX_COMMAND[] =
37 {
38     // 固定頂点属性の設定
39     0xBFFF0000,
40     internal::MakeCommandHeader(0x202, 1, false, 0xF),
41 
42     // ロードアレイの無効化
43     0,
44     internal::MakeCommandHeader(0x205        , 1, false, 0xF),
45     0,
46     internal::MakeCommandHeader(0x205 + 3    , 1, false, 0xF),
47     0,
48     internal::MakeCommandHeader(0x205 + 3 * 2, 1, false, 0xF),
49     0,
50     internal::MakeCommandHeader(0x205 + 3 * 3, 1, false, 0xF),
51     0,
52     internal::MakeCommandHeader(0x205 + 3 * 4, 1, false, 0xF),
53     0,
54     internal::MakeCommandHeader(0x205 + 3 * 5, 1, false, 0xF),
55     0,
56     internal::MakeCommandHeader(0x205 + 3 * 6, 1, false, 0xF),
57     0,
58     internal::MakeCommandHeader(0x205 + 3 * 7, 1, false, 0xF),
59     0,
60     internal::MakeCommandHeader(0x205 + 3 * 8, 1, false, 0xF),
61     0,
62     internal::MakeCommandHeader(0x205 + 3 * 9, 1, false, 0xF),
63     0,
64     internal::MakeCommandHeader(0x205 + 3 * 10, 1, false, 0xF),
65     0,
66     internal::MakeCommandHeader(0x205 + 3 * 11, 1, false, 0xF),
67 
68     1,
69     internal::MakeCommandHeader(0x232, 4, true, 0xF),
70     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
71     0,
72     0,
73     0,
74 
75     2,
76     internal::MakeCommandHeader(0x232, 4, true, 0xF),
77     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
78     0,
79     0,
80     0,
81 
82     3,
83     internal::MakeCommandHeader(0x232, 4, true, 0xF),
84     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
85     0,
86     0,
87     0,
88 
89     4,
90     internal::MakeCommandHeader(0x232, 4, true, 0xF),
91     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
92     0,
93     0,
94     0,
95 
96     5,
97     internal::MakeCommandHeader(0x232, 4, true, 0xF),
98     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
99     0,
100     0,
101     0,
102 
103     6,
104     internal::MakeCommandHeader(0x232, 4, true, 0xF),
105     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
106     0,
107     0,
108     0,
109 
110     7,
111     internal::MakeCommandHeader(0x232, 4, true, 0xF),
112     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
113     0,
114     0,
115     0,
116 
117     8,
118     internal::MakeCommandHeader(0x232, 4, true, 0xF),
119     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
120     0,
121     0,
122     0,
123 
124     9,
125     internal::MakeCommandHeader(0x232, 4, true, 0xF),
126     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
127     0,
128     0,
129     0,
130 
131     10,
132     internal::MakeCommandHeader(0x232, 4, true, 0xF),
133     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
134     0,
135     0,
136     0,
137 
138     11,
139     internal::MakeCommandHeader(0x232, 4, true, 0xF),
140     (ut::Float24::Float32ToBits24( 1.0f ) <<  8),
141     0,
142     0,
143     0
144 };
145 
146 } // namespace
147 
148 //---------------------------------------------------------------------------
149 void
ClearVertexAttribute()150 ClearVertexAttribute()
151 {
152     NWUseCmdlist( CLEAR_VERTEX_COMMAND, sizeof(CLEAR_VERTEX_COMMAND) );
153 }
154 
155 
156 //---------------------------------------------------------------------------
157 template <typename TShape>
158 static void
SetupActivateVertexAttributeCommand_(TShape shape,ResShaderProgramDescription shaderProgramDesc)159 SetupActivateVertexAttributeCommand_(
160     TShape                      shape,
161     ResShaderProgramDescription shaderProgramDesc
162 )
163 {
164     enum
165     {
166         MAX_ATTRIBUTES_NUM        = 12,
167 
168         REG_VTX_SHADER_ATTR_NUM   = 0x2b9, // [3:0] 頂点属性数 - 1
169         REG_VTX_SHADER_ATTR_NUM_2 = 0x242, // [3:0] 頂点族整数 - 1
170         REG_VTX_MAP_0             = 0x2bb, // [31:0] 入力レジスタのインデックス
171         REG_VTX_MAP_1             = 0x2bc, // [15:0] 入力レジスタのインデックス
172         REG_VTX_STREAM_BASE       = 0x200, // [28:1] 頂点アレイのベースアドレス
173         REG_VTX_ARRAY_OFFSET      = 0x203, // [27:0] ロードアレイ0のアドレスオフセット
174         REG_VTX_PARAM_INDEX       = 0x232, // [3:0] 頂点シェーダの入力番号指定
175         REG_GEOM_MAP_0            = 0x28b, // [31:0] 入力レジスタのインデックス
176         REG_GEOM_MAP_1            = 0x28c  // [15:0] 入力レジスタのインデックス
177     };
178 
179     const ShaderBinaryInfo* shaderInfo = shaderProgramDesc.GetShaderBinaryInfo();
180     NW_NULL_ASSERT( shaderInfo );
181 
182     u32 shaderVtxAttrNum = shaderInfo->GetInputRegisterNum( shaderProgramDesc.GetVertexShaderIndex() );
183 
184     // VRAM, FCRAM のメモリマップの中からアドレスの一番小さいものをベースに設定
185     u32 baseAddr = nngxGetPhysicalAddr(nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMA));
186     shape.ref().m_BaseAddress = baseAddr;
187 
188     s32 vtxAttrNum = shape.GetVertexAttributesCount();
189     s32 inputRegNum = shaderVtxAttrNum;
190 
191     u32* command = static_cast<u32*>( NWGetCurrentCmdBuffer() );
192 
193     // シェーダの入力レジスタ数を設定。
194     command[0] = (inputRegNum - 1) | 0xa0000000;
195     command[1] = internal::MakeCommandHeader(REG_VTX_SHADER_ATTR_NUM,   1, false, 0xb);
196 
197     command[2] = (inputRegNum - 1);
198     command[3] = internal::MakeCommandHeader(REG_VTX_SHADER_ATTR_NUM_2, 1, false, 0x1);
199 
200     command[4] = 0;
201     command[5] = internal::MakeCommandHeader(REG_VTX_MAP_0,             2, true,  0xF);
202     command[6] = 0;
203     command[7] = 0;
204 
205     command[8] = baseAddr >> 3;
206     command[9] = internal::MakeCommandHeader(REG_VTX_STREAM_BASE,       3, true,  0xF);
207     command[10] = 0;
208     command[11] = static_cast<u32>(inputRegNum - 1) << 28;
209 
210     u32* inputMapTable   = &command[4];  // 0x2bb
211     u32* inputFormat     = &command[10]; // 0x201
212     u32* vertexParamMask = &command[11]; // 0x202
213 
214     int inputIndex = 0; // 内部頂点属性番号
215     int arrayIndex = 0; // ロードアレイ番号
216     u32 commandIndex = 12;
217 
218     u32 usedFlag = 0;
219 
220     // 0x2bb, 0x2bc に頂点ストリームを前から順に詰めて設定する。
221     // その後に、固定頂点属性を設定する。未使用の項目は Deactivate 用のコマンドであらかじめクリアされている前提とする。
222 
223     // 頂点ストリームを番号の若い順に設定
224     for ( s32 i = 0; i < vtxAttrNum; ++ i )
225     {
226         ResVertexAttribute attribute = shape.GetVertexAttributes( i );
227 
228         if ( attribute.GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM )
229         {
230             // 固定頂点属性は無視する。
231             continue;
232         }
233 
234         if (attribute.GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE)
235         // インターリーブフォーマットの場合。
236         {
237             ResInterleavedVertexStream interleave = ResStaticCast<ResInterleavedVertexStream>(attribute);
238 
239             // ロードアレイの設定。
240             // インターリブ形式なので 1 本のロードアレイに複数の要素が入ります。
241             u32 bufferAddr = nngxGetPhysicalAddr( interleave.GetImageAddress() );
242             s32 streamCount = interleave.GetVertexStreamsCount();
243 
244             command[commandIndex    ] = bufferAddr - baseAddr;
245             command[commandIndex + 1] = internal::MakeCommandHeader(REG_VTX_ARRAY_OFFSET + 3 * arrayIndex, 3, true, 0xF);
246             command[commandIndex + 2] = 0;
247             command[commandIndex + 3] = (interleave.GetStride() << 16) | (streamCount << 28);
248 
249             u32* arraySetting = &command[commandIndex + 2];
250             commandIndex += 4;
251 
252             for ( s32 streamIdx = 0; streamIdx < streamCount; ++streamIdx )
253             {
254                 ResVertexStream stream = interleave.GetVertexStreams( streamIdx );
255 
256                 s32 usage = stream.GetUsage();
257                 NW_ASSERT(0 <= usage && usage < MAX_ATTRIBUTES_NUM);
258 
259                 inputMapTable[ (inputIndex / 8) * 2 ] |= (usage & 0xf) << (4 * (inputIndex % 8)); // (inputIndex >= 8) ? 2 : 0 のアドレスに書き込む。
260                 usedFlag |= 0x1 << usage;
261 
262                 u32 format    = stream.GetFormatType();
263                 u32 dimension = stream.GetDimension();
264 
265                 inputFormat[ inputIndex / 8 ] |= CommandCacheHelper::GetVertexFormat(dimension, format) << ((inputIndex % 8) * 4);
266 
267                 if (streamIdx < 8)
268                 {
269                     arraySetting[0] |= inputIndex << (streamIdx * 4);
270                 }
271                 else
272                 {
273                     arraySetting[1] |= inputIndex << ((streamIdx - 8) * 4);
274                 }
275 
276                 ++inputIndex;
277             }
278 
279         }
280         else
281         // 非インターリーブフォーマットの場合。
282         {
283             // TODO: 今のところ、Usage == 入力レジスタ番号になっているのでそのまま利用。
284             // シェーダバイナリのフォーマットが公開されるとそちらを使った方が良い。
285             s32 usage = attribute.GetUsage();
286             NW_ASSERT(0 <= usage && usage < MAX_ATTRIBUTES_NUM);
287             inputMapTable[ (inputIndex / 8) * 2 ] |= (usage & 0xF) << (4 * (inputIndex % 8));
288             usedFlag |= 0x1 << usage;
289 
290             ResVertexStream stream = ResStaticCast<ResVertexStream>(attribute);
291 
292             u32 format    = stream.GetFormatType();
293             u32 dimension = stream.GetDimension();
294 
295             inputFormat[ inputIndex / 8 ] |= CommandCacheHelper::GetVertexFormat(dimension, format) << ((inputIndex % 8) * 4);
296 
297             // ロードアレイの設定
298             u32 bufferAddr = nngxGetPhysicalAddr( stream.GetImageAddress() );
299 
300             // このクラスでは interleave 形式には対応しないので、(0番目の要素 == 内部頂点属性 index 番目)
301             command[commandIndex] = bufferAddr - baseAddr;
302             command[commandIndex + 1] = internal::MakeCommandHeader(REG_VTX_ARRAY_OFFSET + 3 * arrayIndex, 3, true, 0xF);
303             command[commandIndex + 2] = inputIndex;
304             command[commandIndex + 3] = (CommandCacheHelper::GetVertexSize(dimension, format) << 16) + (1 <<  28);
305 
306             ++inputIndex;
307             commandIndex += 4;
308         }
309 
310         ++arrayIndex;
311     }
312 
313     const u32 HEADER_VTX_PARAM_INDEX = internal::MakeCommandHeader(REG_VTX_PARAM_INDEX, 4, true, 0xF);
314 
315     // 頂点ストリームの後に頂点パラメータを設定。
316     for ( s32 i = 0; i < vtxAttrNum; ++ i )
317     {
318         ResVertexAttribute attribute = shape.GetVertexAttributes( i );
319 
320         if ( attribute.GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM )
321         {
322             ResVertexParamAttribute param = ResStaticCast<ResVertexParamAttribute>(attribute);
323 
324             s32 usage = param.GetUsage();
325             NW_ASSERT(0 <= usage && usage < 12);
326             inputMapTable[ (inputIndex / 8) * 2 ] |= (usage & 0xF) << (4 * (inputIndex % 8));
327             usedFlag |= 0x1 << usage;
328 
329             // 頂点パラメータの場合の処理
330 
331             u32 data[4] = { 0, 0, 0, 0 };
332 
333             int count = param.GetAttributeCount();
334             f32* fdata = param.GetAttribute();
335 
336             for (int j = 0; j < count; ++j)
337             {
338                 data[j] = ut::Float24::Float32ToBits24( fdata[j] );
339             }
340 
341             command[commandIndex]     = inputIndex;
342             command[commandIndex + 1] = HEADER_VTX_PARAM_INDEX;
343             command[commandIndex + 2] = (data[3] <<  8) | (data[2] >> 16);
344             command[commandIndex + 3] = (data[2] << 16) | (data[1] >> 8);
345             command[commandIndex + 4] = (data[1] << 24) | (data[0]);
346             command[commandIndex + 5] = 0;
347 
348             vertexParamMask[0] |= 1 << (16 + inputIndex);
349 
350             ++inputIndex;
351             commandIndex += 6;
352         }
353     }
354 
355     // 残りの部分には元々固定頂点属性が設定されているのでフラグだけ立てておく。
356     while ( inputIndex < shaderVtxAttrNum )
357     {
358         s32 usage = shaderVtxAttrNum - 1;
359         while (usedFlag & (0x1 << usage)) { --usage; }
360         inputMapTable[ (inputIndex / 8) * 2 ] |= (usage & 0xF) << (4 * (inputIndex % 8));
361         usedFlag |= 0x1 << usage;
362 
363     #if 0 // 不具合発生時の確認用コード
364         // 残りの部分には (0,0,0,1) の固定属性を設定
365         command[commandIndex]     = inputIndex;
366         command[commandIndex + 1] = HEADER_VTX_PARAM_INDEX;
367         command[commandIndex + 2] = (ut::Float24::Float32ToBits24( 1.0f ) <<  8);
368         command[commandIndex + 3] = 0;
369         command[commandIndex + 4] = 0;
370         command[commandIndex + 5] = 0;
371         commandIndex += 6;
372     #endif
373 
374         vertexParamMask[0] |= 1 << (16 + inputIndex);
375         ++inputIndex;
376     }
377 
378     const u32 HEADER_GEOM_MAP_0 = internal::MakeCommandHeader(REG_GEOM_MAP_0, 1, false, 0xF);
379     const u32 HEADER_GEOM_MAP_1 = internal::MakeCommandHeader(REG_GEOM_MAP_1, 1, false, 0xF);
380 
381     if (shaderProgramDesc.GetGeometryShaderIndex() >= 0)
382     {
383         // TODO: ジオメトリシェーダの入力マップは、ひとまず 0x76543210, 0xfedcba98 に固定
384         command[commandIndex + 0] = 0x76543210;
385         command[commandIndex + 1] = HEADER_GEOM_MAP_0;
386         command[commandIndex + 2] = 0xfedcba98;
387         command[commandIndex + 3] = HEADER_GEOM_MAP_1;
388         commandIndex += 4;
389     }
390 
391     NWForwardCurrentCmdBuffer( commandIndex * sizeof(u32) );
392 }
393 
394 
395 //---------------------------------------------------------------------------
396 template <typename TShape>
397 static void
SetupDeactivateVertexAttributeCommand_(TShape shape,ResShaderProgramDescription shaderProgramDesc)398 SetupDeactivateVertexAttributeCommand_(
399     TShape                      shape,
400     ResShaderProgramDescription shaderProgramDesc
401 )
402 {
403     NW_UNUSED_VARIABLE(shaderProgramDesc);
404 
405     // NOTE:
406     // ・使用したロードアレイの要素数を 0 にリセットする。
407     // ・使用した頂点の設定を固定頂点属性 (0,0,0,0) にクリアする。
408 
409     enum
410     {
411         REG_VTX_ARRAY_VTXMASK     = 0x202,
412         REG_VTX_ARRAY_OFFSET      = 0x203, // [27:0] ロードアレイ0のアドレスオフセット
413         REG_VTX_PARAM_INDEX       = 0x232, // [3:0] 頂点シェーダの入力番号指定。
414         REG_VTX_MAP_0             = 0x2bb, // [31:0] 入力レジスタのインデックス
415         REG_VTX_MAP_1             = 0x2bc  // [15:0] 入力レジスタのインデックス
416     };
417 
418     s32 vtxAttrNum = shape.GetVertexAttributesCount();
419 
420     u32* command = static_cast<u32*>( NWGetCurrentCmdBuffer() );
421 
422     int inputIndex = 0; // 内部頂点属性番号
423     int arrayIndex = 0; // ロードアレイ番号
424     u32 commandIndex = 0;
425 
426     // 頂点ストリームを番号の若い順に設定
427     for ( s32 i = 0; i < vtxAttrNum; ++ i )
428     {
429         ResVertexAttribute attribute = shape.GetVertexAttributes( i );
430 
431         // 固定頂点属性は後の処理で無効化する。
432         if ( attribute.GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM )
433         {
434             inputIndex++;
435             continue;
436         }
437 
438         if (attribute.GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE)
439         {
440             ResInterleavedVertexStream interleave = ResStaticCast<ResInterleavedVertexStream>(attribute);
441 
442             // ロードアレイの無効化
443             command[commandIndex    ] = 0;
444             command[commandIndex + 1] = internal::MakeCommandHeader(REG_VTX_ARRAY_OFFSET + 2 + 3 * arrayIndex, 1, false, 0xF);
445             commandIndex += 2;
446 
447             s32 streamCount = interleave.GetVertexStreamsCount();
448             inputIndex += streamCount;
449         }
450         else
451         {
452             // ロードアレイの無効化
453             command[commandIndex    ] = 0;
454             command[commandIndex + 1] = internal::MakeCommandHeader(REG_VTX_ARRAY_OFFSET + 2 + 3 * arrayIndex, 1, false, 0xF);
455             commandIndex += 2;
456 
457             ++inputIndex;
458         }
459 
460         ++arrayIndex;
461     }
462 
463     // 入力レジスタマップを初期化
464     // HACK: ここで設定していなくても正しく表示されるかもしれません。
465     {
466         const u32 INPUT_MAP0 = 0x76543210;
467         const u32 INPUT_MAP1 = 0x0000ba98;
468 
469         command[commandIndex++] = INPUT_MAP0;
470         command[commandIndex++] = internal::MakeCommandHeader(REG_VTX_MAP_0,             2, true,  0xF);
471         command[commandIndex++] = INPUT_MAP1;
472         command[commandIndex++] = 0;
473     }
474 
475     command[commandIndex++] = (static_cast<u32>(inputIndex - 1) << 28) | (((0x1 << inputIndex) - 2) << 16);
476     command[commandIndex++] = internal::MakeCommandHeader(REG_VTX_ARRAY_VTXMASK, 1, false, 0xF);
477 
478     const u32 HEADER_VTX_PARAM_INDEX = internal::MakeCommandHeader(REG_VTX_PARAM_INDEX, 4, true, 0xF);
479 
480     // (0,0,0,0) の固定属性を設定
481     for ( int i = 1; i < inputIndex; ++i )
482     {
483         command[commandIndex]     = i;
484         command[commandIndex + 1] = HEADER_VTX_PARAM_INDEX;
485         command[commandIndex + 2] = (ut::Float24::Float32ToBits24( 1.0f ) <<  8);
486         command[commandIndex + 3] = 0;
487         command[commandIndex + 4] = 0;
488         command[commandIndex + 5] = 0;
489         commandIndex += 6;
490     }
491 
492     NWForwardCurrentCmdBuffer( commandIndex * sizeof(u32) );
493 }
494 
495 //--------------------------------------------------------------------------
496 void
SetupVertexAttributeCommand(ResSeparateDataShape shape,ResShaderProgramDescription shaderProgramDesc)497 SetupVertexAttributeCommand(
498     ResSeparateDataShape        shape,
499     ResShaderProgramDescription shaderProgramDesc
500 )
501 {
502     SetupActivateVertexAttributeCommand_( shape, shaderProgramDesc );
503 }
504 
505 //--------------------------------------------------------------------------
506 void
SetupVertexAttributeCommand(ResParticleShape shape,ResShaderProgramDescription shaderProgramDesc)507 SetupVertexAttributeCommand(
508     ResParticleShape            shape,
509     ResShaderProgramDescription shaderProgramDesc
510 )
511 {
512     SetupActivateVertexAttributeCommand_( shape, shaderProgramDesc );
513 }
514 
515 //--------------------------------------------------------------------------
516 void
SetupDeactivateVertexAttributeCommand(ResSeparateDataShape shape,ResShaderProgramDescription shaderProgramDesc)517 SetupDeactivateVertexAttributeCommand(
518     ResSeparateDataShape        shape,
519     ResShaderProgramDescription shaderProgramDesc
520 )
521 {
522     SetupDeactivateVertexAttributeCommand_( shape, shaderProgramDesc );
523 }
524 
525 //--------------------------------------------------------------------------
526 void
SetupDeactivateVertexAttributeCommand(ResParticleShape shape,ResShaderProgramDescription shaderProgramDesc)527 SetupDeactivateVertexAttributeCommand(
528     ResParticleShape            shape,
529     ResShaderProgramDescription shaderProgramDesc
530 )
531 {
532     SetupDeactivateVertexAttributeCommand_( shape, shaderProgramDesc );
533 }
534 
535 //--------------------------------------------------------------------------
536 void
SetupShaderProgramMode(bool useGeometry)537 SetupShaderProgramMode(bool useGeometry)
538 {
539     // 初回時と 頂点シェーダとジオメトリシェーダの切り替え時のみ、
540     // 0x229[1:0]のコマンドとダミーコマンドを積む。
541     {
542         // ジオメトリシェーダのON/OFF切り替え。
543         // ジオメトリシェーダを使用しない場合には、0x244を0にすることで、
544         // 以後、0x2b0-0x2df の設定が 0x280-0x2af にミラーコピーされる。
545 
546         static u32 USE_GEOMETRY_COMMAND[] =
547         {
548             0x00000000, 0x00900251, 0x00000000, 0x00000000,
549             0x00000000, 0x00000000, 0x00000000, 0x00000000,
550             0x00000000, 0x00000000, 0x00000000, 0x00000000,
551             0x00000000, 0x01d00200, 0x00000000, 0x00000000,
552             0x00000000, 0x00000000, 0x00000000, 0x00000000,
553             0x00000000, 0x00000000, 0x00000000, 0x00000000,
554             0x00000000, 0x00000000, 0x00000000, 0x00000000,
555             0x00000000, 0x00000000, 0x00000000, 0x00000000,
556             0x00000000, 0x00000000, 0x00000000, 0x00000000,
557             0x00000000, 0x00000000, 0x00000000, 0x00000000,
558             0x00000000, 0x00000000, 0x00000000, 0x00000000,
559 
560             0x0, 0x00010229,                                // index : 44, 45
561 
562             0x00000000, 0x01d00200, 0x00000000, 0x00000000,
563             0x00000000, 0x00000000, 0x00000000, 0x00000000,
564             0x00000000, 0x00000000, 0x00000000, 0x00000000,
565             0x00000000, 0x00000000, 0x00000000, 0x00000000,
566             0x00000000, 0x00000000, 0x00000000, 0x00000000,
567             0x00000000, 0x00000000, 0x00000000, 0x00000000,
568             0x00000000, 0x00000000, 0x00000000, 0x00000000,
569             0x00000000, 0x00000000, 0x00000000, 0x00000000,
570         };
571 
572         const u32 IDX_REG_229 = 44;
573 
574         if ( useGeometry )
575         {
576             USE_GEOMETRY_COMMAND[ IDX_REG_229 ] = 0x00000002;
577         }
578         else
579         {
580             USE_GEOMETRY_COMMAND[ IDX_REG_229 ] = 0x0;
581         }
582 
583         internal::NWUseCmdlist<sizeof(USE_GEOMETRY_COMMAND)>( &USE_GEOMETRY_COMMAND[0] );
584     }
585 }
586 
587 //--------------------------------------------------------------------------
588 void
SetupDrawElementsCommand(const ResShaderProgramDescription shaderProgram,ResIndexStream indexStream)589 SetupDrawElementsCommand(const ResShaderProgramDescription shaderProgram, ResIndexStream indexStream)
590 {
591     NW_UNUSED_VARIABLE(shaderProgram);
592     NW_UNUSED_VARIABLE(indexStream);
593 }
594 
595 } // namespace internal
596 
597 } // namespace gfx
598 } // namespace nw
599 
600