N64: Add support for non power of two textures for UI texures to squeeze a bit more into the 4 kb TMEM

This commit is contained in:
UnknownShadow200 2023-12-04 20:14:39 +11:00
parent b92327e40c
commit 9661c34b4f
6 changed files with 29 additions and 15 deletions

View File

@ -152,9 +152,11 @@ void Context2D_Alloc(struct Context2D* ctx, int width, int height) {
ctx->height = height; ctx->height = height;
ctx->meta = NULL; ctx->meta = NULL;
/* Allocates a power-of-2 sized bitmap equal to or greater than the given size, and clears it to 0 */ if (!Gfx.SupportsNonPowTwoTextures) {
width = Math_NextPowOf2(width); /* Allocate power-of-2 sized bitmap equal to or greater than the given size */
height = Math_NextPowOf2(height); width = Math_NextPowOf2(width);
height = Math_NextPowOf2(height);
}
ctx->bmp.width = width; ctx->bmp.width = width;
ctx->bmp.height = height; ctx->bmp.height = height;
@ -299,7 +301,7 @@ void Drawer2D_MakeTextTexture(struct Texture* tex, struct DrawTextArgs* args) {
} }
void Context2D_MakeTexture(struct Texture* tex, struct Context2D* ctx) { void Context2D_MakeTexture(struct Texture* tex, struct Context2D* ctx) {
Gfx_RecreateTexture(&tex->ID, &ctx->bmp, 0, false); Gfx_RecreateTexture(&tex->ID, &ctx->bmp, TEXTURE_FLAG_NONPOW2, false);
tex->Width = ctx->width; tex->Width = ctx->width;
tex->Height = ctx->height; tex->Height = ctx->height;

View File

@ -332,7 +332,7 @@ static cc_result ApplySkin(struct Entity* e, struct Bitmap* bmp, struct Stream*
if (e->Model->flags & MODEL_FLAG_CLEAR_HAT) if (e->Model->flags & MODEL_FLAG_CLEAR_HAT)
Entity_ClearHat(bmp, e->SkinType); Entity_ClearHat(bmp, e->SkinType);
Gfx_RecreateTexture(&e->TextureId, bmp, TEXTURE_FLAG_MANAGED, false); e->TextureId = Gfx_CreateTexture(bmp, TEXTURE_FLAG_MANAGED, false);
Entity_SetSkinAll(e, false); Entity_SetSkinAll(e, false);
} }
return 0; return 0;

View File

@ -40,9 +40,12 @@ void Gfx_Create(void);
void Gfx_Free(void); void Gfx_Free(void);
CC_VAR extern struct _GfxData { CC_VAR extern struct _GfxData {
/* Maximum dimensions textures can be created up to. (usually 1024 to 16384) */ /* Maximum dimensions in pixels that a texture can be created up to */
/* NOTE: usually 1024 to 16384 */
int MaxTexWidth, MaxTexHeight; int MaxTexWidth, MaxTexHeight;
float _unused; /* Maximum total size in pixels a texture can consist of */
/* NOTE: Not all graphics backends specify a value for this */
int MaxTexSize;
/* Whether context graphics has been lost (all creation/render calls fail) */ /* Whether context graphics has been lost (all creation/render calls fail) */
cc_bool LostContext; cc_bool LostContext;
/* Whether some textures are created with mipmaps */ /* Whether some textures are created with mipmaps */
@ -53,9 +56,8 @@ CC_VAR extern struct _GfxData {
/* Whether graphics context has been created */ /* Whether graphics context has been created */
cc_bool Created; cc_bool Created;
struct Matrix View, Projection; struct Matrix View, Projection;
/* Maximum size in pixels a texture can consist of */ /* Whether the graphics backend supports non power of two textures */
/* NOTE: Not all graphics backends specify a value for this */ cc_bool SupportsNonPowTwoTextures;
int MaxTexSize;
} Gfx; } Gfx;
extern GfxResourceID Gfx_defaultIb; extern GfxResourceID Gfx_defaultIb;
@ -69,6 +71,8 @@ extern const cc_string Gfx_LowPerfMessage;
#define TEXTURE_FLAG_MANAGED 0x01 #define TEXTURE_FLAG_MANAGED 0x01
/* Texture should allow updating via Gfx_UpdateTexture */ /* Texture should allow updating via Gfx_UpdateTexture */
#define TEXTURE_FLAG_DYNAMIC 0x02 #define TEXTURE_FLAG_DYNAMIC 0x02
/* Texture is deliberately (and not accidentally) being created with non power of two dimensions */
#define TEXTURE_FLAG_NONPOW2 0x04
#define LOWPERF_EXIT_MESSAGE "&eExited reduced performance mode" #define LOWPERF_EXIT_MESSAGE "&eExited reduced performance mode"
@ -77,7 +81,7 @@ void* Gfx_RecreateAndLockVb(GfxResourceID* vb, VertexFormat fmt, int count);
cc_bool Gfx_CheckTextureSize(int width, int height); cc_bool Gfx_CheckTextureSize(int width, int height);
/* Creates a new texture. (and also generates mipmaps if mipmaps) */ /* Creates a new texture. (and also generates mipmaps if mipmaps) */
/* Supported flags: TEXTURE_FLAG_MANAGED, TEXTURE_FLAG_DYNAMIC */ /* See TEXTURE_FLAG values for supported flags */
/* NOTE: Only set mipmaps to true if Gfx_Mipmaps is also true, because whether textures /* NOTE: Only set mipmaps to true if Gfx_Mipmaps is also true, because whether textures
use mipmapping may be either a per-texture or global state depending on the backend */ use mipmapping may be either a per-texture or global state depending on the backend */
CC_API GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps); CC_API GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);

