3DS: Avoid setting viewport all the time

This commit is contained in:
UnknownShadow200 2025-10-08 06:49:10 +11:00
parent ad1623243c
commit 8459f9ed74
3 changed files with 40 additions and 40 deletions

View File

@ -59,6 +59,7 @@ static void Shader_Alloc(struct CCShader* shader, const u8* binData, int binSize
// Switches program to one that can render current vertex format and state
// Loads program and reloads uniforms if needed
static void UpdateAttribFormat(void);
static void SwitchProgram(void) {
struct CCShader* shader;
int index = 0;
@ -69,8 +70,10 @@ static void SwitchProgram(void) {
shader = &shaders[index];
if (shader != gfx_activeShader) {
gfx_activeShader = shader;
C3D_BindProgram(&shader->program);
shaderProgramConfigure(&shader->program, true, false);
}
// TODO avoid explicitly calling this. but needed right now
UpdateAttribFormat();
}
@ -132,6 +135,7 @@ static void InitCitro3D(void) {
// Even though the bottom screen is 320 pixels wide, we use 400 here so that the same ortho matrix
// can be used for both screens. The output is clipped to the actual screen width, anyway.
// TODO avoid this
C3D_RenderTargetInit(&bottomTarget, 240, 400);
C3D_RenderTargetColor(&bottomTarget, GPU_RB_RGBA8);
C3D_RenderTargetSetOutput(&bottomTarget, GFX_BOTTOM, GFX_LEFT, DISPLAY_TRANSFER_FLAGS);
@ -533,6 +537,10 @@ cc_result Gfx_TakeScreenshot(struct Stream* output) {
void Gfx_GetApiInfo(cc_string* info) {
String_Format1(info, "-- Using 3DS --\n", NULL);
PrintMaxTextureInfo(info);
int total = (int)vramSpaceFree();
float totalMB = total / (1024.0f * 1024.0f);
String_Format1(info, "VRAM free: %f2 MB", &totalMB);
}
void Gfx_SetVSync(cc_bool vsync) {
@ -571,9 +579,17 @@ void Gfx_EndFrame(void) {
C3D_FrameEnd(0);
}
void Gfx_OnWindowResize(void) { }
void Gfx_OnWindowResize(void) {
Gfx_SetViewport(0, 0, Game.Width, Game.Height);
}
void Gfx_SetViewport(int x, int y, int w, int h) { }
void Gfx_SetViewport(int x, int y, int w, int h) {
// x and y are swapped and start from right/bottom instead of left/top
x = Game.Width - w - x;
y = Game.Height - h - y;
C3D_SetViewport(y, x, h, w);
}
void Gfx_SetScissor (int x, int y, int w, int h) { }
@ -654,8 +670,8 @@ GfxResourceID Gfx_CreateIb2(int count, Gfx_FillIBFunc fillFunc, void* obj) {
}
void Gfx_BindIb(GfxResourceID ib) {
u32 pa = osConvertVirtToPhys(ib);
GPUCMD_AddWrite(GPUREG_INDEXBUFFER_CONFIG, (pa - BUFFER_BASE_PADDR) | (C3D_UNSIGNED_SHORT << 31));
u32 phys_addr = osConvertVirtToPhys(ib);
pica_set_index_buffer_address(phys_addr);
}
void Gfx_DeleteIb(GfxResourceID* ib) { }
@ -892,6 +908,9 @@ static void UpdateAttribFormat(void) {
if (gfx_format == VERTEX_FORMAT_TEXTURED) {
AttrInfo_AddLoader(attrInfo, 2, GPU_FLOAT, 2); // in_tex
}
cc_bool textured = gfx_format == VERTEX_FORMAT_TEXTURED;
pica_set_vsh_input_count(textured ? 3 : 2);
}
static void UpdateAttribConfig(void) {
@ -928,7 +947,7 @@ void Gfx_SetVertexFormat(VertexFormat fmt) {
gfx_stride = strideSizes[fmt];
SwitchProgram();
UpdateAttribFormat();
//UpdateAttribFormat();
UpdateAttribConfig();
UpdateTexEnv(fmt);
}

View File

@ -8,6 +8,14 @@
// Note that ClassiCube only uses 1 vertex array at present
/*########################################################################################################################*
*-----------------------------------------------------Index buffer config-------------------------------------------------*
*#########################################################################################################################*/
static CC_INLINE void pica_set_index_buffer_address(u32 addr) {
GPUCMD_AddWrite(GPUREG_INDEXBUFFER_CONFIG, (addr - BUFFER_BASE_PADDR) | (C3D_UNSIGNED_SHORT << 31));
}
/*########################################################################################################################*
*---------------------------------------------------------Fog config------------------------------------------------------*
*#########################################################################################################################*/
@ -55,6 +63,12 @@ static CC_INLINE void pica_set_vsh_input_mapping(u32 mappingLo, u32 mappingHi) {
GPUCMD_AddWrite(GPUREG_VSH_ATTRIBUTES_PERMUTATION_HIGH, mappingHi);
}
#define SH_MODE_VSH 0xA0000000
static CC_INLINE void pica_set_vsh_input_count(u32 count) {
GPUCMD_AddMaskedWrite(GPUREG_VSH_INPUTBUFFER_CONFIG, 0xB, SH_MODE_VSH | (count - 1));
GPUCMD_AddWrite(GPUREG_VSH_NUM_ATTR, count - 1);
}
/*########################################################################################################################*
*--------------------------------------------------Vertex shader constants------------------------------------------------*

35
third_party/citro3d.c vendored
View File

@ -127,8 +127,6 @@ enum
static bool C3D_Init(size_t cmdBufSize);
static void C3D_Fini(void);
static void C3D_BindProgram(shaderProgram_s* program);
static void C3D_SetViewport(u32 x, u32 y, u32 w, u32 h);
static void C3D_SetScissor(GPU_SCISSORMODE mode, u32 left, u32 top, u32 right, u32 bottom);
@ -281,7 +279,6 @@ typedef struct
size_t cmdBufSize;
u32 flags;
shaderProgram_s* program;
C3D_AttrInfo attrInfo;
C3D_Effect effect;
@ -305,10 +302,7 @@ enum
C3DiF_FrameBuf = BIT(5),
C3DiF_Viewport = BIT(6),
C3DiF_Scissor = BIT(7),
C3DiF_Program = BIT(8),
C3DiF_TexEnvBuf = BIT(9),
C3DiF_VshCode = BIT(11),
C3DiF_GshCode = BIT(12),
C3DiF_TexStatus = BIT(14),
C3DiF_Gas = BIT(18),
@ -387,20 +381,9 @@ static C3D_AttrInfo* C3D_GetAttrInfo(void)
static void C3Di_AttrInfoBind(C3D_AttrInfo* info)
{
GPUCMD_AddIncrementalWrites(GPUREG_ATTRIBBUFFERS_FORMAT_LOW, (u32*)info->flags, sizeof(info->flags)/sizeof(u32));
GPUCMD_AddMaskedWrite(GPUREG_VSH_INPUTBUFFER_CONFIG, 0xB, 0xA0000000 | (info->attrCount - 1));
GPUCMD_AddWrite(GPUREG_VSH_NUM_ATTR, info->attrCount - 1);
}
#define BUFFER_BASE_PADDR 0x18000000
@ -791,7 +774,6 @@ static bool C3D_FrameDrawOn(C3D_RenderTarget* target)
target->used = true;
C3D_SetFrameBuf(&target->frameBuf);
C3D_SetViewport(0, 0, target->frameBuf.width, target->frameBuf.height);
return true;
}
@ -948,7 +930,7 @@ static void C3Di_OnRestore(void)
C3D_Context* ctx = C3Di_GetContext();
ctx->flags |= C3DiF_AttrInfo | C3DiF_Effect | C3DiF_FrameBuf
| C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode
| C3DiF_Viewport | C3DiF_Scissor
| C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_Gas | C3DiF_Reset;
}
@ -1078,12 +1060,6 @@ static void C3Di_UpdateContext(void)
GPUCMD_AddIncrementalWrites(GPUREG_SCISSORTEST_MODE, ctx->scissor, 3);
}
if (ctx->flags & C3DiF_Program)
{
shaderProgramConfigure(ctx->program, (ctx->flags & C3DiF_VshCode) != 0, (ctx->flags & C3DiF_GshCode) != 0);
ctx->flags &= ~(C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode);
}
if (ctx->flags & C3DiF_AttrInfo)
{
ctx->flags &= ~C3DiF_AttrInfo;
@ -1167,12 +1143,3 @@ static void C3D_Fini(void)
linearFree(ctx->cmdBuf);
ctx->flags = 0;
}
static void C3D_BindProgram(shaderProgram_s* program)
{
C3D_Context* ctx = C3Di_GetContext();
ctx->program = program;
ctx->flags |= C3DiF_Program | C3DiF_AttrInfo;
ctx->flags |= C3DiF_VshCode | C3DiF_GshCode;
}