1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_ResShape.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: 16971 $
14 *---------------------------------------------------------------------------*/
15
16 #include "../precompiled.h"
17
18 #include <nw/ut/ut_ResUtil.h>
19 #include <nw/ut/ut_ResDictionary.h>
20 #include <nw/gfx/gfx_SceneObject.h>
21 #include <nw/gfx/res/gfx_ResShape.h>
22 #include <nw/gfx/res/gfx_ResParticleShape.h>
23 #include <nw/gfx/res/gfx_ResTexture.h>
24 #include <nw/gfx/gfx_Common.h>
25 #include <GLES2/gl2.h>
26 #include <GLES2/gl2ext.h>
27 #include <nw/gfx/gfx_CommandUtil.h>
28
29 #include <nn/gx.h>
30
31 namespace nw {
32 namespace gfx {
33 namespace res {
34
35 typedef void (*BindFunc)(ResShape resShape);
36
37 static void ResShape_Setup(ResShape resShape);
38 static void ResSeparateDataShape_Setup(ResShape resShape);
39 static void ResParticleShape_Setup(ResShape resShape);
40
41 static void ResShape_Cleanup(ResShape resShape);
42 static void ResSeparateDataShape_Cleanup(ResShape resShape);
43 static void ResParticleShape_Cleanup(ResShape resShape);
44
45 static BindFunc sShape_SetupTable[] =
46 {
47 ResSeparateDataShape_Setup,
48 ResParticleShape_Setup
49 };
50
51 static BindFunc sShape_CleanupTable[] =
52 {
53 ResSeparateDataShape_Cleanup,
54 ResParticleShape_Cleanup
55 };
56
57
58
59 //---------------------------------------------------------------------------
60 //! @brief 必要であれば頂点バッファのコピー用のメモリを確保し、転送をおこないます。
61 //!
62 //! @param[in] bufferID メモリ確保用の頂点バッファIDです。
63 //! @param[in] resStream 頂点ストリームリソースです。
64 //! @param[in] loadFlag 頂点バッファの配置メモリフラグです。
65 //---------------------------------------------------------------------------
66 static void
BufferData(u32 bufferID,ResIndexStream resStream,u32 loadFlag)67 BufferData( u32 bufferID, ResIndexStream resStream, u32 loadFlag )
68 {
69 u32 size = resStream.GetStreamCount();
70 GLenum transtype = loadFlag & 0xFFFF0000;
71 void* address = NULL;
72 const u32 NN_GX_MEM_MASK = 0x00030000;
73
74 switch (transtype)
75 {
76 case (NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP):
77 nngxUpdateBuffer( resStream.GetStream(), size );
78 break;
79
80 case (NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP):
81 case (NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP):
82 {
83 GLuint area = (transtype & NN_GX_MEM_MASK);
84 address = __dmpgl_allocator(area, NN_GX_MEM_VERTEXBUFFER, bufferID, size);
85 nngxUpdateBuffer( resStream.GetStream(), size );
86 internal::nwgfxAddVramDmaCommand( resStream.GetStream(), address, size );
87
88 resStream.SetLocationAddress( address );
89 resStream.ref().m_MemoryArea = area;
90 }
91 break;
92
93 case (NN_GX_MEM_FCRAM | GL_COPY_FCRAM_DMP):
94 {
95 address = __dmpgl_allocator(NN_GX_MEM_FCRAM, NN_GX_MEM_VERTEXBUFFER, bufferID, size);
96 std::memcpy( address, resStream.GetStream(), size );
97 nngxUpdateBuffer( address, size );
98
99 resStream.SetLocationAddress( address );
100 resStream.ref().m_MemoryArea = NN_GX_MEM_FCRAM;
101 }
102 break;
103
104 case (NN_GX_MEM_VRAMA | GL_COPY_FCRAM_DMP):
105 case (NN_GX_MEM_VRAMB | GL_COPY_FCRAM_DMP):
106 NW_FATAL_ERROR("GL_COPY_DMA is not supported!");
107 break;
108
109 default:
110 break;
111 }
112 }
113
114 //---------------------------------------------------------------------------
115 //! @brief コピーした頂点情報を開放します。
116 //!
117 //! @param[in] bufferID バッファオブジェクトIDです。
118 //! @param[in] resStream
119 //---------------------------------------------------------------------------
120 static void
DeleteBuffer(u32 bufferID,ResIndexStream resStream)121 DeleteBuffer( u32 bufferID, ResIndexStream resStream )
122 {
123 GLuint area = resStream.ref().m_MemoryArea;
124
125 if (area != ResIndexStreamData::AREA_NO_MALLOC)
126 {
127 void* address = reinterpret_cast<void*>( resStream.GetLocationAddress() );
128 __dmpgl_deallocator( area, NN_GX_MEM_VERTEXBUFFER, bufferID, address );
129 resStream.SetLocationAddress( static_cast<u32>(NULL) );
130 }
131 }
132
133
134 //----------------------------------------
135 Result
Setup()136 ResShape::Setup()
137 {
138 Result result = RESOURCE_RESULT_OK;
139 switch ( this->ref().typeInfo )
140 {
141 case ResSeparateDataShape::TYPE_INFO:
142 {
143 sShape_SetupTable[0]( *this );
144 this->SetFlags(ut::EnableFlag(this->GetFlags(), ResShape::FLAG_HAS_BEEN_SETUP));
145 }
146 break;
147 case ResParticleShape::TYPE_INFO:
148 {
149 sShape_SetupTable[1]( *this );
150 this->SetFlags(ut::EnableFlag(this->GetFlags(), ResShape::FLAG_HAS_BEEN_SETUP));
151 }
152 break;
153 default:
154 {
155 }
156 }
157 return result;
158 }
159
160
161 /*!--------------------------------------------------------------------------*
162 Name: ResShape_Setup
163
164 @brief シェイプのリソース初期化をおこないます。
165
166 @param[in] resShape シェイプリソースです。
167
168 @return なし。
169 *---------------------------------------------------------------------------*/
170 static void
ResShape_Setup(ResShape resShape)171 ResShape_Setup(ResShape resShape)
172 {
173 s32 primSetNum = resShape.GetPrimitiveSetsCount();
174
175 for ( s32 i = 0; i < primSetNum; ++i )
176 {
177 resShape.GetPrimitiveSets( i ).Setup();
178 }
179 }
180
181
182 /*!--------------------------------------------------------------------------*
183 Name: ResSeparateDataShape_Setup
184
185 @brief 複数属性シェイプのリソース初期化をおこないます。
186
187 @param[in] resShape シェイプリソースです。
188
189 @return なし。
190 *---------------------------------------------------------------------------*/
191 static void
ResSeparateDataShape_Setup(ResShape resShape)192 ResSeparateDataShape_Setup(ResShape resShape)
193 {
194 ResShape_Setup( resShape );
195
196 ResSeparateDataShape resSeparateShape = ResStaticCast<ResSeparateDataShape>( resShape );
197
198 s32 vtxAttrNum = resSeparateShape.GetVertexAttributesCount();
199 for ( s32 i = 0; i < vtxAttrNum; ++ i )
200 {
201 resSeparateShape.GetVertexAttributes( i ).Setup();
202 }
203 }
204
205
206 /*!--------------------------------------------------------------------------*
207 Name: ResParticleShape_Setup
208
209 @brief パーティクルシェイプのリソース初期化をおこないます。
210
211 @param[in] resShape シェイプリソースです。
212
213 @return なし。
214 *---------------------------------------------------------------------------*/
215 static void
ResParticleShape_Setup(ResShape resShape)216 ResParticleShape_Setup(ResShape resShape)
217 {
218 NW_UNUSED_VARIABLE(resShape);
219 }
220
221
222 /*!--------------------------------------------------------------------------*
223 Name: ResPrimitiveSet::Setup
224
225 @brief リソースの初期化をおこないます。
226
227 @return なし。
228 *---------------------------------------------------------------------------*/
229 void
Setup()230 ResPrimitiveSet::Setup()
231 {
232 NW_ASSERT( this->IsValid() );
233
234 ResPrimitiveArray primitiveArray = this->GetPrimitives();
235
236 for (ResPrimitiveArray::iterator it = primitiveArray.begin(); it != primitiveArray.end(); ++it)
237 {
238 (*it).Setup();
239 }
240 }
241
242
243 /*!--------------------------------------------------------------------------*
244 Name: ResPrimitive::Setup
245
246 @brief リソースの初期化をおこないます。
247
248 @return なし。
249 *---------------------------------------------------------------------------*/
250 void
Setup()251 ResPrimitive::Setup()
252 {
253 NW_ASSERT( this->IsValid() );
254
255 u32 streamNum = this->GetIndexStreamsCount();
256
257 GLuint* bufferObjects = reinterpret_cast<GLuint*>( this->GetBufferObjects() );
258
259 for ( uint i = 0; i < streamNum; ++i )
260 {
261 ResIndexStream resStream = this->GetIndexStreams( u32(i) );
262 bufferObjects[ i ] = reinterpret_cast<u32>(resStream.ptr());
263
264 if (resStream.GetLocationAddress() != NULL)
265 {
266 resStream.ref().m_MemoryArea = ResIndexStreamData::AREA_NO_MALLOC;
267 continue;
268 }
269
270 u32 size = resStream.GetStreamCount();
271 void* buf = resStream.GetStream();
272
273 // 頂点インデックスバッファのメモリへの読み込み指定
274 int loadFlag = resStream.GetLocationFlag();
275
276 // デフォルトは、FCRAM から NO_COPY。
277 if (loadFlag == 0)
278 {
279 loadFlag = NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP;
280 }
281
282 BufferData( bufferObjects[ i ], resStream, loadFlag );
283 }
284 NW_GL_ASSERT();
285 }
286
287
288 //----------------------------------------
289 void
Cleanup()290 ResShape::Cleanup()
291 {
292 switch ( this->ref().typeInfo )
293 {
294 case ResSeparateDataShape::TYPE_INFO:
295 {
296 sShape_CleanupTable[0]( *this );
297 this->SetFlags(ut::DisableFlag(this->GetFlags(), ResShape::FLAG_HAS_BEEN_SETUP));
298 }
299 break;
300 case ResParticleShape::TYPE_INFO:
301 {
302 sShape_CleanupTable[1]( *this );
303 this->SetFlags(ut::DisableFlag(this->GetFlags(), ResShape::FLAG_HAS_BEEN_SETUP));
304 }
305 break;
306 default:
307 {
308 }
309 }
310 }
311
312 //----------------------------------------
313 static void
ResShape_Cleanup(ResShape resShape)314 ResShape_Cleanup(ResShape resShape)
315 {
316 s32 primSetNum = resShape.GetPrimitiveSetsCount();
317
318 for ( s32 i = 0; i < primSetNum; ++i )
319 {
320 resShape.GetPrimitiveSets( i ).Cleanup();
321 }
322 }
323
324 //----------------------------------------
325 static void
ResSeparateDataShape_Cleanup(ResShape resShape)326 ResSeparateDataShape_Cleanup(ResShape resShape)
327 {
328 ResSeparateDataShape resSeparateShape = ResStaticCast<ResSeparateDataShape>( resShape );
329
330 s32 vtxAttrNum = resSeparateShape.GetVertexAttributesCount();
331
332 for ( s32 i = 0; i < vtxAttrNum; ++ i )
333 {
334 resSeparateShape.GetVertexAttributes( i ).Cleanup();
335 }
336
337 ResShape_Cleanup( resShape );
338 }
339
340 //----------------------------------------
341 static void
ResParticleShape_Cleanup(ResShape resShape)342 ResParticleShape_Cleanup(ResShape resShape)
343 {
344 ResParticleShape resParticleShape = ResStaticCast<ResParticleShape>( resShape );
345 }
346
347
348 //------------------------------------------------------------------------------
349 void
Cleanup()350 ResPrimitiveSet::Cleanup()
351 {
352 NW_ASSERT( this->IsValid() );
353
354 ResPrimitiveArray primitiveArray = this->GetPrimitives();
355
356 for (ResPrimitiveArray::iterator it = primitiveArray.begin(); it != primitiveArray.end(); ++it)
357 {
358 (*it).Cleanup();
359 }
360 }
361
362
363 //------------------------------------------------------------------------------
364 void
Cleanup()365 ResPrimitive::Cleanup()
366 {
367 NW_ASSERT( this->IsValid() );
368
369 u32 streamNum = this->GetIndexStreamsCount();
370
371 GLuint* bufferObjects = reinterpret_cast<GLuint*>( this->GetBufferObjects() );
372
373 for ( uint i = 0; i < streamNum; ++i )
374 {
375 ResIndexStream resStream = this->GetIndexStreams( u32(i) );
376 if (resStream.IsValid() && resStream.ref().m_CommandCache)
377 {
378 CommandCacheManager::Free(resStream.ref().m_CommandCache);
379 resStream.ref().m_CommandCache = NULL;
380 resStream.ref().m_CommandCacheSize = 0;
381 }
382
383 DeleteBuffer( bufferObjects[ i ], resStream );
384 }
385
386 std::memset( bufferObjects, 0, sizeof(GLuint) * streamNum );
387 }
388
389 } /* namespace res */
390 } /* namespace gfx */
391 } /* namespace nw */
392
393