Merge 7c4769e5ad
into ff559d2a90
This commit is contained in:
commit
1c980afe21
@ -4,6 +4,21 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
VRAM_A = 0x00,
|
||||||
|
VRAM_B = 0x01,
|
||||||
|
VRAM_AB = 0x02
|
||||||
|
} VRAM_ALLOCATOR;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates a 0x80-byte aligned buffer to a specific VRAM bank.
|
||||||
|
* @param bank The bank to which the buffer will reside.
|
||||||
|
* @param size Size of the buffer to allocate.
|
||||||
|
* @return The allocated buffer.
|
||||||
|
*/
|
||||||
|
void* vramBankAlloc(VRAM_ALLOCATOR bank, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocates a 0x80-byte aligned buffer.
|
* @brief Allocates a 0x80-byte aligned buffer.
|
||||||
* @param size Size of the buffer to allocate.
|
* @param size Size of the buffer to allocate.
|
||||||
@ -11,6 +26,15 @@
|
|||||||
*/
|
*/
|
||||||
void* vramAlloc(size_t size);
|
void* vramAlloc(size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocates a buffer aligned to the given size in a specific bank.
|
||||||
|
* @param bank The bank to which the buffer will reside
|
||||||
|
* @param size Size of the buffer to allocate.
|
||||||
|
* @param alignment Alignment to use.
|
||||||
|
* @return The allocated buffer.
|
||||||
|
*/
|
||||||
|
void* vramBankMemAlign(VRAM_ALLOCATOR bank, size_t size, size_t alignment);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Allocates a buffer aligned to the given size.
|
* @brief Allocates a buffer aligned to the given size.
|
||||||
* @param size Size of the buffer to allocate.
|
* @param size Size of the buffer to allocate.
|
||||||
@ -41,7 +65,13 @@ size_t vramGetSize(void* mem);
|
|||||||
void vramFree(void* mem);
|
void vramFree(void* mem);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the current VRAM free space.
|
* @brief Gets the current VRAM bank free space.
|
||||||
* @return The current VRAM free space.
|
* @return The current VRAM bank free space.
|
||||||
*/
|
*/
|
||||||
u32 vramSpaceFree(void);
|
u32 vramBankSpaceFree(VRAM_ALLOCATOR bank);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets the current overall VRAM free space.
|
||||||
|
* @return The current overall VRAM free space.
|
||||||
|
*/
|
||||||
|
u32 vramSpaceFree(void);
|
@ -8,21 +8,28 @@ extern "C"
|
|||||||
#include "mem_pool.h"
|
#include "mem_pool.h"
|
||||||
#include "addrmap.h"
|
#include "addrmap.h"
|
||||||
|
|
||||||
static MemPool sVramPool;
|
static MemPool sVramPoolA;
|
||||||
|
static MemPool sVramPoolB;
|
||||||
|
|
||||||
static bool vramInit()
|
static bool vramInit()
|
||||||
{
|
{
|
||||||
auto blk = MemBlock::Create((u8*)0x1F000000, 0x00600000);
|
auto blkA = MemBlock::Create((u8*)0x1F000000, 0x00300000);
|
||||||
if (blk)
|
if (blkA)
|
||||||
{
|
{
|
||||||
sVramPool.AddBlock(blk);
|
auto blkB = MemBlock::Create((u8*)0x1F300000, 0x00300000);
|
||||||
rbtree_init(&sAddrMap, addrMapNodeComparator);
|
if(blkB)
|
||||||
return true;
|
{
|
||||||
|
sVramPoolA.AddBlock(blkA);
|
||||||
|
sVramPoolB.AddBlock(blkB);
|
||||||
|
rbtree_init(&sAddrMap, addrMapNodeComparator);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
free(blkA);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* vramMemAlign(size_t size, size_t alignment)
|
void* vramBankMemAlign(VRAM_ALLOCATOR bank, size_t size, size_t alignment)
|
||||||
{
|
{
|
||||||
// Enforce minimum alignment
|
// Enforce minimum alignment
|
||||||
if (alignment < 16)
|
if (alignment < 16)
|
||||||
@ -39,27 +46,65 @@ void* vramMemAlign(size_t size, size_t alignment)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Initialize the pool if it is not ready
|
// Initialize the pool if it is not ready
|
||||||
if (!sVramPool.Ready() && !vramInit())
|
if (!sVramPoolA.Ready() && !sVramPoolB.Ready() && !vramInit())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
// Allocate the chunk
|
// Allocate the chunk
|
||||||
MemChunk chunk;
|
MemChunk chunk;
|
||||||
if (!sVramPool.Allocate(chunk, size, shift))
|
int bankSet;
|
||||||
return nullptr;
|
if(bank != VRAM_B)
|
||||||
|
{
|
||||||
|
// Attempt Bank A (for both cases)
|
||||||
|
if(!sVramPoolA.Allocate(chunk, size, shift))
|
||||||
|
{
|
||||||
|
if(bank == VRAM_A)
|
||||||
|
return nullptr;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Attempt Bank B
|
||||||
|
if(!sVramPoolB.Allocate(chunk, size, shift))
|
||||||
|
return nullptr;
|
||||||
|
bankSet = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bankSet = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Attempt Bank B only
|
||||||
|
if(!sVramPoolB.Allocate(chunk, size, shift))
|
||||||
|
return nullptr;
|
||||||
|
bankSet = 1;
|
||||||
|
}
|
||||||
|
|
||||||
auto node = newNode(chunk);
|
auto node = newNode(chunk);
|
||||||
if (!node)
|
if (!node)
|
||||||
{
|
{
|
||||||
sVramPool.Deallocate(chunk);
|
if(bankSet)
|
||||||
|
sVramPoolB.Deallocate(chunk);
|
||||||
|
else
|
||||||
|
sVramPoolA.Deallocate(chunk);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rbtree_insert(&sAddrMap, &node->node));
|
if (rbtree_insert(&sAddrMap, &node->node));
|
||||||
return chunk.addr;
|
return chunk.addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* vramMemAlign(size_t size, size_t alignment)
|
||||||
|
{
|
||||||
|
return vramBankMemAlign(VRAM_AB, size, alignment);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* vramBankAlloc(VRAM_ALLOCATOR bank, size_t size)
|
||||||
|
{
|
||||||
|
return vramBankMemAlign(bank, size, 0x80);
|
||||||
|
}
|
||||||
|
|
||||||
void* vramAlloc(size_t size)
|
void* vramAlloc(size_t size)
|
||||||
{
|
{
|
||||||
return vramMemAlign(size, 0x80);
|
return vramBankMemAlign(VRAM_AB, size, 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* vramRealloc(void* mem, size_t size)
|
void* vramRealloc(void* mem, size_t size)
|
||||||
@ -80,13 +125,30 @@ void vramFree(void* mem)
|
|||||||
if (!node) return;
|
if (!node) return;
|
||||||
|
|
||||||
// Free the chunk
|
// Free the chunk
|
||||||
sVramPool.Deallocate(node->chunk);
|
if((u32)mem < 0x1F300000)
|
||||||
|
sVramPoolA.Deallocate(node->chunk);
|
||||||
|
else
|
||||||
|
sVramPoolB.Deallocate(node->chunk);
|
||||||
|
|
||||||
// Free the node
|
// Free the node
|
||||||
delNode(node);
|
delNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 vramBankSpaceFree(VRAM_ALLOCATOR bank)
|
||||||
|
{
|
||||||
|
if(bank != VRAM_B)
|
||||||
|
{
|
||||||
|
u32 space = sVramPoolA.GetFreeSpace();
|
||||||
|
if(bank == VRAM_A)
|
||||||
|
return space;
|
||||||
|
else
|
||||||
|
return space + sVramPoolB.GetFreeSpace();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return sVramPoolB.GetFreeSpace();
|
||||||
|
}
|
||||||
|
|
||||||
u32 vramSpaceFree()
|
u32 vramSpaceFree()
|
||||||
{
|
{
|
||||||
return sVramPool.GetFreeSpace();
|
return sVramPoolA.GetFreeSpace() + sVramPoolB.GetFreeSpace();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user