1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_ResVertex.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: 16687 $
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_ResVertex.h>
22 #include <nw/gfx/gfx_Common.h>
23 #include <GLES2/gl2.h>
24
25 #include <nn/gx.h>
26
27 namespace nw {
28 namespace gfx {
29 namespace res {
30
31 //---------------------------------------------------------------------------
32 //! @brief 必要であれば頂点バッファのコピー用のメモリを確保し、転送をおこないます。
33 //!
34 //! @param[in] bufferID メモリ確保用の頂点バッファIDです。
35 //! @param[in] resStream 頂点ストリームリソースです。
36 //! @param[in] loadFlag 頂点バッファの配置メモリフラグです。
37 //---------------------------------------------------------------------------
38 static void
BufferData(u32 bufferID,ResVertexStreamBase resStream,u32 loadFlag)39 BufferData( u32 bufferID, ResVertexStreamBase resStream, u32 loadFlag )
40 {
41 u32 size = resStream.GetStreamCount();
42 GLenum transtype = loadFlag & 0xFFFF0000;
43 void* address = NULL;
44 const u32 NN_GX_MEM_MASK = 0x00030000;
45
46 switch (transtype)
47 {
48 case (NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP):
49 nngxUpdateBuffer( resStream.GetStream(), size );
50 break;
51
52 case (NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP):
53 case (NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP):
54 {
55 GLuint area = (transtype & NN_GX_MEM_MASK);
56 address = __dmpgl_allocator(area, NN_GX_MEM_VERTEXBUFFER, bufferID, size);
57 nngxUpdateBuffer( resStream.GetStream(), size );
58 internal::nwgfxAddVramDmaCommand( resStream.GetStream(), address, size );
59
60 resStream.SetLocationAddress( address );
61 resStream.ref().m_MemoryArea = area;
62 }
63 break;
64
65 case (NN_GX_MEM_FCRAM | GL_COPY_FCRAM_DMP):
66 {
67 address = __dmpgl_allocator(NN_GX_MEM_FCRAM, NN_GX_MEM_VERTEXBUFFER, bufferID, size);
68 nw::os::MemCpy( address, resStream.GetStream(), size );
69 nngxUpdateBuffer( address, size );
70
71 resStream.SetLocationAddress( address );
72 resStream.ref().m_MemoryArea = NN_GX_MEM_FCRAM;
73 }
74 break;
75
76 case (NN_GX_MEM_VRAMA | GL_COPY_FCRAM_DMP):
77 case (NN_GX_MEM_VRAMB | GL_COPY_FCRAM_DMP):
78 NW_FATAL_ERROR("GL_COPY_DMA is not supported!");
79 break;
80
81 default:
82 break;
83 }
84 }
85
86 static void
DeleteBuffer(u32 bufferID,ResVertexStreamBase resStream)87 DeleteBuffer( u32 bufferID, ResVertexStreamBase resStream )
88 {
89 GLuint area = resStream.ref().m_MemoryArea;
90
91 if (area != ResVertexStreamBaseData::AREA_NO_MALLOC)
92 {
93 void* address = reinterpret_cast<void*>( resStream.GetLocationAddress() );
94 __dmpgl_deallocator( area, NN_GX_MEM_VERTEXBUFFER, bufferID, address );
95 resStream.SetLocationAddress( static_cast<u32>(NULL) );
96 }
97 }
98
99
100 //-----------------------------------------------------------------------------
101 void
Setup()102 ResVertexAttribute::Setup()
103 {
104 NW_ASSERT( this->IsValid() );
105
106 if ( this->GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM )
107 {
108 ResStaticCast<ResVertexParamAttribute>( *this ).Setup();
109 }
110 else if ( this->GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE )
111 {
112 ResStaticCast<ResInterleavedVertexStream>( *this ).Setup();
113 }
114 else
115 {
116 ResStaticCast<ResVertexStream>( *this ).Setup();
117 }
118 }
119
120 //-----------------------------------------------------------------------------
121 void
Cleanup()122 ResVertexAttribute::Cleanup()
123 {
124 NW_ASSERT( this->IsValid() );
125
126 if ( this->GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM )
127 {
128 ResStaticCast<ResVertexParamAttribute>( *this ).Cleanup();
129 }
130 else if ( this->GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE )
131 {
132 ResStaticCast<ResInterleavedVertexStream>(*this).Cleanup();
133 }
134 else
135 {
136 ResStaticCast<ResVertexStream>(*this).Cleanup();
137 }
138 }
139
140 //-----------------------------------------------------------------------------
141 void
Setup()142 ResVertexParamAttribute::Setup()
143 {
144 }
145
146 //-----------------------------------------------------------------------------
147 void
Cleanup()148 ResVertexParamAttribute::Cleanup()
149 {
150 }
151
152 //-----------------------------------------------------------------------------
153 void
Setup()154 ResVertexStream::Setup()
155 {
156 if (ref().m_BufferObject)
157 {
158 return;
159 }
160
161 ResVertexStreamData* dataPtr = ptr();
162 u32 bufferID = reinterpret_cast<u32>( dataPtr );
163 this->ref().m_BufferObject = bufferID;
164
165 // 既にアドレスが設定されている場合にはデータのコピーをおこなわない。
166 if (this->GetLocationAddress() != NULL)
167 {
168 ref().m_MemoryArea = ResVertexStreamBaseData::AREA_NO_MALLOC;
169 return;
170 }
171
172 u32 size = this->GetStreamCount();
173
174 // 頂点バッファのメモリへの読み込み指定
175 int loadFlag = this->GetLocationFlag();
176
177 // デフォルトは、FCRAM から NO_COPY。
178 if (loadFlag == 0)
179 {
180 loadFlag = NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP;
181 }
182
183 BufferData( bufferID, *this, loadFlag );
184 }
185
186 //-----------------------------------------------------------------------------
187 void
Cleanup()188 ResVertexStream::Cleanup()
189 {
190 GLuint bufferID = this->GetBufferObject();
191
192 if ( bufferID == 0 )
193 {
194 return;
195 }
196
197 DeleteBuffer( bufferID, *this );
198 this->SetBufferObject( 0 );
199 }
200
201 //-----------------------------------------------------------------------------
202 void
Setup()203 ResInterleavedVertexStream::Setup()
204 {
205 if (ref().m_BufferObject)
206 {
207 return;
208 }
209
210 u32 bufferID = reinterpret_cast<u32>( this->ptr() );
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 ResInterleavedVertexStream::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 } /* namespace res */
250 } /* namespace gfx */
251 } /* namespace nw */
252
253