Consoles: Avoid checking and uploading unused portions of UI textures on some consoles

This commit is contained in:
UnknownShadow200 2025-07-06 09:39:59 +10:00
parent e41c2b15fb
commit ae2d73cf54
8 changed files with 76 additions and 56 deletions

View File

@ -157,8 +157,7 @@ void Context2D_Alloc(struct Context2D* ctx, int width, int height) {
width = Math_NextPowOf2(width); width = Math_NextPowOf2(width);
height = Math_NextPowOf2(height); height = Math_NextPowOf2(height);
} else if (Gfx.NonPowTwoTexturesSupport == GFX_NONPOW2_UPLOAD) { } else if (Gfx.NonPowTwoTexturesSupport == GFX_NONPOW2_UPLOAD) {
/* Can upload texture without needing to pad up to power of two height */ /* Can upload texture without needing to pad up to power of two */
width = Math_NextPowOf2(width);
} }
if (Gfx.MinTexWidth) { width = max(width, Gfx.MinTexWidth); } if (Gfx.MinTexWidth) { width = max(width, Gfx.MinTexWidth); }
@ -326,16 +325,17 @@ void Context2D_MakeTexture(struct Texture* tex, struct Context2D* ctx) {
tex->width = nouv ? ctx->bmp.width : ctx->width; tex->width = nouv ? ctx->bmp.width : ctx->width;
tex->height = nouv ? ctx->bmp.height : ctx->height; tex->height = nouv ? ctx->bmp.height : ctx->height;
tex->uv.u1 = 0.0f; tex->uv.v1 = 0.0f; tex->uv.u1 = 0.0f;
if (Gfx.NonPowTwoTexturesSupport == GFX_NONPOW2_FULL) { tex->uv.v1 = 0.0f;
tex->uv.u2 = 1.0f; tex->uv.u2 = Context2D_CalcUV(ctx->width, ctx->bmp.width);
tex->uv.v2 = 1.0f; tex->uv.v2 = Context2D_CalcUV(ctx->height, ctx->bmp.height);
} else if (Gfx.NonPowTwoTexturesSupport == GFX_NONPOW2_UPLOAD) { }
tex->uv.u2 = (float)ctx->width / (float)ctx->bmp.width;
tex->uv.v2 = (float)ctx->height / (float)Math_NextPowOf2(ctx->bmp.height); float Context2D_CalcUV(int pixels, int axisLen) {
if (Gfx.NonPowTwoTexturesSupport == GFX_NONPOW2_UPLOAD) {
return (float)pixels / (float)Math_NextPowOf2(axisLen);
} else { } else {
tex->uv.u2 = (float)ctx->width / (float)ctx->bmp.width; return (float)pixels / (float)axisLen;
tex->uv.v2 = (float)ctx->height / (float)ctx->bmp.height;
} }
} }

View File

@ -45,6 +45,7 @@ CC_API void Context2D_Wrap(struct Context2D* ctx, struct Bitmap* bmp);
CC_API void Context2D_Free(struct Context2D* ctx); CC_API void Context2D_Free(struct Context2D* ctx);
/* Creates a texture consisting of the pixels from the backing bitmap of the given 2D context */ /* Creates a texture consisting of the pixels from the backing bitmap of the given 2D context */
CC_API void Context2D_MakeTexture(struct Texture* tex, struct Context2D* ctx); CC_API void Context2D_MakeTexture(struct Texture* tex, struct Context2D* ctx);
float Context2D_CalcUV(int pixels, int axisLen);
/* Draws text using the given font at the given coordinates */ /* Draws text using the given font at the given coordinates */
CC_API void Context2D_DrawText(struct Context2D* ctx, struct DrawTextArgs* args, int x, int y); CC_API void Context2D_DrawText(struct Context2D* ctx, struct DrawTextArgs* args, int x, int y);

View File

