1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: demo_GraphicsMemoryAllocator.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: 25819 $
14 *---------------------------------------------------------------------------*/
15
16 #include <nw/ut/ut_Preprocessor.h>
17 #include <nw/demo/demo_GraphicsMemoryAllocator.h>
18 #include <nn.h>
19 #include <nn/gx.h>
20
21 namespace nw
22 {
23 namespace demo
24 {
25
26 const int ALIGNMENT_SYSTEM_BUFFER = 4;
27 const int ALIGNMENT_VERTEX = 4;
28 const int ALIGNMENT_TEXTURE = 128;
29 const int ALIGNMENT_RENDER_BUFFER = 64; // 24ビットフォーマット(RGB8,D24)のバッファは96Byteアラインが必要
30 const int ALIGNMENT_DISPLAY_BUFFER = 16;
31 const int ALIGNMENT_3D_COMMAND_BUFFER = 16;
32
33 //--------------------------------------------------------------------------
34 void
Initialize(os::IAllocator * allocator)35 GraphicsMemoryAllocator::Initialize(os::IAllocator* allocator)
36 {
37 m_CurrentAddrVramA = nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMA);
38 m_CurrentAddrVramB = nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMB);
39
40 m_DeviceMemoryAllocator = allocator;
41
42 m_Initialized = true;
43 }
44
45 //--------------------------------------------------------------------------
46 void
Finalize(void)47 GraphicsMemoryAllocator::Finalize(void)
48 {
49 m_CurrentAddrVramA = nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMA);
50 m_CurrentAddrVramB = nn::gx::GetVramStartAddr(nn::gx::MEM_VRAMB);
51 }
52
53 //--------------------------------------------------------------------------
54 void*
Allocate(GLenum area,GLenum aim,GLuint id,GLsizei size)55 GraphicsMemoryAllocator::Allocate(GLenum area, GLenum aim, GLuint id, GLsizei size)
56 {
57 NW_UNUSED_VARIABLE(id);
58
59 NW_ASSERTMSG (m_Initialized, "[DEMO:GraphicsMemoryAllocator] not initialized.\n");
60
61 if (size == 0) { return 0; }
62
63 // 現在のところ、VRAM-A or VRAM-B にCTR のシステムのための予約領域がどの程度置かれるのか不明
64
65 // VRAM にアロケートする場合は、簡単のために VRAM をスタックのように扱う
66 // さらに、断片化には対処しない
67 // 断片化に対処するには、確保成功時に area, aim, id といった確保したメモリに対する情報を
68 // のちのデアロケートのために保持しておく必要があるはず
69
70 int addrAlign = 8;
71 void* resultAddr = NULL;
72
73 // 各データの配置に対するアラインメントの制約を考慮
74 switch (aim)
75 {
76 case NN_GX_MEM_SYSTEM:
77 addrAlign = ALIGNMENT_SYSTEM_BUFFER;
78 break;
79 case NN_GX_MEM_TEXTURE:
80 addrAlign = ALIGNMENT_TEXTURE;
81 break;
82 case NN_GX_MEM_VERTEXBUFFER:
83 addrAlign = ALIGNMENT_VERTEX;
84 break;
85 case NN_GX_MEM_RENDERBUFFER:
86 addrAlign = ALIGNMENT_RENDER_BUFFER;
87 break;
88 case NN_GX_MEM_DISPLAYBUFFER:
89 addrAlign = ALIGNMENT_DISPLAY_BUFFER;
90 break;
91 case NN_GX_MEM_COMMANDBUFFER:
92 addrAlign = ALIGNMENT_3D_COMMAND_BUFFER;
93 break;
94 default:
95 NW_FATAL_ERROR("[DEMO:GraphicsMemoryAllocator] invalid parameter.(0x%X)\n", aim);
96 break;
97 }
98
99
100 switch (area)
101 {
102 case NN_GX_MEM_FCRAM:
103 // FCRAM の場合は SDK サポートの拡張ヒープから割り当てるため管理しない
104 resultAddr = m_DeviceMemoryAllocator->Alloc(size, addrAlign);
105 break;
106 case NN_GX_MEM_VRAMA:
107 {
108 if (MathRoundup(m_CurrentAddrVramA, addrAlign) + size > nn::gx::GetVramEndAddr(nn::gx::MEM_VRAMA))
109 {
110 NW_FATAL_ERROR("[DEMO:GraphicsMemoryAllocator] lack of resource on VRAM-A.\n");
111 }
112 m_CurrentAddrVramA = MathRoundup(m_CurrentAddrVramA, addrAlign);
113 resultAddr = reinterpret_cast<void*>(m_CurrentAddrVramA);
114 m_CurrentAddrVramA += size;
115 }
116 break;
117 case NN_GX_MEM_VRAMB:
118 {
119 if (MathRoundup(m_CurrentAddrVramB, addrAlign) + size > nn::gx::GetVramEndAddr(nn::gx::MEM_VRAMB))
120 {
121 NW_FATAL_ERROR("[DEMO:GraphicsMemoryAllocator] lack of resource on VRAM-B.\n");
122 }
123 m_CurrentAddrVramB = MathRoundup(m_CurrentAddrVramB, addrAlign);
124 resultAddr = reinterpret_cast<void*>(m_CurrentAddrVramB);
125 m_CurrentAddrVramB += size;
126 }
127 break;
128 default:
129 // 通常の使用ではまずありえないため FATAL_ERROR
130 NW_FATAL_ERROR("[DEMO:GraphicsMemoryAllocator] invalid parameter.(0x%X)\n", area);
131 break;
132 }
133
134 NW_NULL_ASSERT(resultAddr);
135
136 return resultAddr;
137 }
138
139 //--------------------------------------------------------------------------
140 void
Deallocate(GLenum area,GLenum aim,GLuint id,void * addr)141 GraphicsMemoryAllocator::Deallocate(GLenum area, GLenum aim, GLuint id, void* addr)
142 {
143 NW_ASSERTMSG (m_Initialized, "[DEMO:GraphicsMemoryAllocator] not initialized.\n");
144 NW_UNUSED_VARIABLE(aim);
145 NW_UNUSED_VARIABLE(id);
146
147 switch (area)
148 {
149 case NN_GX_MEM_FCRAM:
150 m_DeviceMemoryAllocator->Free(addr);
151 break;
152
153 default:
154 // TODO: グラフィックスメモリアロケーターのデアロケータを実装する
155 break;
156 }
157 }
158
159
160 } // namespace demo
161 } // namespace nw
162