From 83331bc7e59f483701285bcaf65dec8df80dda36 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 3 May 2019 19:28:15 +0200 Subject: lay base for hi-res rendering IT'S A PILE OF HACKS --- src/GPU.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/GPU.h') diff --git a/src/GPU.h b/src/GPU.h index 50e5f55..a430a32 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -61,7 +61,7 @@ extern u32 VRAMMap_Texture[4]; extern u32 VRAMMap_TexPal[8]; extern u32 VRAMMap_ARM7[2]; -extern u32 Framebuffer[256*192*2]; +extern u32* Framebuffer; extern GPU2D* GPU2D_A; extern GPU2D* GPU2D_B; @@ -74,6 +74,8 @@ void Stop(); void DoSavestate(Savestate* file); +void SetFramebufferScale(int scale); + void MapVRAM_AB(u32 bank, u8 cnt); void MapVRAM_CD(u32 bank, u8 cnt); -- cgit v1.2.3 From c88981b5892ed3faf7cd19302c398debe27d94ed Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 15:01:40 +0200 Subject: split framebuffer. setup doublebuffering inside GPU.cpp. avoid copying a whole framebuffer every frame. better performance at higher res. --- src/GPU.cpp | 94 ++++++++++++++++++++++++++++---------- src/GPU.h | 5 +- src/libui_sdl/DlgVideoSettings.cpp | 2 +- src/libui_sdl/main.cpp | 27 +++++++---- 4 files changed, 91 insertions(+), 37 deletions(-) (limited to 'src/GPU.h') diff --git a/src/GPU.cpp b/src/GPU.cpp index f272129..636c430 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -71,9 +71,9 @@ u32 VRAMMap_TexPal[8]; u32 VRAMMap_ARM7[2]; -u32* Framebuffer; -int FBScale; -int FBScreenStride; +int FrontBuffer; +u32* Framebuffer[2][2]; +int FBScale[2]; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -85,8 +85,12 @@ bool Init() GPU2D_B = new GPU2D(1); if (!GPU3D::Init()) return false; + FrontBuffer = 0; + Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; + Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; + FBScale[0] = -1; FBScale[1] = -1; //SetFramebufferScale(1); - SetFramebufferScale(2); + SetFramebufferScale(1, 1); return true; } @@ -97,7 +101,10 @@ void DeInit() delete GPU2D_B; GPU3D::DeInit(); - if (Framebuffer) delete[] Framebuffer; + if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; + if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; + if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; + if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; } void Reset() @@ -145,22 +152,32 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - for (int i = 0; i < 256*192*2; i++) + for (int i = 0; i < (256*192)<<(FBScale[0]*2); i++) { - Framebuffer[i] = 0xFFFFFFFF; + Framebuffer[0][0][i] = 0xFFFFFFFF; + Framebuffer[1][0][i] = 0xFFFFFFFF; + } + for (int i = 0; i < (256*192)<<(FBScale[1]*2); i++) + { + Framebuffer[0][1][i] = 0xFFFFFFFF; + Framebuffer[1][1][i] = 0xFFFFFFFF; } GPU2D_A->Reset(); GPU2D_B->Reset(); GPU3D::Reset(); - GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]); - GPU2D_B->SetFramebuffer(&Framebuffer[0]); + int backbuf = FrontBuffer ? 0 : 1; + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); } void Stop() { - memset(Framebuffer, 0, FBScreenStride*2*sizeof(u32)); + memset(Framebuffer[0][0], 0, (256*192)<<(FBScale[0]*2)); + memset(Framebuffer[0][1], 0, (256*192)<<(FBScale[1]*2)); + memset(Framebuffer[1][0], 0, (256*192)<<(FBScale[0]*2)); + memset(Framebuffer[1][1], 0, (256*192)<<(FBScale[1]*2)); } void DoSavestate(Savestate* file) @@ -215,13 +232,46 @@ void DoSavestate(Savestate* file) GPU3D::DoSavestate(file); } -void SetFramebufferScale(int scale) +void AssignFramebuffers() +{ + int backbuf = FrontBuffer ? 0 : 1; + if (NDS::PowerControl9 & (1<<15)) + { + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); + } + else + { + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); + } +} + +void SetFramebufferScale(int top, int bottom) { - FBScale = scale; - FBScreenStride = (256*scale) * (192*scale); + if (top != FBScale[0]) + { + FBScale[0] = top; - if (Framebuffer) delete[] Framebuffer; - Framebuffer = new u32[FBScreenStride * 2]; + int fbsize = (256 * 192) << (FBScale[0] * 2); + if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; + if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; + Framebuffer[0][0] = new u32[fbsize]; + Framebuffer[1][0] = new u32[fbsize]; + } + + if (bottom != FBScale[1]) + { + FBScale[1] = bottom; + + int fbsize = (256 * 192) << (FBScale[1] * 2); + if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; + if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; + Framebuffer[0][1] = new u32[fbsize]; + Framebuffer[1][1] = new u32[fbsize]; + } + + AssignFramebuffers(); } @@ -682,16 +732,7 @@ void SetPowerCnt(u32 val) GPU2D_B->SetEnabled(val & (1<<9)); GPU3D::SetEnabled(val & (1<<3), val & (1<<2)); - if (val & (1<<15)) - { - GPU2D_A->SetFramebuffer(&Framebuffer[0]); - GPU2D_B->SetFramebuffer(&Framebuffer[FBScreenStride]); - } - else - { - GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]); - GPU2D_B->SetFramebuffer(&Framebuffer[0]); - } + AssignFramebuffers(); } @@ -762,6 +803,9 @@ void StartHBlank(u32 line) void FinishFrame(u32 lines) { + FrontBuffer = FrontBuffer ? 0 : 1; + AssignFramebuffers(); + TotalScanlines = lines; } diff --git a/src/GPU.h b/src/GPU.h index a430a32..2e47fc4 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -61,7 +61,8 @@ extern u32 VRAMMap_Texture[4]; extern u32 VRAMMap_TexPal[8]; extern u32 VRAMMap_ARM7[2]; -extern u32* Framebuffer; +extern int FrontBuffer; +extern u32* Framebuffer[2][2]; extern GPU2D* GPU2D_A; extern GPU2D* GPU2D_B; @@ -74,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetFramebufferScale(int scale); +void SetFramebufferScale(int top, int bottom); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index ed33cb5..b6544ed 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -160,7 +160,7 @@ void Open() uiRadioButtons* rbApplyScalingTo = uiNewRadioButtons(); uiRadioButtonsAppend(rbApplyScalingTo, "Both screens"); - uiRadioButtonsAppend(rbApplyScalingTo, "Emphasized screen"); + uiRadioButtonsAppend(rbApplyScalingTo, "Emphasized screen (see 'Screen sizing')"); uiRadioButtonsAppend(rbApplyScalingTo, "Top screen"); uiRadioButtonsAppend(rbApplyScalingTo, "Bottom screen"); uiBoxAppend(in_ctrl, uiControl(rbApplyScalingTo), 0); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index a8a5ceb..c8454ed 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -95,7 +95,8 @@ char PrevSRAMPath[1024]; // for savestate 'undo load' bool SavestateLoaded; bool ScreenDrawInited = false; -uiDrawBitmap* ScreenBitmap = NULL; +uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; +SDL_mutex* ScreenMutex; u32* ScreenBuffer; int ScreenScale; @@ -555,7 +556,7 @@ int EmuThreadFunc(void* burp) } } - memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4); + //memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4); uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx @@ -636,24 +637,27 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) if (!ScreenDrawInited) { ScreenDrawInited = true; - ScreenBitmap = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); + ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); + ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); } - if (!ScreenBitmap) return; + if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale}; - uiRect bot = {0, 192*ScreenScale, 256*ScreenScale, 192*ScreenScale}; + uiRect bot = {0, 0, 256*ScreenScale, 192*ScreenScale}; - if (ScreenBuffer) uiDrawBitmapUpdate(ScreenBitmap, ScreenBuffer); + int frontbuf = GPU::FrontBuffer; + uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]); + uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]); uiDrawSave(params->Context); uiDrawTransform(params->Context, &TopScreenTrans); - uiDrawBitmapDraw(params->Context, ScreenBitmap, &top, &TopScreenRect, Config::ScreenFilter==1); + uiDrawBitmapDraw(params->Context, ScreenBitmap[0], &top, &TopScreenRect, Config::ScreenFilter==1); uiDrawRestore(params->Context); uiDrawSave(params->Context); uiDrawTransform(params->Context, &BottomScreenTrans); - uiDrawBitmapDraw(params->Context, ScreenBitmap, &bot, &BottomScreenRect, Config::ScreenFilter==1); + uiDrawBitmapDraw(params->Context, ScreenBitmap[1], &bot, &BottomScreenRect, Config::ScreenFilter==1); uiDrawRestore(params->Context); } @@ -1993,6 +1997,8 @@ int main(int argc, char** argv) uiMenuItemDisable(MenuItem_Reset); uiMenuItemDisable(MenuItem_Stop); + ScreenMutex = SDL_CreateMutex(); + uiAreaHandler areahandler; areahandler.Draw = OnAreaDraw; areahandler.MouseEvent = OnAreaMouseEvent; @@ -2131,7 +2137,10 @@ int main(int argc, char** argv) Config::Save(); - if (ScreenBitmap) uiDrawFreeBitmap(ScreenBitmap); + SDL_DestroyMutex(ScreenMutex); + + if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); + if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); uiUninit(); SDL_Quit(); -- cgit v1.2.3 From c81bcccadc9ac8394ba8d4a836d7c954dd528751 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Thu, 16 May 2019 16:27:45 +0200 Subject: BAHAHAHAHAHAHAHAA --- melonDS.cbp | 1 + src/GPU.cpp | 40 +-- src/GPU.h | 2 +- src/GPU2D.cpp | 169 +++++++----- src/GPU2D.h | 4 +- src/GPU3D.cpp | 4 +- src/GPU3D.h | 9 +- src/GPU3D_OpenGL43.cpp | 641 +----------------------------------------- src/GPU3D_OpenGL43_shaders.h | 645 +++++++++++++++++++++++++++++++++++++++++++ src/GPU3D_Soft.cpp | 7 +- src/libui_sdl/main.cpp | 19 +- 11 files changed, 813 insertions(+), 728 deletions(-) create mode 100644 src/GPU3D_OpenGL43_shaders.h (limited to 'src/GPU.h') diff --git a/melonDS.cbp b/melonDS.cbp index ff01ebf..0bdac7f 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -107,6 +107,7 @@ + diff --git a/src/GPU.cpp b/src/GPU.cpp index f4e9fd4..1d073f5 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -74,6 +74,7 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; int FBScale[2]; +bool Accelerated; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -88,9 +89,8 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; - FBScale[0] = -1; FBScale[1] = -1; - //SetFramebufferScale(1); - SetFramebufferScale(1, 1); + FBScale[0] = -1; FBScale[1] = -1; Accelerated = false; + SetDisplaySettings(0, 0, false); return true; } @@ -247,13 +247,15 @@ void AssignFramebuffers() } } -void SetFramebufferScale(int top, int bottom) -{ - if (top != FBScale[0]) +void SetDisplaySettings(int topscale, int bottomscale, bool accel) +{accel=true; + if (topscale != FBScale[0] || accel != Accelerated) { - FBScale[0] = top; + FBScale[0] = accel ? 0 : topscale; - int fbsize = (256 * 192) << (FBScale[0] * 2); + int fbsize; + if (accel) fbsize = 256*3 * 192; + else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; Framebuffer[0][0] = new u32[fbsize]; @@ -266,21 +268,23 @@ void SetFramebufferScale(int top, int bottom) if (NDS::PowerControl9 & (1<<15)) { GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_A->SetScale(FBScale[0]); - GPU3D::SetScale(FBScale[0]); + GPU2D_A->SetDisplaySettings(FBScale[0], accel); + GPU3D::SetDisplaySettings(topscale, accel); } else { GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_B->SetScale(FBScale[0]); + GPU2D_B->SetDisplaySettings(FBScale[0], accel); } } - if (bottom != FBScale[1]) + if (bottomscale != FBScale[1] || accel != Accelerated) { - FBScale[1] = bottom; + FBScale[1] = accel ? 0 : bottomscale; - int fbsize = (256 * 192) << (FBScale[1] * 2); + int fbsize; + if (accel) fbsize = 256*3 * 192; + else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; Framebuffer[0][1] = new u32[fbsize]; @@ -293,15 +297,17 @@ void SetFramebufferScale(int top, int bottom) if (NDS::PowerControl9 & (1<<15)) { GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_B->SetScale(FBScale[1]); + GPU2D_B->SetDisplaySettings(FBScale[1], accel); } else { GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_A->SetScale(FBScale[1]); - GPU3D::SetScale(FBScale[1]); + GPU2D_A->SetDisplaySettings(FBScale[1], accel); + GPU3D::SetDisplaySettings(bottomscale, accel); } } + + Accelerated = accel; } diff --git a/src/GPU.h b/src/GPU.h index 2e47fc4..cfa8d7d 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -75,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetFramebufferScale(int top, int bottom); +void SetDisplaySettings(int topscale, int bottomscale, bool accel); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 3a99964..34c17ff 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -82,7 +82,6 @@ GPU2D::GPU2D(u32 num) { Num = num; - SetScale(0); } GPU2D::~GPU2D() @@ -216,12 +215,16 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } -void GPU2D::SetScale(int scale) +void GPU2D::SetDisplaySettings(int scale, bool accel) { + if (accel) scale = 0; + Accelerated = accel; + LineScale = scale; LineStride = 256 << (scale*2); - if (scale == 1) DrawPixel = DrawPixel_2x; + if (Accelerated) DrawPixel = DrawPixel_Accel; + else if (scale == 1) DrawPixel = DrawPixel_2x; else if (scale == 2) DrawPixel = DrawPixel_4x; else DrawPixel = DrawPixel_1x; } @@ -623,7 +626,8 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - u32* dst = &Framebuffer[LineStride * line]; + int stride = Accelerated ? (256*3) : LineStride; + u32* dst = &Framebuffer[stride * line]; int n3dline = line; line = GPU::VCount; @@ -652,7 +656,7 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); - if (Num == 0) + if (Num == 0 && !Accelerated) _3DLine = GPU3D::GetLine(n3dline); // always render regular graphics @@ -663,13 +667,13 @@ void GPU2D::DrawScanline(u32 line) case 0: // screen off { for (int i = 0; i < LineStride; i++) - dst[i] = 0xFF3F3F3F; + dst[i] = 0x003F3F3F; } break; case 1: // regular display { - for (int i = 0; i < LineStride; i+=2) + for (int i = 0; i < stride; i+=2) *(u64*)&dst[i] = *(u64*)&BGOBJLine[i]; } break; @@ -783,6 +787,8 @@ void GPU2D::DrawScanline(u32 line) DoCapture(line, capwidth); } + if (Accelerated) return; + // master brightness if (dispmode != 0) { @@ -861,6 +867,8 @@ void GPU2D::DoCapture(u32 line, u32 width) u16* dst = (u16*)GPU::VRAM[dstvram]; u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width); + // TODO: handle 3D in accelerated mode!! + u32* srcA; if (CaptureCnt & (1<<24)) srcA = _3DLine; @@ -1272,88 +1280,91 @@ void GPU2D::DrawScanline_Mode1(u32 line) // color special effects // can likely be optimized - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - - for (int i = 0; i < LineStride; i++) + if (!Accelerated) { - int j = (i >> LineScale) & 0xFF; + u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - u32 val1 = BGOBJLine[i]; - u32 val2 = BGOBJLine[4096+i]; + for (int i = 0; i < LineStride; i++) + { + int j = (i >> LineScale) & 0xFF; - u32 coloreffect, eva, evb; + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[4096+i]; - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; + u32 coloreffect, eva, evb; - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; - coloreffect = 1; + if ((flag1 & 0x80) && (BlendCnt & target2)) + { + // sprite blending + + coloreffect = 1; - if (flag1 & 0x40) + if (flag1 & 0x40) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else + { + eva = EVA; + evb = EVB; + } + } + else if ((flag1 & 0x40) && (BlendCnt & target2)) { - eva = flag1 & 0x1F; - evb = 16 - eva; + // 3D layer blending + + BGOBJLine[i] = ColorBlend5(val1, val2); + continue; } else { - eva = EVA; - evb = EVB; - } - } - else if ((flag1 & 0x40) && (BlendCnt & target2)) - { - // 3D layer blending - - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; + if (flag1 & 0x80) flag1 = 0x10; + else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) - { - if ((bldcnteffect == 1) && (BlendCnt & target2)) + if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) { - coloreffect = 1; - eva = EVA; - evb = EVB; + if ((bldcnteffect == 1) && (BlendCnt & target2)) + { + coloreffect = 1; + eva = EVA; + evb = EVB; + } + else if (bldcnteffect >= 2) + coloreffect = bldcnteffect; + else + coloreffect = 0; } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; else coloreffect = 0; } - else - coloreffect = 0; - } - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; + switch (coloreffect) + { + case 0: + BGOBJLine[i] = val1; + break; - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; + case 1: + BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); + break; - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; + case 2: + BGOBJLine[i] = ColorBrightnessUp(val1, EVY); + break; - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; + case 3: + BGOBJLine[i] = ColorBrightnessDown(val1, EVY); + break; + } } } @@ -1429,6 +1440,17 @@ void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag) *(u64*)(dst+3072+2) = val; } +void GPU2D::DrawPixel_Accel(u32* dst, u16 color, u32 flag) +{ + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + *(dst+512) = *(dst+256); + *(dst+256) = *dst; + *dst = r | (g << 8) | (b << 16) | flag; +} + void GPU2D::DrawBG_3D() { u16 xoff = BGXPos[0]; @@ -1445,7 +1467,18 @@ void GPU2D::DrawBG_3D() iend -= (xoff & 0xFF); } - if (LineScale == 1) + if (Accelerated) + { + for (; i < iend; i++) + { + if (!(WindowMask[i] & 0x01)) continue; + + BGOBJLine[i+512] = BGOBJLine[i+256]; + BGOBJLine[i+256] = BGOBJLine[i]; + BGOBJLine[i] = 0x40000000; // 3D-layer placeholder + } + } + else if (LineScale == 1) { for (; i < iend; i++) { diff --git a/src/GPU2D.h b/src/GPU2D.h index aca1f7e..fc420a5 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,7 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); - void SetScale(int scale); + void SetDisplaySettings(int scale, bool accel); u8 Read8(u32 addr); u16 Read16(u32 addr); @@ -71,6 +71,7 @@ private: u32 LineStride; u32 LineScale; + bool Accelerated; u32 BGOBJLine[1024*4 * 2]; u32* _3DLine; @@ -136,6 +137,7 @@ private: static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); static void DrawPixel_4x(u32* dst, u16 color, u32 flag); + static void DrawPixel_Accel(u32* dst, u16 color, u32 flag); void (*DrawPixel)(u32* dst, u16 color, u32 flag); void DrawBG_3D(); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 8c0588d..61629a7 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -607,9 +607,9 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { - GLRenderer43::SetScale(scale); + GLRenderer43::SetDisplaySettings(scale, accel); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 68bc696..2fe5bee 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,7 +97,7 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void ExecuteCommand(); @@ -110,6 +110,7 @@ void VCount144(); void VBlank(); void VCount215(); u32* GetLine(int line); +void SetupAccelFrame(); void WriteToGXFIFO(u32 val); @@ -127,13 +128,14 @@ bool Init(); void DeInit(); void Reset(); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void SetupRenderThread(); void VCount144(); void RenderFrame(); u32* GetLine(int line); +void SetupAccelFrame(); } @@ -144,11 +146,12 @@ bool Init(); void DeInit(); void Reset(); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void VCount144(); void RenderFrame(); u32* GetLine(int line); +void SetupAccelFrame(); } diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index e76db7f..6db9a18 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -21,6 +21,7 @@ #include "NDS.h" #include "GPU.h" #include "OpenGLSupport.h" +#include "GPU3D_OpenGL43_shaders.h" namespace GPU3D { @@ -33,631 +34,6 @@ namespace GLRenderer43 // * UBO: 3.1 // * glMemoryBarrier: 4.2 -// TODO: consider other way to handle uniforms (UBO?) - -#define kShaderHeader "#version 430" - - -const char* kClearVS = kShaderHeader R"( - -layout(location=0) in vec2 vPosition; - -layout(location=1) uniform uint uDepth; - -void main() -{ - float fdepth = (float(uDepth) / 8388608.0) - 1.0; - gl_Position = vec4(vPosition, fdepth, 1.0); -} -)"; - -const char* kClearFS = kShaderHeader R"( - -layout(location=0) uniform uvec4 uColor; -layout(location=2) uniform uint uOpaquePolyID; -layout(location=3) uniform uint uFogFlag; - -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; - -void main() -{ - oColor = vec4(uColor).bgra / 31.0; - oAttr.r = 0; - oAttr.g = uOpaquePolyID; - oAttr.b = 0; -} -)"; - - -const char* kRenderVSCommon = R"( - -layout(std140, binding=0) uniform uConfig -{ - vec2 uScreenSize; - uint uDispCnt; - vec4 uToonColors[32]; -}; - -layout(location=0) in uvec4 vPosition; -layout(location=1) in uvec4 vColor; -layout(location=2) in ivec2 vTexcoord; -layout(location=3) in uvec3 vPolygonAttr; - -smooth out vec4 fColor; -smooth out vec2 fTexcoord; -flat out uvec3 fPolygonAttr; -)"; - -const char* kRenderFSCommon = R"( - -layout(binding=0) uniform usampler2D TexMem; -layout(binding=1) uniform sampler2D TexPalMem; - -layout(std140, binding=0) uniform uConfig -{ - vec2 uScreenSize; - uint uDispCnt; - vec4 uToonColors[32]; -}; - -smooth in vec4 fColor; -smooth in vec2 fTexcoord; -flat in uvec3 fPolygonAttr; - -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; - -int TexcoordWrap(int c, int maxc, uint mode) -{ - if ((mode & (1<<0)) != 0) - { - if ((mode & (1<<2)) != 0 && (c & maxc) != 0) - return (maxc-1) - (c & (maxc-1)); - else - return (c & (maxc-1)); - } - else - return clamp(c, 0, maxc-1); -} - -vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - pixel.a = (pixel.r & 0xE0); - pixel.a = (pixel.a >> 3) + (pixel.a >> 6); - pixel.r &= 0x1F; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 2; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - pixel.r >>= (2 * (st.x & 3)); - pixel.r &= 0x03; - - addr.y = (addr.y << 2) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 1; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - if ((st.x & 1) != 0) pixel.r >>= 4; - else pixel.r &= 0x0F; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); - uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; - - int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); - if (addr.x >= 0x40000) slot1addr += 0x10000; - - uint palinfo; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo = p.r; - slot1addr++; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo |= (p.r << 8); - - addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); - palinfo >>= 14; - - if (val == 0) - { - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 1) - { - addr.y++; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 2) - { - if (palinfo == 1) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); - } - else - { - addr.y += 2; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - } - else - { - if (palinfo == 2) - { - addr.y += 3; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); - } - else - { - return vec4(0.0); - } - } -} - -vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - pixel.a = (pixel.r & 0xF8) >> 3; - pixel.r &= 0x07; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) << 1; - uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - addr.x++; - uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - vec4 color; - color.r = float(pixelL.r & 0x1F) / 31.0; - color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; - color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; - color.a = float(pixelH.r >> 7); - - return color; -} - -vec4 TextureLookup_Nearest(vec2 st) -{ - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - ivec4 st_full = ivec4(ivec2(st), tw, th); - - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; - - uint type = (attr >> 26) & 0x7; - if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); - else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); - else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); - else return TextureFetch_Direct (vramaddr, st_full, wrapmode); -} - -vec4 TextureLookup_Linear(vec2 texcoord) -{ - ivec2 intpart = ivec2(texcoord); - vec2 fracpart = fract(texcoord); - - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - ivec4 st_full = ivec4(intpart, tw, th); - - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; - - vec4 A, B, C, D; - uint type = (attr >> 26) & 0x7; - if (type == 5) - { - A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); - B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 2) - { - A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 3) - { - A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 4) - { - A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 1) - { - A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); - B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 6) - { - A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); - B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else - { - A = TextureFetch_Direct(vramaddr, st_full , wrapmode); - B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - - float fx = fracpart.x; - vec4 AB; - if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) - AB = vec4(0); - else - { - //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) - // fx = step(0.5, fx); - - AB = mix(A, B, fx); - } - - fx = fracpart.x; - vec4 CD; - if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) - CD = vec4(0); - else - { - //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) - // fx = step(0.5, fx); - - CD = mix(C, D, fx); - } - - fx = fracpart.y; - vec4 ret; - if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) - ret = vec4(0); - else - { - //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) - // fx = step(0.5, fx); - - ret = mix(AB, CD, fx); - } - - return ret; -} - -vec4 FinalColor() -{ - vec4 col; - vec4 vcol = fColor; - uint blendmode = (fPolygonAttr.x >> 4) & 0x3; - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) == 0) - { - // toon - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - vcol.rgb = tooncolor; - } - else - { - // highlight - vcol.rgb = vcol.rrr; - } - } - - if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) - { - // no texture - col = vcol; - } - else - { - vec4 tcol = TextureLookup_Nearest(fTexcoord); - //vec4 tcol = TextureLookup_Linear(fTexcoord); - - if ((blendmode & 1) != 0) - { - // decal - col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); - col.a = vcol.a; - } - else - { - // modulate - col = vcol * tcol; - } - } - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) != 0) - { - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - col.rgb = min(col.rgb + tooncolor, 1.0); - } - } - - return col.bgra; -} -)"; - - -const char* kRenderVS_Z = R"( - -void main() -{ - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xyz *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - -const char* kRenderVS_W = R"( - -smooth out float fZ; - -void main() -{ - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fZ = float(vPosition.z << zshift) / 16777216.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xy *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - - -const char* kRenderFS_ZO = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; -} -)"; - -const char* kRenderFS_WO = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZT = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = 0xFF; -} -)"; - -const char* kRenderFS_WT = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = 0xFF; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZSM = R"( - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; -} -)"; - -const char* kRenderFS_WSM = R"( - -smooth in float fZ; - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; -} -)"; - -const char* kRenderFS_WS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; - gl_FragDepth = fZ; -} -)"; - enum { @@ -721,6 +97,7 @@ GLuint TexMemID; GLuint TexPalMemID; int ScaleFactor; +bool Accelerated; int ScreenW, ScreenH; GLuint FramebufferTex[4]; @@ -968,9 +345,10 @@ void Reset() // } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { ScaleFactor = scale; + Accelerated = accel; // TODO: antialiasing setting ScreenW = 256 << scale; @@ -986,10 +364,12 @@ void SetScale(int scale) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + else glBufferData(GL_PIXEL_PACK_BUFFER, 256*192, NULL, GL_DYNAMIC_READ); if (Framebuffer) delete[] Framebuffer; - Framebuffer = new u32[ScreenW*ScreenH]; + if (accel) Framebuffer = new u32[256*192]; + else Framebuffer = new u32[ScreenW*ScreenH]; } @@ -1533,5 +913,10 @@ u32* GetLine(int line) return &Framebuffer[stride * line]; } +void SetupAccelFrame() +{ + // +} + } } diff --git a/src/GPU3D_OpenGL43_shaders.h b/src/GPU3D_OpenGL43_shaders.h new file mode 100644 index 0000000..8a69566 --- /dev/null +++ b/src/GPU3D_OpenGL43_shaders.h @@ -0,0 +1,645 @@ +/* + Copyright 2016-2019 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef GPU3D_OPENGL43_SHADERS_H +#define GPU3D_OPENGL43_SHADERS_H + +#define kShaderHeader "#version 430" + + +const char* kClearVS = kShaderHeader R"( + +layout(location=0) in vec2 vPosition; + +layout(location=1) uniform uint uDepth; + +void main() +{ + float fdepth = (float(uDepth) / 8388608.0) - 1.0; + gl_Position = vec4(vPosition, fdepth, 1.0); +} +)"; + +const char* kClearFS = kShaderHeader R"( + +layout(location=0) uniform uvec4 uColor; +layout(location=2) uniform uint uOpaquePolyID; +layout(location=3) uniform uint uFogFlag; + +layout(location=0) out vec4 oColor; +layout(location=1) out uvec3 oAttr; + +void main() +{ + oColor = vec4(uColor).bgra / 31.0; + oAttr.r = 0; + oAttr.g = uOpaquePolyID; + oAttr.b = 0; +} +)"; + + +const char* kRenderVSCommon = R"( + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + +layout(location=0) in uvec4 vPosition; +layout(location=1) in uvec4 vColor; +layout(location=2) in ivec2 vTexcoord; +layout(location=3) in uvec3 vPolygonAttr; + +smooth out vec4 fColor; +smooth out vec2 fTexcoord; +flat out uvec3 fPolygonAttr; +)"; + +const char* kRenderFSCommon = R"( + +layout(binding=0) uniform usampler2D TexMem; +layout(binding=1) uniform sampler2D TexPalMem; + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + +smooth in vec4 fColor; +smooth in vec2 fTexcoord; +flat in uvec3 fPolygonAttr; + +layout(location=0) out vec4 oColor; +layout(location=1) out uvec3 oAttr; + +int TexcoordWrap(int c, int maxc, uint mode) +{ + if ((mode & (1<<0)) != 0) + { + if ((mode & (1<<2)) != 0 && (c & maxc) != 0) + return (maxc-1) - (c & (maxc-1)); + else + return (c & (maxc-1)); + } + else + return clamp(c, 0, maxc-1); +} + +vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + pixel.a = (pixel.r & 0xE0); + pixel.a = (pixel.a >> 3) + (pixel.a >> 6); + pixel.r &= 0x1F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 2; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + pixel.r >>= (2 * (st.x & 3)); + pixel.r &= 0x03; + + addr.y = (addr.y << 2) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 1; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + if ((st.x & 1) != 0) pixel.r >>= 4; + else pixel.r &= 0x0F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); + uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + + int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); + if (addr.x >= 0x40000) slot1addr += 0x10000; + + uint palinfo; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo = p.r; + slot1addr++; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo |= (p.r << 8); + + addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); + palinfo >>= 14; + + if (val == 0) + { + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 1) + { + addr.y++; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 2) + { + if (palinfo == 1) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); + } + else + { + addr.y += 2; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + } + else + { + if (palinfo == 2) + { + addr.y += 3; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); + } + else + { + return vec4(0.0); + } + } +} + +vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + pixel.a = (pixel.r & 0xF8) >> 3; + pixel.r &= 0x07; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) << 1; + uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + addr.x++; + uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + vec4 color; + color.r = float(pixelL.r & 0x1F) / 31.0; + color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; + color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; + color.a = float(pixelH.r >> 7); + + return color; +} + +vec4 TextureLookup_Nearest(vec2 st) +{ + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(ivec2(st), tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + uint type = (attr >> 26) & 0x7; + if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); + else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); + else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); + else return TextureFetch_Direct (vramaddr, st_full, wrapmode); +} + +vec4 TextureLookup_Linear(vec2 texcoord) +{ + ivec2 intpart = ivec2(texcoord); + vec2 fracpart = fract(texcoord); + + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(intpart, tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + vec4 A, B, C, D; + uint type = (attr >> 26) & 0x7; + if (type == 5) + { + A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); + B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 2) + { + A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 3) + { + A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 4) + { + A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 1) + { + A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); + B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 6) + { + A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); + B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else + { + A = TextureFetch_Direct(vramaddr, st_full , wrapmode); + B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + + float fx = fracpart.x; + vec4 AB; + if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) + AB = vec4(0); + else + { + //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) + // fx = step(0.5, fx); + + AB = mix(A, B, fx); + } + + fx = fracpart.x; + vec4 CD; + if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) + CD = vec4(0); + else + { + //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) + // fx = step(0.5, fx); + + CD = mix(C, D, fx); + } + + fx = fracpart.y; + vec4 ret; + if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) + ret = vec4(0); + else + { + //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) + // fx = step(0.5, fx); + + ret = mix(AB, CD, fx); + } + + return ret; +} + +vec4 FinalColor() +{ + vec4 col; + vec4 vcol = fColor; + uint blendmode = (fPolygonAttr.x >> 4) & 0x3; + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) == 0) + { + // toon + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + vcol.rgb = tooncolor; + } + else + { + // highlight + vcol.rgb = vcol.rrr; + } + } + + if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) + { + // no texture + col = vcol; + } + else + { + vec4 tcol = TextureLookup_Nearest(fTexcoord); + //vec4 tcol = TextureLookup_Linear(fTexcoord); + + if ((blendmode & 1) != 0) + { + // decal + col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); + col.a = vcol.a; + } + else + { + // modulate + col = vcol * tcol; + } + } + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) != 0) + { + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + col.rgb = min(col.rgb + tooncolor, 1.0); + } + } + + return col.bgra; +} +)"; + + +const char* kRenderVS_Z = R"( + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xyz *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + +const char* kRenderVS_W = R"( + +smooth out float fZ; + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fZ = float(vPosition.z << zshift) / 16777216.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xy *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + + +const char* kRenderFS_ZO = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; +} +)"; + +const char* kRenderFS_WO = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZT = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = 0xFF; +} +)"; + +const char* kRenderFS_WT = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = 0xFF; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZSM = R"( + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = 0xFF; + oAttr.b = 1; +} +)"; + +const char* kRenderFS_WSM = R"( + +smooth in float fZ; + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = 0xFF; + oAttr.b = 1; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; + + oColor = col; +} +)"; + +const char* kRenderFS_WS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; + + oColor = col; + gl_FragDepth = fZ; +} +)"; + +#endif // GPU3D_OPENGL43_SHADERS_H diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index ac5cd93..20283d3 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -138,7 +138,7 @@ void Reset() SetupRenderThread(); } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n"); } @@ -2122,5 +2122,10 @@ u32* GetLine(int line) return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset]; } +void SetupAccelFrame() +{ + // TODO +} + } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 47f5f13..b77d67f 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -240,8 +240,8 @@ void GLDrawing_DrawScreen() x1 = TopScreenRect.X + TopScreenRect.Width; y1 = TopScreenRect.Y + TopScreenRect.Height; - scwidth = 256 << ScreenScale[0]; - scheight = 192 << ScreenScale[0]; + scwidth = 256;// << ScreenScale[0]; + scheight = 192;// << ScreenScale[0]; switch (ScreenRotation) { @@ -286,8 +286,8 @@ void GLDrawing_DrawScreen() x1 = BottomScreenRect.X + BottomScreenRect.Width; y1 = BottomScreenRect.Y + BottomScreenRect.Height; - scwidth = 256 << ScreenScale[1]; - scheight = 192 << ScreenScale[1]; + scwidth = 256;// << ScreenScale[1]; + scheight = 192;// << ScreenScale[1]; switch (ScreenRotation) { @@ -349,9 +349,13 @@ void GLDrawing_DrawScreen() int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256< Date: Tue, 21 May 2019 22:28:46 +0200 Subject: welp. progress --- src/Config.cpp | 2 + src/Config.h | 1 + src/GPU.cpp | 42 +---- src/GPU.h | 2 +- src/GPU2D.cpp | 2 +- src/GPU2D.h | 2 +- src/GPU3D.cpp | 51 ++++--- src/GPU3D.h | 11 +- src/GPU3D_OpenGL.cpp | 144 ++++++++---------- src/GPU3D_Soft.cpp | 15 -- src/libui_sdl/DlgVideoSettings.cpp | 174 ++++++++++++++++----- src/libui_sdl/PlatformConfig.cpp | 6 +- src/libui_sdl/PlatformConfig.h | 3 +- src/libui_sdl/main.cpp | 303 ++++++++++++++++++++----------------- 14 files changed, 403 insertions(+), 355 deletions(-) (limited to 'src/GPU.h') diff --git a/src/Config.cpp b/src/Config.cpp index aca3d4f..42f18c7 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -31,6 +31,7 @@ const char* kConfigFile = "melonDS.ini"; int _3DRenderer; int Threaded3D; +int GL_ScaleFactor; int GL_Antialias; ConfigEntry ConfigFile[] = @@ -38,6 +39,7 @@ ConfigEntry ConfigFile[] = {"3DRenderer", 0, &_3DRenderer, 1, NULL, 0}, {"Threaded3D", 0, &Threaded3D, 1, NULL, 0}, + {"GL_ScaleFactor", 0, &GL_ScaleFactor, 1, NULL, 0}, {"GL_Antialias", 0, &GL_Antialias, 0, NULL, 0}, {"", -1, NULL, 0, NULL, 0} diff --git a/src/Config.h b/src/Config.h index 8dc97d5..6ffc495 100644 --- a/src/Config.h +++ b/src/Config.h @@ -43,6 +43,7 @@ void Save(); extern int _3DRenderer; extern int Threaded3D; +extern int GL_ScaleFactor; extern int GL_Antialias; } diff --git a/src/GPU.cpp b/src/GPU.cpp index 8b94c94..959129e 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -73,7 +73,6 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; -int ScreenScale[2]; bool Accelerated; GPU2D* GPU2D_A; @@ -89,8 +88,8 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; - ScreenScale[0] = -1; ScreenScale[1] = -1; Accelerated = false; - SetDisplaySettings(0, 0, false); + Accelerated = false; + SetDisplaySettings(false); return true; } @@ -247,12 +246,10 @@ void AssignFramebuffers() } } -void SetDisplaySettings(int topscale, int bottomscale, bool accel) -{accel=true; +void SetDisplaySettings(bool accel) +{ if (accel != Accelerated) { - ScreenScale[0] = accel ? 0 : topscale; - int fbsize; if (accel) fbsize = (256*3 + 2) * 192; else fbsize = 256 * 192; @@ -273,35 +270,8 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) AssignFramebuffers(); } - if (topscale != ScreenScale[0]) - { - ScreenScale[0] = topscale; - - if (NDS::PowerControl9 & (1<<15)) - { - GPU2D_A->SetDisplaySettings(ScreenScale[0], accel); - GPU3D::SetDisplaySettings(ScreenScale[0], accel); - } - else - { - GPU2D_B->SetDisplaySettings(ScreenScale[0], accel); - } - } - - if (bottomscale != ScreenScale[1] || accel != Accelerated) - { - ScreenScale[1] = bottomscale; - - if (NDS::PowerControl9 & (1<<15)) - { - GPU2D_B->SetDisplaySettings(ScreenScale[1], accel); - } - else - { - GPU2D_A->SetDisplaySettings(ScreenScale[1], accel); - GPU3D::SetDisplaySettings(ScreenScale[1], accel); - } - } + GPU2D_A->SetDisplaySettings(accel); + GPU2D_B->SetDisplaySettings(accel); Accelerated = accel; } diff --git a/src/GPU.h b/src/GPU.h index cfa8d7d..b6f6473 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -75,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetDisplaySettings(int topscale, int bottomscale, bool accel); +void SetDisplaySettings(bool accel); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index fe1645e..88249ba 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -215,7 +215,7 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } -void GPU2D::SetDisplaySettings(int scale, bool accel) +void GPU2D::SetDisplaySettings(bool accel) { Accelerated = accel; diff --git a/src/GPU2D.h b/src/GPU2D.h index eb159f7..78e62f5 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,7 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); - void SetDisplaySettings(int scale, bool accel); + void SetDisplaySettings(bool accel); u8 Read8(u32 addr); u16 Read16(u32 addr); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 04ec55e..0ca3cd4 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -156,6 +156,8 @@ u32 NumCommands, CurCommand, ParamCount, TotalParams; bool GeometryEnabled; bool RenderingEnabled; +int Renderer; + u32 DispCnt; u8 AlphaRefVal, AlphaRef; @@ -275,16 +277,16 @@ bool Init() CmdStallQueue = new FIFO(64); - //if (!SoftRenderer::Init()) return false; - if (!GLRenderer::Init()) return false; + Renderer = -1; + // SetRenderer() will be called to set it up later return true; } void DeInit() { - //SoftRenderer::DeInit(); - GLRenderer::DeInit(); + if (Renderer == 0) SoftRenderer::DeInit(); + else GLRenderer::DeInit(); delete CmdFIFO; delete CmdPIPE; @@ -384,8 +386,8 @@ void Reset() FlushAttributes = 0; ResetRenderingState(); - //SoftRenderer::Reset(); - GLRenderer::Reset(); + if (Renderer == 0) SoftRenderer::Reset(); + else GLRenderer::Reset(); } void DoSavestate(Savestate* file) @@ -607,14 +609,24 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } -void SetDisplaySettings(int scale, bool accel) -{ - GLRenderer::SetDisplaySettings(scale, accel); -} -int GetScale() +int SetRenderer(int renderer) { - return GLRenderer::GetScale(); + //if (renderer == Renderer) return renderer; + + //if (Renderer == 0) SoftRenderer::DeInit(); + //else GLRenderer::DeInit(); + + if (renderer == 1) + { + if (!GLRenderer::Init()) + renderer = 0; + } + + if (renderer == 0) SoftRenderer::Init(); + + Renderer = renderer; + return renderer; } @@ -2354,7 +2366,7 @@ void CheckFIFODMA() void VCount144() { - //SoftRenderer::VCount144(); + if (Renderer == 0) SoftRenderer::VCount144(); } @@ -2436,19 +2448,14 @@ void VBlank() void VCount215() { - //SoftRenderer::RenderFrame(); - GLRenderer::RenderFrame(); + if (Renderer == 0) SoftRenderer::RenderFrame(); + else GLRenderer::RenderFrame(); } u32* GetLine(int line) { - //return SoftRenderer::GetLine(line); - return GLRenderer::GetLine(line); -} - -void SetupAccelFrame() -{ - GLRenderer::SetupAccelFrame(); + if (Renderer == 0) return SoftRenderer::GetLine(line); + else return GLRenderer::GetLine(line); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 280b99e..36c6c0f 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,8 +97,8 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); + +int SetRenderer(int renderer); void ExecuteCommand(); @@ -129,15 +129,11 @@ bool Init(); void DeInit(); void Reset(); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); - void SetupRenderThread(); void VCount144(); void RenderFrame(); u32* GetLine(int line); -void SetupAccelFrame(); } @@ -148,8 +144,7 @@ bool Init(); void DeInit(); void Reset(); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); +void SetDisplaySettings(int scale, bool antialias); void RenderFrame(); void PrepareCaptureFrame(); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 0bb7e42..30c77bf 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -95,13 +95,13 @@ GLuint TexMemID; GLuint TexPalMemID; int ScaleFactor; -bool Accelerated; +bool Antialias; int ScreenW, ScreenH; GLuint FramebufferTex[8]; int FrontBuffer; GLuint FramebufferID[4], PixelbufferID; -u32* Framebuffer = NULL; +u32 Framebuffer[256*192]; @@ -176,26 +176,6 @@ bool Init() printf("OpenGL: renderer: %s\n", renderer); printf("OpenGL: version: %s\n", version); - int barg1, barg2; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &barg1); - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &barg2); - printf("max texture: %d\n", barg1); - printf("max comb. texture: %d\n", barg2); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &barg1); - printf("max tex size: %d\n", barg1); - - glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &barg1); - printf("max arraytex levels: %d\n", barg1); - - /*glGetIntegerv(GL_NUM_EXTENSIONS, &barg1); - printf("extensions: %d\n", barg1); - for (int i = 0; i < barg1; i++) - { - const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i); - printf("- %s\n", ext); - }*/ - glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); @@ -317,6 +297,12 @@ bool Init() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[1], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); + glDrawBuffers(2, fbassign); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[6], 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[7], 0); glDrawBuffers(2, fbassign); @@ -324,8 +310,9 @@ bool Init() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glEnable(GL_BLEND); + // TODO: these are said to require GL 4.0; use the regular ones instead? glBlendFuncSeparatei(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - glBlendEquationSeparatei(0, GL_ADD, GL_MAX); + glBlendEquationSeparatei(0, GL_FUNC_ADD, GL_MAX); glBlendFuncSeparatei(1, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); glGenBuffers(1, &PixelbufferID); @@ -347,7 +334,7 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); - +printf("init done. %04X\n", glGetError()); return true; } @@ -375,44 +362,55 @@ void DeInit() void Reset() { - // } -void SetDisplaySettings(int scale, bool accel) +void SetDisplaySettings(int scale, bool antialias) { + if (antialias) scale *= 2; + ScaleFactor = scale; - Accelerated = accel; - - // TODO: antialiasing setting - ScreenW = 256 << scale; - ScreenH = 192 << scale; - - glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + Antialias = antialias; - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + ScreenW = 256 * scale; + ScreenH = 192 * scale; - if (Framebuffer) delete[] Framebuffer; - if (accel) Framebuffer = new u32[256*192]; - else Framebuffer = new u32[ScreenW*ScreenH]; -} + if (!antialias) + { + glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + } + else + { + glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW/2, ScreenH/2, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW/2, ScreenH/2, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + } -int GetScale() -{ - return ScaleFactor; + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); } @@ -496,10 +494,10 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) while (z > 0xFFFF) { z >>= 1; zshift++; } u32 x, y; - if (ScaleFactor > 0) + if (ScaleFactor > 1) { - x = vtx->HiresPosition[0] >> (4-ScaleFactor); - y = vtx->HiresPosition[1] >> (4-ScaleFactor); + x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; + y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; } else { @@ -829,8 +827,8 @@ void RenderFrame() glViewport(0, 0, ScreenW, ScreenH); - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); - FrontBuffer = FrontBuffer ? 0 : 1; + if (Antialias) glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); + else glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -902,26 +900,15 @@ void RenderFrame() RenderSceneChunk(0, 192); } - if (false) + if (Antialias) { - glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[0]); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[1]); + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[2]); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[FrontBuffer]); glBlitFramebuffer(0, 0, ScreenW, ScreenH, 0, 0, ScreenW/2, ScreenH/2, GL_COLOR_BUFFER_BIT, GL_LINEAR); - - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); } - else - { - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - } - - /*if (!Accelerated) - { - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glReadPixels(0, 0, 256< 8) Config::GL_ScaleFactor = 8; + + old_renderer = Config::_3DRenderer; + old_gldisplay = Config::ScreenUseGL; + old_threaded3D = Config::Threaded3D; + old_resolution = Config::GL_ScaleFactor; + old_antialias = Config::GL_Antialias; + + uiCheckboxSetChecked(cbGLDisplay, Config::ScreenUseGL); + uiCheckboxSetChecked(cbThreaded3D, Config::Threaded3D); + uiComboboxSetSelected(cbResolution, Config::GL_ScaleFactor-1); + uiCheckboxSetChecked(cbAntialias, Config::GL_Antialias); + uiRadioButtonsSetSelected(rbRenderer, Config::_3DRenderer); + UpdateControls(); uiControlShow(uiControl(win)); } diff --git a/src/libui_sdl/PlatformConfig.cpp b/src/libui_sdl/PlatformConfig.cpp index 065d9c2..f700ecb 100644 --- a/src/libui_sdl/PlatformConfig.cpp +++ b/src/libui_sdl/PlatformConfig.cpp @@ -40,9 +40,8 @@ int ScreenLayout; int ScreenSizing; int ScreenFilter; -int ScreenScale; +int ScreenUseGL; int ScreenRatio; -int ScreenScaleMode; int LimitFPS; @@ -105,9 +104,8 @@ ConfigEntry PlatformConfigFile[] = {"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0}, {"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0}, - {"ScreenScale", 0, &ScreenScale, 0, NULL, 0}, + {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0}, {"ScreenRatio", 0, &ScreenRatio, 0, NULL, 0}, - {"ScreenScaleMode", 0, &ScreenScaleMode, 0, NULL, 0}, {"LimitFPS", 0, &LimitFPS, 1, NULL, 0}, diff --git a/src/libui_sdl/PlatformConfig.h b/src/libui_sdl/PlatformConfig.h index 0cff1d2..013a0a7 100644 --- a/src/libui_sdl/PlatformConfig.h +++ b/src/libui_sdl/PlatformConfig.h @@ -48,9 +48,8 @@ extern int ScreenLayout; extern int ScreenSizing; extern int ScreenFilter; -extern int ScreenScale; +extern int ScreenUseGL; extern int ScreenRatio; -extern int ScreenScaleMode; extern int LimitFPS; diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index b499da7..f0d7b74 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -100,6 +100,9 @@ char PrevSRAMPath[1024]; // for savestate 'undo load' bool SavestateLoaded; +bool Screen_UseGL; +int _3DRenderer; + bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; @@ -117,8 +120,7 @@ float GL_ScreenVertices[2 * 3*2 * 4]; // position/texcoord GLuint GL_ScreenTexture; bool GL_ScreenSizeDirty; -int ScreenScale[3]; -int ScreenScaleMode; +int GL_3DScale; int ScreenGap = 0; int ScreenLayout = 0; @@ -161,14 +163,14 @@ void GetSavestateName(int slot, char* filename, int len); -bool GLDrawing_Init() +bool GLScreen_Init() { if (!OpenGL_Init()) return false; if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader")) return false; -printf("GL init looking good\n"); + GLuint uni_id; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); @@ -211,11 +213,11 @@ printf("GL init looking good\n"); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1024, 1536, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); GL_ScreenSizeDirty = true; -printf("finished w/ err: %04X\n", glGetError()); + return true; } -void GLDrawing_DeInit() +void GLScreen_DeInit() { glDeleteTextures(1, &GL_ScreenTexture); @@ -225,7 +227,7 @@ void GLDrawing_DeInit() OpenGL_DeleteShaderProgram(GL_ScreenShader); } -void GLDrawing_DrawScreen() +void GLScreen_DrawScreen() { if (GL_ScreenSizeDirty) { @@ -233,8 +235,8 @@ void GLDrawing_DrawScreen() GL_ShaderConfig.uScreenSize[0] = WindowWidth; GL_ShaderConfig.uScreenSize[1] = WindowHeight; - GL_ShaderConfig.u3DScale = 1 << GPU3D::GetScale(); - + GL_ShaderConfig.u3DScale = GL_3DScale; +printf("updating GL scale: %d\n", GL_3DScale); glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); if (unibuf) memcpy(unibuf, &GL_ShaderConfig, sizeof(GL_ShaderConfig)); @@ -257,8 +259,8 @@ void GLDrawing_DrawScreen() x1 = TopScreenRect.X + TopScreenRect.Width; y1 = TopScreenRect.Y + TopScreenRect.Height; - scwidth = 256;// << ScreenScale[0]; - scheight = 192;// << ScreenScale[0]; + scwidth = 256; + scheight = 192; switch (ScreenRotation) { @@ -303,8 +305,8 @@ void GLDrawing_DrawScreen() x1 = BottomScreenRect.X + BottomScreenRect.Width; y1 = BottomScreenRect.Y + BottomScreenRect.Height; - scwidth = 256;// << ScreenScale[1]; - scheight = 192;// << ScreenScale[1]; + scwidth = 256; + scheight = 192; switch (ScreenRotation) { @@ -376,7 +378,8 @@ void GLDrawing_DrawScreen() GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); glActiveTexture(GL_TEXTURE1); - GPU3D::SetupAccelFrame(); + if (_3DRenderer != 0) + GPU3D::GLRenderer::SetupAccelFrame(); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBindVertexArray(GL_ScreenVertexArrayID); @@ -384,7 +387,89 @@ void GLDrawing_DrawScreen() glFlush(); uiGLSwapBuffers(GLContext); - uiAreaQueueRedrawAll(MainDrawArea); +} + +void ScreenCreateArea(bool opengl) +{ + bool opengl_good = opengl; + if (opengl_good) + { + MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); + uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); + uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); + uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); + GLContext = uiAreaGetGLContext(MainDrawArea); + if (!GLContext) opengl_good = false; + } + + if (opengl_good) + { + uiGLMakeContextCurrent(GLContext); + if (!GLScreen_Init()) opengl_good = false; + } + + if (opengl_good) + { + //if (_3DRenderer != 0) + { + _3DRenderer = GPU3D::SetRenderer(_3DRenderer); + if (_3DRenderer != 0) + GPU3D::GLRenderer::SetDisplaySettings(Config::GL_ScaleFactor, Config::GL_Antialias); + else if (RunningSomething) + GPU3D::SoftRenderer::SetupRenderThread(); + } + uiGLMakeContextCurrent(NULL); + } + else + { + if (opengl) + { + uiWindowSetChild(MainWindow, NULL); + uiControlDestroy(uiControl(MainDrawArea)); + } + + Screen_UseGL = false; + + MainDrawArea = uiNewArea(&MainDrawAreaHandler); + uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); + uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); + uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); + ScreenDrawInited = false; + } + + uiControlShow(uiControl(MainWindow)); + uiControlSetFocus(uiControl(MainDrawArea)); +} + +void ScreenSetMethod(bool opengl) +{ + int oldstatus = EmuRunning; + EmuRunning = 3; + while (EmuStatus != 3); + + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + if (_3DRenderer != 0) GPU3D::GLRenderer::DeInit(); + else GPU3D::SoftRenderer::DeInit(); + GLScreen_DeInit(); + uiGLMakeContextCurrent(NULL); + } + else + { + if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); + if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); + } + + uiWindowSetChild(MainWindow, NULL); + uiControlDestroy(uiControl(MainDrawArea)); + + Screen_UseGL = Config::ScreenUseGL; + _3DRenderer = Config::_3DRenderer; + + ScreenCreateArea(opengl); + + EmuRunning = oldstatus; } void MicLoadWav(char* name) @@ -642,8 +727,11 @@ void FeedMicInput() int EmuThreadFunc(void* burp) { - uiGLMakeContextCurrent(GLContext); - GLDrawing_Init(); + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + GLScreen_Init(); + } NDS::Init(); @@ -652,13 +740,8 @@ int EmuThreadFunc(void* burp) MainScreenPos[2] = 0; AutoScreenSizing = 0; - // FIXME - ScreenScale[2] = Config::ScreenScale; - ScreenScale[0] = ScreenScale[2]; - ScreenScale[1] = ScreenScale[2]; - - int lastscale[2] = {ScreenScale[0], ScreenScale[1]}; - GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false); + GPU::SetDisplaySettings(_3DRenderer != 0); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); Touching = false; KeyInputMask = 0xFFF; @@ -773,7 +856,7 @@ int EmuThreadFunc(void* burp) // microphone input FeedMicInput(); - uiGLMakeContextCurrent(GLContext); + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); // auto screen layout { @@ -804,22 +887,16 @@ int EmuThreadFunc(void* burp) } } - if (ScreenScale[0] != lastscale[0] || - ScreenScale[1] != lastscale[1]) - { - GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false); - ScreenDrawInited = false; - } - // emulate u32 nlines = NDS::RunFrame(); if (EmuRunning == 0) break; - GLDrawing_DrawScreen(); - - //uiAreaQueueRedrawAll(MainDrawArea); - //uiGLSwapBuffers(GLContext); + if (Screen_UseGL) + { + GLScreen_DrawScreen(); + } + uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx float framerate = (1000.0f * nlines) / (60.0f * 263.0f); @@ -869,13 +946,16 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 2) { - uiGLMakeContextCurrent(GLContext); - - //uiAreaQueueRedrawAll(MainDrawArea); - //uiGLSwapBuffers(GLContext); - GLDrawing_DrawScreen(); + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + GLScreen_DrawScreen(); + } + uiAreaQueueRedrawAll(MainDrawArea); } + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + EmuStatus = EmuRunning; SDL_Delay(100); @@ -889,7 +969,7 @@ int EmuThreadFunc(void* burp) NDS::DeInit(); Platform::LAN_DeInit(); - GLDrawing_DeInit(); + if (Screen_UseGL) GLScreen_DeInit(); return 44203; } @@ -897,22 +977,21 @@ int EmuThreadFunc(void* burp) void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) { - // TODO: recreate bitmap if screen scale changed if (!ScreenDrawInited) { if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); ScreenDrawInited = true; - ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256<Context, 256<Context, 256, 192); + ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192); } if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; if (!GPU::Framebuffer[0][0]) return; - uiRect top = {0, 0, 256< 8) GL_3DScale = 8; MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, w, h, Config::WindowMaximized, 1, 1); uiWindowOnClosing(MainWindow, OnCloseWindow, NULL); @@ -2346,11 +2378,7 @@ int main(int argc, char** argv) MainDrawAreaHandler.Resize = OnAreaResize; ScreenDrawInited = false; - //MainDrawArea = uiNewArea(&MainDrawAreaHandler); - MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); - uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); - uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); - uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable? + ScreenCreateArea(Screen_UseGL); ScreenRotation = Config::ScreenRotation; ScreenGap = Config::ScreenGap; @@ -2377,15 +2405,6 @@ int main(int argc, char** argv) OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]); - // TODO: fail gracefully, support older OpenGL, etc - GLContext = uiAreaGetGLContext(MainDrawArea); - uiGLMakeContextCurrent(GLContext); - - void* testor = uiGLGetProcAddress("glUseProgram"); - void* testor2 = uiGLGetProcAddress("glBindFramebuffer"); - printf("OPENGL: %p %p\n", testor, testor2); - uiGLMakeContextCurrent(NULL); - SDL_AudioSpec whatIwant, whatIget; memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); whatIwant.freq = 47340; @@ -2454,8 +2473,6 @@ int main(int argc, char** argv) } } - uiControlShow(uiControl(MainWindow)); - uiControlSetFocus(uiControl(MainDrawArea)); uiMain(); EmuRunning = 0; -- cgit v1.2.3