/*---------------------------------------------------------------------------* Project: NintendoWare File: gfx_ResVertex.cpp Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 16687 $ *---------------------------------------------------------------------------*/ #include "../precompiled.h" #include #include #include #include #include #include #include namespace nw { namespace gfx { namespace res { //--------------------------------------------------------------------------- //! @brief 必要であれば頂点バッファのコピー用のメモリを確保し、転送をおこないます。 //! //! @param[in] bufferID メモリ確保用の頂点バッファIDです。 //! @param[in] resStream 頂点ストリームリソースです。 //! @param[in] loadFlag 頂点バッファの配置メモリフラグです。 //--------------------------------------------------------------------------- static void BufferData( u32 bufferID, ResVertexStreamBase resStream, u32 loadFlag ) { u32 size = resStream.GetStreamCount(); GLenum transtype = loadFlag & 0xFFFF0000; void* address = NULL; const u32 NN_GX_MEM_MASK = 0x00030000; switch (transtype) { case (NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP): nngxUpdateBuffer( resStream.GetStream(), size ); break; case (NN_GX_MEM_VRAMA | GL_NO_COPY_FCRAM_DMP): case (NN_GX_MEM_VRAMB | GL_NO_COPY_FCRAM_DMP): { GLuint area = (transtype & NN_GX_MEM_MASK); address = __dmpgl_allocator(area, NN_GX_MEM_VERTEXBUFFER, bufferID, size); nngxUpdateBuffer( resStream.GetStream(), size ); internal::nwgfxAddVramDmaCommand( resStream.GetStream(), address, size ); resStream.SetLocationAddress( address ); resStream.ref().m_MemoryArea = area; } break; case (NN_GX_MEM_FCRAM | GL_COPY_FCRAM_DMP): { address = __dmpgl_allocator(NN_GX_MEM_FCRAM, NN_GX_MEM_VERTEXBUFFER, bufferID, size); std::memcpy( address, resStream.GetStream(), size ); nngxUpdateBuffer( address, size ); resStream.SetLocationAddress( address ); resStream.ref().m_MemoryArea = NN_GX_MEM_FCRAM; } break; case (NN_GX_MEM_VRAMA | GL_COPY_FCRAM_DMP): case (NN_GX_MEM_VRAMB | GL_COPY_FCRAM_DMP): NW_FATAL_ERROR("GL_COPY_DMA is not supported!"); break; default: break; } } static void DeleteBuffer( u32 bufferID, ResVertexStreamBase resStream ) { GLuint area = resStream.ref().m_MemoryArea; if (area != ResVertexStreamBaseData::AREA_NO_MALLOC) { void* address = reinterpret_cast( resStream.GetLocationAddress() ); __dmpgl_deallocator( area, NN_GX_MEM_VERTEXBUFFER, bufferID, address ); resStream.SetLocationAddress( static_cast(NULL) ); } } //----------------------------------------------------------------------------- void ResVertexAttribute::Setup() { NW_ASSERT( this->IsValid() ); if ( this->GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM ) { ResStaticCast( *this ).Setup(); } else if ( this->GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE ) { ResStaticCast( *this ).Setup(); } else { ResStaticCast( *this ).Setup(); } } //----------------------------------------------------------------------------- void ResVertexAttribute::Cleanup() { NW_ASSERT( this->IsValid() ); if ( this->GetFlags() & ResVertexAttributeData::FLAG_VERTEX_PARAM ) { ResStaticCast( *this ).Cleanup(); } else if ( this->GetFlags() & ResVertexAttributeData::FLAG_INTERLEAVE ) { ResStaticCast(*this).Cleanup(); } else { ResStaticCast(*this).Cleanup(); } } //----------------------------------------------------------------------------- void ResVertexParamAttribute::Setup() { } //----------------------------------------------------------------------------- void ResVertexParamAttribute::Cleanup() { } //----------------------------------------------------------------------------- void ResVertexStream::Setup() { if (ref().m_BufferObject) { return; } ResVertexStreamData* dataPtr = ptr(); u32 bufferID = reinterpret_cast( dataPtr ); this->ref().m_BufferObject = bufferID; // 既にアドレスが設定されている場合にはデータのコピーをおこなわない。 if (this->GetLocationAddress() != NULL) { ref().m_MemoryArea = ResVertexStreamBaseData::AREA_NO_MALLOC; return; } u32 size = this->GetStreamCount(); // 頂点バッファのメモリへの読み込み指定 int loadFlag = this->GetLocationFlag(); // デフォルトは、FCRAM から NO_COPY。 if (loadFlag == 0) { loadFlag = NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP; } BufferData( bufferID, *this, loadFlag ); } //----------------------------------------------------------------------------- void ResVertexStream::Cleanup() { GLuint bufferID = this->GetBufferObject(); if ( bufferID == 0 ) { return; } DeleteBuffer( bufferID, *this ); this->SetBufferObject( 0 ); } //----------------------------------------------------------------------------- void ResInterleavedVertexStream::Setup() { if (ref().m_BufferObject) { return; } u32 bufferID = reinterpret_cast( this->ptr() ); this->ref().m_BufferObject = bufferID; // 既にアドレスが設定されている場合にはデータのコピーをおこなわない。 if ( this->GetLocationAddress() != NULL ) { ref().m_MemoryArea = ResVertexStreamBaseData::AREA_NO_MALLOC; return; } u32 size = this->GetStreamCount(); // 頂点バッファのメモリへの読み込み指定 int loadFlag = this->GetLocationFlag(); // デフォルトは、FCRAM から NO_COPY。 if (loadFlag == 0) { loadFlag = NN_GX_MEM_FCRAM | GL_NO_COPY_FCRAM_DMP; } BufferData( bufferID, *this, loadFlag ); } //----------------------------------------------------------------------------- void ResInterleavedVertexStream::Cleanup() { GLuint bufferID = this->GetBufferObject(); if ( bufferID == 0 ) { return; } DeleteBuffer( bufferID, *this ); this->SetBufferObject( 0 ); } } /* namespace res */ } /* namespace gfx */ } /* namespace nw */