1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-03-13 23:59:41 +01: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;
#elif _3DS
#include <3ds.h>
#define _OS_3DS 1
#define _GAPI_C3D 1

View File

@ -1,9 +1,7 @@
#ifndef H_GAPI_C3D
#define H_GAPI_C3D
#include <3ds.h>
#include <citro3d.h>
#include "core.h"
#define PROFILE_MARKER(title)
@ -34,11 +32,10 @@ namespace GAPI {
ubyte4 light;
};
int VRAM = 0;
int VRAM_TOTAL = 0;
void mmLogVRAM(int size) {
VRAM += size;
LOG("VRAM: %d = %d kb\n", size / 1024, VRAM / 1024);
void mmLogVRAM() {
LOG("VRAM: %d / %d kb\n", (VRAM_TOTAL - vramSpaceFree()) / 1024, VRAM_TOTAL / 1024);
}
bool mmIsVRAM(void *addr) {
@ -49,11 +46,11 @@ namespace GAPI {
void* mmAlloc(size_t size) {
void *addr = vramAlloc(size);
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);
ASSERT(addr);
} else {
mmLogVRAM(size);
mmLogVRAM();
}
return addr;
}
@ -61,8 +58,8 @@ namespace GAPI {
void mmFree(void *addr) {
if (!addr) return;
if (mmIsVRAM(addr)) {
mmLogVRAM(-vramGetSize(addr));
vramFree(addr);
mmLogVRAM();
} else {
linearFree(addr);
}
@ -70,7 +67,7 @@ namespace GAPI {
void mmCopy(void *dst, void *src, size_t size) {
if (mmIsVRAM(dst)) {
GSPGPU_FlushDataCache(dst, size);
GSPGPU_FlushDataCache(src, size);
GX_RequestDma((u32*)src, (u32*)dst, size);
gspWaitForDMA();
} else {
@ -321,7 +318,7 @@ namespace GAPI {
C3D_Tex tex;
C3D_TexCube texCube;
C3D_RenderTarget *target[6];
C3D_RenderTarget *target;
void convertImage32(uint32 *dst, uint32 *src, int dstWidth, int dstHeight, int srcWidth, int srcHeight) {
// 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) {
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) {
@ -472,9 +470,7 @@ namespace GAPI {
ASSERT(ret);
if (mmIsVRAM(tex.data)) {
mmLogVRAM(C3D_TexCalcTotalSize(tex.size, tex.maxLevel) * (isCube ? 6 : 1));
}
mmLogVRAM();
if (data && !isCube) {
update(data);
@ -486,17 +482,10 @@ namespace GAPI {
}
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);
mmLogVRAM();
free(target);
}
void generateMipMap() {
@ -739,12 +728,7 @@ namespace GAPI {
DepthBuffer &db = depthBuffers[group];
int size = width * height;
switch (format) {
case GPU_RB_DEPTH16 : size *= 2; break;
case GPU_RB_DEPTH24 : size *= 3; break;
case GPU_RB_DEPTH24_STENCIL8 : size *= 4; break;
}
int size = C3D_CalcDepthBufSize(width, height, format);
if (!db.data) {
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;
}
LOG("! can't fit depth %dx%d %d ([%d] = %d)\n", width, height, size / 1024, group, db.size / 1024);
ASSERT(false);
return NULL;
}
C3D_RenderTarget* checkRenderTarget(Texture *texture, int face, int group, GPU_DEPTHBUF depthFmt) {
if (!texture->target[face]) {
if (face > 0) {
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));
void *depthBuf = getDepthBuffer(texture->width, texture->height, group, depthFmt);
C3D_FrameBufDepth(&target->frameBuf, depthBuf, depthFmt);
texture->target[face] = target;
if (!texture->target[face].frameBuf.colorBuf) {
LOG("create RT for face:%d %dx%d\n", face, texture->width, texture->height);
C3D_FrameBuf &fb = texture->target[face].frameBuf;
fb.colorBuf = (texture->opt & OPT_CUBEMAP) ? texture->texCube.data[face] : texture->tex.data;
fb.depthBuf = getDepthBuffer(texture->width, texture->height, group, depthFmt);
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() {
memset(depthBuffers, 0, sizeof(depthBuffers));
gfxInitDefault();
vramAlloc(0);
VRAM_TOTAL = vramSpaceFree();
consoleInit(GFX_BOTTOM, NULL);
LOG("Vendor : %s\n", "DMP");
@ -832,11 +827,13 @@ namespace GAPI {
int height = tex->width;
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);
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);

View File

@ -235,6 +235,7 @@ struct Inventory {
};
IGame *game;
Texture *title;
Texture *background[3]; // [LEFT EYE or SINGLE, RIGHT EYE, TEMP]
Video *video;
@ -592,7 +593,8 @@ struct Inventory {
}
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;
}
@ -615,7 +617,7 @@ struct Inventory {
}
}
Inventory() : game(NULL), itemsCount(0) {
Inventory() : game(NULL), title(NULL), itemsCount(0) {
memset(background, 0, sizeof(background));
reset();
}
@ -630,10 +632,17 @@ struct Inventory {
delete items[i];
itemsCount = 0;
if (background[0] == title) {
background[0] = NULL;
}
for (int i = 0; i < COUNT(background); i++) {
delete background[i];
background[i] = NULL;
}
delete title;
title = NULL;
}
void reset() {
@ -1392,14 +1401,13 @@ struct Inventory {
}
Texture* getBackgroundTarget(int view) {
if (background[0] && (background[0]->origWidth != INV_BG_SIZE || background[0]->origHeight != INV_BG_SIZE)) {
delete background[0];
if (background[0] == title) {
background[0] = NULL;
}
for (int i = 0; i < COUNT(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
CFLAGS := -g -w -Ofast -ffast-math -mword-relocations \
CFLAGS := -g0 -w -Ofast -ffast-math -mword-relocations \
-fomit-frame-pointer -ffunction-sections \
$(ARCH)

View File

@ -10,6 +10,8 @@
#ifdef _DEBUG
#if defined(_OS_LINUX) || defined(_OS_RPI) || defined(_OS_CLOVER)
#define debugBreak() raise(SIGTRAP);
#elif defined(_OS_3DS)
#define debugBreak() svcBreak(USERBREAK_ASSERT);
#else
#define debugBreak() _asm { int 3 }
#endif
@ -23,12 +25,7 @@
#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)
#endif
#define ASSERTV(expr) (expr) ? 1 : 0
#ifdef PROFILE