1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_ResVertex.cpp
4
5 Copyright (C)2009-2011 Nintendo/HAL Laboratory, Inc. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain proprietary
8 information of Nintendo and/or its licensed developers and are protected by
9 national and international copyright laws. They may not be disclosed to third
10 parties or copied or duplicated in any form, in whole or in part, without the
11 prior written consent of Nintendo.
12
13 The content herein is highly confidential and should be handled accordingly.
14
15 $Revision: $
16 *---------------------------------------------------------------------------*/
17
18 #include "../precompiled.h"
19
20 #include <nw/ut/ut_ResUtil.h>
21 #include <nw/ut/ut_ResDictionary.h>
22 #include <nw/gfx/gfx_SceneObject.h>
23 #include <nw/gfx/res/gfx_ResVertex.h>
24 #include <nw/gfx/gfx_Common.h>
25 #include <GLES2/gl2.h>
26
27 #include <nn/gx.h>
28
29 namespace nw {
30 namespace gfx {
31 namespace res {
32
33 //---------------------------------------------------------------------------
34 //! @brief 必要であれば頂点バッファのコピー用のメモリを確保し、転送をおこないます。
35 //!
36 //! @param[in] bufferID メモリ確保用の頂点バッファIDです。
37 //! @param[in] resStream 頂点ストリームリソースです。
38 //! @param[in] loadFlag 頂点バッファの配置メモリフラグです。
39 //---------------------------------------------------------------------------
40 static void
BufferData(u32 bufferID,ResVertexStreamBase resStream,u32 loadFlag)41 BufferData( u32 bufferID, ResVertexStreamBase resStream, u32 loadFlag )
42 {
43 u32 size = resStream.GetStreamCount();
44 GLenum transtype = loadFlag & 0xFFFF0000;
45 void* address = NULL;
46 const u32 NN_GX_MEM_MASK = 0x00030000;
47
48 switch (transtype)
49 {
50 case (NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP):
51 nngxUpdateBuffer( resStream.GetStream(), size );
52 break;
53
54 case (NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP):
55 case (NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP):
56 {
57 GLuint area = (transtype & NN_GX_MEM_MASK);
58 address = __dmpgl_allocator(area, NN_GX_MEM_VERTEXBUFFER, bufferID, size);
59 nngxAddVramDmaCommand( resStream.GetStream(), address, size );
60
61 resStream.SetLocationAddress( address );
62 resStream.ref().m_MemoryArea = area;
63 }
64 break;
65
66 case (NN_GX_MEM_FCRAM | GL_COPY_FCRAM_DMP):
67 {
68 address = __dmpgl_allocator(NN_GX_MEM_FCRAM, NN_GX_MEM_VERTEXBUFFER, bufferID, size);
69 nw::os::MemCpy( address, resStream.GetStream(), size );
70 nngxUpdateBuffer( address, size );
71
72 resStream.SetLocationAddress( address );
73 resStream.ref().m_MemoryArea = NN_GX_MEM_FCRAM;
74 }
75 break;
76
77 case (NN_GX_MEM_VRAMA | GL_COPY_FCRAM_DMP):
78 case (NN_GX_MEM_VRAMB | GL_COPY_FCRAM_DMP):
79 NW_FATAL_ERROR("GL_COPY_DMA is not supported!");
80 break;
81
82 default:
83 break;
84 }
85 }
86
87 static void
DeleteBuffer(u32 bufferID,ResVertexStreamBase resStream)88 DeleteBuffer( u32 bufferID, ResVertexStreamBase resStream )
89 {
90 GLuint area = resStream.ref().m_MemoryArea;
91
92 if (area != ResVertexStreamBaseData::AREA_NO_MALLOC)
93 {
94 void* address = reinterpret_cast<void*>( resStream.GetLocationAddress() );
95 __dmpgl_deallocator( area, NN_GX_MEM_VERTEXBUFFER, bufferID, address );
96 resStream.SetLocationAddress( static_cast<u32>(NULL) );
97 }
98 }
99
100
101 //-----------------------------------------------------------------------------
102 void
Setup()103 ResVertexAttribute::Setup()
104 {
105 NW_ASSERT( this->IsValid() );
106
107 if ( this->GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM )
108 {
109 ResStaticCast<ResVertexParamAttribute>( *this ).Setup();
110 }
111 else if ( this->GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE )
112 {
113 ResStaticCast<ResInterleavedVertexStream>( *this ).Setup();
114 }
115 else
116 {
117 ResStaticCast<ResVertexStream>( *this ).Setup();
118 }
119 }
120
121 //-----------------------------------------------------------------------------
122 void
Cleanup()123 ResVertexAttribute::Cleanup()
124 {
125 NW_ASSERT( this->IsValid() );
126
127 if ( this->GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM )
128 {
129 ResStaticCast<ResVertexParamAttribute>( *this ).Cleanup();
130 }
131 else if ( this->GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE )
132 {
133 ResStaticCast<ResInterleavedVertexStream>(*this).Cleanup();
134 }
135 else
136 {
137 ResStaticCast<ResVertexStream>(*this).Cleanup();
138 }
139 }
140
141 //----------------------------------------------------------
142 u32
GetVertexCount()143 ResVertexAttribute::GetVertexCount()
144 {
145 NW_ASSERT( this->IsValid() );
146
147 if ( this->GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM )
148 {
149 // 頂点を持っていないので 0 を返す。
150 return 0;
151 }
152 else if ( this->GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE )
153 {
154 ResInterleavedVertexStream stream =
155 ResStaticCast<ResInterleavedVertexStream>( *this );
156 return stream.GetStreamCount() / stream.GetStride();
157 }
158 else
159 {
160 ResVertexStream stream = ResStaticCast<ResVertexStream>( *this );
161
162 size_t sizePerVertex;
163 switch (stream.GetFormatType())
164 {
165 case GL_BYTE:
166 case GL_UNSIGNED_BYTE:
167 sizePerVertex = 1;
168 break;
169 case GL_SHORT:
170 // case GL_UNSIGNED_SHORT: 対応していない。
171 sizePerVertex = 2;
172 break;
173 case GL_INT:
174 case GL_UNSIGNED_INT:
175 case GL_FLOAT:
176 sizePerVertex = 4;
177 break;
178 default:
179 NW_FATAL_ERROR("Unsupported format\n");
180 }
181
182 sizePerVertex *= stream.GetDimension();
183
184 return stream.GetStreamCount() / sizePerVertex;
185 }
186 }
187
188 //-----------------------------------------------------------------------------
189 void
Setup()190 ResVertexParamAttribute::Setup()
191 {
192 }
193
194 //-----------------------------------------------------------------------------
195 void
Cleanup()196 ResVertexParamAttribute::Cleanup()
197 {
198 }
199
200 //-----------------------------------------------------------------------------
201 void
Setup()202 ResVertexStream::Setup()
203 {
204 if (ref().m_BufferObject)
205 {
206 return;
207 }
208
209 ResVertexStreamData* dataPtr = ptr();
210 u32 bufferID = reinterpret_cast<u32>( dataPtr );
211 this->ref().m_BufferObject = bufferID;
212
213 // 既にアドレスが設定されている場合にはデータのコピーをおこなわない。
214 if (this->GetLocationAddress() != NULL)
215 {
216 ref().m_MemoryArea = ResVertexStreamBaseData::AREA_NO_MALLOC;
217 return;
218 }
219
220 u32 size = this->GetStreamCount();
221
222 // 頂点バッファのメモリへの読み込み指定
223 int loadFlag = this->GetLocationFlag();
224
225 // デフォルトは、FCRAM から NO_COPY。
226 if (loadFlag == 0)
227 {
228 loadFlag = NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP;
229 }
230
231 BufferData( bufferID, *this, loadFlag );
232 }
233
234 //-----------------------------------------------------------------------------
235 void
Cleanup()236 ResVertexStream::Cleanup()
237 {
238 GLuint bufferID = this->GetBufferObject();
239
240 if ( bufferID == 0 )
241 {
242 return;
243 }
244
245 DeleteBuffer( bufferID, *this );
246 this->SetBufferObject( 0 );
247 }
248
249 //-----------------------------------------------------------------------------
250 void
Setup()251 ResInterleavedVertexStream::Setup()
252 {
253 if (ref().m_BufferObject)
254 {
255 return;
256 }
257
258 u32 bufferID = reinterpret_cast<u32>( this->ptr() );
259 this->ref().m_BufferObject = bufferID;
260
261 // 既にアドレスが設定されている場合にはデータのコピーをおこなわない。
262 if ( this->GetLocationAddress() != NULL )
263 {
264 ref().m_MemoryArea = ResVertexStreamBaseData::AREA_NO_MALLOC;
265 return;
266 }
267
268 u32 size = this->GetStreamCount();
269
270 // 頂点バッファのメモリへの読み込み指定
271 int loadFlag = this->GetLocationFlag();
272
273 // デフォルトは、FCRAM から NO_COPY。
274 if (loadFlag == 0)
275 {
276 loadFlag = NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP;
277 }
278
279 BufferData( bufferID, *this, loadFlag );
280 }
281
282 //-----------------------------------------------------------------------------
283 void
Cleanup()284 ResInterleavedVertexStream::Cleanup()
285 {
286 GLuint bufferID = this->GetBufferObject();
287
288 if ( bufferID == 0 )
289 {
290 return;
291 }
292
293 DeleteBuffer( bufferID, *this );
294 this->SetBufferObject( 0 );
295 }
296
297
298 //----------------------------------------------------------
299 u32
GetVertexCount()300 ResIndexStream::GetVertexCount()
301 {
302 NW_ASSERT( this->IsValid() );
303
304 size_t sizePerVertex;
305 switch (this->GetFormatType())
306 {
307 case GL_BYTE:
308 case GL_UNSIGNED_BYTE:
309 sizePerVertex = 1;
310 break;
311 case GL_SHORT:
312 // case GL_UNSIGNED_SHORT: 対応していない。
313 sizePerVertex = 2;
314 break;
315 case GL_INT:
316 case GL_UNSIGNED_INT:
317 case GL_FLOAT:
318 sizePerVertex = 4;
319 break;
320 default:
321 NW_FATAL_ERROR("Unsupported format\n");
322 }
323
324 return this->GetStreamCount() / sizePerVertex;
325 }
326
327 } /* namespace res */
328 } /* namespace gfx */
329 } /* namespace nw */
330
331