mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-08-03 10:47:39 -04:00
PS2: Work on supporting 4HL/4HH pixel formats
This commit is contained in:
parent
b0f2597e38
commit
3ff478f3ef
@ -182,22 +182,21 @@ void Gfx_VRAM_Reset(void) {
|
||||
vram_pointer = 0;
|
||||
}
|
||||
|
||||
static int AllocVRAM(int width, int height, int psm) {
|
||||
// Returns size in words
|
||||
static int VRAM_Size(int width, int height, int psm) {
|
||||
width = ALIGNUP(width, 64);
|
||||
|
||||
// Returns size in words
|
||||
// TODO move the >> out ?
|
||||
switch (psm)
|
||||
{
|
||||
case GS_PSM_4:
|
||||
return width * (height >> 3);
|
||||
case GS_PSM_8:
|
||||
return width * (height >> 2);
|
||||
case GS_PSM_4:
|
||||
return (width * height) >> 3;
|
||||
case GS_PSM_8:
|
||||
return (width * height) >> 2;
|
||||
case GS_PSM_16:
|
||||
case GS_PSM_16S:
|
||||
case GS_PSMZ_16:
|
||||
case GS_PSMZ_16S:
|
||||
return width * (height >> 1);
|
||||
case GS_PSMZ_16S:
|
||||
return (width * height) >> 1;
|
||||
case GS_PSM_24:
|
||||
case GS_PSM_32:
|
||||
case GS_PSM_8H:
|
||||
@ -211,7 +210,7 @@ static int AllocVRAM(int width, int height, int psm) {
|
||||
}
|
||||
|
||||
int Gfx_VRAM_Alloc(int width, int height, int psm) {
|
||||
int size = AllocVRAM(width, height, psm);
|
||||
int size = VRAM_Size(width, height, psm);
|
||||
int addr = vram_pointer;
|
||||
|
||||
vram_pointer += size;
|
||||
@ -219,7 +218,7 @@ int Gfx_VRAM_Alloc(int width, int height, int psm) {
|
||||
}
|
||||
|
||||
int Gfx_VRAM_AllocPaged(int width, int height, int psm) {
|
||||
int size = AllocVRAM(width, height, psm);
|
||||
int size = VRAM_Size(width, height, psm);
|
||||
int addr = vram_pointer;
|
||||
|
||||
// Align to 2048 words / 8192 bytes (VRAM page alignment)
|
||||
@ -372,11 +371,13 @@ static void ApplyPalette(BitmapCol* palette, int pal_index) {
|
||||
#define TEXMEM_BLOCK_SIZE 64
|
||||
|
||||
#define TEXMEM_MAX_BLOCKS (VRAM_SIZE_WORDS / TEXMEM_BLOCK_SIZE)
|
||||
static cc_uint8 tex_4hl_table[TEXMEM_MAX_BLOCKS / BLOCKS_PER_PAGE];
|
||||
static cc_uint8 tex_4hh_table[TEXMEM_MAX_BLOCKS / BLOCKS_PER_PAGE];
|
||||
static cc_uint8 tex_4HL_table[TEXMEM_MAX_BLOCKS / BLOCKS_PER_PAGE];
|
||||
static cc_uint8 tex_4HH_table[TEXMEM_MAX_BLOCKS / BLOCKS_PER_PAGE];
|
||||
static int texmem_4bpp_blocks;
|
||||
|
||||
static unsigned tex_offset;
|
||||
#define TEXMEM_4BPP_TO_VRAM(block) ((block) * TEXMEM_BLOCK_SIZE)
|
||||
|
||||
static void InitTextureMem(void) {
|
||||
tex_offset = Gfx_VRAM_Alloc(256, 256, GS_PSM_32);
|
||||
|
||||
@ -387,13 +388,31 @@ static void InitTextureMem(void) {
|
||||
/*########################################################################################################################*
|
||||
*---------------------------------------------------------Textures--------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
typedef struct CCTexture_ {
|
||||
struct GPUTexture {
|
||||
cc_uint16 width, height; // 4 bytes
|
||||
cc_uint32 padding; // 4 bytes
|
||||
cc_uint16 base, blocks; // 4 bytes
|
||||
cc_uint16 log2_w, log2_h; // 4 bytes
|
||||
cc_uint16 format, pal_index; // 4 bytes
|
||||
BitmapCol pixels[]; // must be aligned to 16 bytes
|
||||
} CCTexture;
|
||||
};
|
||||
#define GS_TEXTURE_STRIDE(tex) max(64, 1 << (tex)->log2_w)
|
||||
|
||||
static void UploadToVRAM(struct GPUTexture* tex, int dst_addr) {
|
||||
// TODO terrible perf
|
||||
DMAFlushBuffer();
|
||||
dma_wait_fast();
|
||||
|
||||
// 4bpp has extra garbage pixels when odd rows
|
||||
int src_w = tex->width, src_h = tex->height;
|
||||
if (tex->format != GS_PSM_32 && (src_w & 1)) src_w++;
|
||||
|
||||
int dst_stride = GS_TEXTURE_STRIDE(tex);
|
||||
Gfx_TransferPixels(tex->pixels, src_w, src_h,
|
||||
tex->format, dst_addr, dst_stride);
|
||||
|
||||
// TODO terrible perf
|
||||
Q = dma_beg + 1;
|
||||
}
|
||||
|
||||
static void ConvertTexture_Palette(cc_uint8* dst, struct Bitmap* bmp, int rowWidth, BitmapCol* palette, int pal_count) {
|
||||
int width = (bmp->width + 1) >> 1;
|
||||
@ -417,7 +436,7 @@ static int Log2Dimension(int len) { return Math_ilog2(Math_NextPowOf2(len)); }
|
||||
|
||||
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
|
||||
int size = bmp->width * bmp->height * 4;
|
||||
CCTexture* tex = (CCTexture*)memalign(16, 32 + size);
|
||||
struct GPUTexture* tex = (struct GPUTexture*)memalign(16, 32 + size);
|
||||
|
||||
tex->width = bmp->width;
|
||||
tex->height = bmp->height;
|
||||
@ -444,6 +463,32 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
|
||||
tex->format = GS_PSM_4;
|
||||
tex->pal_index = pal_index;
|
||||
ConvertTexture_Palette((cc_uint8*)tex->pixels, bmp, rowWidth, palette, pal_count);
|
||||
|
||||
int size = VRAM_Size(1 << tex->log2_w, max(64, 1 << tex->log2_h), GS_PSM_4HH);
|
||||
// TODO fix properly. alignup instead
|
||||
int blocks = SIZE_TO_BLOCKS(size, TEXMEM_BLOCK_SIZE);
|
||||
tex->blocks = blocks;
|
||||
|
||||
// Try to store entirely in VRAM in upper bits of colour framebuffers
|
||||
int base = blockalloc_alloc(tex_4HL_table, texmem_4bpp_blocks, blocks);
|
||||
if (base >= 0) {
|
||||
tex->base = base;
|
||||
tex->format = GS_PSM_4HL;
|
||||
|
||||
//Platform_Log4("ALLOC to 4HL: %i @ %i (%i X %i)", &base, &blocks, &bmp->width, &bmp->height);
|
||||
UploadToVRAM(tex, TEXMEM_4BPP_TO_VRAM(base));
|
||||
return realloc(tex, sizeof(struct GPUTexture));
|
||||
}
|
||||
|
||||
base = blockalloc_alloc(tex_4HH_table, texmem_4bpp_blocks, blocks);
|
||||
if (base >= 0) {
|
||||
tex->base = base;
|
||||
tex->format = GS_PSM_4HH;
|
||||
|
||||
//Platform_Log4("ALLOC to 4HH: %i @ %i (%i X %i)", &base, &blocks, &bmp->width, &bmp->height);
|
||||
UploadToVRAM(tex, TEXMEM_4BPP_TO_VRAM(base));
|
||||
return realloc(tex, sizeof(struct GPUTexture));
|
||||
}
|
||||
} else {
|
||||
tex->format = GS_PSM_32;
|
||||
CopyPixels(tex->pixels, bmp->width * BITMAPCOLOR_SIZE,
|
||||
@ -453,7 +498,9 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
|
||||
return tex;
|
||||
}
|
||||
|
||||
static void UpdateTextureBuffer(int context, CCTexture* tex, unsigned buf_addr, unsigned buf_stride) {
|
||||
static void UpdateTextureBuffer(int context, struct GPUTexture* tex, unsigned buf_addr) {
|
||||
unsigned buf_stride = GS_TEXTURE_STRIDE(tex);
|
||||
|
||||
PACK_GIFTAG(Q, GIF_SET_TAG(1,0,0,0, GIF_FLG_PACKED, 1), GIF_REG_AD);
|
||||
Q++;
|
||||
|
||||
@ -471,34 +518,30 @@ static void UpdateTextureBuffer(int context, CCTexture* tex, unsigned buf_addr,
|
||||
|
||||
void Gfx_BindTexture(GfxResourceID texId) {
|
||||
if (!texId) texId = white_square;
|
||||
CCTexture* tex = (CCTexture*)texId;
|
||||
struct GPUTexture* tex = (struct GPUTexture*)texId;
|
||||
|
||||
unsigned dst_width = 1 << tex->log2_w;
|
||||
unsigned dst_addr = tex_offset;
|
||||
// GS stores stride in 64 block units
|
||||
// (i.e. gs_stride = real_stride >> 6, so min stride is 64)
|
||||
unsigned dst_stride = max(64, dst_width);
|
||||
int dst_addr = tex_offset;
|
||||
|
||||
// TODO terrible perf
|
||||
DMAFlushBuffer();
|
||||
dma_wait_fast();
|
||||
|
||||
// 4bpp has extra garbage pixels when odd rows
|
||||
int src_w = tex->width, src_h = tex->height;
|
||||
if (tex->format != GS_PSM_32 && (src_w & 1)) src_w++;
|
||||
|
||||
Gfx_TransferPixels(tex->pixels, src_w, src_h,
|
||||
tex->format, dst_addr, dst_stride);
|
||||
|
||||
// TODO terrible perf
|
||||
Q = dma_beg + 1;
|
||||
UpdateTextureBuffer(0, tex, dst_addr, dst_stride);
|
||||
if (tex->format == GS_PSM_4HH || tex->format == GS_PSM_4HL) {
|
||||
// No need to upload to vram
|
||||
dst_addr = TEXMEM_4BPP_TO_VRAM(tex->base);
|
||||
} else {
|
||||
UploadToVRAM(tex, dst_addr);
|
||||
}
|
||||
UpdateTextureBuffer(0, tex, dst_addr);
|
||||
}
|
||||
|
||||
void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||
CCTexture* tex = (CCTexture*)(*texId);
|
||||
struct GPUTexture* tex = (struct GPUTexture*)(*texId);
|
||||
if (!tex) return;
|
||||
|
||||
if (tex->format == GS_PSM_4HH) {
|
||||
blockalloc_dealloc(tex_4HH_table, tex->base, tex->blocks);
|
||||
}
|
||||
if (tex->format == GS_PSM_4HL) {
|
||||
blockalloc_dealloc(tex_4HL_table, tex->base, tex->blocks);
|
||||
}
|
||||
|
||||
if (tex->format != GS_PSM_32) {
|
||||
blockalloc_dealloc(pal_table, tex->pal_index, 1);
|
||||
}
|
||||
@ -508,7 +551,7 @@ void Gfx_DeleteTexture(GfxResourceID* texId) {
|
||||
}
|
||||
|
||||
void Gfx_UpdateTexture(GfxResourceID texId, int x, int y, struct Bitmap* part, int rowWidth, cc_bool mipmaps) {
|
||||
CCTexture* tex = (CCTexture*)texId;
|
||||
struct GPUTexture* tex = (struct GPUTexture*)texId;
|
||||
BitmapCol* dst = (tex->pixels + x) + y * tex->width;
|
||||
|
||||
CopyPixels(dst, tex->width * BITMAPCOLOR_SIZE,
|
||||
|
Loading…
x
Reference in New Issue
Block a user