Compare commits

..

No commits in common. "master" and "v1.6.0" have entirely different histories.

13 changed files with 31 additions and 99 deletions

View File

@ -9,8 +9,8 @@ endif
include $(DEVKITARM)/3ds_rules include $(DEVKITARM)/3ds_rules
export CITRO3D_MAJOR := 1 export CITRO3D_MAJOR := 1
export CITRO3D_MINOR := 7 export CITRO3D_MINOR := 6
export CITRO3D_PATCH := 1 export CITRO3D_PATCH := 0
VERSION := $(CITRO3D_MAJOR).$(CITRO3D_MINOR).$(CITRO3D_PATCH) VERSION := $(CITRO3D_MAJOR).$(CITRO3D_MINOR).$(CITRO3D_PATCH)
@ -31,11 +31,11 @@ INCLUDES := include
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
CFLAGS := -g -Wall -Wno-sizeof-array-div -Werror -mword-relocations \ CFLAGS := -g -Wall -Werror -mword-relocations \
-ffunction-sections -fdata-sections \ -ffunction-sections -fdata-sections \
$(ARCH) $(BUILD_CFLAGS) $(ARCH) $(BUILD_CFLAGS)
CFLAGS += $(INCLUDE) -D__3DS__ -DCITRO3D_BUILD CFLAGS += $(INCLUDE) -DARM11 -D_3DS -DCITRO3D_BUILD
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11
@ -114,7 +114,7 @@ debug:
lib/libcitro3d.a : lib release $(SOURCES) $(INCLUDES) lib/libcitro3d.a : lib release $(SOURCES) $(INCLUDES)
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \ @$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
BUILD_CFLAGS="-DNDEBUG=1 -O2 -fomit-frame-pointer -fno-math-errno" \ BUILD_CFLAGS="-DNDEBUG=1 -O2 -fomit-frame-pointer" \
DEPSDIR=$(CURDIR)/release \ DEPSDIR=$(CURDIR)/release \
--no-print-directory -C release \ --no-print-directory -C release \
-f $(CURDIR)/Makefile -f $(CURDIR)/Makefile

View File

@ -77,14 +77,6 @@ enum
void C3D_LightEnvFresnel(C3D_LightEnv* env, GPU_FRESNELSEL selector); void C3D_LightEnvFresnel(C3D_LightEnv* env, GPU_FRESNELSEL selector);
void C3D_LightEnvBumpMode(C3D_LightEnv* env, GPU_BUMPMODE mode); void C3D_LightEnvBumpMode(C3D_LightEnv* env, GPU_BUMPMODE mode);
void C3D_LightEnvBumpSel(C3D_LightEnv* env, int texUnit); void C3D_LightEnvBumpSel(C3D_LightEnv* env, int texUnit);
/**
* @brief Configures whether to use the z component of the normal map.
* @param[out] env Pointer to light environment structure.
* @param[in] enable false if the z component is reconstructed from the xy components
* of the normal map, true if the z component is taken from the normal map.
*/
void C3D_LightEnvBumpNormalZ(C3D_LightEnv *env, bool enable);
void C3D_LightEnvShadowMode(C3D_LightEnv* env, u32 mode); void C3D_LightEnvShadowMode(C3D_LightEnv* env, u32 mode);
void C3D_LightEnvShadowSel(C3D_LightEnv* env, int texUnit); void C3D_LightEnvShadowSel(C3D_LightEnv* env, int texUnit);
void C3D_LightEnvClampHighlights(C3D_LightEnv* env, bool clamp); void C3D_LightEnvClampHighlights(C3D_LightEnv* env, bool clamp);

View File

