1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-07 13:46:45 +02:00

fix 3DS stability

This commit is contained in:
XProger
2020-02-19 05:12:41 +03:00
parent 515e268456
commit 5803810069
5 changed files with 57 additions and 53 deletions

View File

@@ -96,6 +96,8 @@
extern int WEBGL_VERSION; extern int WEBGL_VERSION;
#elif _3DS #elif _3DS
#include <3ds.h>
#define _OS_3DS 1 #define _OS_3DS 1
#define _GAPI_C3D 1 #define _GAPI_C3D 1

View File

@@ -1,9 +1,7 @@
#ifndef H_GAPI_C3D #ifndef H_GAPI_C3D
#define H_GAPI_C3D #define H_GAPI_C3D
#include <3ds.h>
#include <citro3d.h> #include <citro3d.h>
#include "core.h" #include "core.h"
#define PROFILE_MARKER(title) #define PROFILE_MARKER(title)
@@ -34,11 +32,10 @@ namespace GAPI {
ubyte4 light; ubyte4 light;
}; };
int VRAM = 0; int VRAM_TOTAL = 0;
void mmLogVRAM(int size) { void mmLogVRAM() {
VRAM += size; LOG("VRAM: %d / %d kb\n", (VRAM_TOTAL - vramSpaceFree()) / 1024, VRAM_TOTAL / 1024);
LOG("VRAM: %d = %d kb\n", size / 1024, VRAM / 1024);
} }
bool mmIsVRAM(void *addr) { bool mmIsVRAM(void *addr) {
@@ -49,11 +46,11 @@ namespace GAPI {
void* mmAlloc(size_t size) { void* mmAlloc(size_t size) {
void *addr = vramAlloc(size); void *addr = vramAlloc(size);
if (!addr) { if (!addr) {
LOG("! OUT OF VRAM %d + %d\n", VRAM / 1024, size / 1024); LOG("! OUT OF VRAM %d < %d\n", vramSpaceFree() / 1024, size / 1024);
addr = linearAlloc(size); addr = linearAlloc(size);
ASSERT(addr); ASSERT(addr);
} else { } else {
mmLogVRAM(size); mmLogVRAM();
} }
return addr; return addr;
} }
@@ -61,8 +58,8 @@ namespace GAPI {
void mmFree(void *addr) { void mmFree(void *addr) {
if (!addr) return; if (!addr) return;
if (mmIsVRAM(addr)) { if (mmIsVRAM(addr)) {
mmLogVRAM(-vramGetSize(addr));
vramFree(addr); vramFree(addr);
mmLogVRAM();
} else { } else {
linearFree(addr); linearFree(addr);
} }
@@ -70,7 +67,7 @@ namespace GAPI {
void mmCopy(void *dst, void *src, size_t size) { void mmCopy(void *dst, void *src, size_t size) {
if (mmIsVRAM(dst)) { if (mmIsVRAM(dst)) {
GSPGPU_FlushDataCache(dst, size); GSPGPU_FlushDataCache(src, size);
GX_RequestDma((u32*)src, (u32*)dst, size); GX_RequestDma((u32*)src, (u32*)dst, size);
gspWaitForDMA(); gspWaitForDMA();
} else { } else {
@@ -321,7 +318,7 @@ namespace GAPI {
C3D_Tex tex; C3D_Tex tex;
C3D_TexCube texCube; C3D_TexCube texCube;
C3D_RenderTarget *target[6]; C3D_RenderTarget *target;
void convertImage32(uint32 *dst, uint32 *src, int dstWidth, int dstHeight, int srcWidth, int srcHeight) { void convertImage32(uint32 *dst, uint32 *src, int dstWidth, int dstHeight, int srcWidth, int srcHeight) {
// 8x8 tiles swizzling // 8x8 tiles swizzling
@@ -422,7 +419,8 @@ namespace GAPI {
Texture(int width, int height, int depth, uint32 opt) : width(width), height(height), origWidth(width), origHeight(height), fmt(FMT_RGBA), opt(opt) { Texture(int width, int height, int depth, uint32 opt) : width(width), height(height), origWidth(width), origHeight(height), fmt(FMT_RGBA), opt(opt) {
opt |= OPT_NEAREST; opt |= OPT_NEAREST;
memset(target, 0, sizeof(target)); target = (C3D_RenderTarget*)malloc(sizeof(C3D_RenderTarget) * 6);
memset(target, 0, sizeof(C3D_RenderTarget) * 6);
} }
void init(void *data) { void init(void *data) {
@@ -472,9 +470,7 @@ namespace GAPI {
ASSERT(ret); ASSERT(ret);
if (mmIsVRAM(tex.data)) { mmLogVRAM();
mmLogVRAM(C3D_TexCalcTotalSize(tex.size, tex.maxLevel) * (isCube ? 6 : 1));
}
if (data && !isCube) { if (data && !isCube) {
update(data); update(data);
@@ -486,17 +482,10 @@ namespace GAPI {
} }
void deinit() { void deinit() {
for (int i = 0; i < 6; i++) {
if (target[i]) {
C3D_RenderTargetDelete(target[i]);
}
}
if (mmIsVRAM(tex.data)) {
mmLogVRAM(-C3D_TexCalcTotalSize(tex.size, tex.maxLevel) * ((opt & OPT_CUBEMAP) ? 6 : 1));
}
C3D_TexDelete(&tex); C3D_TexDelete(&tex);
mmLogVRAM();
free(target);
} }
void generateMipMap() { void generateMipMap() {
@@ -739,12 +728,7 @@ namespace GAPI {
DepthBuffer &db = depthBuffers[group]; DepthBuffer &db = depthBuffers[group];
int size = width * height; int size = C3D_CalcDepthBufSize(width, height, format);
switch (format) {
case GPU_RB_DEPTH16 : size *= 2; break;
case GPU_RB_DEPTH24 : size *= 3; break;
case GPU_RB_DEPTH24_STENCIL8 : size *= 4; break;
}
if (!db.data) { if (!db.data) {
LOG("alloc depth alias group %d (size: %d %dx%d)\n", group, size / 1024, width, height); LOG("alloc depth alias group %d (size: %d %dx%d)\n", group, size / 1024, width, height);
@@ -758,28 +742,39 @@ namespace GAPI {
return db.data; return db.data;
} }
LOG("! can't fit depth %dx%d %d ([%d] = %d)\n", width, height, size / 1024, group, db.size / 1024);
ASSERT(false); ASSERT(false);
return NULL; return NULL;
} }
C3D_RenderTarget* checkRenderTarget(Texture *texture, int face, int group, GPU_DEPTHBUF depthFmt) { C3D_RenderTarget* checkRenderTarget(Texture *texture, int face, int group, GPU_DEPTHBUF depthFmt) {
if (!texture->target[face]) { if (!texture->target[face].frameBuf.colorBuf) {
if (face > 0) {
LOG("create RT for face:%d %dx%d\n", face, texture->width, texture->height); LOG("create RT for face:%d %dx%d\n", face, texture->width, texture->height);
}
C3D_RenderTarget *target = C3D_RenderTargetCreateFromTex(&texture->tex, GPU_TEXFACE(face), 0, GPU_DEPTHBUF(-1)); C3D_FrameBuf &fb = texture->target[face].frameBuf;
void *depthBuf = getDepthBuffer(texture->width, texture->height, group, depthFmt); fb.colorBuf = (texture->opt & OPT_CUBEMAP) ? texture->texCube.data[face] : texture->tex.data;
C3D_FrameBufDepth(&target->frameBuf, depthBuf, depthFmt); fb.depthBuf = getDepthBuffer(texture->width, texture->height, group, depthFmt);
texture->target[face] = target; fb.colorFmt = GPU_COLORBUF(formats[texture->fmt].format);
fb.depthFmt = depthFmt;
fb.colorMask = 0x0F;
fb.depthMask = 0x02; // no stencil
fb.width = texture->width;
fb.height = texture->height;
fb.block32 = false;
} }
return texture->target[face]; return &texture->target[face];
} }
void init() { void init() {
memset(depthBuffers, 0, sizeof(depthBuffers)); memset(depthBuffers, 0, sizeof(depthBuffers));
gfxInitDefault(); gfxInitDefault();
vramAlloc(0);
VRAM_TOTAL = vramSpaceFree();
consoleInit(GFX_BOTTOM, NULL); consoleInit(GFX_BOTTOM, NULL);
LOG("Vendor : %s\n", "DMP"); LOG("Vendor : %s\n", "DMP");
@@ -832,11 +827,13 @@ namespace GAPI {
int height = tex->width; int height = tex->width;
C3D_RenderTarget *target = C3D_RenderTargetCreate(width, height, GPU_RB_RGB8, C3D_DEPTHTYPE(-1)); C3D_RenderTarget *target = C3D_RenderTargetCreate(width, height, GPU_RB_RGB8, C3D_DEPTHTYPE(-1));
mmLogVRAM(width * height * 3); mmLogVRAM();
void *depthBuf = getDepthBuffer(width, height, 0, GPU_RB_DEPTH16); void *depthBuf = getDepthBuffer(width, height, 0, GPU_RB_DEPTH16);
C3D_FrameBufDepth(&target->frameBuf, depthBuf, GPU_RB_DEPTH16); C3D_FrameBufDepth(&target->frameBuf, depthBuf, GPU_RB_DEPTH16);
GAPI::defTarget[i] = tex->target[0] = target; tex->target[0] = *target;
GAPI::defTarget[i] = &tex->target[0];
} }
C3D_RenderTargetSetOutput(defTarget[0], GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS); C3D_RenderTargetSetOutput(defTarget[0], GFX_TOP, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);

View File

@@ -235,6 +235,7 @@ struct Inventory {
}; };
IGame *game; IGame *game;
Texture *title;
Texture *background[3]; // [LEFT EYE or SINGLE, RIGHT EYE, TEMP] Texture *background[3]; // [LEFT EYE or SINGLE, RIGHT EYE, TEMP]
Video *video; Video *video;
@@ -592,7 +593,8 @@ struct Inventory {
} }
inv->titleTimer = inv->game->getLevel()->isTitle() ? 0.0f : 3.0f; inv->titleTimer = inv->game->getLevel()->isTitle() ? 0.0f : 3.0f;
inv->background[0] = Texture::Load(*stream); inv->title = Texture::Load(*stream);
inv->background[0] = inv->title;
delete stream; delete stream;
} }
@@ -615,7 +617,7 @@ struct Inventory {
} }
} }
Inventory() : game(NULL), itemsCount(0) { Inventory() : game(NULL), title(NULL), itemsCount(0) {
memset(background, 0, sizeof(background)); memset(background, 0, sizeof(background));
reset(); reset();
} }
@@ -630,10 +632,17 @@ struct Inventory {
delete items[i]; delete items[i];
itemsCount = 0; itemsCount = 0;
if (background[0] == title) {
background[0] = NULL;
}
for (int i = 0; i < COUNT(background); i++) { for (int i = 0; i < COUNT(background); i++) {
delete background[i]; delete background[i];
background[i] = NULL; background[i] = NULL;
} }
delete title;
title = NULL;
} }
void reset() { void reset() {
@@ -1392,14 +1401,13 @@ struct Inventory {
} }
Texture* getBackgroundTarget(int view) { Texture* getBackgroundTarget(int view) {
if (background[0] && (background[0]->origWidth != INV_BG_SIZE || background[0]->origHeight != INV_BG_SIZE)) { if (background[0] == title) {
delete background[0];
background[0] = NULL; background[0] = NULL;
} }
for (int i = 0; i < COUNT(background); i++) { for (int i = 0; i < COUNT(background); i++) {
if (!background[i]) { if (!background[i]) {
background[i] = new Texture(INV_BG_SIZE, INV_BG_SIZE, 1, FMT_RGB16, OPT_TARGET); background[i] = new Texture(INV_BG_SIZE, INV_BG_SIZE, 1, FMT_RGBA, OPT_TARGET);
} }
} }

View File

@@ -48,7 +48,7 @@ APP_DESCRIPTION := Classic Tomb Raider open-source engine
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
CFLAGS := -g -w -Ofast -ffast-math -mword-relocations \ CFLAGS := -g0 -w -Ofast -ffast-math -mword-relocations \
-fomit-frame-pointer -ffunction-sections \ -fomit-frame-pointer -ffunction-sections \
$(ARCH) $(ARCH)

View File

@@ -10,6 +10,8 @@
#ifdef _DEBUG #ifdef _DEBUG
#if defined(_OS_LINUX) || defined(_OS_RPI) || defined(_OS_CLOVER) #if defined(_OS_LINUX) || defined(_OS_RPI) || defined(_OS_CLOVER)
#define debugBreak() raise(SIGTRAP); #define debugBreak() raise(SIGTRAP);
#elif defined(_OS_3DS)
#define debugBreak() svcBreak(USERBREAK_ASSERT);
#else #else
#define debugBreak() _asm { int 3 } #define debugBreak() _asm { int 3 }
#endif #endif
@@ -23,12 +25,7 @@
#else #else
#ifdef _OS_3DS
#define ASSERT(expr) if (expr) {} else { LOG("ASSERT:\n %s:%d\n %s => %s\n", __FILE__, __LINE__, __FUNCTION__, #expr); /* svcSleepThread(3000000000LL);*/ abort(); }
#else
#define ASSERT(expr) #define ASSERT(expr)
#endif
#define ASSERTV(expr) (expr) ? 1 : 0 #define ASSERTV(expr) (expr) ? 1 : 0
#ifdef PROFILE #ifdef PROFILE