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