@ -13,12 +13,7 @@
* The one true circumference-to-radius ratio. * The one true circumference-to-radius ratio.
* See http://tauday.com/tau-manifesto * See http://tauday.com/tau-manifesto
*/ */
#define M_TAU (6.28318530717958647692528676655900576) #define M_TAU (2*M_PI)
// Define the legacy circle constant as well
#ifndef M_PI
#define M_PI (M_TAU/2)
#endif
/** /**
* @brief Convert an angle from revolutions to radians * @brief Convert an angle from revolutions to radians

View File

@ -64,11 +64,6 @@ C3D_RenderTarget* C3D_RenderTargetCreateFromTex(C3D_Tex* tex, GPU_TEXFACE face,
void C3D_RenderTargetDelete(C3D_RenderTarget* target); void C3D_RenderTargetDelete(C3D_RenderTarget* target);
void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t screen, gfx3dSide_t side, u32 transferFlags); void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t screen, gfx3dSide_t side, u32 transferFlags);
static inline void C3D_RenderTargetDetachOutput(C3D_RenderTarget* target)
{
C3D_RenderTargetSetOutput(NULL, target->screen, target->side, 0);
}
static inline void C3D_RenderTargetClear(C3D_RenderTarget* target, C3D_ClearBits clearBits, u32 clearColor, u32 clearDepth) static inline void C3D_RenderTargetClear(C3D_RenderTarget* target, C3D_ClearBits clearBits, u32 clearColor, u32 clearDepth)
{ {
C3D_FrameBufClear(&target->frameBuf, clearBits, clearColor, clearDepth); C3D_FrameBufClear(&target->frameBuf, clearBits, clearColor, clearDepth);

View File

@ -41,7 +41,7 @@ typedef struct
}; };
} C3D_Tex; } C3D_Tex;
typedef struct CTR_ALIGN(8) typedef struct ALIGN(8)
{ {
u16 width; u16 width;
u16 height; u16 height;

View File

@ -1,5 +1,5 @@
#pragma once #pragma once
#if defined(__3DS__) || defined(_3DS) #ifdef _3DS
#include <3ds.h> #include <3ds.h>
#else #else
#include <stdbool.h> #include <stdbool.h>

View File

@ -38,7 +38,7 @@ extern "C" {
#endif #endif
/** @brief Subtexture /** @brief Subtexture
* @note If top < bottom, the subtexture is rotated 1/4 revolution counter-clockwise * @note If top > bottom, the subtexture is rotated 1/4 revolution counter-clockwise
*/ */
typedef struct Tex3DS_SubTexture typedef struct Tex3DS_SubTexture
{ {

View File

@ -42,12 +42,10 @@ static void C3Di_AptEventHook(APT_HookType hookType, C3D_UNUSED void* param)
case APTHOOK_ONSUSPEND: case APTHOOK_ONSUSPEND:
{ {
C3Di_RenderQueueWaitDone(); C3Di_RenderQueueWaitDone();
C3Di_RenderQueueDisableVBlank();
break; break;
} }
case APTHOOK_ONRESTORE: case APTHOOK_ONRESTORE:
{ {
C3Di_RenderQueueEnableVBlank();
ctx->flags |= C3DiF_AttrInfo | C3DiF_BufInfo | C3DiF_Effect | C3DiF_FrameBuf ctx->flags |= C3DiF_AttrInfo | C3DiF_BufInfo | C3DiF_Effect | C3DiF_FrameBuf
| C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode | C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode
| C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_LightEnv | C3DiF_Gas; | C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_LightEnv | C3DiF_Gas;

View File

@ -124,18 +124,6 @@ static inline bool C3Di_TexIs2D(C3D_Tex* tex)
return !typeIsCube(C3D_TexGetType(tex)); return !typeIsCube(C3D_TexGetType(tex));
} }
static inline bool addrIsVRAM(const void* addr)
{
u32 vaddr = (u32)addr;
return vaddr >= OS_VRAM_VADDR && vaddr < OS_VRAM_VADDR + OS_VRAM_SIZE;
}
static inline vramAllocPos addrGetVRAMBank(const void* addr)
{
u32 vaddr = (u32)addr;
return vaddr < OS_VRAM_VADDR + OS_VRAM_SIZE/2 ? VRAM_ALLOC_A : VRAM_ALLOC_B;
}
void C3Di_UpdateContext(void); void C3Di_UpdateContext(void);
void C3Di_AttrInfoBind(C3D_AttrInfo* info); void C3Di_AttrInfoBind(C3D_AttrInfo* info);
void C3Di_BufInfoBind(C3D_BufInfo* info); void C3Di_BufInfoBind(C3D_BufInfo* info);
@ -156,5 +144,3 @@ bool C3Di_SplitFrame(u32** pBuf, u32* pSize);
void C3Di_RenderQueueInit(void); void C3Di_RenderQueueInit(void);
void C3Di_RenderQueueExit(void); void C3Di_RenderQueueExit(void);
void C3Di_RenderQueueWaitDone(void); void C3Di_RenderQueueWaitDone(void);
void C3Di_RenderQueueEnableVBlank(void);
void C3Di_RenderQueueDisableVBlank(void);

View File

@ -250,14 +250,6 @@ void C3D_LightEnvBumpSel(C3D_LightEnv* env, int texUnit)
env->flags |= C3DF_LightEnv_Dirty; env->flags |= C3DF_LightEnv_Dirty;
} }
void C3D_LightEnvBumpNormalZ(C3D_LightEnv *env, bool usez) {
if (usez)
env->conf.config[0] |= BIT(30);
else
env->conf.config[0] &= ~BIT(30);
env->flags |= C3DF_LightEnv_Dirty;
}
void C3D_LightEnvShadowMode(C3D_LightEnv* env, u32 mode) void C3D_LightEnvShadowMode(C3D_LightEnv* env, u32 mode)
{ {
mode &= 0xF<<16; mode &= 0xF<<16;

View File

@ -9,7 +9,7 @@ static C3D_RenderTarget *linkedTarget[3];
static TickCounter gpuTime, cpuTime; static TickCounter gpuTime, cpuTime;
static bool inFrame, inSafeTransfer, measureGpuTime; static bool inFrame, inSafeTransfer, measureGpuTime;
static bool needSwapTop, needSwapBot, isTopStereo; static bool needSwapTop, needSwapBot;
static float framerate = 60.0f; static float framerate = 60.0f;
static float framerateCounter[2] = { 60.0f, 60.0f }; static float framerateCounter[2] = { 60.0f, 60.0f };
static u32 frameCounter[2]; static u32 frameCounter[2];
@ -61,12 +61,12 @@ static void onQueueFinish(gxCmdQueue_s* queue)
{ {
if (needSwapTop) if (needSwapTop)
{ {
gfxScreenSwapBuffers(GFX_TOP, isTopStereo); gfxConfigScreen(GFX_TOP, false);
needSwapTop = false; needSwapTop = false;
} }
if (needSwapBot) if (needSwapBot)
{ {
gfxScreenSwapBuffers(GFX_BOTTOM, false); gfxConfigScreen(GFX_BOTTOM, false);
needSwapBot = false; needSwapBot = false;
} }
} }
@ -99,23 +99,12 @@ static bool C3Di_WaitAndClearQueue(s64 timeout)
return true; return true;
} }
void C3Di_RenderQueueEnableVBlank(void)
{
gspSetEventCallback(GSPGPU_EVENT_VBlank0, onVBlank0, NULL, false);
gspSetEventCallback(GSPGPU_EVENT_VBlank1, onVBlank1, NULL, false);
}
void C3Di_RenderQueueDisableVBlank(void)
{
gspSetEventCallback(GSPGPU_EVENT_VBlank0, NULL, NULL, false);
gspSetEventCallback(GSPGPU_EVENT_VBlank1, NULL, NULL, false);
}
void C3Di_RenderQueueInit(void) void C3Di_RenderQueueInit(void)
{ {
C3D_Context* ctx = C3Di_GetContext(); C3D_Context* ctx = C3Di_GetContext();
C3Di_RenderQueueEnableVBlank(); gspSetEventCallback(GSPGPU_EVENT_VBlank0, onVBlank0, NULL, false);
gspSetEventCallback(GSPGPU_EVENT_VBlank1, onVBlank1, NULL, false);
GX_BindQueue(&ctx->gxQueue); GX_BindQueue(&ctx->gxQueue);
gxCmdQueueSetCallback(&ctx->gxQueue, onQueueFinish, NULL); gxCmdQueueSetCallback(&ctx->gxQueue, onQueueFinish, NULL);
@ -131,7 +120,8 @@ void C3Di_RenderQueueExit(void)
gxCmdQueueSetCallback(&C3Di_GetContext()->gxQueue, NULL, NULL); gxCmdQueueSetCallback(&C3Di_GetContext()->gxQueue, NULL, NULL);
GX_BindQueue(NULL); GX_BindQueue(NULL);
C3Di_RenderQueueDisableVBlank(); gspSetEventCallback(GSPGPU_EVENT_VBlank0, NULL, NULL, false);
gspSetEventCallback(GSPGPU_EVENT_VBlank1, NULL, NULL, false);
for (i = 0; i < 3; i ++) for (i = 0; i < 3; i ++)
linkedTarget[i] = NULL; linkedTarget[i] = NULL;
@ -217,7 +207,6 @@ void C3D_FrameEnd(u8 flags)
int i; int i;
C3D_RenderTarget* target; C3D_RenderTarget* target;
isTopStereo = false;
for (i = 2; i >= 0; i --) for (i = 2; i >= 0; i --)
{ {
target = linkedTarget[i]; target = linkedTarget[i];
@ -226,11 +215,7 @@ void C3D_FrameEnd(u8 flags)
target->used = false; target->used = false;
C3D_FrameBufTransfer(&target->frameBuf, target->screen, target->side, target->transferFlags); C3D_FrameBufTransfer(&target->frameBuf, target->screen, target->side, target->transferFlags);
if (target->screen == GFX_TOP) if (target->screen == GFX_TOP)
{
needSwapTop = true; needSwapTop = true;
if (target->side == GFX_RIGHT)
isTopStereo = true;
}
else if (target->screen == GFX_BOTTOM) else if (target->screen == GFX_BOTTOM)
needSwapBot = true; needSwapBot = true;
} }
@ -284,10 +269,7 @@ C3D_RenderTarget* C3D_RenderTargetCreate(int width, int height, GPU_COLORBUF col
if (C3D_DEPTHTYPE_OK(depthFmt)) if (C3D_DEPTHTYPE_OK(depthFmt))
{ {
depthFmtReal = C3D_DEPTHTYPE_VAL(depthFmt); depthFmtReal = C3D_DEPTHTYPE_VAL(depthFmt);
size_t depthSize = C3D_CalcDepthBufSize(width,height,depthFmtReal); depthBuf = vramAlloc(C3D_CalcDepthBufSize(width,height,depthFmtReal));
vramAllocPos vramBank = addrGetVRAMBank(colorBuf);
depthBuf = vramAllocAt(depthSize, vramBank ^ VRAM_ALLOC_ANY); // Attempt opposite bank first...
if (!depthBuf) depthBuf = vramAllocAt(depthSize, vramBank); // ... if that fails, attempt same bank
if (!depthBuf) goto _fail1; if (!depthBuf) goto _fail1;
} }
@ -316,7 +298,6 @@ _fail0:
C3D_RenderTarget* C3D_RenderTargetCreateFromTex(C3D_Tex* tex, GPU_TEXFACE face, int level, C3D_DEPTHTYPE depthFmt) C3D_RenderTarget* C3D_RenderTargetCreateFromTex(C3D_Tex* tex, GPU_TEXFACE face, int level, C3D_DEPTHTYPE depthFmt)
{ {
if (!addrIsVRAM(tex->data)) return NULL; // Render targets must be in VRAM
C3D_RenderTarget* target = C3Di_RenderTargetNew(); C3D_RenderTarget* target = C3Di_RenderTargetNew();
if (!target) return NULL; if (!target) return NULL;
@ -326,10 +307,7 @@ C3D_RenderTarget* C3D_RenderTargetCreateFromTex(C3D_Tex* tex, GPU_TEXFACE face,
if (C3D_DEPTHTYPE_OK(depthFmt)) if (C3D_DEPTHTYPE_OK(depthFmt))
{ {
GPU_DEPTHBUF depthFmtReal = C3D_DEPTHTYPE_VAL(depthFmt); GPU_DEPTHBUF depthFmtReal = C3D_DEPTHTYPE_VAL(depthFmt);
size_t depthSize = C3D_CalcDepthBufSize(fb->width,fb->height,depthFmtReal); void* depthBuf = vramAlloc(C3D_CalcDepthBufSize(fb->width,fb->height,depthFmtReal));
vramAllocPos vramBank = addrGetVRAMBank(tex->data);
void* depthBuf = vramAllocAt(depthSize, vramBank ^ VRAM_ALLOC_ANY); // Attempt opposite bank first...
if (!depthBuf) depthBuf = vramAllocAt(depthSize, vramBank); // ... if that fails, attempt same bank
if (!depthBuf) if (!depthBuf)
{ {
free(target); free(target);
@ -362,9 +340,6 @@ void C3D_RenderTargetDelete(C3D_RenderTarget* target)
{ {
if (inFrame) if (inFrame)
svcBreak(USERBREAK_PANIC); // Shouldn't happen. svcBreak(USERBREAK_PANIC); // Shouldn't happen.
if (target->linked)
C3D_RenderTargetDetachOutput(target);
else
C3Di_WaitAndClearQueue(-1); C3Di_WaitAndClearQueue(-1);
C3Di_RenderTargetDestroy(target); C3Di_RenderTargetDestroy(target);
} }
@ -375,19 +350,12 @@ void C3D_RenderTargetSetOutput(C3D_RenderTarget* target, gfxScreen_t screen, gfx
if (screen==GFX_BOTTOM) id = 2; if (screen==GFX_BOTTOM) id = 2;
else if (side==GFX_RIGHT) id = 1; else if (side==GFX_RIGHT) id = 1;
if (linkedTarget[id]) if (linkedTarget[id])
{
linkedTarget[id]->linked = false; linkedTarget[id]->linked = false;
if (!inFrame)
C3Di_WaitAndClearQueue(-1);
}
linkedTarget[id] = target; linkedTarget[id] = target;
if (target)
{
target->linked = true; target->linked = true;
target->transferFlags = transferFlags; target->transferFlags = transferFlags;
target->screen = screen; target->screen = screen;
target->side = side; target->side = side;
}
} }
static void C3Di_SafeDisplayTransfer(u32* inadr, u32 indim, u32* outadr, u32 outdim, u32 flags) static void C3Di_SafeDisplayTransfer(u32* inadr, u32 indim, u32* outadr, u32 outdim, u32 flags)

View File

@ -30,6 +30,12 @@ static inline size_t fmtSize(GPU_TEXCOLOR fmt)
} }
} }
static inline bool addrIsVRAM(const void* addr)
{
u32 vaddr = (u32)addr;
return vaddr >= 0x1F000000 && vaddr < 0x1F600000;
}
static inline bool checkTexSize(u32 size) static inline bool checkTexSize(u32 size)
{ {
if (size < 8 || size > 1024) if (size < 8 || size > 1024)

View File

@ -47,10 +47,10 @@ ICON :=
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft
CFLAGS := -g -Wall -O3 -mword-relocations \ CFLAGS := -g -Wall -O3 -mword-relocations \
-ffunction-sections \ -fomit-frame-pointer -ffunction-sections \
$(ARCH) $(ARCH)
CFLAGS += $(INCLUDE) -D__3DS__ CFLAGS += $(INCLUDE) -DARM11 -D_3DS
CXXFLAGS := $(CFLAGS) -fno-rtti -std=gnu++11 CXXFLAGS := $(CFLAGS) -fno-rtti -std=gnu++11