/*---------------------------------------------------------------------------* Project: NintendoWare File: demo_GraphicsMemoryAllocator.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: 25820 $ *---------------------------------------------------------------------------*/ #include #include #include #include namespace nw { namespace demo { const int ALIGNMENT_SYSTEM_BUFFER = 4; const int ALIGNMENT_VERTEX = 4; const int ALIGNMENT_TEXTURE = 128; const int ALIGNMENT_RENDER_BUFFER = 64; // 24ビットフォーマット(RGB8,D24)のバッファは96Byteアラインが必要 const int ALIGNMENT_DISPLAY_BUFFER = 16; const int ALIGNMENT_3D_COMMAND_BUFFER = 16; //-------------------------------------------------------------------------- void GraphicsMemoryAllocator::Initialize(os::IAllocator* allocator) { m_CurrentAddrVramA = nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMA); m_CurrentAddrVramB = nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMB); m_DeviceMemoryAllocator = allocator; m_Initialized = true; } //-------------------------------------------------------------------------- void GraphicsMemoryAllocator::Finalize(void) { m_CurrentAddrVramA = nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMA); m_CurrentAddrVramB = nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMB); } //-------------------------------------------------------------------------- void* GraphicsMemoryAllocator::Allocate(GLenum area, GLenum aim, GLuint id, GLsizei size) { NW_UNUSED_VARIABLE(id); NW_ASSERTMSG (m_Initialized, "[DEMO:GraphicsMemoryAllocator] not initialized.\n"); if (size == 0) { return 0; } // 現在のところ、VRAM-A or VRAM-B にCTR のシステムのための予約領域がどの程度置かれるのか不明 // VRAM にアロケートする場合は、簡単のために VRAM をスタックのように扱う // さらに、断片化には対処しない // 断片化に対処するには、確保成功時に area, aim, id といった確保したメモリに対する情報を // のちのデアロケートのために保持しておく必要があるはず int addrAlign = 8; void* resultAddr = NULL; // 各データの配置に対するアラインメントの制約を考慮 switch (aim) { case NN_GX_MEM_SYSTEM: addrAlign = ALIGNMENT_SYSTEM_BUFFER; break; case NN_GX_MEM_TEXTURE: addrAlign = ALIGNMENT_TEXTURE; break; case NN_GX_MEM_VERTEXBUFFER: addrAlign = ALIGNMENT_VERTEX; break; case NN_GX_MEM_RENDERBUFFER: addrAlign = ALIGNMENT_RENDER_BUFFER; break; case NN_GX_MEM_DISPLAYBUFFER: addrAlign = ALIGNMENT_DISPLAY_BUFFER; break; case NN_GX_MEM_COMMANDBUFFER: addrAlign = ALIGNMENT_3D_COMMAND_BUFFER; break; default: NW_FATAL_ERROR("[DEMO:GraphicsMemoryAllocator] invalid parameter.(0x%X)\n", aim); break; } switch (area) { case NN_GX_MEM_FCRAM: // FCRAM の場合は SDK サポートの拡張ヒープから割り当てるため管理しない resultAddr = m_DeviceMemoryAllocator->Alloc(size, addrAlign); break; case NN_GX_MEM_VRAMA: { if (MathRoundup(m_CurrentAddrVramA, addrAlign) + size > nn::gx::GetVramEndAddr(nn::gx::MEM_VRAMA)) { NW_FATAL_ERROR("[DEMO:GraphicsMemoryAllocator] lack of resource on VRAM-A.\n"); } m_CurrentAddrVramA = MathRoundup(m_CurrentAddrVramA, addrAlign); resultAddr = reinterpret_cast(m_CurrentAddrVramA); m_CurrentAddrVramA += size; } break; case NN_GX_MEM_VRAMB: { if (MathRoundup(m_CurrentAddrVramB, addrAlign) + size > nn::gx::GetVramEndAddr(nn::gx::MEM_VRAMB)) { NW_FATAL_ERROR("[DEMO:GraphicsMemoryAllocator] lack of resource on VRAM-B.\n"); } m_CurrentAddrVramB = MathRoundup(m_CurrentAddrVramB, addrAlign); resultAddr = reinterpret_cast(m_CurrentAddrVramB); m_CurrentAddrVramB += size; } break; default: // 通常の使用ではまずありえないため FATAL_ERROR NW_FATAL_ERROR("[DEMO:GraphicsMemoryAllocator] invalid parameter.(0x%X)\n", area); break; } NW_NULL_ASSERT(resultAddr); return resultAddr; } //-------------------------------------------------------------------------- void GraphicsMemoryAllocator::Deallocate(GLenum area, GLenum aim, GLuint id, void* addr) { NW_ASSERTMSG (m_Initialized, "[DEMO:GraphicsMemoryAllocator] not initialized.\n"); NW_UNUSED_VARIABLE(aim); NW_UNUSED_VARIABLE(id); switch (area) { case NN_GX_MEM_FCRAM: m_DeviceMemoryAllocator->Free(addr); break; default: // TODO: グラフィックスメモリアロケーターのデアロケータを実装する break; } } } // namespace demo } // namespace nw