3DS: Fix never freeing textures, oops

Also redesign PNG encoding API to support a context parameter
This commit is contained in:
UnknownShadow200 2024-03-29 19:12:42 +11:00
parent 5f95ce2fea
commit 1bc589b8e5
9 changed files with 29 additions and 37 deletions

View File

@ -645,9 +645,9 @@ static void Png_EncodeRow(const cc_uint8* cur, const cc_uint8* prior, cc_uint8*
best[0] = bestFilter; best[0] = bestFilter;
} }
static BitmapCol* DefaultGetRow(struct Bitmap* bmp, int y) { return Bitmap_GetRow(bmp, y); } static BitmapCol* DefaultGetRow(struct Bitmap* bmp, int y, void* ctx) { return Bitmap_GetRow(bmp, y); }
cc_result Png_Encode(struct Bitmap* bmp, struct Stream* stream, cc_result Png_Encode(struct Bitmap* bmp, struct Stream* stream,
Png_RowGetter getRow, cc_bool alpha) { Png_RowGetter getRow, cc_bool alpha, void* ctx) {
cc_uint8 tmp[32]; cc_uint8 tmp[32];
/* TODO: This should be * 4 for alpha (should switch to mem_alloc though) */ /* TODO: This should be * 4 for alpha (should switch to mem_alloc though) */
cc_uint8 prevLine[PNG_MAX_DIMS * 3], curLine[PNG_MAX_DIMS * 3]; cc_uint8 prevLine[PNG_MAX_DIMS * 3], curLine[PNG_MAX_DIMS * 3];
@ -691,7 +691,7 @@ cc_result Png_Encode(struct Bitmap* bmp, struct Stream* stream,
Mem_Set(prevLine, 0, lineSize); Mem_Set(prevLine, 0, lineSize);
for (y = 0; y < bmp->height; y++) { for (y = 0; y < bmp->height; y++) {
BitmapCol* src = getRow(bmp, y); BitmapCol* src = getRow(bmp, y, ctx);
cc_uint8* prev = (y & 1) == 0 ? prevLine : curLine; cc_uint8* prev = (y & 1) == 0 ? prevLine : curLine;
cc_uint8* cur = (y & 1) == 0 ? curLine : prevLine; cc_uint8* cur = (y & 1) == 0 ? curLine : prevLine;

View File

@ -89,7 +89,7 @@ CC_API void Bitmap_Scale(struct Bitmap* dst, struct Bitmap* src,
/* Whether data starts with PNG format signature/identifier. */ /* Whether data starts with PNG format signature/identifier. */
cc_bool Png_Detect(const cc_uint8* data, cc_uint32 len); cc_bool Png_Detect(const cc_uint8* data, cc_uint32 len);
typedef BitmapCol* (*Png_RowGetter)(struct Bitmap* bmp, int row); typedef BitmapCol* (*Png_RowGetter)(struct Bitmap* bmp, int row, void* ctx);
/* /*
Decodes a bitmap in PNG format. Partially based off information from Decodes a bitmap in PNG format. Partially based off information from
https://handmade.network/forums/wip/t/2363-implementing_a_basic_png_reader_the_handmade_way https://handmade.network/forums/wip/t/2363-implementing_a_basic_png_reader_the_handmade_way
@ -100,5 +100,5 @@ CC_API cc_result Png_Decode(struct Bitmap* bmp, struct Stream* stream);
/* getRow is optional. Can be used to modify how rows are encoded. (e.g. flip image) */ /* getRow is optional. Can be used to modify how rows are encoded. (e.g. flip image) */
/* if alpha is non-zero, RGBA channels are saved, otherwise only RGB channels are. */ /* if alpha is non-zero, RGBA channels are saved, otherwise only RGB channels are. */
cc_result Png_Encode(struct Bitmap* bmp, struct Stream* stream, cc_result Png_Encode(struct Bitmap* bmp, struct Stream* stream,
Png_RowGetter getRow, cc_bool alpha); Png_RowGetter getRow, cc_bool alpha, void* ctx);
#endif #endif

View File

@ -445,7 +445,7 @@ void Gfx_EndFrame(void) {
if (gfx_minFrameMs) LimitFPS(); if (gfx_minFrameMs) LimitFPS();
GPUBuffers_DeleteUnreferenced(); GPUBuffers_DeleteUnreferenced();
//GPUTextures_DeleteUnreferenced(); GPUTextures_DeleteUnreferenced();
frameCounter++; frameCounter++;
} }

View File

@ -1055,13 +1055,8 @@ void Gfx_DepthOnlyRendering(cc_bool depthOnly) {
/*########################################################################################################################* /*########################################################################################################################*
*-----------------------------------------------------------Misc----------------------------------------------------------* *-----------------------------------------------------------Misc----------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static BitmapCol* D3D11_GetRow(struct Bitmap* bmp, int y) { static BitmapCol* D3D11_GetRow(struct Bitmap* bmp, int y, void* ctx) {
// You were expecting a BitmapCol*, but it was me, D3D11_MAPPED_SUBRESOURCE*! D3D11_MAPPED_SUBRESOURCE* buffer = (D3D11_MAPPED_SUBRESOURCE*)ctx;
// This is necessary because the stride of the mapped backbuffer often doesn't equal width of the bitmap
// e.g. with backbuffer width of 854, stride is 3456 bytes instead of expected 3416 (854*4)
// Therefore have to calculate row address manually instead of using Bitmap_GetRow
D3D11_MAPPED_SUBRESOURCE* buffer = (D3D11_MAPPED_SUBRESOURCE*)bmp->scan0;
char* row = (char*)buffer->pData + y * buffer->RowPitch; char* row = (char*)buffer->pData + y * buffer->RowPitch;
return (BitmapCol*)row; return (BitmapCol*)row;
} }
@ -1094,8 +1089,8 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) {
hr = ID3D11DeviceContext_Map(context, tmp, 0, D3D11_MAP_READ, 0, &buffer); hr = ID3D11DeviceContext_Map(context, tmp, 0, D3D11_MAP_READ, 0, &buffer);
if (hr) goto finished; if (hr) goto finished;
{ {
Bitmap_Init(bmp, desc.Width, desc.Height, (BitmapCol*)&buffer); Bitmap_Init(bmp, desc.Width, desc.Height, NULL);
hr = Png_Encode(&bmp, output, D3D11_GetRow, false); hr = Png_Encode(&bmp, output, D3D11_GetRow, false, &buffer);
} }
ID3D11DeviceContext_Unmap(context, tmp, 0); ID3D11DeviceContext_Unmap(context, tmp, 0);

View File

@ -812,7 +812,7 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) {
if (res) goto finished; if (res) goto finished;
{ {
Bitmap_Init(bmp, desc.Width, desc.Height, (BitmapCol*)rect.pBits); Bitmap_Init(bmp, desc.Width, desc.Height, (BitmapCol*)rect.pBits);
res = Png_Encode(&bmp, output, NULL, false); res = Png_Encode(&bmp, output, NULL, false, NULL);
if (res) { IDirect3DSurface9_UnlockRect(temp); goto finished; } if (res) { IDirect3DSurface9_UnlockRect(temp); goto finished; }
} }
res = IDirect3DSurface9_UnlockRect(temp); res = IDirect3DSurface9_UnlockRect(temp);

View File

@ -65,24 +65,21 @@ static void LogOverEXI(char* msg, int len) {
EXI_Unlock( EXI_CHANNEL_0); EXI_Unlock( EXI_CHANNEL_0);
} }
// dolphin recognises this function name (if loaded as .elf), and will patch it
// to also log the message to dolphin's console at OSREPORT-HLE log level
void CC_NOINLINE __write_console(int fd, const char* msg, const u32* size) {
write(STDOUT_FILENO, msg, *size); // this can be intercepted by libogc debug console
}
void Platform_Log(const char* msg, int len) { void Platform_Log(const char* msg, int len) {
char tmp[256 + 1]; char tmp[256 + 1];
len = min(len, 256); len = min(len, 256);
// See EXI_DeviceIPL.cpp, \r is what triggers message to be logged // See EXI_DeviceIPL.cpp in Dolphin, \r is what triggers buffered message to be logged
Mem_Copy(tmp, msg, len); tmp[len] = '\r'; Mem_Copy(tmp, msg, len); tmp[len] = '\r';
LogOverEXI(buffer, size); LogOverEXI(tmp, len + 1);
} }
#define GCWII_EPOCH_ADJUST 946684800ULL // GameCube/Wii time epoch is year 2000, not 1970
TimeMS DateTime_CurrentUTC(void) { TimeMS DateTime_CurrentUTC(void) {
struct timeval cur; u64 raw = gettime();
gettimeofday(&cur, NULL); u64 secs = ticks_to_secs(raw);
return (cc_uint64)cur.tv_sec + UNIX_EPOCH_SECONDS; return secs + UNIX_EPOCH_SECONDS + GCWII_EPOCH_ADJUST;
} }
void DateTime_CurrentLocal(struct DateTime* t) { void DateTime_CurrentLocal(struct DateTime* t) {

View File

@ -593,7 +593,7 @@ static cc_result ZipWriter_WritePng(struct Stream* dst, struct ResourceZipEntry*
cc_result res; cc_result res;
if ((res = ZipWriter_LocalFile(dst, e))) return res; if ((res = ZipWriter_LocalFile(dst, e))) return res;
if ((res = Png_Encode(src, dst, NULL, true))) return res; if ((res = Png_Encode(src, dst, NULL, true, NULL))) return res;
return ZipWriter_FixupLocalFile(dst, e); return ZipWriter_FixupLocalFile(dst, e);
} }

View File

@ -232,7 +232,7 @@ void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, f
/*########################################################################################################################* /*########################################################################################################################*
*-----------------------------------------------------------Misc----------------------------------------------------------* *-----------------------------------------------------------Misc----------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static BitmapCol* GL_GetRow(struct Bitmap* bmp, int y) { static BitmapCol* GL_GetRow(struct Bitmap* bmp, int y, void* ctx) {
/* OpenGL stores bitmap in bottom-up order, so flip order when saving */ /* OpenGL stores bitmap in bottom-up order, so flip order when saving */
return Bitmap_GetRow(bmp, (bmp->height - 1) - y); return Bitmap_GetRow(bmp, (bmp->height - 1) - y);
} }
@ -249,7 +249,7 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) {
if (!bmp.scan0) return ERR_OUT_OF_MEMORY; if (!bmp.scan0) return ERR_OUT_OF_MEMORY;
glReadPixels(0, 0, bmp.width, bmp.height, PIXEL_FORMAT, TRANSFER_FORMAT, bmp.scan0); glReadPixels(0, 0, bmp.width, bmp.height, PIXEL_FORMAT, TRANSFER_FORMAT, bmp.scan0);
res = Png_Encode(&bmp, output, GL_GetRow, false); res = Png_Encode(&bmp, output, GL_GetRow, false, NULL);
Mem_Free(bmp.scan0); Mem_Free(bmp.scan0);
return res; return res;
} }