From 75f8cbf953093bc539af67c77d18263767bb3474 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 31 Mar 2019 21:15:45 +0200 Subject: draft API for OpenGL shito in libui --- src/GPU.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 14e562e..ad39007 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -20,7 +20,7 @@ #include #include "NDS.h" #include "GPU.h" - +u64 vbltime; namespace GPU { @@ -811,7 +811,7 @@ void StartScanline(u32 line) else { if (VCount == 192) - { + {//printf("- VBLANK -\n");vbltime=NDS::ARM9Timestamp; // VBlank DispStat[0] |= (1<<0); DispStat[1] |= (1<<0); -- cgit v1.2.3 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.cpp | 32 ++++++++++++++++++++++++-------- src/GPU.h | 4 +++- src/GPU2D.cpp | 13 ++++++++++++- src/libui_sdl/main.cpp | 30 +++++++++++++++++++++++------- 4 files changed, 62 insertions(+), 17 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index ad39007..f272129 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -71,7 +71,9 @@ u32 VRAMMap_TexPal[8]; u32 VRAMMap_ARM7[2]; -u32 Framebuffer[256*192*2]; +u32* Framebuffer; +int FBScale; +int FBScreenStride; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -83,6 +85,9 @@ bool Init() GPU2D_B = new GPU2D(1); if (!GPU3D::Init()) return false; + //SetFramebufferScale(1); + SetFramebufferScale(2); + return true; } @@ -91,6 +96,8 @@ void DeInit() delete GPU2D_A; delete GPU2D_B; GPU3D::DeInit(); + + if (Framebuffer) delete[] Framebuffer; } void Reset() @@ -147,13 +154,13 @@ void Reset() GPU2D_B->Reset(); GPU3D::Reset(); - GPU2D_A->SetFramebuffer(&Framebuffer[256*192]); - GPU2D_B->SetFramebuffer(&Framebuffer[256*0]); + GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]); + GPU2D_B->SetFramebuffer(&Framebuffer[0]); } void Stop() { - memset(Framebuffer, 0, 256*192*2*4); + memset(Framebuffer, 0, FBScreenStride*2*sizeof(u32)); } void DoSavestate(Savestate* file) @@ -208,6 +215,15 @@ void DoSavestate(Savestate* file) GPU3D::DoSavestate(file); } +void SetFramebufferScale(int scale) +{ + FBScale = scale; + FBScreenStride = (256*scale) * (192*scale); + + if (Framebuffer) delete[] Framebuffer; + Framebuffer = new u32[FBScreenStride * 2]; +} + // VRAM mapping notes // @@ -668,13 +684,13 @@ void SetPowerCnt(u32 val) if (val & (1<<15)) { - GPU2D_A->SetFramebuffer(&Framebuffer[256*0]); - GPU2D_B->SetFramebuffer(&Framebuffer[256*192]); + GPU2D_A->SetFramebuffer(&Framebuffer[0]); + GPU2D_B->SetFramebuffer(&Framebuffer[FBScreenStride]); } else { - GPU2D_A->SetFramebuffer(&Framebuffer[256*192]); - GPU2D_B->SetFramebuffer(&Framebuffer[256*0]); + GPU2D_A->SetFramebuffer(&Framebuffer[FBScreenStride]); + GPU2D_B->SetFramebuffer(&Framebuffer[0]); } } 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); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index b120cd8..cc428ce 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -551,7 +551,7 @@ void GPU2D::Write32(u32 addr, u32 val) void GPU2D::DrawScanline(u32 line) { - u32* dst = &Framebuffer[256*line]; + u32* dst = &Framebuffer[256*4*line]; u32 mode1gfx[256]; // request each 3D scanline in advance @@ -725,6 +725,17 @@ void GPU2D::DrawScanline(u32 line) dst[i] = c | ((c & 0x00C0C0C0) >> 6) | 0xFF000000; } + + // hax + for (int i = 255; i >= 0; i--) + { + u32 c = dst[i]; + + dst[i*2] = c; + dst[i*2+1] = c; + dst[i*2+512] = c; + dst[i*2+513] = c; + } } void GPU2D::VBlank() diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 2705560..cc4e15d 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -95,7 +95,9 @@ bool SavestateLoaded; bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap = NULL; -u32 ScreenBuffer[256*384]; +u32* ScreenBuffer; + +int ScreenScale; int ScreenGap = 0; int ScreenLayout = 0; @@ -396,6 +398,8 @@ int EmuThreadFunc(void* burp) uiGLMakeContextCurrent(GLContext); NDS::Init(); + ScreenBuffer = new u32[(256*ScreenScale) * (384*ScreenScale)]; + MainScreenPos[0] = 0; MainScreenPos[1] = 0; MainScreenPos[2] = 0; @@ -550,7 +554,7 @@ int EmuThreadFunc(void* burp) } } - memcpy(ScreenBuffer, GPU::Framebuffer, 256*384*4); + memcpy(ScreenBuffer, GPU::Framebuffer, (256*ScreenScale)*(384*ScreenScale)*4); uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx @@ -616,6 +620,8 @@ int EmuThreadFunc(void* burp) if (joybuttons) delete[] joybuttons; + delete[] ScreenBuffer; + NDS::DeInit(); Platform::LAN_DeInit(); @@ -625,16 +631,17 @@ int EmuThreadFunc(void* burp) void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) { + // TODO: recreate bitmap if screen scale changed if (!ScreenDrawInited) { ScreenDrawInited = true; - ScreenBitmap = uiDrawNewBitmap(params->Context, 256, 384); + ScreenBitmap = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); } if (!ScreenBitmap) return; - uiRect top = {0, 0, 256, 192}; - uiRect bot = {0, 192, 256, 192}; + uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale}; + uiRect bot = {0, 192*ScreenScale, 256*ScreenScale, 192*ScreenScale}; uiDrawBitmapUpdate(ScreenBitmap, ScreenBuffer); @@ -817,6 +824,9 @@ void SetupScreenRects(int width, int height) screenH = 192; } + screenW *= ScreenScale; + screenH *= ScreenScale; + uiRect *topscreen, *bottomscreen; if (ScreenRotation == 1 || ScreenRotation == 2) { @@ -1010,6 +1020,9 @@ void SetMinSize(int w, int h) int cw, ch; uiWindowContentSize(MainWindow, &cw, &ch); + w *= ScreenScale; + h *= ScreenScale; + uiControlSetMinSize(uiControl(MainDrawArea), w, h); if ((cw < w) || (ch < h)) { @@ -1535,8 +1548,8 @@ void OnSetScreenSize(uiMenuItem* item, uiWindow* window, void* param) int factor = *(int*)param; bool isHori = (ScreenRotation == 1 || ScreenRotation == 3); - int w = 256*factor; - int h = 192*factor; + int w = 256*factor * ScreenScale; + int h = 192*factor * ScreenScale; if (ScreenLayout == 0) // natural { @@ -1947,6 +1960,9 @@ int main(int argc, char** argv) WindowWidth = w; WindowHeight = h; + //ScreenScale = 1; + ScreenScale = 2; // HAW HAW HAW + MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, w, h, Config::WindowMaximized, 1, 1); uiWindowOnClosing(MainWindow, OnCloseWindow, NULL); -- 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.cpp') 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 0a464c504de43bbcd4a0bedf982e8f0e16cf0f32 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 16:32:53 +0200 Subject: de-hardcode the GL renderer. init framebuffer to black. fix bugs. --- src/GPU.cpp | 33 +++++++++++++++- src/GPU3D.cpp | 5 +++ src/GPU3D.h | 5 +++ src/GPU3D_OpenGL43.cpp | 104 ++++++++++++++++++++++++++++++------------------- src/GPU3D_Soft.cpp | 5 +++ src/libui_sdl/main.cpp | 1 + 6 files changed, 111 insertions(+), 42 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 636c430..a904a90 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -92,6 +92,11 @@ bool Init() //SetFramebufferScale(1); SetFramebufferScale(1, 1); + 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)); + return true; } @@ -258,6 +263,19 @@ void SetFramebufferScale(int top, int bottom) if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; Framebuffer[0][0] = new u32[fbsize]; Framebuffer[1][0] = new u32[fbsize]; + + int backbuf = FrontBuffer ? 0 : 1; + if (NDS::PowerControl9 & (1<<15)) + { + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); + GPU2D_A->SetScale(FBScale[0]); + GPU3D::SetScale(FBScale[0]); + } + else + { + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); + GPU2D_B->SetScale(FBScale[0]); + } } if (bottom != FBScale[1]) @@ -269,9 +287,20 @@ void SetFramebufferScale(int top, int bottom) if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; Framebuffer[0][1] = new u32[fbsize]; Framebuffer[1][1] = new u32[fbsize]; - } - AssignFramebuffers(); + int backbuf = FrontBuffer ? 0 : 1; + if (NDS::PowerControl9 & (1<<15)) + { + GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); + GPU2D_B->SetScale(FBScale[1]); + } + else + { + GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); + GPU2D_A->SetScale(FBScale[1]); + GPU3D::SetScale(FBScale[1]); + } + } } diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 3be8ee1..8c0588d 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -607,6 +607,11 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } +void SetScale(int scale) +{ + GLRenderer43::SetScale(scale); +} + void MatrixLoadIdentity(s32* m) diff --git a/src/GPU3D.h b/src/GPU3D.h index 53712ad..68bc696 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,6 +97,7 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); +void SetScale(int scale); void ExecuteCommand(); @@ -126,6 +127,8 @@ bool Init(); void DeInit(); void Reset(); +void SetScale(int scale); + void SetupRenderThread(); void VCount144(); @@ -141,6 +144,8 @@ bool Init(); void DeInit(); void Reset(); +void SetScale(int scale); + void VCount144(); void RenderFrame(); u32* GetLine(int line); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 1e4f9d7..3bd8932 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -650,9 +650,12 @@ u32 NumTriangles; GLuint TexMemID; GLuint TexPalMemID; +int ScaleFactor; +int ScreenW, ScreenH; + GLuint FramebufferTex[4]; GLuint FramebufferID[2], PixelbufferID; -u8 Framebuffer[512*384*4]; +u32* Framebuffer = NULL; bool ChunkedRendering = false; @@ -863,13 +866,6 @@ bool Init() glEnable(GL_STENCIL_TEST); - // TODO: make configurable (hires, etc) - // set those to 2x the final resolution for antialiased rendering - int screenW = 512; - int screenH = 384; - - - glViewport(0, 0, screenW, screenH); glDepthRange(0, 1); glClearDepth(1.0); @@ -897,8 +893,7 @@ bool Init() kRenderVS_W, kRenderFS_WS)) return false; - ShaderConfig.uScreenSize[0] = screenW; - ShaderConfig.uScreenSize[1] = screenH; + memset(&ShaderConfig, 0, sizeof(ShaderConfig)); glGenBuffers(1, &ShaderConfigUBO); glBindBuffer(GL_UNIFORM_BUFFER, ShaderConfigUBO); @@ -959,7 +954,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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_RGBA, screenW, screenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); // depth/stencil buffer @@ -968,7 +962,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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_DEPTH24_STENCIL8, screenW, screenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); // attribute buffer @@ -980,7 +973,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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_RGB8UI, screenW, screenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); // downscale framebuffer, for antialiased mode @@ -990,7 +982,6 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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_RGBA, screenW/2, screenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -1004,8 +995,6 @@ bool Init() glBlendFuncSeparatei(1, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); glGenBuffers(1, &PixelbufferID); - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, screenW*screenH*4, NULL, GL_DYNAMIC_READ); glActiveTexture(GL_TEXTURE0); glGenTextures(1, &TexMemID); @@ -1041,6 +1030,32 @@ void Reset() // } +void SetScale(int scale) +{ + ScaleFactor = scale; + + // TODO: antialiasing setting + ScreenW = 256 << scale; + ScreenH = 192 << scale; + + glViewport(0, 0, ScreenW, ScreenH); + + 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_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + 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 (Framebuffer) delete[] Framebuffer; + Framebuffer = new u32[ScreenW*ScreenH]; +} + void SetupPolygon(RendererPolygon* rp, Polygon* polygon) { @@ -1120,14 +1135,19 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) u32 zshift = 0; while (z > 0xFFFF) { z >>= 1; zshift++; } - u32 x = vtx->HiresPosition[0] >> 3; - u32 y = vtx->HiresPosition[1] >> 3; - *vptr++ = x | (y << 16); + u32 x, y; + if (ScaleFactor > 0) + { + x = vtx->HiresPosition[0] >> (4-ScaleFactor); + y = vtx->HiresPosition[1] >> (4-ScaleFactor); + } + else + { + x = vtx->FinalPosition[0]; + y = vtx->FinalPosition[1]; + } - // TODO hires-upgraded positions? - //*vptr++ = vtx->FinalPosition[0] | (vtx->FinalPosition[1] << 16); - //*vptr++ = (vtx->FinalPosition[0] << 1) | (vtx->FinalPosition[1] << 17); - //*vptr++ = (vtx->FinalPosition[0] << 2) | (vtx->FinalPosition[1] << 18); + *vptr++ = x | (y << 16); *vptr++ = z | (w << 16); *vptr++ = (vtx->FinalColor[0] >> 1) | @@ -1163,7 +1183,7 @@ void RenderSceneChunk(int y, int h) u32 flags = 0; if (RenderPolygonRAM[0]->WBuffer) flags |= RenderFlag_WBuffer; - if (h != 192) glScissor(0, y*2, 256*2, h*2); + if (h != 192) glScissor(0, y<> 2) | (a >> 3); } - return (u32*)&Framebuffer[512*2*4 * line]; + return &Framebuffer[stride * line]; } } diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index 932b5d4..ac5cd93 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -138,6 +138,11 @@ void Reset() SetupRenderThread(); } +void SetScale(int scale) +{ + printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n"); +} + // Notes on the interpolator: diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index ab7ed33..2853a90 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -642,6 +642,7 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) } if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; + if (!GPU::Framebuffer[0][0]) return; uiRect top = {0, 0, 256*ScreenScale, 192*ScreenScale}; uiRect bot = {0, 0, 256*ScreenScale, 192*ScreenScale}; -- cgit v1.2.3 From f5ba35ca9f42974f250c0241ccf18a3f36da79c4 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 16:47:34 +0200 Subject: don't scale the screen gap --- src/GPU.cpp | 11 ++++++----- src/libui_sdl/DlgVideoSettings.cpp | 8 +++++++- src/libui_sdl/main.cpp | 27 +++++++++++++++++---------- 3 files changed, 30 insertions(+), 16 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index a904a90..f4e9fd4 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -92,11 +92,6 @@ bool Init() //SetFramebufferScale(1); SetFramebufferScale(1, 1); - 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)); - return true; } @@ -264,6 +259,9 @@ void SetFramebufferScale(int top, int bottom) Framebuffer[0][0] = new u32[fbsize]; Framebuffer[1][0] = new u32[fbsize]; + memset(Framebuffer[0][0], 0, fbsize*4); + memset(Framebuffer[1][0], 0, fbsize*4); + int backbuf = FrontBuffer ? 0 : 1; if (NDS::PowerControl9 & (1<<15)) { @@ -288,6 +286,9 @@ void SetFramebufferScale(int top, int bottom) Framebuffer[0][1] = new u32[fbsize]; Framebuffer[1][1] = new u32[fbsize]; + memset(Framebuffer[0][1], 0, fbsize*4); + memset(Framebuffer[1][1], 0, fbsize*4); + int backbuf = FrontBuffer ? 0 : 1; if (NDS::PowerControl9 & (1<<15)) { diff --git a/src/libui_sdl/DlgVideoSettings.cpp b/src/libui_sdl/DlgVideoSettings.cpp index b6544ed..4d5de71 100644 --- a/src/libui_sdl/DlgVideoSettings.cpp +++ b/src/libui_sdl/DlgVideoSettings.cpp @@ -46,7 +46,12 @@ int OnCloseWindow(uiWindow* window, void* blarg) return 1; } -// +void OnResolutionChanged(uiRadioButtons* rb, void* blarg) +{ + int id = uiRadioButtonsSelected(rb); + + printf("res=%d\n", id); +} void OnCancel(uiButton* btn, void* blarg) { @@ -144,6 +149,7 @@ void Open() uiBoxAppend(in_ctrl, uiControl(lbl), 0); uiRadioButtons* rbResolution = uiNewRadioButtons(); + uiRadioButtonsOnSelected(rbResolution, OnResolutionChanged, NULL); uiRadioButtonsAppend(rbResolution, "1x"); uiRadioButtonsAppend(rbResolution, "2x"); uiRadioButtonsAppend(rbResolution, "4x"); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 2853a90..b79853e 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -834,7 +834,6 @@ void SetupScreenRects(int width, int height) screenW *= ScreenScale; screenH *= ScreenScale; - gap *= ScreenScale; uiRect *topscreen, *bottomscreen; if (ScreenRotation == 1 || ScreenRotation == 2) @@ -1029,9 +1028,6 @@ void SetMinSize(int w, int h) int cw, ch; uiWindowContentSize(MainWindow, &cw, &ch); - w *= ScreenScale; - h *= ScreenScale; - uiControlSetMinSize(uiControl(MainDrawArea), w, h); if ((cw < w) || (ch < h)) { @@ -1534,26 +1530,31 @@ void EnsureProperMinSize() { bool isHori = (ScreenRotation == 1 || ScreenRotation == 3); + int w0 = 256 * ScreenScale; + int h0 = 192 * ScreenScale; + int w1 = 256 * ScreenScale; + int h1 = 192 * ScreenScale; + if (ScreenLayout == 0) // natural { if (isHori) - SetMinSize(384+ScreenGap, 256); + SetMinSize(h0+ScreenGap+h1, std::max(w0,w1)); else - SetMinSize(256, 384+ScreenGap); + SetMinSize(std::max(w0,w1), h0+ScreenGap+h1); } else if (ScreenLayout == 1) // vertical { if (isHori) - SetMinSize(192, 512+ScreenGap); + SetMinSize(std::max(h0,h1), w0+ScreenGap+w1); else - SetMinSize(256, 384+ScreenGap); + SetMinSize(std::max(w0,w1), h0+ScreenGap+h1); } else // horizontal { if (isHori) - SetMinSize(384+ScreenGap, 256); + SetMinSize(h0+ScreenGap+h1, std::max(w0,w1)); else - SetMinSize(512+ScreenGap, 192); + SetMinSize(w0+ScreenGap+w1, std::max(h0,h1)); } } @@ -1565,6 +1566,8 @@ void OnSetScreenSize(uiMenuItem* item, uiWindow* window, void* param) int w = 256*factor * ScreenScale; int h = 192*factor * ScreenScale; + // FIXME + if (ScreenLayout == 0) // natural { if (isHori) @@ -1696,6 +1699,10 @@ void ApplyNewSettings(int type) Platform::LAN_DeInit(); Platform::LAN_Init(); } + else if (type == 2) // upscaling/video settings + { + // + } EmuRunning = prevstatus; } -- 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.cpp') 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: Thu, 16 May 2019 20:58:07 +0200 Subject: BAHAHAHHHH HARK HARK HARK --- src/GPU.cpp | 4 +- src/GPU2D.cpp | 25 +++++++-- src/GPU3D.cpp | 10 ++++ src/GPU3D.h | 3 ++ src/GPU3D_OpenGL43.cpp | 118 +++++++++++++++++------------------------ src/GPU3D_Soft.cpp | 5 ++ src/libui_sdl/main.cpp | 11 ++-- src/libui_sdl/main_shaders.h | 123 ++++++++++++++++++++++++++++++++++++++++++- 8 files changed, 219 insertions(+), 80 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 1d073f5..8142e47 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -254,7 +254,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[0] = accel ? 0 : topscale; int fbsize; - if (accel) fbsize = 256*3 * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; @@ -283,7 +283,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[1] = accel ? 0 : bottomscale; int fbsize; - if (accel) fbsize = 256*3 * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 34c17ff..f80eb85 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -626,7 +626,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3) : LineStride; + int stride = Accelerated ? (256*3 + 1) : LineStride; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -787,7 +787,17 @@ void GPU2D::DrawScanline(u32 line) DoCapture(line, capwidth); } - if (Accelerated) return; + if (Accelerated) + { + u32 ctl = (BlendCnt & 0x3FFF); + ctl |= ((DispCnt & 0x30000) >> 2); + ctl |= (EVA << 16); + ctl |= (EVB << 21); + ctl |= (EVY << 26); + + dst[256*3] = ctl; + return; + } // master brightness if (dispmode != 0) @@ -1367,6 +1377,13 @@ void GPU2D::DrawScanline_Mode1(u32 line) } } } + else + { + for (int i = 0; i < 256; i++) + { + BGOBJLine[i] |= ((WindowMask[i] & 0x20) << 18); + } + } if (BGMosaicY >= BGMosaicYMax) { @@ -1471,11 +1488,13 @@ void GPU2D::DrawBG_3D() { for (; i < iend; i++) { + int pos = xoff++; + if (!(WindowMask[i] & 0x01)) continue; BGOBJLine[i+512] = BGOBJLine[i+256]; BGOBJLine[i+256] = BGOBJLine[i]; - BGOBJLine[i] = 0x40000000; // 3D-layer placeholder + BGOBJLine[i] = 0x40000000 | pos; // 3D-layer placeholder } } else if (LineScale == 1) diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 61629a7..ec395ad 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -612,6 +612,11 @@ void SetDisplaySettings(int scale, bool accel) GLRenderer43::SetDisplaySettings(scale, accel); } +int GetScale() +{ + return GLRenderer43::GetScale(); +} + void MatrixLoadIdentity(s32* m) @@ -2441,6 +2446,11 @@ u32* GetLine(int line) return GLRenderer43::GetLine(line); } +void SetupAccelFrame() +{ + GLRenderer43::SetupAccelFrame(); +} + void WriteToGXFIFO(u32 val) { diff --git a/src/GPU3D.h b/src/GPU3D.h index 2fe5bee..10c8966 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -98,6 +98,7 @@ void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void ExecuteCommand(); @@ -129,6 +130,7 @@ void DeInit(); void Reset(); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void SetupRenderThread(); @@ -147,6 +149,7 @@ void DeInit(); void Reset(); void SetDisplaySettings(int scale, bool accel); +int GetScale(); void VCount144(); void RenderFrame(); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 6db9a18..0181192 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -100,7 +100,8 @@ int ScaleFactor; bool Accelerated; int ScreenW, ScreenH; -GLuint FramebufferTex[4]; +GLuint FramebufferTex[6]; +int FrontBuffer; GLuint FramebufferID[2], PixelbufferID; u32* Framebuffer = NULL; @@ -262,8 +263,10 @@ bool Init() glGenFramebuffers(2, &FramebufferID[0]); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - // color buffer - glGenTextures(4, &FramebufferTex[0]); + glGenTextures(6, &FramebufferTex[0]); + FrontBuffer = 0; + + // color buffers glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); @@ -271,33 +274,39 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); - // depth/stencil buffer glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[1], 0); + + // depth/stencil buffer + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); // attribute buffer // R: opaque polyID (for edgemarking) // G: opaque polyID (for shadows, suppressed when rendering translucent polygons) // B: stencil flag - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[2], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); // downscale framebuffer, for antialiased mode glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -330,7 +339,7 @@ bool Init() glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); // opaque polyID / shadow bits + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); // opaque polyID / shadow bits return true; } @@ -357,11 +366,13 @@ void SetDisplaySettings(int scale, bool accel) 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_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + 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_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); 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); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); @@ -372,6 +383,11 @@ void SetDisplaySettings(int scale, bool accel) else Framebuffer = new u32[ScreenW*ScreenH]; } +int GetScale() +{ + return ScaleFactor; +} + void SetupPolygon(RendererPolygon* rp, Polygon* polygon) { @@ -756,6 +772,12 @@ void RenderFrame() glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glColorMaski(1, GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + if (Accelerated) + { + int backbuf = FrontBuffer ? 0 : 1; + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[backbuf], 0); + } + // clear buffers // TODO: clear bitmap // TODO: check whether 'clear polygon ID' affects translucent polyID @@ -818,15 +840,7 @@ void RenderFrame() glBindBuffer(GL_ARRAY_BUFFER, VertexBufferID); glBufferSubData(GL_ARRAY_BUFFER, 0, NumVertices*7*4, VertexBuffer); - if (!ChunkedRendering) - { - RenderSceneChunk(0, 192); - } - else - { - glEnable(GL_SCISSOR_TEST); - RenderSceneChunk(0, 48); - } + RenderSceneChunk(0, 192); } if (false) @@ -842,63 +856,24 @@ void RenderFrame() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); } - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + if (!Accelerated) + { + glReadBuffer(GL_COLOR_ATTACHMENT0); + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - if (!ChunkedRendering) glReadPixels(0, 0, 256<> 6) & 0x3; + + if (dispmode == 1) + { + uint eva = ctl.b & 0x1F; + uint evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); + uint evy = ctl.a >> 2; + + uvec4 top = pixel; + uvec4 mid = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0); + uvec4 bot = texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0); + + uint winmask = top.b >> 7; + + if ((top.a & 0x40) != 0) + { + float xpos = top.r + fract(fTexcoord.x); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } + else top = mid; + } + else if ((mid.a & 0x40) != 0) + { + float xpos = mid.r + fract(fTexcoord.x); + uvec4 _3dpix = uvec4(texelFetch(_3DTex, ivec2(vec2(xpos, fTexcoord.y)*u3DScale), 0).bgra + * vec4(63,63,63,31)); + + if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } + } + else + { + // conditional texture fetch no good for performance, apparently + //texelFetch(_3DTex, ivec2(0, fTexcoord.y*2), 0); + bot = mid; + } + + top.b &= 0x3F; + bot.b &= 0x3F; + + uint target2; + if ((bot.a & 0x80) != 0) target2 = 0x10; + else if ((bot.a & 0x40) != 0) target2 = 0x01; + else target2 = bot.a; + bool t2pass = ((ctl.g & target2) != 0); + + uint coloreffect = 0; + + if ((top.a & 0x80) != 0 && t2pass) + { + // sprite blending + + coloreffect = 1; + + if ((top.a & 0x40) != 0) + { + eva = top.a & 0x1F; + evb = 16 - eva; + } + } + else if ((top.a & 0x40) != 0 && t2pass) + { + // 3D layer blending + + coloreffect = 4; + eva = (top.a & 0x1F) + 1; + evb = 32 - eva; + } + else + { + if ((top.a & 0x80) != 0) top.a = 0x10; + else if ((top.a & 0x40) != 0) top.a = 0x01; + + if ((ctl.r & top.a) != 0 && winmask != 0) + { + uint effect = ctl.r >> 6; + if ((effect != 1) || t2pass) coloreffect = effect; + } + } + + if (coloreffect == 0) + { + pixel = top; + } + else if (coloreffect == 1) + { + pixel = ((top * eva) + (bot * evb)) >> 4; + pixel = min(pixel, 0x3F); + } + else if (coloreffect == 2) + { + pixel = top; + pixel += ((uvec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (coloreffect == 3) + { + pixel = top; + pixel -= (pixel * evy) >> 4; + } + else + { + pixel = ((top * eva) + (bot * evb)) >> 5; + if (eva <= 16) pixel += uvec4(1,1,1,0); + pixel = min(pixel, 0x3F); + } + } + + pixel.rgb <<= 2; + pixel.rgb |= (pixel.rgb >> 6); + // TODO: filters - oColor = vec4(vec3(pixel.bgr) / 255.0, 1.0); + oColor = vec4(vec3(pixel.rgb) / 255.0, 1.0); + //oColor = texelFetch(_3DTex, ivec2(fTexcoord*4), 0).bgra; } )"; -- cgit v1.2.3 From de287825eec01aaa5e8ab925171cd75d86a23cb4 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 17 May 2019 22:50:41 +0200 Subject: start work on display capture also fix a bug in the compositing shader --- src/GPU.cpp | 2 +- src/GPU2D.cpp | 20 +++++++++-- src/GPU3D.h | 1 + src/GPU3D_OpenGL43.cpp | 81 ++++++++++++++++++++++++++++++++++++-------- src/libui_sdl/main_shaders.h | 6 ++-- 5 files changed, 88 insertions(+), 22 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 8142e47..1799ef8 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -907,7 +907,7 @@ void StartScanline(u32 line) else { if (VCount == 192) - {//printf("- VBLANK -\n");vbltime=NDS::ARM9Timestamp; + { // VBlank DispStat[0] |= (1<<0); DispStat[1] |= (1<<0); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index f80eb85..e18f30e 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -656,8 +656,16 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); - if (Num == 0 && !Accelerated) - _3DLine = GPU3D::GetLine(n3dline); + if (Num == 0) + { + if (!Accelerated) + _3DLine = GPU3D::GetLine(n3dline); + else if ((CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + { + _3DLine = GPU3D::GetLine(n3dline); + //GPU3D::GLRenderer43::PrepareCaptureFrame(); + } + } // always render regular graphics DrawScanline_Mode1(line); @@ -862,6 +870,12 @@ void GPU2D::VBlankEnd() BGMosaicYMax = BGMosaicSize[1]; OBJMosaicY = 0; OBJMosaicYMax = OBJMosaicSize[1]; + + // TODO: make optional + if ((Num == 0) && (CaptureCnt & (1<<31)) && (((CaptureCnt >> 29) & 0x3) != 1)) + { + GPU3D::GLRenderer43::PrepareCaptureFrame(); + } } @@ -884,7 +898,7 @@ void GPU2D::DoCapture(u32 line, u32 width) srcA = _3DLine; else srcA = BGOBJLine; - +srcA = _3DLine; u16* srcB = NULL; u32 srcBaddr = line * 256; diff --git a/src/GPU3D.h b/src/GPU3D.h index 10c8966..708811f 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -153,6 +153,7 @@ int GetScale(); void VCount144(); void RenderFrame(); +void PrepareCaptureFrame(); u32* GetLine(int line); void SetupAccelFrame(); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 062e40e..72956fb 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -100,9 +100,9 @@ int ScaleFactor; bool Accelerated; int ScreenW, ScreenH; -GLuint FramebufferTex[6]; +GLuint FramebufferTex[8]; int FrontBuffer; -GLuint FramebufferID[2], PixelbufferID; +GLuint FramebufferID[4], PixelbufferID; u32* Framebuffer = NULL; bool ChunkedRendering = false; @@ -260,10 +260,10 @@ bool Init() glVertexAttribIPointer(3, 3, GL_UNSIGNED_INT, 7*4, (void*)(4*4)); - glGenFramebuffers(2, &FramebufferID[0]); + glGenFramebuffers(4, &FramebufferID[0]); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - glGenTextures(6, &FramebufferTex[0]); + glGenTextures(8, &FramebufferTex[0]); FrontBuffer = 0; // color buffers @@ -286,7 +286,12 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // attribute buffer // R: opaque polyID (for edgemarking) @@ -297,16 +302,40 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); - // downscale framebuffer, for antialiased mode - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + // downscale framebuffer for antialiased mode + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); + + // downscale framebuffer for display capture (always 256x192) + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[3]); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[3]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + 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_RGBA, 256, 192, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[3], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[1], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[6], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[7], 0); glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); @@ -373,10 +402,13 @@ void SetDisplaySettings(int scale, bool accel) 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); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - 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); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); if (Framebuffer) delete[] Framebuffer; if (accel) Framebuffer = new u32[256*192]; @@ -774,7 +806,8 @@ void RenderFrame() if (Accelerated) { - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); + //glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[FrontBuffer], 0); + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); FrontBuffer = FrontBuffer ? 0 : 1; } @@ -856,18 +889,36 @@ void RenderFrame() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); } - if (!Accelerated) + /*if (!Accelerated) { glReadBuffer(GL_COLOR_ATTACHMENT0); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); glReadPixels(0, 0, 256<> 7; - if ((top.a & 0x40) != 0) + if ((top.a & 0xC0) == 0x40) { float xpos = top.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); @@ -96,7 +96,7 @@ void main() if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } else top = mid; } - else if ((mid.a & 0x40) != 0) + else if ((mid.a & 0xC0) == 0x40) { float xpos = mid.r + fract(fTexcoord.x); float ypos = mod(fTexcoord.y, 768); -- cgit v1.2.3 From f5a7cb71fd17d5eb97ce3325892a2c769258c8ce Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 18 May 2019 01:42:50 +0200 Subject: also, do master brightness --- src/GPU.cpp | 4 ++-- src/GPU2D.cpp | 3 ++- src/libui_sdl/main.cpp | 4 ++-- src/libui_sdl/main_shaders.h | 24 +++++++++++++++++++++++- 4 files changed, 29 insertions(+), 6 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 1799ef8..23e4fa8 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -254,7 +254,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[0] = accel ? 0 : topscale; int fbsize; - if (accel) fbsize = (256*3 + 1) * 192; + if (accel) fbsize = (256*3 + 2) * 192; else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; @@ -283,7 +283,7 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) FBScale[1] = accel ? 0 : bottomscale; int fbsize; - if (accel) fbsize = (256*3 + 1) * 192; + if (accel) fbsize = (256*3 + 2) * 192; else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 9ec240b..88436db 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -626,7 +626,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3 + 1) : LineStride; + int stride = Accelerated ? (256*3 + 2) : LineStride; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -804,6 +804,7 @@ void GPU2D::DrawScanline(u32 line) ctl |= (EVY << 26); dst[256*3] = ctl; + dst[256*3 + 1] = MasterBrightness; return; } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index f4a1fdb..27f0369 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -367,9 +367,9 @@ void GLDrawing_DrawScreen() GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256<> 6) & 0x3; if (dispmode == 1) @@ -182,6 +183,27 @@ ivec4 zog=pixel; } } + if (dispmode != 0) + { + int brightmode = mbright.g >> 6; + if (brightmode == 1) + { + // up + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; + } + else if (brightmode == 2) + { + // down + int evy = mbright.r & 0x1F; + if (evy > 16) evy = 16; + + pixel -= (pixel * evy) >> 4; + } + } + pixel.rgb <<= 2; pixel.rgb |= (pixel.rgb >> 6); -- cgit v1.2.3 From 50cc38d78180e48e2eac0aabe344c231ffc0f0fb Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 19 May 2019 19:47:23 +0200 Subject: botch more code --- src/GPU.cpp | 68 +++++++++++++++++++++++++++++-------------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 23e4fa8..8b94c94 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -73,7 +73,7 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; -int FBScale[2]; +int ScreenScale[2]; bool Accelerated; GPU2D* GPU2D_A; @@ -89,7 +89,7 @@ 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; Accelerated = false; + ScreenScale[0] = -1; ScreenScale[1] = -1; Accelerated = false; SetDisplaySettings(0, 0, false); return true; @@ -152,12 +152,12 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - for (int i = 0; i < (256*192)<<(FBScale[0]*2); i++) + for (int i = 0; i < (256*192); i++) { Framebuffer[0][0][i] = 0xFFFFFFFF; Framebuffer[1][0][i] = 0xFFFFFFFF; } - for (int i = 0; i < (256*192)<<(FBScale[1]*2); i++) + for (int i = 0; i < (256*192); i++) { Framebuffer[0][1][i] = 0xFFFFFFFF; Framebuffer[1][1][i] = 0xFFFFFFFF; @@ -174,10 +174,10 @@ void Reset() void Stop() { - 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)); + memset(Framebuffer[0][0], 0, 256*192); + memset(Framebuffer[0][1], 0, 256*192); + memset(Framebuffer[1][0], 0, 256*192); + memset(Framebuffer[1][1], 0, 256*192); } void DoSavestate(Savestate* file) @@ -249,61 +249,57 @@ void AssignFramebuffers() void SetDisplaySettings(int topscale, int bottomscale, bool accel) {accel=true; - if (topscale != FBScale[0] || accel != Accelerated) + if (accel != Accelerated) { - FBScale[0] = accel ? 0 : topscale; + ScreenScale[0] = accel ? 0 : topscale; int fbsize; if (accel) fbsize = (256*3 + 2) * 192; - else fbsize = (256 * 192) << (FBScale[0] * 2); + else fbsize = 256 * 192; if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; + if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; + if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; Framebuffer[0][0] = new u32[fbsize]; Framebuffer[1][0] = new u32[fbsize]; + Framebuffer[0][1] = new u32[fbsize]; + Framebuffer[1][1] = new u32[fbsize]; memset(Framebuffer[0][0], 0, fbsize*4); memset(Framebuffer[1][0], 0, fbsize*4); + memset(Framebuffer[0][1], 0, fbsize*4); + memset(Framebuffer[1][1], 0, fbsize*4); + + AssignFramebuffers(); + } + + if (topscale != ScreenScale[0]) + { + ScreenScale[0] = topscale; - int backbuf = FrontBuffer ? 0 : 1; if (NDS::PowerControl9 & (1<<15)) { - GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_A->SetDisplaySettings(FBScale[0], accel); - GPU3D::SetDisplaySettings(topscale, accel); + GPU2D_A->SetDisplaySettings(ScreenScale[0], accel); + GPU3D::SetDisplaySettings(ScreenScale[0], accel); } else { - GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_B->SetDisplaySettings(FBScale[0], accel); + GPU2D_B->SetDisplaySettings(ScreenScale[0], accel); } } - if (bottomscale != FBScale[1] || accel != Accelerated) + if (bottomscale != ScreenScale[1] || accel != Accelerated) { - FBScale[1] = accel ? 0 : bottomscale; - - int fbsize; - if (accel) fbsize = (256*3 + 2) * 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]; - Framebuffer[1][1] = new u32[fbsize]; - - memset(Framebuffer[0][1], 0, fbsize*4); - memset(Framebuffer[1][1], 0, fbsize*4); + ScreenScale[1] = bottomscale; - int backbuf = FrontBuffer ? 0 : 1; if (NDS::PowerControl9 & (1<<15)) { - GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_B->SetDisplaySettings(FBScale[1], accel); + GPU2D_B->SetDisplaySettings(ScreenScale[1], accel); } else { - GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_A->SetDisplaySettings(FBScale[1], accel); - GPU3D::SetDisplaySettings(bottomscale, accel); + GPU2D_A->SetDisplaySettings(ScreenScale[1], accel); + GPU3D::SetDisplaySettings(ScreenScale[1], accel); } } -- cgit v1.2.3 From db396e992b670fa419123474068e100c9f706b2f Mon Sep 17 00:00:00 2001 From: Arisotura 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.cpp') 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 From 0bb3321262fcdff4edc3636e7301db70e5ff0533 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Fri, 24 May 2019 02:29:16 +0200 Subject: getting somewhere?? --- src/GPU.cpp | 18 ++++++++++++------ src/GPU3D.cpp | 1 + src/libui_sdl/main.cpp | 34 +++++++++++++++++++++------------- 3 files changed, 34 insertions(+), 19 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index 959129e..a7ea2a4 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -151,12 +151,15 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - for (int i = 0; i < (256*192); i++) + int fbsize; + if (Accelerated) fbsize = (256*3 + 2) * 192; + else fbsize = 256 * 192; + for (int i = 0; i < fbsize; i++) { Framebuffer[0][0][i] = 0xFFFFFFFF; Framebuffer[1][0][i] = 0xFFFFFFFF; } - for (int i = 0; i < (256*192); i++) + for (int i = 0; i < fbsize; i++) { Framebuffer[0][1][i] = 0xFFFFFFFF; Framebuffer[1][1][i] = 0xFFFFFFFF; @@ -173,10 +176,13 @@ void Reset() void Stop() { - memset(Framebuffer[0][0], 0, 256*192); - memset(Framebuffer[0][1], 0, 256*192); - memset(Framebuffer[1][0], 0, 256*192); - memset(Framebuffer[1][1], 0, 256*192); + int fbsize; + if (Accelerated) fbsize = (256*3 + 2) * 192; + else fbsize = 256 * 192; + memset(Framebuffer[0][0], 0, fbsize*4); + memset(Framebuffer[0][1], 0, fbsize*4); + memset(Framebuffer[1][0], 0, fbsize*4); + memset(Framebuffer[1][1], 0, fbsize*4); } void DoSavestate(Savestate* file) diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 115b31f..770c874 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -624,6 +624,7 @@ int InitRenderer(bool hasGL) if (renderer == 0) SoftRenderer::Init(); Renderer = renderer; + GPU::SetDisplaySettings(Renderer != 0); return renderer; } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index efebc8d..e17827d 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -374,14 +374,24 @@ void GLScreen_DrawScreen() int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); - /*glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256<Context, 256, 192); ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192); - printf("D2D bitmaps inited\n"); } -if (!ScreenBitmap[0] || !ScreenBitmap[1]) printf("draw but no bitmaps :(\n"); + + int frontbuf = GPU::FrontBuffer; if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; - if (!GPU::Framebuffer[0][0]) return; + if (!GPU::Framebuffer[frontbuf][1]) return; uiRect top = {0, 0, 256, 192}; uiRect bot = {0, 0, 256, 192}; - int frontbuf = GPU::FrontBuffer; uiDrawBitmapUpdate(ScreenBitmap[0], GPU::Framebuffer[frontbuf][0]); uiDrawBitmapUpdate(ScreenBitmap[1], GPU::Framebuffer[frontbuf][1]); -- cgit v1.2.3 From 70a324371451b872dc5b4bba3cff696ad7a1cbb3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 19:36:47 +0200 Subject: simpler GPU-compositing. will make it easier to grab neighbor 2D/3D pixels individually for filtering. --- src/GPU.cpp | 6 +- src/GPU2D.cpp | 322 ++++++++++++++++++++++--------------------- src/GPU2D.h | 1 + src/GPU3D_OpenGL.cpp | 2 + src/libui_sdl/main.cpp | 44 +++--- src/libui_sdl/main_shaders.h | 142 +++++++------------ 6 files changed, 248 insertions(+), 269 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index a7ea2a4..fe23a77 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -152,7 +152,7 @@ void Reset() VRAMMap_ARM7[1] = 0; int fbsize; - if (Accelerated) fbsize = (256*3 + 2) * 192; + if (Accelerated) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; for (int i = 0; i < fbsize; i++) { @@ -177,7 +177,7 @@ void Reset() void Stop() { int fbsize; - if (Accelerated) fbsize = (256*3 + 2) * 192; + if (Accelerated) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; memset(Framebuffer[0][0], 0, fbsize*4); memset(Framebuffer[0][1], 0, fbsize*4); @@ -257,7 +257,7 @@ void SetDisplaySettings(bool accel) if (accel != Accelerated) { int fbsize; - if (accel) fbsize = (256*3 + 2) * 192; + if (accel) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 88249ba..4fe2209 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -617,10 +617,78 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) return rb | g | 0xFF000000; } +u32 GPU2D::ColorComposite(int i, u32 val1, u32 val2) +{ + u32 coloreffect = 0; + u32 eva, evb; + + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; + + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; + + if ((flag1 & 0x80) && (BlendCnt & target2)) + { + // sprite blending + + coloreffect = 1; + + if (flag1 & 0x40) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else + { + eva = EVA; + evb = EVB; + } + } + else if ((flag1 & 0x40) && (BlendCnt & target2)) + { + // 3D layer blending + + coloreffect = 4; + } + else + { + if (flag1 & 0x80) flag1 = 0x10; + else if (flag1 & 0x40) flag1 = 0x01; + + if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + { + coloreffect = (BlendCnt >> 6) & 0x3; + + if (coloreffect == 1) + { + if (BlendCnt & target2) + { + eva = EVA; + evb = EVB; + } + else + coloreffect = 0; + } + } + } + + switch (coloreffect) + { + case 0: return val1; + case 1: return ColorBlend4(val1, val2, eva, evb); + case 2: return ColorBrightnessUp(val1, EVY); + case 3: return ColorBrightnessDown(val1, EVY); + case 4: return ColorBlend5(val1, val2); + } +} + void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3 + 2) : 256; + int stride = Accelerated ? (256*3 + 1) : 256; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -648,7 +716,6 @@ void GPU2D::DrawScanline(u32 line) if (Accelerated) { dst[256*3] = 0; - dst[256*3 + 1] = 0; } return; } @@ -747,14 +814,7 @@ void GPU2D::DrawScanline(u32 line) if (Accelerated) { - u32 ctl = (BlendCnt & 0x3FFF); - ctl |= ((DispCnt & 0x30000) >> 2); - ctl |= (EVA << 16); - ctl |= (EVB << 21); - ctl |= (EVY << 26); - - dst[256*3] = ctl; - dst[256*3 + 1] = MasterBrightness; + dst[256*3] = MasterBrightness | (DispCnt & 0x30000); return; } @@ -858,111 +918,57 @@ void GPU2D::DoCapture(u32 line, u32 width) // but when doing display capture, we do need the composited output // so we do it here - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < 256; i++) { u32 val1 = BGOBJLine[i]; - u32 val3 = BGOBJLine[256+i]; - u32 val2 = BGOBJLine[512+i]; + u32 val2 = BGOBJLine[256+i]; + u32 val3 = BGOBJLine[512+i]; + + u32 compmode = (val3 >> 24) & 0xF; - if ((val1 >> 30) == 1) + if (compmode == 4) { - u32 _3dval = _3DLine[val1 & 0xFF]; + // 3D on top, blending + + u32 _3dval = _3DLine[val3 & 0xFF]; if ((_3dval >> 24) > 0) - { - val1 = _3dval | 0x40000000; - val2 = val3; - } + val1 = ColorBlend5(_3dval, val1); else - val1 = val3; + val1 = val2; } - else if ((val3 >> 30) == 1) + else if (compmode == 1) { + // 3D on bottom, blending + u32 _3dval = _3DLine[val3 & 0xFF]; if ((_3dval >> 24) > 0) - val2 = _3dval | 0x40000000; - } - else - val2 = val3; - - val1 &= ~0x00800000; - val2 &= ~0x00800000; - - u32 coloreffect, eva, evb; - - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; - - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; - - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending - - coloreffect = 1; - - if (flag1 & 0x40) { - eva = flag1 & 0x1F; - evb = 16 - eva; + u32 eva = (val3 >> 8) & 0x1F; + u32 evb = (val3 >> 16) & 0x1F; + + val1 = ColorBlend4(val1, _3dval, eva, evb); } else - { - eva = EVA; - evb = EVB; - } + val1 = val2; } - else if ((flag1 & 0x40) && (BlendCnt & target2)) + else if (compmode <= 3) { - // 3D layer blending + // 3D on top, normal/fade - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; - - if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + u32 _3dval = _3DLine[val3 & 0xFF]; + if ((_3dval >> 24) > 0) { - if ((bldcnteffect == 1) && (BlendCnt & target2)) - { - coloreffect = 1; - eva = EVA; - evb = EVB; - } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; - else - coloreffect = 0; + u32 evy = (val3 >> 8) & 0x1F; + + val1 = _3dval; + if (compmode == 2) val1 = ColorBrightnessUp(val1, evy); + else if (compmode == 3) val1 = ColorBrightnessDown(val1, evy); } else - coloreffect = 0; + val1 = val2; } - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; - - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; - - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; - - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; - } + BGOBJLine[i] = val1; } } } @@ -1374,94 +1380,102 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) if (!Accelerated) { - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < 256; i++) { u32 val1 = BGOBJLine[i]; u32 val2 = BGOBJLine[256+i]; - u32 coloreffect, eva, evb; + BGOBJLine[i] = ColorComposite(i, val1, val2); + } + } + else + { + if (Num == 0) + { + for (int i = 0; i < 256; i++) + { + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[256+i]; + u32 val3 = BGOBJLine[512+i]; - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; + u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending + u32 target1; + if (flag1 & 0x80) target1 = 0x0010; + else if (flag1 & 0x40) target1 = 0x0001; + else target1 = flag1; - coloreffect = 1; + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; - if (flag1 & 0x40) + if (((flag1 & 0xC0) == 0x40) && (BlendCnt & target2)) { - eva = flag1 & 0x1F; - evb = 16 - eva; + // 3D on top, blending + + BGOBJLine[i] = val2; + BGOBJLine[256+i] = ColorComposite(i, val2, val3); + BGOBJLine[512+i] = 0x04000000 | (val1 & 0xFF); } - else + else if ((flag1 & 0xC0) == 0x40) { - eva = EVA; - evb = EVB; - } - } - else if ((flag1 & 0x40) && (BlendCnt & target2)) - { - // 3D layer blending + // 3D on top, normal/fade - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; + if (bldcnteffect == 1) bldcnteffect = 0; + if (!(BlendCnt & 0x0001)) bldcnteffect = 0; + if (!(WindowMask[i] & 0x20)) bldcnteffect = 0; - if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + BGOBJLine[i] = val2; + BGOBJLine[256+i] = ColorComposite(i, val2, val3); + BGOBJLine[512+i] = (bldcnteffect << 24) | (EVY << 8) | (val1 & 0xFF); + } + else if (((flag2 & 0xC0) == 0x40) && ((BlendCnt & 0x01C0) == 0x0140)) { - if ((bldcnteffect == 1) && (BlendCnt & target2)) + // 3D on bottom, blending + + u32 eva, evb; + if ((flag1 & 0xC0) == 0xC0) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else if ((BlendCnt & target1) && (WindowMask[i] & 0x20)) { - coloreffect = 1; eva = EVA; evb = EVB; } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; else - coloreffect = 0; + bldcnteffect = 7; + + BGOBJLine[i] = val1; + BGOBJLine[256+i] = ColorComposite(i, val1, val3); + BGOBJLine[512+i] = (bldcnteffect << 24) | (EVB << 16) | (EVA << 8) | (val1 & 0xFF); } else - coloreffect = 0; - } - - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; - - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; - - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; + { + // no potential 3D pixel involved - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; + BGOBJLine[i] = ColorComposite(i, val1, val2); + BGOBJLine[256+i] = 0; + BGOBJLine[512+i] = 0x07000000; + } } } - } - else - { - for (int i = 0; i < 256; i++) + else { - BGOBJLine[i] |= ((WindowMask[i] & 0x20) << 18); + for (int i = 0; i < 256; i++) + { + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[256+i]; + + BGOBJLine[i] = ColorComposite(i, val1, val2); + BGOBJLine[256+i] = 0; + BGOBJLine[512+i] = 0x07000000; + } } } diff --git a/src/GPU2D.h b/src/GPU2D.h index 78e62f5..21b43f1 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -127,6 +127,7 @@ private: u32 ColorBlend5(u32 val1, u32 val2); u32 ColorBrightnessUp(u32 val, u32 factor); u32 ColorBrightnessDown(u32 val, u32 factor); + u32 ColorComposite(int i, u32 val1, u32 val2); template void DrawScanlineBGMode(u32 line, u32 nsprites); void DrawScanlineBGMode6(u32 line, u32 nsprites); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 9144792..c759147 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -890,6 +890,8 @@ void RenderSceneChunk(int y, int h) glBindBuffer(GL_ARRAY_BUFFER, ClearVertexBufferID); glBindVertexArray(ClearVertexArrayID); glDrawArrays(GL_TRIANGLES, 0, 2*3); + + glFlush(); } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 3a99d95..2e0c271 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -216,7 +216,7 @@ bool GLScreen_Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 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_RGBA8UI, 1024, 1536, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 256*3 + 1, 192*2, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); GL_ScreenSizeDirty = true; @@ -317,31 +317,31 @@ void GLScreen_DrawScreen() switch (ScreenRotation) { case 0: - s0 = 0; t0 = 768; - s1 = scwidth; t1 = 768; - s2 = 0; t2 = 768+scheight; - s3 = scwidth; t3 = 768+scheight; + s0 = 0; t0 = 192; + s1 = scwidth; t1 = 192; + s2 = 0; t2 = 192+scheight; + s3 = scwidth; t3 = 192+scheight; break; case 1: - s0 = 0; t0 = 768+scheight; - s1 = 0; t1 = 768; - s2 = scwidth; t2 = 768+scheight; - s3 = scwidth; t3 = 768; + s0 = 0; t0 = 192+scheight; + s1 = 0; t1 = 192; + s2 = scwidth; t2 = 192+scheight; + s3 = scwidth; t3 = 192; break; case 2: - s0 = scwidth; t0 = 768+scheight; - s1 = 0; t1 = 768+scheight; - s2 = scwidth; t2 = 768; - s3 = 0; t3 = 768; + s0 = scwidth; t0 = 192+scheight; + s1 = 0; t1 = 192+scheight; + s2 = scwidth; t2 = 192; + s3 = 0; t3 = 192; break; case 3: - s0 = scwidth; t0 = 768; - s1 = scwidth; t1 = 768+scheight; - s2 = 0; t2 = 768; - s3 = 0; t3 = 768+scheight; + s0 = scwidth; t0 = 192; + s1 = scwidth; t1 = 192+scheight; + s2 = 0; t2 = 192; + s3 = 0; t3 = 192+scheight; break; } @@ -381,14 +381,14 @@ void GLScreen_DrawScreen() { glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 2, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256*3 + 1, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 768, 256*3 + 2, 192, GL_RGBA_INTEGER, + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256*3 + 1, 192, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); } } @@ -2241,11 +2241,13 @@ void DestroyMainWindow() void RecreateMainWindow(bool opengl) { - int winX, winY; + int winX, winY, maxi; uiWindowPosition(MainWindow, &winX, &winY); + maxi = uiWindowMaximized(MainWindow); DestroyMainWindow(); CreateMainWindow(opengl); uiWindowSetPosition(MainWindow, winX, winY); + uiWindowSetMaximized(MainWindow, maxi); } diff --git a/src/libui_sdl/main_shaders.h b/src/libui_sdl/main_shaders.h index d6d898d..a855f1b 100644 --- a/src/libui_sdl/main_shaders.h +++ b/src/libui_sdl/main_shaders.h @@ -66,121 +66,81 @@ void main() { ivec4 pixel = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord), 0)); - // bit0-13: BLDCNT - // bit14-15: DISPCNT display mode - // bit16-20: EVA - // bit21-25: EVB - // bit26-30: EVY - ivec4 ctl = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); - ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3 + 1, int(fTexcoord.y)), 0)); - int dispmode = (ctl.g >> 6) & 0x3; + ivec4 mbright = ivec4(texelFetch(ScreenTex, ivec2(256*3, int(fTexcoord.y)), 0)); + int dispmode = mbright.b & 0x3; if (dispmode == 1) { - int eva = ctl.b & 0x1F; - int evb = (ctl.b >> 5) | ((ctl.a & 0x03) << 3); - int evy = ctl.a >> 2; + ivec4 val1 = pixel; + ivec4 val2 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); + ivec4 val3 = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); - ivec4 top = pixel; - ivec4 mid = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(256,0), 0)); - ivec4 bot = ivec4(texelFetch(ScreenTex, ivec2(fTexcoord) + ivec2(512,0), 0)); + int compmode = val3.a & 0xF; + int eva, evb, evy; - int winmask = top.b >> 7; - - if ((top.a & 0xC0) == 0x40) + if (compmode == 4) { - float xpos = top.r + fract(fTexcoord.x); - float ypos = mod(fTexcoord.y, 768); - ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra - * vec4(63,63,63,31)); + // 3D on top, blending - if (_3dpix.a > 0) { top = _3dpix; top.a |= 0x40; bot = mid; } - else top = mid; - } - else if ((mid.a & 0xC0) == 0x40) - { - float xpos = mid.r + fract(fTexcoord.x); - float ypos = mod(fTexcoord.y, 768); + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra * vec4(63,63,63,31)); - if (_3dpix.a > 0) { bot = _3dpix; bot.a |= 0x40; } - } - else - { - // conditional texture fetch no good for performance, apparently - //texelFetch(_3DTex, ivec2(0, fTexcoord.y*2), 0); - bot = mid; - } - - top.b &= 0x3F; - bot.b &= 0x3F; - - int target2; - if ((bot.a & 0x80) != 0) target2 = 0x10; - else if ((bot.a & 0x40) != 0) target2 = 0x01; - else target2 = bot.a; - bool t2pass = ((ctl.g & target2) != 0); - - int coloreffect = 0; + if (_3dpix.a > 0) + { + eva = (_3dpix.a & 0x1F) + 1; + evb = 32 - eva; - if ((top.a & 0x80) != 0 && t2pass) + val1 = ((_3dpix * eva) + (val1 * evb)) >> 5; + if (eva <= 16) val1 += ivec4(1,1,1,0); + val1 = min(val1, 0x3F); + } + else + val1 = val2; + } + else if (compmode == 1) { - // sprite blending + // 3D on bottom, blending - coloreffect = 1; + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); - if ((top.a & 0x40) != 0) + if (_3dpix.a > 0) { - eva = top.a & 0x1F; - evb = 16 - eva; + eva = val3.g; + evb = val3.b; + + val1 = ((val1 * eva) + (_3dpix * evb)) >> 4; + val1 = min(val1, 0x3F); } + else + val1 = val2; } - else if ((top.a & 0x40) != 0 && t2pass) + else if (compmode <= 3) { - // 3D layer blending + // 3D on top, normal/fade - coloreffect = 4; - eva = (top.a & 0x1F) + 1; - evb = 32 - eva; - } - else - { - if ((top.a & 0x80) != 0) top.a = 0x10; - else if ((top.a & 0x40) != 0) top.a = 0x01; + float xpos = val3.r + fract(fTexcoord.x); + float ypos = mod(fTexcoord.y, 192); + ivec4 _3dpix = ivec4(texelFetch(_3DTex, ivec2(vec2(xpos, ypos)*u3DScale), 0).bgra + * vec4(63,63,63,31)); - if ((ctl.r & top.a) != 0 && winmask != 0) + if (_3dpix.a > 0) { - int effect = ctl.r >> 6; - if ((effect != 1) || t2pass) coloreffect = effect; + evy = val3.g; + + val1 = _3dpix; + if (compmode == 2) val1 += ((ivec4(0x3F,0x3F,0x3F,0) - val1) * evy) >> 4; + else if (compmode == 3) val1 -= (val1 * evy) >> 4; } + else + val1 = val2; } - if (coloreffect == 0) - { - pixel = top; - } - else if (coloreffect == 1) - { - pixel = ((top * eva) + (bot * evb)) >> 4; - pixel = min(pixel, 0x3F); - } - else if (coloreffect == 2) - { - pixel = top; - pixel += ((ivec4(0x3F,0x3F,0x3F,0) - pixel) * evy) >> 4; - } - else if (coloreffect == 3) - { - pixel = top; - pixel -= (pixel * evy) >> 4; - } - else - { - pixel = ((top * eva) + (bot * evb)) >> 5; - if (eva <= 16) pixel += ivec4(1,1,1,0); - pixel = min(pixel, 0x3F); - } + pixel = val1; } if (dispmode != 0) -- cgit v1.2.3 From 9ed1dda9ca18e571fc6613885ac944bbb938cd9a Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sat, 25 May 2019 19:52:56 +0200 Subject: fix possible crash --- src/GPU.cpp | 41 +++++++++++++++++++---------------------- src/libui_sdl/main.cpp | 2 +- 2 files changed, 20 insertions(+), 23 deletions(-) (limited to 'src/GPU.cpp') diff --git a/src/GPU.cpp b/src/GPU.cpp index fe23a77..d1870fd 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -150,7 +150,7 @@ void Reset() VRAMMap_ARM7[0] = 0; VRAMMap_ARM7[1] = 0; - +printf("RESET: ACCEL=%d FRAMEBUFFER=%p\n", Accelerated, Framebuffer[0][0]); int fbsize; if (Accelerated) fbsize = (256*3 + 1) * 192; else fbsize = 256 * 192; @@ -254,27 +254,24 @@ void AssignFramebuffers() void SetDisplaySettings(bool accel) { - if (accel != Accelerated) - { - int fbsize; - if (accel) fbsize = (256*3 + 1) * 192; - else fbsize = 256 * 192; - if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; - if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; - if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; - if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; - Framebuffer[0][0] = new u32[fbsize]; - Framebuffer[1][0] = new u32[fbsize]; - Framebuffer[0][1] = new u32[fbsize]; - Framebuffer[1][1] = new u32[fbsize]; - - memset(Framebuffer[0][0], 0, fbsize*4); - memset(Framebuffer[1][0], 0, fbsize*4); - memset(Framebuffer[0][1], 0, fbsize*4); - memset(Framebuffer[1][1], 0, fbsize*4); - - AssignFramebuffers(); - } + int fbsize; + if (accel) fbsize = (256*3 + 1) * 192; + else fbsize = 256 * 192; + if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; + if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; + if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; + if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; + Framebuffer[0][0] = new u32[fbsize]; + Framebuffer[1][0] = new u32[fbsize]; + Framebuffer[0][1] = new u32[fbsize]; + Framebuffer[1][1] = new u32[fbsize]; + + memset(Framebuffer[0][0], 0, fbsize*4); + memset(Framebuffer[1][0], 0, fbsize*4); + memset(Framebuffer[0][1], 0, fbsize*4); + memset(Framebuffer[1][1], 0, fbsize*4); + + AssignFramebuffers(); GPU2D_A->SetDisplaySettings(accel); GPU2D_B->SetDisplaySettings(accel); diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index f6ef397..874d8ff 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -384,7 +384,7 @@ void GLScreen_DrawScreen() OpenGL_UseShaderProgram(GL_ScreenShaderAccel); glBindFramebuffer(GL_FRAMEBUFFER, 0); - glClearColor(0, 1, 0, 1); + glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); int frontbuf = GPU::FrontBuffer; -- cgit v1.2.3