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