View File

@ -33,6 +33,7 @@ void Gfx_Create(void) {
Gfx.MaxTexSize = 1024; // TMEM only has 4 KB in it Gfx.MaxTexSize = 1024; // TMEM only has 4 KB in it
Gfx.Created = true; Gfx.Created = true;
Gfx.SupportsNonPowTwoTextures = true;
Gfx_RestoreState(); Gfx_RestoreState();
GL_UpdateVsync(); GL_UpdateVsync();
} }
@ -137,9 +138,10 @@ static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_boo
bmp->width * 4); bmp->width * 4);
} }
rdpq_texparms_t params = (rdpq_texparms_t){ rdpq_texparms_t params =
.s.repeats = REPEAT_INFINITE, {
.t.repeats = REPEAT_INFINITE, .s.repeats = (flags & TEXTURE_FLAG_NONPOW2) ? 1 : REPEAT_INFINITE,
.t.repeats = (flags & TEXTURE_FLAG_NONPOW2) ? 1 : REPEAT_INFINITE,
}; };
// rdpq_tex_upload(TILE0, &tex->surface, &params); // rdpq_tex_upload(TILE0, &tex->surface, &params);

View File

@ -36,6 +36,8 @@ void Window_Init(void) {
WindowInfo.Exists = true; WindowInfo.Exists = true;
Input.Sources = INPUT_SOURCE_GAMEPAD; Input.Sources = INPUT_SOURCE_GAMEPAD;
DisplayInfo.ContentOffsetX = 10;
DisplayInfo.ContentOffsetY = 10;
joypad_init(); joypad_init();
} }

View File

@ -362,9 +362,13 @@ cc_bool Gfx_CheckTextureSize(int width, int height) {
static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps); static GfxResourceID Gfx_AllocTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps);
GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) { GfxResourceID Gfx_CreateTexture(struct Bitmap* bmp, cc_uint8 flags, cc_bool mipmaps) {
if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) { if (Gfx.SupportsNonPowTwoTextures && (flags & TEXTURE_FLAG_NONPOW2)) {
/* Texture is being deliberately created and can be successfully created */
/* with non power of two dimensions. Typically used for UI textures */
} else if (!Math_IsPowOf2(bmp->width) || !Math_IsPowOf2(bmp->height)) {
Logger_Abort("Textures must have power of two dimensions"); Logger_Abort("Textures must have power of two dimensions");
} }
if (Gfx.LostContext) return 0; if (Gfx.LostContext) return 0;
if (!Gfx_CheckTextureSize(bmp->width, bmp->height)) return 0; if (!Gfx_CheckTextureSize(bmp->width, bmp->height)) return 0;