@ -143,6 +143,7 @@ void Gfx_Create(void) {
vramSetBankE(VRAM_E_TEX_PALETTE); vramSetBankE(VRAM_E_TEX_PALETTE);
Gfx_SetFaceCulling(false); Gfx_SetFaceCulling(false);
Gfx.NonPowTwoTexturesSupport = GFX_NONPOW2_UPLOAD;
} }
cc_bool Gfx_TryRestoreContext(void) { cc_bool Gfx_TryRestoreContext(void) {
@ -349,24 +350,27 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
CCTexture* tex = Mem_TryAllocCleared(1, sizeof(CCTexture)); CCTexture* tex = Mem_TryAllocCleared(1, sizeof(CCTexture));
if (!tex) return 0; if (!tex) return 0;
tex->width = bmp->width; int dst_w = Math_NextPowOf2(bmp->width);
tex->height = bmp->height; int dst_h = Math_NextPowOf2(bmp->height);
tex->width = dst_w;
tex->height = dst_h;
BitmapCol palette[256]; BitmapCol palette[256];
int pal_count = CalcPalette(palette, bmp, rowWidth); int pal_count = CalcPalette(palette, bmp, rowWidth);
int tex_size, tex_fmt; int tex_size, tex_fmt;
if (pal_count <= 4) { if (pal_count <= 4) {
tex_size = bmp->width * bmp->height / 4; // 2 bits per pixel tex_size = dst_w * dst_h / 4; // 2 bits per pixel
tex_fmt = GL_RGB4; tex_fmt = GL_RGB4;
} else if (pal_count <= 16) { } else if (pal_count <= 16) {
tex_size = bmp->width * bmp->height / 2; // 4 bits per pixel tex_size = dst_w * dst_h / 2; // 4 bits per pixel
tex_fmt = GL_RGB16; tex_fmt = GL_RGB16;
} else if (pal_count <= 256) { } else if (pal_count <= 256) {
tex_size = bmp->width * bmp->height; // 8 bits per pixel tex_size = dst_w * dst_h; // 8 bits per pixel
tex_fmt = GL_RGB256; tex_fmt = GL_RGB256;
} else { } else {
tex_size = bmp->width * bmp->height * 2; // 16 bits per pixel tex_size = dst_w * dst_h * 2; // 16 bits per pixel
tex_fmt = GL_RGBA; tex_fmt = GL_RGBA;
} }
@ -384,15 +388,15 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
u32 banks = vramSetPrimaryBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD); u32 banks = vramSetPrimaryBanks(VRAM_A_LCD, VRAM_B_LCD, VRAM_C_LCD, VRAM_D_LCD);
int stride; int stride;
int width = bmp->width, height = bmp->height; int src_w = bmp->width, src_h = bmp->height;
BitmapCol* row = bmp->scan0; BitmapCol* row = bmp->scan0;
if (tex_fmt == GL_RGB4) { if (tex_fmt == GL_RGB4) {
stride = width >> 3; stride = dst_w >> 3;
for (int y = 0; y < height; y++, row += rowWidth) for (int y = 0; y < src_h; y++, row += rowWidth)
{ {
for (int x = 0; x < width; x++) for (int x = 0; x < src_w; x++)
{ {
int idx = FindInPalette(palette, pal_count, row[x]); int idx = FindInPalette(palette, pal_count, row[x]);
@ -405,11 +409,11 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
CopyHWords(tmp, addr + stride * y, stride); CopyHWords(tmp, addr + stride * y, stride);
} }
} else if (tex_fmt == GL_RGB16) { } else if (tex_fmt == GL_RGB16) {
stride = width >> 2; stride = dst_w >> 2;
for (int y = 0; y < height; y++, addr += stride, row += rowWidth) for (int y = 0; y < src_h; y++, addr += stride, row += rowWidth)
{ {
for (int x = 0; x < width; x++) for (int x = 0; x < src_w; x++)
{ {
int idx = FindInPalette(palette, pal_count, row[x]); int idx = FindInPalette(palette, pal_count, row[x]);
@ -422,20 +426,20 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
CopyHWords(tmp, addr, stride); CopyHWords(tmp, addr, stride);
} }
} else if (tex_fmt == GL_RGB256) { } else if (tex_fmt == GL_RGB256) {
stride = width >> 1; stride = dst_w >> 1;
for (int y = 0; y < height; y++, addr += stride, row += rowWidth) for (int y = 0; y < src_h; y++, addr += stride, row += rowWidth)
{ {
for (int x = 0; x < width; x++) for (int x = 0; x < src_w; x++)
{ {
tmp[x] = FindInPalette(palette, pal_count, row[x]); tmp[x] = FindInPalette(palette, pal_count, row[x]);
} }
CopyHWords(tmp, addr, stride); CopyHWords(tmp, addr, stride);
} }
} else { } else {
stride = width; stride = dst_w;
for (int y = 0; y < height; y++, addr += stride, row += rowWidth) for (int y = 0; y < src_h; y++, addr += stride, row += rowWidth)
{ {
CopyHWords(row, addr, stride); CopyHWords(row, addr, stride);
} }
@ -443,8 +447,8 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
vramRestorePrimaryBanks(banks); vramRestorePrimaryBanks(banks);
int sSize = (Math_ilog2(tex->width) - 3) << 20; int sSize = (Math_ilog2(dst_w) - 3) << 20;
int tSize = (Math_ilog2(tex->height) - 3) << 23; int tSize = (Math_ilog2(dst_h) - 3) << 23;
tex->texFormat = (offset >> 3) | sSize | tSize | (tex_fmt << 26) | tex->texFormat = (offset >> 3) | sSize | tSize | (tex_fmt << 26) |
GL_TEXTURE_WRAP_S | GL_TEXTURE_WRAP_T | TEXGEN_TEXCOORD | GL_TEXTURE_COLOR0_TRANSPARENT; GL_TEXTURE_WRAP_S | GL_TEXTURE_WRAP_T | TEXGEN_TEXCOORD | GL_TEXTURE_COLOR0_TRANSPARENT;

View File

@ -260,6 +260,7 @@ void Gfx_Create(void) {
Gfx_RestoreState(); Gfx_RestoreState();
gfx_format = -1; gfx_format = -1;
Gfx.NonPowTwoTexturesSupport = GFX_NONPOW2_UPLOAD;
} }
void Gfx_Free(void) { Gfx_FreeState(); } void Gfx_Free(void) { Gfx_FreeState(); }
@ -608,24 +609,27 @@ static CC_INLINE void TwiddleCalcFactors(unsigned w, unsigned h,
} }
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) { GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
int size = bmp->width * bmp->height * 4; int dst_w = Math_NextPowOf2(bmp->width);
int dst_h = Math_NextPowOf2(bmp->height);
int size = dst_w * dst_h * 4;
CCTexture* tex = (CCTexture*)rsxMemalign(128, 128 + size); CCTexture* tex = (CCTexture*)rsxMemalign(128, 128 + size);
tex->width = bmp->width; tex->width = dst_w;
tex->height = bmp->height; tex->height = dst_h;
cc_uint32* dst = tex->pixels; cc_uint32* dst = tex->pixels;
int width = bmp->width, height = bmp->height; int src_w = bmp->width, src_h = bmp->height;
unsigned maskX, maskY; unsigned maskX, maskY;
unsigned X = 0, Y = 0; unsigned X = 0, Y = 0;
TwiddleCalcFactors(width, height, &maskX, &maskY); TwiddleCalcFactors(dst_w, dst_h, &maskX, &maskY);
for (int y = 0; y < height; y++) for (int y = 0; y < src_h; y++)
{ {
cc_uint32* src = bmp->scan0 + y * rowWidth; cc_uint32* src = bmp->scan0 + y * rowWidth;
X = 0; X = 0;
for (int x = 0; x < width; x++, src++) for (int x = 0; x < src_w; x++, src++)
{ {
dst[X | Y] = *src; dst[X | Y] = *src;
X = (X - maskX) & maskX; X = (X - maskX) & maskX;

View File

@ -401,7 +401,7 @@ void TextAtlas_Make(struct TextAtlas* atlas, const cc_string* chars, struct Font
} }
Context2D_Free(&ctx); Context2D_Free(&ctx);
atlas->uScale = 1.0f / (float)ctx.bmp.width; atlas->uScale = Context2D_CalcUV(1, ctx.bmp.width);
atlas->tex.uv.u2 = atlas->offset * atlas->uScale; atlas->tex.uv.u2 = atlas->offset * atlas->uScale;
atlas->tex.width = atlas->offset; atlas->tex.width = atlas->offset;
} }

View File

@ -754,17 +754,20 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
if (pal_count > 0) ApplyPalette(palette, pal_count, pal_index); if (pal_count > 0) ApplyPalette(palette, pal_count, pal_index);
} }
tex->log2_w = Log2Dimension(bmp->width); int dst_w = Math_NextPowOf2(bmp->width);
tex->log2_h = Log2Dimension(bmp->height); int dst_h = Math_NextPowOf2(bmp->height);
tex->log2_w = Math_ilog2(dst_w);
tex->log2_h = Math_ilog2(dst_h);
if (pal_count > 0) { if (pal_count > 0) {
tex->format = PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_4BPP_PAL(pal_index); tex->format = PVR_TXRFMT_PAL4BPP | PVR_TXRFMT_4BPP_PAL(pal_index);
// 4bpp = 2 pixels in 1 byte // 4bpp = 2 pixels in 1 byte
tex->size = bmp->width * bmp->height / 2; tex->size = dst_w * dst_h / 2;
} else { } else {
tex->format = PVR_TXRFMT_ARGB4444; tex->format = PVR_TXRFMT_ARGB4444;
// 16 bpp = 1 pixel in 2 bytes // 16 bpp = 1 pixel in 2 bytes
tex->size = bmp->width * bmp->height * 2; tex->size = dst_w * dst_h * 2;
} }
tex->data = texmem_alloc(tex->size); tex->data = texmem_alloc(tex->size);

View File

@ -579,6 +579,7 @@ void Gfx_Create(void) {
Gfx_SetDepthTest(true); Gfx_SetDepthTest(true);
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED); Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
Gfx_RestoreState(); Gfx_RestoreState();
Gfx.NonPowTwoTexturesSupport = GFX_NONPOW2_UPLOAD;
} }
void Gfx_Free(void) { void Gfx_Free(void) {
@ -703,21 +704,24 @@ static CC_INLINE void TwiddleCalcFactors(unsigned w, unsigned h,
*---------------------------------------------------------Textures--------------------------------------------------------* *---------------------------------------------------------Textures--------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) { GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
int size = bmp->width * bmp->height * 4; int dst_w = Math_NextPowOf2(bmp->width);
int dst_h = Math_NextPowOf2(bmp->height);
int size = dst_w * dst_h * 4;
struct GPUTexture* tex = GPUTexture_Alloc(size); struct GPUTexture* tex = GPUTexture_Alloc(size);
cc_uint32* dst = tex->data; cc_uint32* dst = tex->data;
int width = bmp->width, height = bmp->height; int src_w = bmp->width, src_h = bmp->height;
unsigned maskX, maskY; unsigned maskX, maskY;
unsigned X = 0, Y = 0; unsigned X = 0, Y = 0;
TwiddleCalcFactors(width, height, &maskX, &maskY); TwiddleCalcFactors(dst_w, dst_h, &maskX, &maskY);
for (int y = 0; y < height; y++) for (int y = 0; y < src_h; y++)
{ {
cc_uint32* src = bmp->scan0 + y * rowWidth; cc_uint32* src = bmp->scan0 + y * rowWidth;
X = 0; X = 0;
for (int x = 0; x < width; x++, src++) for (int x = 0; x < src_w; x++, src++)
{ {
dst[X | Y] = *src; dst[X | Y] = *src;
X = (X - maskX) & maskX; X = (X - maskX) & maskX;
@ -726,7 +730,7 @@ GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags,
} }
sceGxmTextureInitSwizzled(&tex->texture, dst, sceGxmTextureInitSwizzled(&tex->texture, dst,
SCE_GXM_TEXTURE_FORMAT_A8B8G8R8, width, height, 0); SCE_GXM_TEXTURE_FORMAT_A8B8G8R8, dst_w, dst_h, 0);
sceGxmTextureSetUAddrMode(&tex->texture, SCE_GXM_TEXTURE_ADDR_REPEAT); sceGxmTextureSetUAddrMode(&tex->texture, SCE_GXM_TEXTURE_ADDR_REPEAT);
sceGxmTextureSetVAddrMode(&tex->texture, SCE_GXM_TEXTURE_ADDR_REPEAT); sceGxmTextureSetVAddrMode(&tex->texture, SCE_GXM_TEXTURE_ADDR_REPEAT);

View File

@ -118,6 +118,7 @@ void Gfx_Create(void) {
SetupShaders(); SetupShaders();
Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED); Gfx_SetVertexFormat(VERTEX_FORMAT_COLOURED);
ResetState(); ResetState();
Gfx.NonPowTwoTexturesSupport = GFX_NONPOW2_UPLOAD;
// 1x1 dummy white texture // 1x1 dummy white texture
struct Bitmap bmp; struct Bitmap bmp;
@ -174,25 +175,28 @@ static CC_INLINE void TwiddleCalcFactors(unsigned w, unsigned h,
static int Log2Dimension(int len) { return Math_ilog2(Math_NextPowOf2(len)); } 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) { GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, int rowWidth, cc_uint8 flags, cc_bool mipmaps) {
int size = bmp->width * bmp->height * 4; int dst_w = Math_NextPowOf2(bmp->width);
int dst_h = Math_NextPowOf2(bmp->height);
int size = dst_w * dst_h * 4;
CCTexture* tex = Mem_Alloc(1, sizeof(CCTexture), "GPU texture"); CCTexture* tex = Mem_Alloc(1, sizeof(CCTexture), "GPU texture");
tex->pixels = MmAllocateContiguousMemoryEx(size, 0, MAX_RAM_ADDR, 0, PAGE_WRITECOMBINE | PAGE_READWRITE); tex->pixels = MmAllocateContiguousMemoryEx(size, 0, MAX_RAM_ADDR, 0, PAGE_WRITECOMBINE | PAGE_READWRITE);
tex->log2_w = Log2Dimension(bmp->width); tex->log2_w = Math_ilog2(dst_w);
tex->log2_h = Log2Dimension(bmp->height); tex->log2_h = Math_ilog2(dst_h);
cc_uint32* dst = tex->pixels; cc_uint32* dst = tex->pixels;
int width = bmp->width, height = bmp->height; int src_w = bmp->width, src_h = bmp->height;
unsigned maskX, maskY; unsigned maskX, maskY;
unsigned X = 0, Y = 0; unsigned X = 0, Y = 0;
TwiddleCalcFactors(width, height, &maskX, &maskY); TwiddleCalcFactors(dst_w, dst_h, &maskX, &maskY);
for (int y = 0; y < height; y++) for (int y = 0; y < src_h; y++)
{ {
cc_uint32* src = bmp->scan0 + y * rowWidth; cc_uint32* src = bmp->scan0 + y * rowWidth;
X = 0; X = 0;
for (int x = 0; x < width; x++, src++) for (int x = 0; x < src_w; x++, src++)
{ {
dst[X | Y] = *src; dst[X | Y] = *src;
X = (X - maskX) & maskX; X = (X - maskX) & maskX;