From fb4f972cad62d0c84b563b6b53e313b6cf2c9029 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Wed, 8 May 2019 01:58:34 +0200 Subject: hires hax. somewhat functional --- src/GPU2D.h | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'src/GPU2D.h') diff --git a/src/GPU2D.h b/src/GPU2D.h index d7c4e3f..7ffe798 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -68,6 +68,9 @@ private: bool Enabled; u32* Framebuffer; + u32 LineStride; + u32 LineScale; + u16 DispFIFO[16]; u32 DispFIFOReadPtr; u32 DispFIFOWritePtr; @@ -114,13 +117,20 @@ private: u32 BGExtPalStatus[4]; u32 OBJExtPalStatus; - template void DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst); - void DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst); - void DrawScanline_Mode1(u32 line, u32* dst); + u32 ColorBlend4(u32 val1, u32 val2, u32 eva, u32 evb); + u32 ColorBlend5(u32 val1, u32 val2); + u32 ColorBrightnessUp(u32 val, u32 factor); + u32 ColorBrightnessDown(u32 val, u32 factor); + + template void DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx); + void DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx); + void DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx); - void DrawPixel(u32* dst, u16 color, u32 flag); + static void DrawPixel_1x(u32* dst, u16 color, u32 flag); + static void DrawPixel_2x(u32* dst, u16 color, u32 flag); + void (*DrawPixel)(u32* dst, u16 color, u32 flag); - void DrawBG_3D(u32 line, u32* dst); + void DrawBG_3D(u32 line, u32* dst, u32* src); void DrawBG_Text(u32 line, u32* dst, u32 bgnum); void DrawBG_Affine(u32 line, u32* dst, u32 bgnum); void DrawBG_Extended(u32 line, u32* dst, u32 bgnum); @@ -132,7 +142,7 @@ private: template void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst); template void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst); - void DoCapture(u32 line, u32 width, u32* src); + void DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx); void CalculateWindowMask(u32 line, u8* mask); }; -- cgit v1.2.3 From 2a0bc4e700d99de3e532eb3952081757f9e874df Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 15:45:58 +0200 Subject: make GPU2D somewhat more flexible. change LineScale to be log2. --- src/GPU2D.cpp | 302 ++++++++++++++++++++++++------------------------- src/GPU2D.h | 37 +++--- src/libui_sdl/main.cpp | 4 +- 3 files changed, 170 insertions(+), 173 deletions(-) (limited to 'src/GPU2D.h') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 505468d..0ddc5fb 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -613,15 +613,13 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { u32* dst = &Framebuffer[256*4*line]; - u32 mode1gfx[1024]; - u32* _3dgfx; // HAX - LineScale = 2; + LineScale = 1; LineStride = 1024; DrawPixel = DrawPixel_2x; - int _3dline = line; + int n3dline = line; line = GPU::VCount; bool forceblank = false; @@ -649,10 +647,10 @@ void GPU2D::DrawScanline(u32 line) dispmode &= (Num ? 0x1 : 0x3); if (Num == 0) - _3dgfx = GPU3D::GetLine(_3dline); + _3DLine = GPU3D::GetLine(n3dline); // always render regular graphics - DrawScanline_Mode1(line, mode1gfx, _3dgfx); + DrawScanline_Mode1(line); switch (dispmode) { @@ -666,7 +664,7 @@ void GPU2D::DrawScanline(u32 line) case 1: // regular display { for (int i = 0; i < LineStride; i+=2) - *(u64*)&dst[i] = *(u64*)&mode1gfx[i]; + *(u64*)&dst[i] = *(u64*)&BGOBJLine[i]; } break; @@ -685,9 +683,9 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - int d = i*LineScale; + int d = i << LineScale; dst[d] = r | (g << 8) | (b << 16); - if (LineScale >= 2) + if (LineScale == 1) { dst[d+1] = dst[d]; dst[d+512] = dst[d]; @@ -714,9 +712,9 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - int d = i*LineScale; + int d = i << LineScale; dst[d] = r | (g << 8) | (b << 16); - if (LineScale >= 2) + if (LineScale == 1) { dst[d+1] = dst[d]; dst[d+512] = dst[d]; @@ -740,7 +738,7 @@ void GPU2D::DrawScanline(u32 line) } if (line < capheight) - DoCapture(line, capwidth, mode1gfx, _3dgfx); + DoCapture(line, capwidth); } // master brightness @@ -809,7 +807,7 @@ void GPU2D::VBlankEnd() } -void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) +void GPU2D::DoCapture(u32 line, u32 width) { u32 dstvram = (CaptureCnt >> 16) & 0x3; @@ -821,8 +819,11 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) u16* dst = (u16*)GPU::VRAM[dstvram]; u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width); + u32* srcA; if (CaptureCnt & (1<<24)) - src = _3dgfx; + srcA = _3DLine; + else + srcA = BGOBJLine; u16* srcB = NULL; u32 srcBaddr = line * 256; @@ -851,7 +852,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) { for (u32 i = 0; i < width; i++) { - u32 val = src[i * LineScale]; + u32 val = srcA[i << LineScale]; // TODO: check what happens when alpha=0 @@ -902,7 +903,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) { for (u32 i = 0; i < width; i++) { - u32 val = src[i * LineScale]; + u32 val = srcA[i << LineScale]; // TODO: check what happens when alpha=0 @@ -936,7 +937,7 @@ void GPU2D::DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx) { for (u32 i = 0; i < width; i++) { - u32 val = src[i * LineScale]; + u32 val = srcA[i << LineScale]; // TODO: check what happens when alpha=0 @@ -1062,15 +1063,15 @@ void GPU2D::CheckWindows(u32 line) else if (line == Win1Coords[2]) Win1Active |= 0x1; } -void GPU2D::CalculateWindowMask(u32 line, u8* mask) +void GPU2D::CalculateWindowMask(u32 line) { for (u32 i = 0; i < 256; i++) - mask[i] = WinCnt[2]; // window outside + WindowMask[i] = WinCnt[2]; // window outside if ((DispCnt & (1<<15)) && (DispCnt & (1<<12))) { // OBJ window - DrawSpritesWindow(line, mask); + DrawSpritesWindow(line); } if (DispCnt & (1<<14)) @@ -1084,7 +1085,7 @@ void GPU2D::CalculateWindowMask(u32 line, u8* mask) if (i == x2) Win1Active &= ~0x2; else if (i == x1) Win1Active |= 0x2; - if (Win1Active == 0x3) mask[i] = WinCnt[1]; + if (Win1Active == 0x3) WindowMask[i] = WinCnt[1]; } } @@ -1099,14 +1100,14 @@ void GPU2D::CalculateWindowMask(u32 line, u8* mask) if (i == x2) Win0Active &= ~0x2; else if (i == x1) Win0Active |= 0x2; - if (Win0Active == 0x3) mask[i] = WinCnt[0]; + if (Win0Active == 0x3) WindowMask[i] = WinCnt[0]; } } } template -void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx) +void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites) { for (int i = 3; i >= 0; i--) { @@ -1115,11 +1116,11 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, if (DispCnt & 0x0800) { if (bgmode >= 3) - DrawBG_Extended(line, dst, 3); + DrawBG_Extended(line, 3); else if (bgmode >= 1) - DrawBG_Affine(line, dst, 3); + DrawBG_Affine(line, 3); else - DrawBG_Text(line, dst, 3); + DrawBG_Text(line, 3); } } if ((BGCnt[2] & 0x3) == i) @@ -1127,18 +1128,18 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, if (DispCnt & 0x0400) { if (bgmode == 5) - DrawBG_Extended(line, dst, 2); + DrawBG_Extended(line, 2); else if (bgmode == 4 || bgmode == 2) - DrawBG_Affine(line, dst, 2); + DrawBG_Affine(line, 2); else - DrawBG_Text(line, dst, 2); + DrawBG_Text(line, 2); } } if ((BGCnt[1] & 0x3) == i) { if (DispCnt & 0x0200) { - DrawBG_Text(line, dst, 1); + DrawBG_Text(line, 1); } } if ((BGCnt[0] & 0x3) == i) @@ -1146,17 +1147,17 @@ void GPU2D::DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, if (DispCnt & 0x0100) { if ((!Num) && (DispCnt & 0x8)) - DrawBG_3D(line, dst, _3dgfx); + DrawBG_3D(); else - DrawBG_Text(line, dst, 0); + DrawBG_Text(line, 0); } } if ((DispCnt & 0x1000) && nsprites) - InterleaveSprites(spritebuf, 0x8000 | (i<<16), dst); + InterleaveSprites(0x8000 | (i<<16)); } } -void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx) +void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites) { if (Num) { @@ -1170,7 +1171,7 @@ void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst { if (DispCnt & 0x0400) { - DrawBG_Large(line, dst); + DrawBG_Large(line); } } if ((BGCnt[0] & 0x3) == i) @@ -1178,19 +1179,16 @@ void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst if (DispCnt & 0x0100) { if (DispCnt & 0x8) - DrawBG_3D(line, dst, _3dgfx); + DrawBG_3D(); } } if ((DispCnt & 0x1000) && nsprites) - InterleaveSprites(spritebuf, 0x8000 | (i<<16), dst); + InterleaveSprites(0x8000 | (i<<16)); } } -void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) +void GPU2D::DrawScanline_Mode1(u32 line) { - u32 linebuf[1024*2 + 64]; - u8* windowmask = (u8*)&linebuf[1024*2]; - u64 backdrop; if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; else backdrop = *(u16*)&GPU::Palette[0]; @@ -1204,29 +1202,29 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) backdrop |= (backdrop << 32); for (int i = 0; i < LineStride; i+=2) - *(u64*)&linebuf[i] = backdrop; + *(u64*)&BGOBJLine[i] = backdrop; } if (DispCnt & 0xE000) - CalculateWindowMask(line, windowmask); + CalculateWindowMask(line); else - memset(windowmask, 0xFF, 256); + memset(WindowMask, 0xFF, 256); // prerender sprites - u32 spritebuf[256]; u32 nsprites = 0; - memset(spritebuf, 0, 256*4); - if (DispCnt & 0x1000) nsprites = DrawSprites(line, spritebuf); + u32 nsprites = 0; + memset(OBJLine, 0, 256*4); + if (DispCnt & 0x1000) nsprites = DrawSprites(line); // TODO: what happens in mode 7? mode 6 on the sub engine? switch (DispCnt & 0x7) { - case 0: DrawScanlineBGMode<0>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 1: DrawScanlineBGMode<1>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 2: DrawScanlineBGMode<2>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 3: DrawScanlineBGMode<3>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 4: DrawScanlineBGMode<4>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 5: DrawScanlineBGMode<5>(line, nsprites, spritebuf, linebuf, _3dgfx); break; - case 6: DrawScanlineBGMode6(line, nsprites, spritebuf, linebuf, _3dgfx); break; + case 0: DrawScanlineBGMode<0>(line, nsprites); break; + case 1: DrawScanlineBGMode<1>(line, nsprites); break; + case 2: DrawScanlineBGMode<2>(line, nsprites); break; + case 3: DrawScanlineBGMode<3>(line, nsprites); break; + case 4: DrawScanlineBGMode<4>(line, nsprites); break; + case 5: DrawScanlineBGMode<5>(line, nsprites); break; + case 6: DrawScanlineBGMode6(line, nsprites); break; } // color special effects @@ -1236,10 +1234,10 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) for (int i = 0; i < LineStride; i++) { - int j = (i & 0x1FF) >> 1; // FIXME!!!!!! + int j = (i >> LineScale) & 0xFF; - u32 val1 = linebuf[i]; - u32 val2 = linebuf[1024+i]; + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[4096+i]; u32 coloreffect, eva, evb; @@ -1272,7 +1270,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) { // 3D layer blending - dst[i] = ColorBlend5(val1, val2); + BGOBJLine[i] = ColorBlend5(val1, val2); continue; } else @@ -1280,7 +1278,7 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) if (flag1 & 0x80) flag1 = 0x10; else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (windowmask[j] & 0x20)) + if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) { if ((bldcnteffect == 1) && (BlendCnt & target2)) { @@ -1300,19 +1298,19 @@ void GPU2D::DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx) switch (coloreffect) { case 0: - dst[i] = val1; + BGOBJLine[i] = val1; break; case 1: - dst[i] = ColorBlend4(val1, val2, eva, evb); + BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); break; case 2: - dst[i] = ColorBrightnessUp(val1, EVY); + BGOBJLine[i] = ColorBrightnessUp(val1, EVY); break; case 3: - dst[i] = ColorBrightnessDown(val1, EVY); + BGOBJLine[i] = ColorBrightnessDown(val1, EVY); break; } } @@ -1341,7 +1339,7 @@ void GPU2D::DrawPixel_1x(u32* dst, u16 color, u32 flag) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - *(dst+1024) = *dst; + *(dst+4096) = *dst; *dst = r | (g << 8) | (b << 16) | flag; } @@ -1354,17 +1352,15 @@ void GPU2D::DrawPixel_2x(u32* dst, u16 color, u32 flag) u64 val = r | (g << 8) | (b << 16) | flag; val |= (val << 32); - *(u64*)(dst+1024) = *(u64*)dst; - *(u64*)(dst+1536) = *(u64*)(dst+512); + *(u64*)(dst+4096) = *(u64*)dst; + *(u64*)(dst+4096+512) = *(u64*)(dst+512); *(u64*)dst = val; *(u64*)(dst+512) = val; } -void GPU2D::DrawBG_3D(u32 line, u32* dst, u32* src) +void GPU2D::DrawBG_3D() { - u8* windowmask = (u8*)&dst[1024*2]; - u16 xoff = BGXPos[0]; int i = 0; int iend = 256; @@ -1383,61 +1379,60 @@ void GPU2D::DrawBG_3D(u32 line, u32* dst, u32* src) { for (; i < iend; i++) { - u32 c = src[xoff]; - xoff++; - - if ((c >> 24) == 0) continue; - if (!(windowmask[i] & 0x01)) continue; - - dst[i+1024] = dst[i]; - dst[i] = c | 0x40000000; - } - } - else if (LineScale == 2) - { - for (; i < iend; i++) - { - int is = i * 2; - int xs = xoff * 2; + int is = i << 1; + int xs = xoff << 1; u32 c; xoff++; - if (!(windowmask[i] & 0x01)) continue; + if (!(WindowMask[i] & 0x01)) continue; - c = src[xs]; + c = _3DLine[xs]; if ((c >> 24) != 0) { - dst[is+1024] = dst[is]; - dst[is] = c | 0x40000000; + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; } - c = src[xs+1]; is++; + c = _3DLine[xs+1]; is++; if ((c >> 24) != 0) { - dst[is+1024] = dst[is]; - dst[is] = c | 0x40000000; + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; } - c = src[xs+512]; is += 511; + c = _3DLine[xs+512]; is += 511; if ((c >> 24) != 0) { - dst[is+1024] = dst[is]; - dst[is] = c | 0x40000000; + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; } - c = src[xs+513]; is++; + c = _3DLine[xs+513]; is++; if ((c >> 24) != 0) { - dst[is+1024] = dst[is]; - dst[is] = c | 0x40000000; + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; } } } + else + { + for (; i < iend; i++) + { + u32 c = _3DLine[xoff]; + xoff++; + + if ((c >> 24) == 0) continue; + if (!(WindowMask[i] & 0x01)) continue; + + BGOBJLine[i+4096] = BGOBJLine[i]; + BGOBJLine[i] = c | 0x40000000; + } + } } -void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum) +void GPU2D::DrawBG_Text(u32 line, u32 bgnum) { - u8* windowmask = (u8*)&dst[1024*2]; u16 bgcnt = BGCnt[bgnum]; u32 xmos = 0, xmossize = 0; @@ -1522,7 +1517,7 @@ void GPU2D::DrawBG_Text(u32 line, u32* dst, u32 bgnum) } // draw pixel - if (windowmask[i] & (1< 0) { if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000< 0) { if (color & 0x8000) - DrawPixel(&dst[i*LineScale], color, 0x01000000<(tilemapaddr + (((((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)) << 1)); if (color & 0x8000) - DrawPixel(&dst[i*LineScale], color, 0x01000000< 0) { if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000< 0) { if (color) - DrawPixel(&dst[i*LineScale], curpal[color], 0x01000000<(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&dst[i*LineScale], curpal[color], 0x01000000< 0) { if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<<2); + DrawPixel(&BGOBJLine[i<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&dst[i*LineScale], pal[color], 0x01000000<<2); + DrawPixel(&BGOBJLine[i<> 9) & 0x1F; - DrawSprite_Rotscale(attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos, dst); + DrawSprite_Rotscale(attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos); nsprites++; } else @@ -2082,7 +2072,7 @@ u32 GPU2D::DrawSprites(u32 line, u32* dst) if (attrib[1] & 0x2000) ypos = height-1 - ypos; - DrawSprite_Normal(attrib, width, xpos, ypos, dst); + DrawSprite_Normal(attrib, width, xpos, ypos); nsprites++; } } @@ -2091,7 +2081,7 @@ u32 GPU2D::DrawSprites(u32 line, u32* dst) return nsprites; } -void GPU2D::DrawSpritesWindow(u32 line, u8* dst) +void GPU2D::DrawSpritesWindow(u32 line) { u16* oam = (u16*)&GPU::OAM[Num ? 0x400 : 0]; @@ -2142,7 +2132,7 @@ void GPU2D::DrawSpritesWindow(u32 line, u8* dst) u32 rotparamgroup = (attrib[1] >> 9) & 0x1F; - DrawSprite_Rotscale(attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos, (u32*)dst); + DrawSprite_Rotscale(attrib, &oam[(rotparamgroup*16) + 3], boundwidth, boundheight, width, height, xpos, ypos); } else { @@ -2166,13 +2156,13 @@ void GPU2D::DrawSpritesWindow(u32 line, u8* dst) if (attrib[1] & 0x2000) ypos = height-1 - ypos; - DrawSprite_Normal(attrib, width, xpos, ypos, (u32*)dst); + DrawSprite_Normal(attrib, width, xpos, ypos); } } } template -void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst) +void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos) { u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000; u32 tilenum = attrib[2] & 0x03FF; @@ -2274,8 +2264,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 if (color & 0x8000) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = color | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = color | prio; } } else @@ -2338,8 +2328,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } } else @@ -2396,8 +2386,8 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } } else @@ -2416,7 +2406,7 @@ void GPU2D::DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 } template -void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst) +void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos) { u32 prio = ((attrib[2] & 0x0C00) << 6) | 0x8000; u32 tilenum = attrib[2] & 0x03FF; @@ -2510,8 +2500,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color & 0x8000) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = color | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = color | prio; } xoff++; @@ -2537,8 +2527,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color & 0x8000) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = color | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = color | prio; } xoff++; @@ -2597,8 +2587,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } xoff++; @@ -2626,8 +2616,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } xoff++; @@ -2675,8 +2665,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } xoff++; @@ -2709,8 +2699,8 @@ void GPU2D::DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* d if (color) { - if (window) ((u8*)dst)[xpos] = WinCnt[3]; - else dst[xpos] = pal[color] | prio; + if (window) WindowMask[xpos] = WinCnt[3]; + else OBJLine[xpos] = pal[color] | prio; } xoff++; diff --git a/src/GPU2D.h b/src/GPU2D.h index 7ffe798..bc50e1a 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,6 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); + void SetScale(int scale); u8 Read8(u32 addr); u16 Read16(u32 addr); @@ -71,6 +72,12 @@ private: u32 LineStride; u32 LineScale; + u32 BGOBJLine[1024*4 * 2]; + u32* _3DLine; + + u8 WindowMask[256]; + u32 OBJLine[256]; + u16 DispFIFO[16]; u32 DispFIFOReadPtr; u32 DispFIFOWritePtr; @@ -122,29 +129,29 @@ private: u32 ColorBrightnessUp(u32 val, u32 factor); u32 ColorBrightnessDown(u32 val, u32 factor); - template void DrawScanlineBGMode(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx); - void DrawScanlineBGMode6(u32 line, u32 nsprites, u32* spritebuf, u32* dst, u32* _3dgfx); - void DrawScanline_Mode1(u32 line, u32* dst, u32* _3dgfx); + template void DrawScanlineBGMode(u32 line, u32 nsprites); + void DrawScanlineBGMode6(u32 line, u32 nsprites); + void DrawScanline_Mode1(u32 line); static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); void (*DrawPixel)(u32* dst, u16 color, u32 flag); - void DrawBG_3D(u32 line, u32* dst, u32* src); - void DrawBG_Text(u32 line, u32* dst, u32 bgnum); - void DrawBG_Affine(u32 line, u32* dst, u32 bgnum); - void DrawBG_Extended(u32 line, u32* dst, u32 bgnum); - void DrawBG_Large(u32 line, u32* dst); + void DrawBG_3D(); + void DrawBG_Text(u32 line, u32 bgnum); + void DrawBG_Affine(u32 line, u32 bgnum); + void DrawBG_Extended(u32 line, u32 bgnum); + void DrawBG_Large(u32 line); - void InterleaveSprites(u32* buf, u32 prio, u32* dst); - u32 DrawSprites(u32 line, u32* dst); - void DrawSpritesWindow(u32 line, u8* dst); - template void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos, u32* dst); - template void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos, u32* dst); + void InterleaveSprites(u32 prio); + u32 DrawSprites(u32 line); + void DrawSpritesWindow(u32 line); + template void DrawSprite_Rotscale(u16* attrib, u16* rotparams, u32 boundwidth, u32 boundheight, u32 width, u32 height, s32 xpos, s32 ypos); + template void DrawSprite_Normal(u16* attrib, u32 width, s32 xpos, s32 ypos); - void DoCapture(u32 line, u32 width, u32* src, u32* _3dgfx); + void DoCapture(u32 line, u32 width); - void CalculateWindowMask(u32 line, u8* mask); + void CalculateWindowMask(u32 line); }; #endif diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index c8454ed..ab7ed33 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -637,8 +637,8 @@ void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) if (!ScreenDrawInited) { ScreenDrawInited = true; - ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); - ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 384*ScreenScale); + ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 192*ScreenScale); + ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256*ScreenScale, 192*ScreenScale); } if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; -- cgit v1.2.3 From a32c5c99bbfc46f8284f8903e9a9ec506d4ac5f3 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 12 May 2019 15:58:12 +0200 Subject: finish de-hardcoding it. also, code 4x variant (not that I guarantee it to be fast, but hey, it's here) --- src/GPU2D.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/GPU2D.h | 1 + 2 files changed, 108 insertions(+), 6 deletions(-) (limited to 'src/GPU2D.h') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 0ddc5fb..521d86a 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -82,6 +82,7 @@ GPU2D::GPU2D(u32 num) { Num = num; + SetScale(0); } GPU2D::~GPU2D() @@ -215,6 +216,16 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } +void GPU2D::SetScale(int scale) +{ + LineScale = scale; + LineStride = 256 << (scale*2); + + if (scale == 1) DrawPixel = DrawPixel_2x; + else if (scale == 2) DrawPixel = DrawPixel_4x; + else DrawPixel = DrawPixel_1x; +} + u8 GPU2D::Read8(u32 addr) { @@ -612,12 +623,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - u32* dst = &Framebuffer[256*4*line]; - - // HAX - LineScale = 1; - LineStride = 1024; - DrawPixel = DrawPixel_2x; + u32* dst = &Framebuffer[LineStride * line]; int n3dline = line; line = GPU::VCount; @@ -691,6 +697,24 @@ void GPU2D::DrawScanline(u32 line) dst[d+512] = dst[d]; dst[d+513] = dst[d]; } + else if (LineScale == 2) + { + dst[d+1] = dst[d]; + dst[d+2] = dst[d]; + dst[d+3] = dst[d]; + dst[d+1024] = dst[d]; + dst[d+1024+1] = dst[d]; + dst[d+1024+2] = dst[d]; + dst[d+1024+3] = dst[d]; + dst[d+2048] = dst[d]; + dst[d+2048+1] = dst[d]; + dst[d+2048+2] = dst[d]; + dst[d+2048+3] = dst[d]; + dst[d+3072] = dst[d]; + dst[d+3072+1] = dst[d]; + dst[d+3072+2] = dst[d]; + dst[d+3072+3] = dst[d]; + } } } else @@ -720,6 +744,24 @@ void GPU2D::DrawScanline(u32 line) dst[d+512] = dst[d]; dst[d+513] = dst[d]; } + else if (LineScale == 2) + { + dst[d+1] = dst[d]; + dst[d+2] = dst[d]; + dst[d+3] = dst[d]; + dst[d+1024] = dst[d]; + dst[d+1024+1] = dst[d]; + dst[d+1024+2] = dst[d]; + dst[d+1024+3] = dst[d]; + dst[d+2048] = dst[d]; + dst[d+2048+1] = dst[d]; + dst[d+2048+2] = dst[d]; + dst[d+2048+3] = dst[d]; + dst[d+3072] = dst[d]; + dst[d+3072+1] = dst[d]; + dst[d+3072+2] = dst[d]; + dst[d+3072+3] = dst[d]; + } } } break; @@ -1359,6 +1401,34 @@ void GPU2D::DrawPixel_2x(u32* dst, u16 color, u32 flag) *(u64*)(dst+512) = val; } +void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag) +{ + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + u64 val = r | (g << 8) | (b << 16) | flag; + val |= (val << 32); + + *(u64*)(dst+4096) = *(u64*)dst; + *(u64*)(dst+4096+2) = *(u64*)(dst+2); + *(u64*)(dst+4096+1024) = *(u64*)(dst+1024); + *(u64*)(dst+4096+1024+2) = *(u64*)(dst+1024+2); + *(u64*)(dst+4096+2048) = *(u64*)(dst+2048); + *(u64*)(dst+4096+2048+2) = *(u64*)(dst+2048+2); + *(u64*)(dst+4096+3072) = *(u64*)(dst+3072); + *(u64*)(dst+4096+3072+2) = *(u64*)(dst+3072+2); + + *(u64*)dst = val; + *(u64*)(dst+2) = val; + *(u64*)(dst+1024) = val; + *(u64*)(dst+1024+2) = val; + *(u64*)(dst+2048) = val; + *(u64*)(dst+2048+2) = val; + *(u64*)(dst+3072) = val; + *(u64*)(dst+3072+2) = val; +} + void GPU2D::DrawBG_3D() { u16 xoff = BGXPos[0]; @@ -1415,6 +1485,37 @@ void GPU2D::DrawBG_3D() } } } + else if (LineScale == 2) + { + for (; i < iend; i++) + { + int is = i << 1; + int xs = xoff << 1; + u32 c; + + xoff++; + if (!(WindowMask[i] & 0x01)) continue; + + for (int by = 0; by < 4; by++) + { + for (int bx = 0; bx < 4; bx++) + { + c = _3DLine[xs]; + if ((c >> 24) != 0) + { + BGOBJLine[is+4096] = BGOBJLine[is]; + BGOBJLine[is] = c | 0x40000000; + } + + is++; + xs++; + } + + is += 1021; + xs += 1021; + } + } + } else { for (; i < iend; i++) diff --git a/src/GPU2D.h b/src/GPU2D.h index bc50e1a..aca1f7e 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -135,6 +135,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); void (*DrawPixel)(u32* dst, u16 color, u32 flag); void DrawBG_3D(); -- 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/GPU2D.h') diff --git a/melonDS.cbp b/melonDS.cbp index ff01ebf..0bdac7f 100644 --- a/melonDS.cbp +++ b/melonDS.cbp @@ -107,6 +107,7 @@ + diff --git a/src/GPU.cpp b/src/GPU.cpp index f4e9fd4..1d073f5 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -74,6 +74,7 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; int FBScale[2]; +bool Accelerated; GPU2D* GPU2D_A; GPU2D* GPU2D_B; @@ -88,9 +89,8 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; - FBScale[0] = -1; FBScale[1] = -1; - //SetFramebufferScale(1); - SetFramebufferScale(1, 1); + FBScale[0] = -1; FBScale[1] = -1; Accelerated = false; + SetDisplaySettings(0, 0, false); return true; } @@ -247,13 +247,15 @@ void AssignFramebuffers() } } -void SetFramebufferScale(int top, int bottom) -{ - if (top != FBScale[0]) +void SetDisplaySettings(int topscale, int bottomscale, bool accel) +{accel=true; + if (topscale != FBScale[0] || accel != Accelerated) { - FBScale[0] = top; + FBScale[0] = accel ? 0 : topscale; - int fbsize = (256 * 192) << (FBScale[0] * 2); + int fbsize; + if (accel) fbsize = 256*3 * 192; + else fbsize = (256 * 192) << (FBScale[0] * 2); if (Framebuffer[0][0]) delete[] Framebuffer[0][0]; if (Framebuffer[1][0]) delete[] Framebuffer[1][0]; Framebuffer[0][0] = new u32[fbsize]; @@ -266,21 +268,23 @@ void SetFramebufferScale(int top, int bottom) if (NDS::PowerControl9 & (1<<15)) { GPU2D_A->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_A->SetScale(FBScale[0]); - GPU3D::SetScale(FBScale[0]); + GPU2D_A->SetDisplaySettings(FBScale[0], accel); + GPU3D::SetDisplaySettings(topscale, accel); } else { GPU2D_B->SetFramebuffer(Framebuffer[backbuf][0]); - GPU2D_B->SetScale(FBScale[0]); + GPU2D_B->SetDisplaySettings(FBScale[0], accel); } } - if (bottom != FBScale[1]) + if (bottomscale != FBScale[1] || accel != Accelerated) { - FBScale[1] = bottom; + FBScale[1] = accel ? 0 : bottomscale; - int fbsize = (256 * 192) << (FBScale[1] * 2); + int fbsize; + if (accel) fbsize = 256*3 * 192; + else fbsize = (256 * 192) << (FBScale[1] * 2); if (Framebuffer[0][1]) delete[] Framebuffer[0][1]; if (Framebuffer[1][1]) delete[] Framebuffer[1][1]; Framebuffer[0][1] = new u32[fbsize]; @@ -293,15 +297,17 @@ void SetFramebufferScale(int top, int bottom) if (NDS::PowerControl9 & (1<<15)) { GPU2D_B->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_B->SetScale(FBScale[1]); + GPU2D_B->SetDisplaySettings(FBScale[1], accel); } else { GPU2D_A->SetFramebuffer(Framebuffer[backbuf][1]); - GPU2D_A->SetScale(FBScale[1]); - GPU3D::SetScale(FBScale[1]); + GPU2D_A->SetDisplaySettings(FBScale[1], accel); + GPU3D::SetDisplaySettings(bottomscale, accel); } } + + Accelerated = accel; } diff --git a/src/GPU.h b/src/GPU.h index 2e47fc4..cfa8d7d 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -75,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetFramebufferScale(int top, int bottom); +void SetDisplaySettings(int topscale, int bottomscale, bool accel); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 3a99964..34c17ff 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -82,7 +82,6 @@ GPU2D::GPU2D(u32 num) { Num = num; - SetScale(0); } GPU2D::~GPU2D() @@ -216,12 +215,16 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } -void GPU2D::SetScale(int scale) +void GPU2D::SetDisplaySettings(int scale, bool accel) { + if (accel) scale = 0; + Accelerated = accel; + LineScale = scale; LineStride = 256 << (scale*2); - if (scale == 1) DrawPixel = DrawPixel_2x; + if (Accelerated) DrawPixel = DrawPixel_Accel; + else if (scale == 1) DrawPixel = DrawPixel_2x; else if (scale == 2) DrawPixel = DrawPixel_4x; else DrawPixel = DrawPixel_1x; } @@ -623,7 +626,8 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - u32* dst = &Framebuffer[LineStride * line]; + int stride = Accelerated ? (256*3) : LineStride; + u32* dst = &Framebuffer[stride * line]; int n3dline = line; line = GPU::VCount; @@ -652,7 +656,7 @@ void GPU2D::DrawScanline(u32 line) u32 dispmode = DispCnt >> 16; dispmode &= (Num ? 0x1 : 0x3); - if (Num == 0) + if (Num == 0 && !Accelerated) _3DLine = GPU3D::GetLine(n3dline); // always render regular graphics @@ -663,13 +667,13 @@ void GPU2D::DrawScanline(u32 line) case 0: // screen off { for (int i = 0; i < LineStride; i++) - dst[i] = 0xFF3F3F3F; + dst[i] = 0x003F3F3F; } break; case 1: // regular display { - for (int i = 0; i < LineStride; i+=2) + for (int i = 0; i < stride; i+=2) *(u64*)&dst[i] = *(u64*)&BGOBJLine[i]; } break; @@ -783,6 +787,8 @@ void GPU2D::DrawScanline(u32 line) DoCapture(line, capwidth); } + if (Accelerated) return; + // master brightness if (dispmode != 0) { @@ -861,6 +867,8 @@ void GPU2D::DoCapture(u32 line, u32 width) u16* dst = (u16*)GPU::VRAM[dstvram]; u32 dstaddr = (((CaptureCnt >> 18) & 0x3) << 14) + (line * width); + // TODO: handle 3D in accelerated mode!! + u32* srcA; if (CaptureCnt & (1<<24)) srcA = _3DLine; @@ -1272,88 +1280,91 @@ void GPU2D::DrawScanline_Mode1(u32 line) // color special effects // can likely be optimized - u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - - for (int i = 0; i < LineStride; i++) + if (!Accelerated) { - int j = (i >> LineScale) & 0xFF; + u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - u32 val1 = BGOBJLine[i]; - u32 val2 = BGOBJLine[4096+i]; + for (int i = 0; i < LineStride; i++) + { + int j = (i >> LineScale) & 0xFF; - u32 coloreffect, eva, evb; + u32 val1 = BGOBJLine[i]; + u32 val2 = BGOBJLine[4096+i]; - u32 flag1 = val1 >> 24; - u32 flag2 = val2 >> 24; + u32 coloreffect, eva, evb; - u32 target2; - if (flag2 & 0x80) target2 = 0x1000; - else if (flag2 & 0x40) target2 = 0x0100; - else target2 = flag2 << 8; + u32 flag1 = val1 >> 24; + u32 flag2 = val2 >> 24; - if ((flag1 & 0x80) && (BlendCnt & target2)) - { - // sprite blending + u32 target2; + if (flag2 & 0x80) target2 = 0x1000; + else if (flag2 & 0x40) target2 = 0x0100; + else target2 = flag2 << 8; - coloreffect = 1; + if ((flag1 & 0x80) && (BlendCnt & target2)) + { + // sprite blending + + coloreffect = 1; - if (flag1 & 0x40) + if (flag1 & 0x40) + { + eva = flag1 & 0x1F; + evb = 16 - eva; + } + else + { + eva = EVA; + evb = EVB; + } + } + else if ((flag1 & 0x40) && (BlendCnt & target2)) { - eva = flag1 & 0x1F; - evb = 16 - eva; + // 3D layer blending + + BGOBJLine[i] = ColorBlend5(val1, val2); + continue; } else { - eva = EVA; - evb = EVB; - } - } - else if ((flag1 & 0x40) && (BlendCnt & target2)) - { - // 3D layer blending - - BGOBJLine[i] = ColorBlend5(val1, val2); - continue; - } - else - { - if (flag1 & 0x80) flag1 = 0x10; - else if (flag1 & 0x40) flag1 = 0x01; + if (flag1 & 0x80) flag1 = 0x10; + else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) - { - if ((bldcnteffect == 1) && (BlendCnt & target2)) + if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) { - coloreffect = 1; - eva = EVA; - evb = EVB; + if ((bldcnteffect == 1) && (BlendCnt & target2)) + { + coloreffect = 1; + eva = EVA; + evb = EVB; + } + else if (bldcnteffect >= 2) + coloreffect = bldcnteffect; + else + coloreffect = 0; } - else if (bldcnteffect >= 2) - coloreffect = bldcnteffect; else coloreffect = 0; } - else - coloreffect = 0; - } - switch (coloreffect) - { - case 0: - BGOBJLine[i] = val1; - break; + switch (coloreffect) + { + case 0: + BGOBJLine[i] = val1; + break; - case 1: - BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); - break; + case 1: + BGOBJLine[i] = ColorBlend4(val1, val2, eva, evb); + break; - case 2: - BGOBJLine[i] = ColorBrightnessUp(val1, EVY); - break; + case 2: + BGOBJLine[i] = ColorBrightnessUp(val1, EVY); + break; - case 3: - BGOBJLine[i] = ColorBrightnessDown(val1, EVY); - break; + case 3: + BGOBJLine[i] = ColorBrightnessDown(val1, EVY); + break; + } } } @@ -1429,6 +1440,17 @@ void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag) *(u64*)(dst+3072+2) = val; } +void GPU2D::DrawPixel_Accel(u32* dst, u16 color, u32 flag) +{ + u8 r = (color & 0x001F) << 1; + u8 g = (color & 0x03E0) >> 4; + u8 b = (color & 0x7C00) >> 9; + + *(dst+512) = *(dst+256); + *(dst+256) = *dst; + *dst = r | (g << 8) | (b << 16) | flag; +} + void GPU2D::DrawBG_3D() { u16 xoff = BGXPos[0]; @@ -1445,7 +1467,18 @@ void GPU2D::DrawBG_3D() iend -= (xoff & 0xFF); } - if (LineScale == 1) + if (Accelerated) + { + for (; i < iend; i++) + { + if (!(WindowMask[i] & 0x01)) continue; + + BGOBJLine[i+512] = BGOBJLine[i+256]; + BGOBJLine[i+256] = BGOBJLine[i]; + BGOBJLine[i] = 0x40000000; // 3D-layer placeholder + } + } + else if (LineScale == 1) { for (; i < iend; i++) { diff --git a/src/GPU2D.h b/src/GPU2D.h index aca1f7e..fc420a5 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,7 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); - void SetScale(int scale); + void SetDisplaySettings(int scale, bool accel); u8 Read8(u32 addr); u16 Read16(u32 addr); @@ -71,6 +71,7 @@ private: u32 LineStride; u32 LineScale; + bool Accelerated; u32 BGOBJLine[1024*4 * 2]; u32* _3DLine; @@ -136,6 +137,7 @@ private: static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); static void DrawPixel_4x(u32* dst, u16 color, u32 flag); + static void DrawPixel_Accel(u32* dst, u16 color, u32 flag); void (*DrawPixel)(u32* dst, u16 color, u32 flag); void DrawBG_3D(); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 8c0588d..61629a7 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -607,9 +607,9 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { - GLRenderer43::SetScale(scale); + GLRenderer43::SetDisplaySettings(scale, accel); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 68bc696..2fe5bee 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,7 +97,7 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void ExecuteCommand(); @@ -110,6 +110,7 @@ void VCount144(); void VBlank(); void VCount215(); u32* GetLine(int line); +void SetupAccelFrame(); void WriteToGXFIFO(u32 val); @@ -127,13 +128,14 @@ bool Init(); void DeInit(); void Reset(); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void SetupRenderThread(); void VCount144(); void RenderFrame(); u32* GetLine(int line); +void SetupAccelFrame(); } @@ -144,11 +146,12 @@ bool Init(); void DeInit(); void Reset(); -void SetScale(int scale); +void SetDisplaySettings(int scale, bool accel); void VCount144(); void RenderFrame(); u32* GetLine(int line); +void SetupAccelFrame(); } diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index e76db7f..6db9a18 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -21,6 +21,7 @@ #include "NDS.h" #include "GPU.h" #include "OpenGLSupport.h" +#include "GPU3D_OpenGL43_shaders.h" namespace GPU3D { @@ -33,631 +34,6 @@ namespace GLRenderer43 // * UBO: 3.1 // * glMemoryBarrier: 4.2 -// TODO: consider other way to handle uniforms (UBO?) - -#define kShaderHeader "#version 430" - - -const char* kClearVS = kShaderHeader R"( - -layout(location=0) in vec2 vPosition; - -layout(location=1) uniform uint uDepth; - -void main() -{ - float fdepth = (float(uDepth) / 8388608.0) - 1.0; - gl_Position = vec4(vPosition, fdepth, 1.0); -} -)"; - -const char* kClearFS = kShaderHeader R"( - -layout(location=0) uniform uvec4 uColor; -layout(location=2) uniform uint uOpaquePolyID; -layout(location=3) uniform uint uFogFlag; - -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; - -void main() -{ - oColor = vec4(uColor).bgra / 31.0; - oAttr.r = 0; - oAttr.g = uOpaquePolyID; - oAttr.b = 0; -} -)"; - - -const char* kRenderVSCommon = R"( - -layout(std140, binding=0) uniform uConfig -{ - vec2 uScreenSize; - uint uDispCnt; - vec4 uToonColors[32]; -}; - -layout(location=0) in uvec4 vPosition; -layout(location=1) in uvec4 vColor; -layout(location=2) in ivec2 vTexcoord; -layout(location=3) in uvec3 vPolygonAttr; - -smooth out vec4 fColor; -smooth out vec2 fTexcoord; -flat out uvec3 fPolygonAttr; -)"; - -const char* kRenderFSCommon = R"( - -layout(binding=0) uniform usampler2D TexMem; -layout(binding=1) uniform sampler2D TexPalMem; - -layout(std140, binding=0) uniform uConfig -{ - vec2 uScreenSize; - uint uDispCnt; - vec4 uToonColors[32]; -}; - -smooth in vec4 fColor; -smooth in vec2 fTexcoord; -flat in uvec3 fPolygonAttr; - -layout(location=0) out vec4 oColor; -layout(location=1) out uvec3 oAttr; - -int TexcoordWrap(int c, int maxc, uint mode) -{ - if ((mode & (1<<0)) != 0) - { - if ((mode & (1<<2)) != 0 && (c & maxc) != 0) - return (maxc-1) - (c & (maxc-1)); - else - return (c & (maxc-1)); - } - else - return clamp(c, 0, maxc-1); -} - -vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - pixel.a = (pixel.r & 0xE0); - pixel.a = (pixel.a >> 3) + (pixel.a >> 6); - pixel.r &= 0x1F; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 2; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - pixel.r >>= (2 * (st.x & 3)); - pixel.r &= 0x03; - - addr.y = (addr.y << 2) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) >> 1; - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - if ((st.x & 1) != 0) pixel.r >>= 4; - else pixel.r &= 0x0F; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, max(step(1,pixel.r),alpha0)); -} - -vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); - uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; - - int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); - if (addr.x >= 0x40000) slot1addr += 0x10000; - - uint palinfo; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo = p.r; - slot1addr++; - p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); - palinfo |= (p.r << 8); - - addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); - palinfo >>= 14; - - if (val == 0) - { - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 1) - { - addr.y++; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (val == 2) - { - if (palinfo == 1) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); - } - else - { - addr.y += 2; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - } - else - { - if (palinfo == 2) - { - addr.y += 3; - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4(color.rgb, 1.0); - } - else if (palinfo == 3) - { - vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - addr.y++; - vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); - } - else - { - return vec4(0.0); - } - } -} - -vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x); - uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - pixel.a = (pixel.r & 0xF8) >> 3; - pixel.r &= 0x07; - - addr.y = (addr.y << 3) + int(pixel.r); - vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); - - return vec4(color.rgb, float(pixel.a)/31.0); -} - -vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) -{ - st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); - st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); - - addr.x += ((st.y * st.z) + st.x) << 1; - uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - addr.x++; - uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); - - vec4 color; - color.r = float(pixelL.r & 0x1F) / 31.0; - color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; - color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; - color.a = float(pixelH.r >> 7); - - return color; -} - -vec4 TextureLookup_Nearest(vec2 st) -{ - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - ivec4 st_full = ivec4(ivec2(st), tw, th); - - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; - - uint type = (attr >> 26) & 0x7; - if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); - else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); - else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); - else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); - else return TextureFetch_Direct (vramaddr, st_full, wrapmode); -} - -vec4 TextureLookup_Linear(vec2 texcoord) -{ - ivec2 intpart = ivec2(texcoord); - vec2 fracpart = fract(texcoord); - - uint attr = fPolygonAttr.y; - uint paladdr = fPolygonAttr.z; - - float alpha0; - if ((attr & (1<<29)) != 0) alpha0 = 0.0; - else alpha0 = 1.0; - - int tw = 8 << int((attr >> 20) & 0x7); - int th = 8 << int((attr >> 23) & 0x7); - ivec4 st_full = ivec4(intpart, tw, th); - - ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); - uint wrapmode = attr >> 16; - - vec4 A, B, C, D; - uint type = (attr >> 26) & 0x7; - if (type == 5) - { - A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); - B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 2) - { - A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 3) - { - A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 4) - { - A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); - B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); - C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); - D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); - } - else if (type == 1) - { - A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); - B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else if (type == 6) - { - A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); - B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - else - { - A = TextureFetch_Direct(vramaddr, st_full , wrapmode); - B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); - C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); - D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); - } - - float fx = fracpart.x; - vec4 AB; - if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) - AB = vec4(0); - else - { - //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) - // fx = step(0.5, fx); - - AB = mix(A, B, fx); - } - - fx = fracpart.x; - vec4 CD; - if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) - CD = vec4(0); - else - { - //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) - // fx = step(0.5, fx); - - CD = mix(C, D, fx); - } - - fx = fracpart.y; - vec4 ret; - if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) - ret = vec4(0); - else - { - //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) - // fx = step(0.5, fx); - - ret = mix(AB, CD, fx); - } - - return ret; -} - -vec4 FinalColor() -{ - vec4 col; - vec4 vcol = fColor; - uint blendmode = (fPolygonAttr.x >> 4) & 0x3; - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) == 0) - { - // toon - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - vcol.rgb = tooncolor; - } - else - { - // highlight - vcol.rgb = vcol.rrr; - } - } - - if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) - { - // no texture - col = vcol; - } - else - { - vec4 tcol = TextureLookup_Nearest(fTexcoord); - //vec4 tcol = TextureLookup_Linear(fTexcoord); - - if ((blendmode & 1) != 0) - { - // decal - col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); - col.a = vcol.a; - } - else - { - // modulate - col = vcol * tcol; - } - } - - if (blendmode == 2) - { - if ((uDispCnt & (1<<1)) != 0) - { - vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; - col.rgb = min(col.rgb + tooncolor, 1.0); - } - } - - return col.bgra; -} -)"; - - -const char* kRenderVS_Z = R"( - -void main() -{ - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xyz *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - -const char* kRenderVS_W = R"( - -smooth out float fZ; - -void main() -{ - uint attr = vPolygonAttr.x; - uint zshift = (attr >> 16) & 0x1F; - - vec4 fpos; - fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; - fZ = float(vPosition.z << zshift) / 16777216.0; - fpos.w = float(vPosition.w) / 65536.0f; - fpos.xy *= fpos.w; - - fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); - fTexcoord = vec2(vTexcoord) / 16.0; - fPolygonAttr = vPolygonAttr; - - gl_Position = fpos; -} -)"; - - -const char* kRenderFS_ZO = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; -} -)"; - -const char* kRenderFS_WO = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 30.5/31) discard; - - oColor = col; - oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZT = R"( - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = 0xFF; -} -)"; - -const char* kRenderFS_WT = R"( - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - oColor = col; - oAttr.g = 0xFF; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZSM = R"( - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; -} -)"; - -const char* kRenderFS_WSM = R"( - -smooth in float fZ; - -void main() -{ - oColor = vec4(0,0,0,1); - oAttr.g = 0xFF; - oAttr.b = 1; - gl_FragDepth = fZ; -} -)"; - -const char* kRenderFS_ZS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; -} -)"; - -const char* kRenderFS_WS = R"( - -layout(binding=2) uniform usampler2D iAttrTex; -//layout(origin_upper_left) in vec4 gl_FragCoord; - -smooth in float fZ; - -void main() -{ - vec4 col = FinalColor(); - if (col.a < 0.5/31) discard; - if (col.a >= 30.5/31) discard; - - uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); - if (iAttr.b != 1) discard; - if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; - - oColor = col; - gl_FragDepth = fZ; -} -)"; - enum { @@ -721,6 +97,7 @@ GLuint TexMemID; GLuint TexPalMemID; int ScaleFactor; +bool Accelerated; int ScreenW, ScreenH; GLuint FramebufferTex[4]; @@ -968,9 +345,10 @@ void Reset() // } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { ScaleFactor = scale; + Accelerated = accel; // TODO: antialiasing setting ScreenW = 256 << scale; @@ -986,10 +364,12 @@ void SetScale(int scale) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + if (accel) glBufferData(GL_PIXEL_PACK_BUFFER, ScreenW*ScreenH*4, NULL, GL_DYNAMIC_READ); + else glBufferData(GL_PIXEL_PACK_BUFFER, 256*192, NULL, GL_DYNAMIC_READ); if (Framebuffer) delete[] Framebuffer; - Framebuffer = new u32[ScreenW*ScreenH]; + if (accel) Framebuffer = new u32[256*192]; + else Framebuffer = new u32[ScreenW*ScreenH]; } @@ -1533,5 +913,10 @@ u32* GetLine(int line) return &Framebuffer[stride * line]; } +void SetupAccelFrame() +{ + // +} + } } diff --git a/src/GPU3D_OpenGL43_shaders.h b/src/GPU3D_OpenGL43_shaders.h new file mode 100644 index 0000000..8a69566 --- /dev/null +++ b/src/GPU3D_OpenGL43_shaders.h @@ -0,0 +1,645 @@ +/* + Copyright 2016-2019 Arisotura + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef GPU3D_OPENGL43_SHADERS_H +#define GPU3D_OPENGL43_SHADERS_H + +#define kShaderHeader "#version 430" + + +const char* kClearVS = kShaderHeader R"( + +layout(location=0) in vec2 vPosition; + +layout(location=1) uniform uint uDepth; + +void main() +{ + float fdepth = (float(uDepth) / 8388608.0) - 1.0; + gl_Position = vec4(vPosition, fdepth, 1.0); +} +)"; + +const char* kClearFS = kShaderHeader R"( + +layout(location=0) uniform uvec4 uColor; +layout(location=2) uniform uint uOpaquePolyID; +layout(location=3) uniform uint uFogFlag; + +layout(location=0) out vec4 oColor; +layout(location=1) out uvec3 oAttr; + +void main() +{ + oColor = vec4(uColor).bgra / 31.0; + oAttr.r = 0; + oAttr.g = uOpaquePolyID; + oAttr.b = 0; +} +)"; + + +const char* kRenderVSCommon = R"( + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + +layout(location=0) in uvec4 vPosition; +layout(location=1) in uvec4 vColor; +layout(location=2) in ivec2 vTexcoord; +layout(location=3) in uvec3 vPolygonAttr; + +smooth out vec4 fColor; +smooth out vec2 fTexcoord; +flat out uvec3 fPolygonAttr; +)"; + +const char* kRenderFSCommon = R"( + +layout(binding=0) uniform usampler2D TexMem; +layout(binding=1) uniform sampler2D TexPalMem; + +layout(std140, binding=0) uniform uConfig +{ + vec2 uScreenSize; + uint uDispCnt; + vec4 uToonColors[32]; +}; + +smooth in vec4 fColor; +smooth in vec2 fTexcoord; +flat in uvec3 fPolygonAttr; + +layout(location=0) out vec4 oColor; +layout(location=1) out uvec3 oAttr; + +int TexcoordWrap(int c, int maxc, uint mode) +{ + if ((mode & (1<<0)) != 0) + { + if ((mode & (1<<2)) != 0 && (c & maxc) != 0) + return (maxc-1) - (c & (maxc-1)); + else + return (c & (maxc-1)); + } + else + return clamp(c, 0, maxc-1); +} + +vec4 TextureFetch_A3I5(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + pixel.a = (pixel.r & 0xE0); + pixel.a = (pixel.a >> 3) + (pixel.a >> 6); + pixel.r &= 0x1F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_I2(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 2; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + pixel.r >>= (2 * (st.x & 3)); + pixel.r &= 0x03; + + addr.y = (addr.y << 2) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I4(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) >> 1; + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + if ((st.x & 1) != 0) pixel.r >>= 4; + else pixel.r &= 0x0F; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_I8(ivec2 addr, ivec4 st, uint wrapmode, float alpha0) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, max(step(1,pixel.r),alpha0)); +} + +vec4 TextureFetch_Compressed(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y & 0x3FC) * (st.z>>2)) + (st.x & 0x3FC) + (st.y & 0x3); + uvec4 p = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + uint val = (p.r >> (2 * (st.x & 0x3))) & 0x3; + + int slot1addr = 0x20000 + ((addr.x & 0x1FFFC) >> 1); + if (addr.x >= 0x40000) slot1addr += 0x10000; + + uint palinfo; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo = p.r; + slot1addr++; + p = texelFetch(TexMem, ivec2(slot1addr&0x3FF, slot1addr>>10), 0); + palinfo |= (p.r << 8); + + addr.y = (addr.y << 3) + ((int(palinfo) & 0x3FFF) << 1); + palinfo >>= 14; + + if (val == 0) + { + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 1) + { + addr.y++; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (val == 2) + { + if (palinfo == 1) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb + color1.rgb) / 2.0, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*5.0 + color1.rgb*3.0) / 8.0, 1.0); + } + else + { + addr.y += 2; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + } + else + { + if (palinfo == 2) + { + addr.y += 3; + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4(color.rgb, 1.0); + } + else if (palinfo == 3) + { + vec4 color0 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + addr.y++; + vec4 color1 = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + return vec4((color0.rgb*3.0 + color1.rgb*5.0) / 8.0, 1.0); + } + else + { + return vec4(0.0); + } + } +} + +vec4 TextureFetch_A5I3(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x); + uvec4 pixel = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + pixel.a = (pixel.r & 0xF8) >> 3; + pixel.r &= 0x07; + + addr.y = (addr.y << 3) + int(pixel.r); + vec4 color = texelFetch(TexPalMem, ivec2(addr.y&0x3FF, addr.y>>10), 0); + + return vec4(color.rgb, float(pixel.a)/31.0); +} + +vec4 TextureFetch_Direct(ivec2 addr, ivec4 st, uint wrapmode) +{ + st.x = TexcoordWrap(st.x, st.z, wrapmode>>0); + st.y = TexcoordWrap(st.y, st.w, wrapmode>>1); + + addr.x += ((st.y * st.z) + st.x) << 1; + uvec4 pixelL = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + addr.x++; + uvec4 pixelH = texelFetch(TexMem, ivec2(addr.x&0x3FF, addr.x>>10), 0); + + vec4 color; + color.r = float(pixelL.r & 0x1F) / 31.0; + color.g = float((pixelL.r >> 5) | ((pixelH.r & 0x03) << 3)) / 31.0; + color.b = float((pixelH.r & 0x7C) >> 2) / 31.0; + color.a = float(pixelH.r >> 7); + + return color; +} + +vec4 TextureLookup_Nearest(vec2 st) +{ + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(ivec2(st), tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + uint type = (attr >> 26) & 0x7; + if (type == 5) return TextureFetch_Compressed(vramaddr, st_full, wrapmode); + else if (type == 2) return TextureFetch_I2 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 3) return TextureFetch_I4 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 4) return TextureFetch_I8 (vramaddr, st_full, wrapmode, alpha0); + else if (type == 1) return TextureFetch_A3I5 (vramaddr, st_full, wrapmode); + else if (type == 6) return TextureFetch_A5I3 (vramaddr, st_full, wrapmode); + else return TextureFetch_Direct (vramaddr, st_full, wrapmode); +} + +vec4 TextureLookup_Linear(vec2 texcoord) +{ + ivec2 intpart = ivec2(texcoord); + vec2 fracpart = fract(texcoord); + + uint attr = fPolygonAttr.y; + uint paladdr = fPolygonAttr.z; + + float alpha0; + if ((attr & (1<<29)) != 0) alpha0 = 0.0; + else alpha0 = 1.0; + + int tw = 8 << int((attr >> 20) & 0x7); + int th = 8 << int((attr >> 23) & 0x7); + ivec4 st_full = ivec4(intpart, tw, th); + + ivec2 vramaddr = ivec2(int(attr & 0xFFFF) << 3, int(paladdr)); + uint wrapmode = attr >> 16; + + vec4 A, B, C, D; + uint type = (attr >> 26) & 0x7; + if (type == 5) + { + A = TextureFetch_Compressed(vramaddr, st_full , wrapmode); + B = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Compressed(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Compressed(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 2) + { + A = TextureFetch_I2(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I2(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I2(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I2(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 3) + { + A = TextureFetch_I4(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I4(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I4(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I4(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 4) + { + A = TextureFetch_I8(vramaddr, st_full , wrapmode, alpha0); + B = TextureFetch_I8(vramaddr, st_full + ivec4(1,0,0,0), wrapmode, alpha0); + C = TextureFetch_I8(vramaddr, st_full + ivec4(0,1,0,0), wrapmode, alpha0); + D = TextureFetch_I8(vramaddr, st_full + ivec4(1,1,0,0), wrapmode, alpha0); + } + else if (type == 1) + { + A = TextureFetch_A3I5(vramaddr, st_full , wrapmode); + B = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A3I5(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A3I5(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else if (type == 6) + { + A = TextureFetch_A5I3(vramaddr, st_full , wrapmode); + B = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_A5I3(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_A5I3(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + else + { + A = TextureFetch_Direct(vramaddr, st_full , wrapmode); + B = TextureFetch_Direct(vramaddr, st_full + ivec4(1,0,0,0), wrapmode); + C = TextureFetch_Direct(vramaddr, st_full + ivec4(0,1,0,0), wrapmode); + D = TextureFetch_Direct(vramaddr, st_full + ivec4(1,1,0,0), wrapmode); + } + + float fx = fracpart.x; + vec4 AB; + if (A.a < (0.5/31.0) && B.a < (0.5/31.0)) + AB = vec4(0); + else + { + //if (A.a < (0.5/31.0) || B.a < (0.5/31.0)) + // fx = step(0.5, fx); + + AB = mix(A, B, fx); + } + + fx = fracpart.x; + vec4 CD; + if (C.a < (0.5/31.0) && D.a < (0.5/31.0)) + CD = vec4(0); + else + { + //if (C.a < (0.5/31.0) || D.a < (0.5/31.0)) + // fx = step(0.5, fx); + + CD = mix(C, D, fx); + } + + fx = fracpart.y; + vec4 ret; + if (AB.a < (0.5/31.0) && CD.a < (0.5/31.0)) + ret = vec4(0); + else + { + //if (AB.a < (0.5/31.0) || CD.a < (0.5/31.0)) + // fx = step(0.5, fx); + + ret = mix(AB, CD, fx); + } + + return ret; +} + +vec4 FinalColor() +{ + vec4 col; + vec4 vcol = fColor; + uint blendmode = (fPolygonAttr.x >> 4) & 0x3; + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) == 0) + { + // toon + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + vcol.rgb = tooncolor; + } + else + { + // highlight + vcol.rgb = vcol.rrr; + } + } + + if ((((fPolygonAttr.y >> 26) & 0x7) == 0) || ((uDispCnt & (1<<0)) == 0)) + { + // no texture + col = vcol; + } + else + { + vec4 tcol = TextureLookup_Nearest(fTexcoord); + //vec4 tcol = TextureLookup_Linear(fTexcoord); + + if ((blendmode & 1) != 0) + { + // decal + col.rgb = (tcol.rgb * tcol.a) + (vcol.rgb * (1.0-tcol.a)); + col.a = vcol.a; + } + else + { + // modulate + col = vcol * tcol; + } + } + + if (blendmode == 2) + { + if ((uDispCnt & (1<<1)) != 0) + { + vec3 tooncolor = uToonColors[int(vcol.r * 31)].rgb; + col.rgb = min(col.rgb + tooncolor, 1.0); + } + } + + return col.bgra; +} +)"; + + +const char* kRenderVS_Z = R"( + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fpos.z = (float(vPosition.z << zshift) / 8388608.0) - 1.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xyz *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + +const char* kRenderVS_W = R"( + +smooth out float fZ; + +void main() +{ + uint attr = vPolygonAttr.x; + uint zshift = (attr >> 16) & 0x1F; + + vec4 fpos; + fpos.xy = ((vec2(vPosition.xy) * 2.0) / uScreenSize) - 1.0; + fZ = float(vPosition.z << zshift) / 16777216.0; + fpos.w = float(vPosition.w) / 65536.0f; + fpos.xy *= fpos.w; + + fColor = vec4(vColor) / vec4(255.0,255.0,255.0,31.0); + fTexcoord = vec2(vTexcoord) / 16.0; + fPolygonAttr = vPolygonAttr; + + gl_Position = fpos; +} +)"; + + +const char* kRenderFS_ZO = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; +} +)"; + +const char* kRenderFS_WO = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 30.5/31) discard; + + oColor = col; + oAttr.g = (fPolygonAttr.x >> 24) & 0x3F; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZT = R"( + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = 0xFF; +} +)"; + +const char* kRenderFS_WT = R"( + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + oColor = col; + oAttr.g = 0xFF; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZSM = R"( + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = 0xFF; + oAttr.b = 1; +} +)"; + +const char* kRenderFS_WSM = R"( + +smooth in float fZ; + +void main() +{ + oColor = vec4(0,0,0,1); + oAttr.g = 0xFF; + oAttr.b = 1; + gl_FragDepth = fZ; +} +)"; + +const char* kRenderFS_ZS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; + + oColor = col; +} +)"; + +const char* kRenderFS_WS = R"( + +layout(binding=2) uniform usampler2D iAttrTex; +//layout(origin_upper_left) in vec4 gl_FragCoord; + +smooth in float fZ; + +void main() +{ + vec4 col = FinalColor(); + if (col.a < 0.5/31) discard; + if (col.a >= 30.5/31) discard; + + uvec4 iAttr = texelFetch(iAttrTex, ivec2(gl_FragCoord.xy), 0); + if (iAttr.b != 1) discard; + if (iAttr.g == ((fPolygonAttr.x >> 24) & 0x3F)) discard; + + oColor = col; + gl_FragDepth = fZ; +} +)"; + +#endif // GPU3D_OPENGL43_SHADERS_H diff --git a/src/GPU3D_Soft.cpp b/src/GPU3D_Soft.cpp index ac5cd93..20283d3 100644 --- a/src/GPU3D_Soft.cpp +++ b/src/GPU3D_Soft.cpp @@ -138,7 +138,7 @@ void Reset() SetupRenderThread(); } -void SetScale(int scale) +void SetDisplaySettings(int scale, bool accel) { printf("SOFT RENDERER SCALE FACTOR: TODO!!!\n"); } @@ -2122,5 +2122,10 @@ u32* GetLine(int line) return &ColorBuffer[(line * ScanlineWidth) + FirstPixelOffset]; } +void SetupAccelFrame() +{ + // TODO +} + } } diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index 47f5f13..b77d67f 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -240,8 +240,8 @@ void GLDrawing_DrawScreen() x1 = TopScreenRect.X + TopScreenRect.Width; y1 = TopScreenRect.Y + TopScreenRect.Height; - scwidth = 256 << ScreenScale[0]; - scheight = 192 << ScreenScale[0]; + scwidth = 256;// << ScreenScale[0]; + scheight = 192;// << ScreenScale[0]; switch (ScreenRotation) { @@ -286,8 +286,8 @@ void GLDrawing_DrawScreen() x1 = BottomScreenRect.X + BottomScreenRect.Width; y1 = BottomScreenRect.Y + BottomScreenRect.Height; - scwidth = 256 << ScreenScale[1]; - scheight = 192 << ScreenScale[1]; + scwidth = 256;// << ScreenScale[1]; + scheight = 192;// << ScreenScale[1]; switch (ScreenRotation) { @@ -349,9 +349,13 @@ void GLDrawing_DrawScreen() int frontbuf = GPU::FrontBuffer; glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, GL_ScreenTexture); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256< Date: Sat, 18 May 2019 01:21:46 +0200 Subject: actually finish display capture in hardware-accel mode --- src/GPU2D.cpp | 123 +++++++++++++++++++++++++++++++++++++++++++++++-- src/GPU2D.h | 2 +- src/GPU3D_OpenGL43.cpp | 1 - 3 files changed, 121 insertions(+), 5 deletions(-) (limited to 'src/GPU2D.h') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index e18f30e..4a98248 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -668,7 +668,7 @@ void GPU2D::DrawScanline(u32 line) } // always render regular graphics - DrawScanline_Mode1(line); + DrawScanline_BGOBJ(line); switch (dispmode) { @@ -895,10 +895,127 @@ void GPU2D::DoCapture(u32 line, u32 width) u32* srcA; if (CaptureCnt & (1<<24)) + { srcA = _3DLine; + } else + { srcA = BGOBJLine; -srcA = _3DLine; + if (Accelerated) + { + // in accelerated mode, compositing is normally done on the GPU + // 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]; + + if ((val1 >> 30) == 1) + { + u32 _3dval = _3DLine[i]; + if ((_3dval >> 24) > 0) + { + val1 = _3dval | 0x40000000; + val2 = val3; + } + else + val1 = val3; + } + else if ((val3 >> 30) == 1) + { + u32 _3dval = _3DLine[i]; + 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; + } + 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 ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) + { + if ((bldcnteffect == 1) && (BlendCnt & target2)) + { + coloreffect = 1; + eva = EVA; + evb = EVB; + } + else if (bldcnteffect >= 2) + coloreffect = bldcnteffect; + else + coloreffect = 0; + } + 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; + + case 3: + BGOBJLine[i] = ColorBrightnessDown(val1, EVY); + break; + } + } + } + } + u16* srcB = NULL; u32 srcBaddr = line * 256; @@ -1261,7 +1378,7 @@ void GPU2D::DrawScanlineBGMode6(u32 line, u32 nsprites) } } -void GPU2D::DrawScanline_Mode1(u32 line) +void GPU2D::DrawScanline_BGOBJ(u32 line) { u64 backdrop; if (Num) backdrop = *(u16*)&GPU::Palette[0x400]; diff --git a/src/GPU2D.h b/src/GPU2D.h index fc420a5..c19ddf7 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -132,7 +132,7 @@ private: template void DrawScanlineBGMode(u32 line, u32 nsprites); void DrawScanlineBGMode6(u32 line, u32 nsprites); - void DrawScanline_Mode1(u32 line); + void DrawScanline_BGOBJ(u32 line); static void DrawPixel_1x(u32* dst, u16 color, u32 flag); static void DrawPixel_2x(u32* dst, u16 color, u32 flag); diff --git a/src/GPU3D_OpenGL43.cpp b/src/GPU3D_OpenGL43.cpp index 72956fb..71960ae 100644 --- a/src/GPU3D_OpenGL43.cpp +++ b/src/GPU3D_OpenGL43.cpp @@ -272,7 +272,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); - glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[0], 0); glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); -- cgit v1.2.3 From cd8236303ec178a25f07408c892ed5f941fe3273 Mon Sep 17 00:00:00 2001 From: Arisotura Date: Sun, 19 May 2019 19:37:13 +0200 Subject: begin botching the code BAHAHAHAAAA --- src/GPU2D.cpp | 247 ++++++++++------------------------------------------------ src/GPU2D.h | 8 +- 2 files changed, 42 insertions(+), 213 deletions(-) (limited to 'src/GPU2D.h') diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index 88436db..e810275 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -217,16 +217,10 @@ void GPU2D::SetFramebuffer(u32* buf) void GPU2D::SetDisplaySettings(int scale, bool accel) { - if (accel) scale = 0; Accelerated = accel; - LineScale = scale; - LineStride = 256 << (scale*2); - - if (Accelerated) DrawPixel = DrawPixel_Accel; - else if (scale == 1) DrawPixel = DrawPixel_2x; - else if (scale == 2) DrawPixel = DrawPixel_4x; - else DrawPixel = DrawPixel_1x; + if (Accelerated) DrawPixel = DrawPixel_Accel; + else DrawPixel = DrawPixel_Normal; } @@ -626,7 +620,7 @@ u32 GPU2D::ColorBrightnessDown(u32 val, u32 factor) void GPU2D::DrawScanline(u32 line) { - int stride = Accelerated ? (256*3 + 2) : LineStride; + int stride = Accelerated ? (256*3 + 2) : 256; u32* dst = &Framebuffer[stride * line]; int n3dline = line; @@ -648,8 +642,14 @@ void GPU2D::DrawScanline(u32 line) if (forceblank) { - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) dst[i] = 0xFFFFFFFF; + + if (Accelerated) + { + dst[256*3] = 0; + dst[256*3 + 1] = 0; + } return; } @@ -674,7 +674,7 @@ void GPU2D::DrawScanline(u32 line) { case 0: // screen off { - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) dst[i] = 0x003F3F3F; } break; @@ -701,37 +701,12 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - int d = i << LineScale; - dst[d] = r | (g << 8) | (b << 16); - if (LineScale == 1) - { - dst[d+1] = dst[d]; - dst[d+512] = dst[d]; - dst[d+513] = dst[d]; - } - else if (LineScale == 2) - { - dst[d+1] = dst[d]; - dst[d+2] = dst[d]; - dst[d+3] = dst[d]; - dst[d+1024] = dst[d]; - dst[d+1024+1] = dst[d]; - dst[d+1024+2] = dst[d]; - dst[d+1024+3] = dst[d]; - dst[d+2048] = dst[d]; - dst[d+2048+1] = dst[d]; - dst[d+2048+2] = dst[d]; - dst[d+2048+3] = dst[d]; - dst[d+3072] = dst[d]; - dst[d+3072+1] = dst[d]; - dst[d+3072+2] = dst[d]; - dst[d+3072+3] = dst[d]; - } + dst[i] = r | (g << 8) | (b << 16); } } else { - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) { dst[i] = 0; } @@ -748,32 +723,7 @@ void GPU2D::DrawScanline(u32 line) u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - int d = i << LineScale; - dst[d] = r | (g << 8) | (b << 16); - if (LineScale == 1) - { - dst[d+1] = dst[d]; - dst[d+512] = dst[d]; - dst[d+513] = dst[d]; - } - else if (LineScale == 2) - { - dst[d+1] = dst[d]; - dst[d+2] = dst[d]; - dst[d+3] = dst[d]; - dst[d+1024] = dst[d]; - dst[d+1024+1] = dst[d]; - dst[d+1024+2] = dst[d]; - dst[d+1024+3] = dst[d]; - dst[d+2048] = dst[d]; - dst[d+2048+1] = dst[d]; - dst[d+2048+2] = dst[d]; - dst[d+2048+3] = dst[d]; - dst[d+3072] = dst[d]; - dst[d+3072+1] = dst[d]; - dst[d+3072+2] = dst[d]; - dst[d+3072+3] = dst[d]; - } + dst[i] = r | (g << 8) | (b << 16); } } break; @@ -817,7 +767,7 @@ void GPU2D::DrawScanline(u32 line) u32 factor = MasterBrightness & 0x1F; if (factor > 16) factor = 16; - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) { dst[i] = ColorBrightnessUp(dst[i], factor); } @@ -828,7 +778,7 @@ void GPU2D::DrawScanline(u32 line) u32 factor = MasterBrightness & 0x1F; if (factor > 16) factor = 16; - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) { dst[i] = ColorBrightnessDown(dst[i], factor); } @@ -838,7 +788,7 @@ void GPU2D::DrawScanline(u32 line) // convert to 32-bit BGRA // note: 32-bit RGBA would be more straightforward, but // BGRA seems to be more compatible (Direct2D soft, cairo...) - for (int i = 0; i < LineStride; i+=2) + for (int i = 0; i < 256; i+=2) { u64 c = *(u64*)&dst[i]; @@ -1044,7 +994,7 @@ void GPU2D::DoCapture(u32 line, u32 width) { for (u32 i = 0; i < width; i++) { - u32 val = srcA[i << LineScale]; + u32 val = srcA[i]; // TODO: check what happens when alpha=0 @@ -1095,7 +1045,7 @@ void GPU2D::DoCapture(u32 line, u32 width) { for (u32 i = 0; i < width; i++) { - u32 val = srcA[i << LineScale]; + u32 val = srcA[i]; // TODO: check what happens when alpha=0 @@ -1129,7 +1079,7 @@ void GPU2D::DoCapture(u32 line, u32 width) { for (u32 i = 0; i < width; i++) { - u32 val = srcA[i << LineScale]; + u32 val = srcA[i]; // TODO: check what happens when alpha=0 @@ -1393,7 +1343,7 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) backdrop = r | (g << 8) | (b << 16) | 0x20000000; backdrop |= (backdrop << 32); - for (int i = 0; i < LineStride; i+=2) + for (int i = 0; i < 256; i+=2) *(u64*)&BGOBJLine[i] = backdrop; } @@ -1426,12 +1376,10 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) { u32 bldcnteffect = (BlendCnt >> 6) & 0x3; - for (int i = 0; i < LineStride; i++) + for (int i = 0; i < 256; i++) { - int j = (i >> LineScale) & 0xFF; - u32 val1 = BGOBJLine[i]; - u32 val2 = BGOBJLine[4096+i]; + u32 val2 = BGOBJLine[256+i]; u32 coloreffect, eva, evb; @@ -1472,7 +1420,7 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) if (flag1 & 0x80) flag1 = 0x10; else if (flag1 & 0x40) flag1 = 0x01; - if ((BlendCnt & flag1) && (WindowMask[j] & 0x20)) + if ((BlendCnt & flag1) && (WindowMask[i] & 0x20)) { if ((bldcnteffect == 1) && (BlendCnt & target2)) { @@ -1535,60 +1483,16 @@ void GPU2D::DrawScanline_BGOBJ(u32 line) } -void GPU2D::DrawPixel_1x(u32* dst, u16 color, u32 flag) +void GPU2D::DrawPixel_Normal(u32* dst, u16 color, u32 flag) { u8 r = (color & 0x001F) << 1; u8 g = (color & 0x03E0) >> 4; u8 b = (color & 0x7C00) >> 9; - *(dst+4096) = *dst; + *(dst+256) = *dst; *dst = r | (g << 8) | (b << 16) | flag; } -void GPU2D::DrawPixel_2x(u32* dst, u16 color, u32 flag) -{ - u8 r = (color & 0x001F) << 1; - u8 g = (color & 0x03E0) >> 4; - u8 b = (color & 0x7C00) >> 9; - - u64 val = r | (g << 8) | (b << 16) | flag; - val |= (val << 32); - - *(u64*)(dst+4096) = *(u64*)dst; - *(u64*)(dst+4096+512) = *(u64*)(dst+512); - - *(u64*)dst = val; - *(u64*)(dst+512) = val; -} - -void GPU2D::DrawPixel_4x(u32* dst, u16 color, u32 flag) -{ - u8 r = (color & 0x001F) << 1; - u8 g = (color & 0x03E0) >> 4; - u8 b = (color & 0x7C00) >> 9; - - u64 val = r | (g << 8) | (b << 16) | flag; - val |= (val << 32); - - *(u64*)(dst+4096) = *(u64*)dst; - *(u64*)(dst+4096+2) = *(u64*)(dst+2); - *(u64*)(dst+4096+1024) = *(u64*)(dst+1024); - *(u64*)(dst+4096+1024+2) = *(u64*)(dst+1024+2); - *(u64*)(dst+4096+2048) = *(u64*)(dst+2048); - *(u64*)(dst+4096+2048+2) = *(u64*)(dst+2048+2); - *(u64*)(dst+4096+3072) = *(u64*)(dst+3072); - *(u64*)(dst+4096+3072+2) = *(u64*)(dst+3072+2); - - *(u64*)dst = val; - *(u64*)(dst+2) = val; - *(u64*)(dst+1024) = val; - *(u64*)(dst+1024+2) = val; - *(u64*)(dst+2048) = val; - *(u64*)(dst+2048+2) = val; - *(u64*)(dst+3072) = val; - *(u64*)(dst+3072+2) = val; -} - void GPU2D::DrawPixel_Accel(u32* dst, u16 color, u32 flag) { u8 r = (color & 0x001F) << 1; @@ -1629,77 +1533,6 @@ void GPU2D::DrawBG_3D() BGOBJLine[i] = 0x40000000 | pos; // 3D-layer placeholder } } - else if (LineScale == 1) - { - for (; i < iend; i++) - { - int is = i << 1; - int xs = xoff << 1; - u32 c; - - xoff++; - if (!(WindowMask[i] & 0x01)) continue; - - c = _3DLine[xs]; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - - c = _3DLine[xs+1]; is++; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - - c = _3DLine[xs+512]; is += 511; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - - c = _3DLine[xs+513]; is++; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - } - } - else if (LineScale == 2) - { - for (; i < iend; i++) - { - int is = i << 2; - int xs = xoff << 2; - u32 c; - - xoff++; - if (!(WindowMask[i] & 0x01)) continue; - - for (int by = 0; by < 4; by++) - { - for (int bx = 0; bx < 4; bx++) - { - c = _3DLine[xs]; - if ((c >> 24) != 0) - { - BGOBJLine[is+4096] = BGOBJLine[is]; - BGOBJLine[is] = c | 0x40000000; - } - - is++; - xs++; - } - - is += 1020; - xs += 1020; - } - } - } else { for (; i < iend; i++) @@ -1710,7 +1543,7 @@ void GPU2D::DrawBG_3D() if ((c >> 24) == 0) continue; if (!(WindowMask[i] & 0x01)) continue; - BGOBJLine[i+4096] = BGOBJLine[i]; + BGOBJLine[i+256] = BGOBJLine[i]; BGOBJLine[i] = c | 0x40000000; } } @@ -1814,7 +1647,7 @@ void GPU2D::DrawBG_Text(u32 line, u32 bgnum) xmos--; if (color) - DrawPixel(&BGOBJLine[i< 0) { if (color) - DrawPixel(&BGOBJLine[i<(tilesetaddr + (curtile << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&BGOBJLine[i< 0) { if (color & 0x8000) - DrawPixel(&BGOBJLine[i<(tilemapaddr + (((((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)) << 1)); if (color & 0x8000) - DrawPixel(&BGOBJLine[i< 0) { if (color) - DrawPixel(&BGOBJLine[i<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&BGOBJLine[i< 0) { if (color) - DrawPixel(&BGOBJLine[i<(tilesetaddr + ((curtile & 0x03FF) << 6) + (tileyoff << 3) + tilexoff); if (color) - DrawPixel(&BGOBJLine[i< 0) { if (color) - DrawPixel(&BGOBJLine[i<(tilemapaddr + (((rotY & ymask) >> 8) << yshift) + ((rotX & xmask) >> 8)); if (color) - DrawPixel(&BGOBJLine[i< 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/GPU2D.h') diff --git a/src/Config.cpp b/src/Config.cpp index aca3d4f..42f18c7 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -31,6 +31,7 @@ const char* kConfigFile = "melonDS.ini"; int _3DRenderer; int Threaded3D; +int GL_ScaleFactor; int GL_Antialias; ConfigEntry ConfigFile[] = @@ -38,6 +39,7 @@ ConfigEntry ConfigFile[] = {"3DRenderer", 0, &_3DRenderer, 1, NULL, 0}, {"Threaded3D", 0, &Threaded3D, 1, NULL, 0}, + {"GL_ScaleFactor", 0, &GL_ScaleFactor, 1, NULL, 0}, {"GL_Antialias", 0, &GL_Antialias, 0, NULL, 0}, {"", -1, NULL, 0, NULL, 0} diff --git a/src/Config.h b/src/Config.h index 8dc97d5..6ffc495 100644 --- a/src/Config.h +++ b/src/Config.h @@ -43,6 +43,7 @@ void Save(); extern int _3DRenderer; extern int Threaded3D; +extern int GL_ScaleFactor; extern int GL_Antialias; } diff --git a/src/GPU.cpp b/src/GPU.cpp index 8b94c94..959129e 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -73,7 +73,6 @@ u32 VRAMMap_ARM7[2]; int FrontBuffer; u32* Framebuffer[2][2]; -int ScreenScale[2]; bool Accelerated; GPU2D* GPU2D_A; @@ -89,8 +88,8 @@ bool Init() FrontBuffer = 0; Framebuffer[0][0] = NULL; Framebuffer[0][1] = NULL; Framebuffer[1][0] = NULL; Framebuffer[1][1] = NULL; - ScreenScale[0] = -1; ScreenScale[1] = -1; Accelerated = false; - SetDisplaySettings(0, 0, false); + Accelerated = false; + SetDisplaySettings(false); return true; } @@ -247,12 +246,10 @@ void AssignFramebuffers() } } -void SetDisplaySettings(int topscale, int bottomscale, bool accel) -{accel=true; +void SetDisplaySettings(bool accel) +{ if (accel != Accelerated) { - ScreenScale[0] = accel ? 0 : topscale; - int fbsize; if (accel) fbsize = (256*3 + 2) * 192; else fbsize = 256 * 192; @@ -273,35 +270,8 @@ void SetDisplaySettings(int topscale, int bottomscale, bool accel) AssignFramebuffers(); } - if (topscale != ScreenScale[0]) - { - ScreenScale[0] = topscale; - - if (NDS::PowerControl9 & (1<<15)) - { - GPU2D_A->SetDisplaySettings(ScreenScale[0], accel); - GPU3D::SetDisplaySettings(ScreenScale[0], accel); - } - else - { - GPU2D_B->SetDisplaySettings(ScreenScale[0], accel); - } - } - - if (bottomscale != ScreenScale[1] || accel != Accelerated) - { - ScreenScale[1] = bottomscale; - - if (NDS::PowerControl9 & (1<<15)) - { - GPU2D_B->SetDisplaySettings(ScreenScale[1], accel); - } - else - { - GPU2D_A->SetDisplaySettings(ScreenScale[1], accel); - GPU3D::SetDisplaySettings(ScreenScale[1], accel); - } - } + GPU2D_A->SetDisplaySettings(accel); + GPU2D_B->SetDisplaySettings(accel); Accelerated = accel; } diff --git a/src/GPU.h b/src/GPU.h index cfa8d7d..b6f6473 100644 --- a/src/GPU.h +++ b/src/GPU.h @@ -75,7 +75,7 @@ void Stop(); void DoSavestate(Savestate* file); -void SetDisplaySettings(int topscale, int bottomscale, bool accel); +void SetDisplaySettings(bool accel); void MapVRAM_AB(u32 bank, u8 cnt); diff --git a/src/GPU2D.cpp b/src/GPU2D.cpp index fe1645e..88249ba 100644 --- a/src/GPU2D.cpp +++ b/src/GPU2D.cpp @@ -215,7 +215,7 @@ void GPU2D::SetFramebuffer(u32* buf) Framebuffer = buf; } -void GPU2D::SetDisplaySettings(int scale, bool accel) +void GPU2D::SetDisplaySettings(bool accel) { Accelerated = accel; diff --git a/src/GPU2D.h b/src/GPU2D.h index eb159f7..78e62f5 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -31,7 +31,7 @@ public: void SetEnabled(bool enable) { Enabled = enable; } void SetFramebuffer(u32* buf); - void SetDisplaySettings(int scale, bool accel); + void SetDisplaySettings(bool accel); u8 Read8(u32 addr); u16 Read16(u32 addr); diff --git a/src/GPU3D.cpp b/src/GPU3D.cpp index 04ec55e..0ca3cd4 100644 --- a/src/GPU3D.cpp +++ b/src/GPU3D.cpp @@ -156,6 +156,8 @@ u32 NumCommands, CurCommand, ParamCount, TotalParams; bool GeometryEnabled; bool RenderingEnabled; +int Renderer; + u32 DispCnt; u8 AlphaRefVal, AlphaRef; @@ -275,16 +277,16 @@ bool Init() CmdStallQueue = new FIFO(64); - //if (!SoftRenderer::Init()) return false; - if (!GLRenderer::Init()) return false; + Renderer = -1; + // SetRenderer() will be called to set it up later return true; } void DeInit() { - //SoftRenderer::DeInit(); - GLRenderer::DeInit(); + if (Renderer == 0) SoftRenderer::DeInit(); + else GLRenderer::DeInit(); delete CmdFIFO; delete CmdPIPE; @@ -384,8 +386,8 @@ void Reset() FlushAttributes = 0; ResetRenderingState(); - //SoftRenderer::Reset(); - GLRenderer::Reset(); + if (Renderer == 0) SoftRenderer::Reset(); + else GLRenderer::Reset(); } void DoSavestate(Savestate* file) @@ -607,14 +609,24 @@ void SetEnabled(bool geometry, bool rendering) if (!rendering) ResetRenderingState(); } -void SetDisplaySettings(int scale, bool accel) -{ - GLRenderer::SetDisplaySettings(scale, accel); -} -int GetScale() +int SetRenderer(int renderer) { - return GLRenderer::GetScale(); + //if (renderer == Renderer) return renderer; + + //if (Renderer == 0) SoftRenderer::DeInit(); + //else GLRenderer::DeInit(); + + if (renderer == 1) + { + if (!GLRenderer::Init()) + renderer = 0; + } + + if (renderer == 0) SoftRenderer::Init(); + + Renderer = renderer; + return renderer; } @@ -2354,7 +2366,7 @@ void CheckFIFODMA() void VCount144() { - //SoftRenderer::VCount144(); + if (Renderer == 0) SoftRenderer::VCount144(); } @@ -2436,19 +2448,14 @@ void VBlank() void VCount215() { - //SoftRenderer::RenderFrame(); - GLRenderer::RenderFrame(); + if (Renderer == 0) SoftRenderer::RenderFrame(); + else GLRenderer::RenderFrame(); } u32* GetLine(int line) { - //return SoftRenderer::GetLine(line); - return GLRenderer::GetLine(line); -} - -void SetupAccelFrame() -{ - GLRenderer::SetupAccelFrame(); + if (Renderer == 0) return SoftRenderer::GetLine(line); + else return GLRenderer::GetLine(line); } diff --git a/src/GPU3D.h b/src/GPU3D.h index 280b99e..36c6c0f 100644 --- a/src/GPU3D.h +++ b/src/GPU3D.h @@ -97,8 +97,8 @@ void Reset(); void DoSavestate(Savestate* file); void SetEnabled(bool geometry, bool rendering); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); + +int SetRenderer(int renderer); void ExecuteCommand(); @@ -129,15 +129,11 @@ bool Init(); void DeInit(); void Reset(); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); - void SetupRenderThread(); void VCount144(); void RenderFrame(); u32* GetLine(int line); -void SetupAccelFrame(); } @@ -148,8 +144,7 @@ bool Init(); void DeInit(); void Reset(); -void SetDisplaySettings(int scale, bool accel); -int GetScale(); +void SetDisplaySettings(int scale, bool antialias); void RenderFrame(); void PrepareCaptureFrame(); diff --git a/src/GPU3D_OpenGL.cpp b/src/GPU3D_OpenGL.cpp index 0bb7e42..30c77bf 100644 --- a/src/GPU3D_OpenGL.cpp +++ b/src/GPU3D_OpenGL.cpp @@ -95,13 +95,13 @@ GLuint TexMemID; GLuint TexPalMemID; int ScaleFactor; -bool Accelerated; +bool Antialias; int ScreenW, ScreenH; GLuint FramebufferTex[8]; int FrontBuffer; GLuint FramebufferID[4], PixelbufferID; -u32* Framebuffer = NULL; +u32 Framebuffer[256*192]; @@ -176,26 +176,6 @@ bool Init() printf("OpenGL: renderer: %s\n", renderer); printf("OpenGL: version: %s\n", version); - int barg1, barg2; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &barg1); - glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &barg2); - printf("max texture: %d\n", barg1); - printf("max comb. texture: %d\n", barg2); - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &barg1); - printf("max tex size: %d\n", barg1); - - glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &barg1); - printf("max arraytex levels: %d\n", barg1); - - /*glGetIntegerv(GL_NUM_EXTENSIONS, &barg1); - printf("extensions: %d\n", barg1); - for (int i = 0; i < barg1; i++) - { - const GLubyte* ext = glGetStringi(GL_EXTENSIONS, i); - printf("- %s\n", ext); - }*/ - glEnable(GL_DEPTH_TEST); glEnable(GL_STENCIL_TEST); @@ -317,6 +297,12 @@ bool Init() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[1], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[4], 0); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[5], 0); + glDrawBuffers(2, fbassign); + + glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); + glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, FramebufferTex[2], 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, FramebufferTex[6], 0); glFramebufferTexture(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, FramebufferTex[7], 0); glDrawBuffers(2, fbassign); @@ -324,8 +310,9 @@ bool Init() glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); glEnable(GL_BLEND); + // TODO: these are said to require GL 4.0; use the regular ones instead? glBlendFuncSeparatei(0, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE); - glBlendEquationSeparatei(0, GL_ADD, GL_MAX); + glBlendEquationSeparatei(0, GL_FUNC_ADD, GL_MAX); glBlendFuncSeparatei(1, GL_ONE, GL_ZERO, GL_ONE, GL_ZERO); glGenBuffers(1, &PixelbufferID); @@ -347,7 +334,7 @@ bool Init() glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB5_A1, 1024, 48, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL); - +printf("init done. %04X\n", glGetError()); return true; } @@ -375,44 +362,55 @@ void DeInit() void Reset() { - // } -void SetDisplaySettings(int scale, bool accel) +void SetDisplaySettings(int scale, bool antialias) { + if (antialias) scale *= 2; + ScaleFactor = scale; - Accelerated = accel; - - // TODO: antialiasing setting - ScreenW = 256 << scale; - ScreenH = 192 << scale; - - glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); - glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + Antialias = antialias; - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); + ScreenW = 256 * scale; + ScreenH = 192 * scale; - if (Framebuffer) delete[] Framebuffer; - if (accel) Framebuffer = new u32[256*192]; - else Framebuffer = new u32[ScreenW*ScreenH]; -} + if (!antialias) + { + glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, 1, 1, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, 1, 1, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + } + else + { + glBindTexture(GL_TEXTURE_2D, FramebufferTex[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW/2, ScreenH/2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[2]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[4]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW/2, ScreenH/2, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[5]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW/2, ScreenH/2, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[6]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, ScreenW, ScreenH, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL); + glBindTexture(GL_TEXTURE_2D, FramebufferTex[7]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB8UI, ScreenW, ScreenH, 0, GL_RGB_INTEGER, GL_UNSIGNED_BYTE, NULL); + } -int GetScale() -{ - return ScaleFactor; + glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); + glBufferData(GL_PIXEL_PACK_BUFFER, 256*192*4, NULL, GL_DYNAMIC_READ); } @@ -496,10 +494,10 @@ void BuildPolygons(RendererPolygon* polygons, int npolys) while (z > 0xFFFF) { z >>= 1; zshift++; } u32 x, y; - if (ScaleFactor > 0) + if (ScaleFactor > 1) { - x = vtx->HiresPosition[0] >> (4-ScaleFactor); - y = vtx->HiresPosition[1] >> (4-ScaleFactor); + x = (vtx->HiresPosition[0] * ScaleFactor) >> 4; + y = (vtx->HiresPosition[1] * ScaleFactor) >> 4; } else { @@ -829,8 +827,8 @@ void RenderFrame() glViewport(0, 0, ScreenW, ScreenH); - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); - FrontBuffer = FrontBuffer ? 0 : 1; + if (Antialias) glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[2]); + else glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[FrontBuffer]); glDisable(GL_BLEND); glColorMaski(0, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -902,26 +900,15 @@ void RenderFrame() RenderSceneChunk(0, 192); } - if (false) + if (Antialias) { - glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[0]); - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[1]); + glBindFramebuffer(GL_READ_FRAMEBUFFER, FramebufferID[2]); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FramebufferID[FrontBuffer]); glBlitFramebuffer(0, 0, ScreenW, ScreenH, 0, 0, ScreenW/2, ScreenH/2, GL_COLOR_BUFFER_BIT, GL_LINEAR); - - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[1]); } - else - { - glBindFramebuffer(GL_FRAMEBUFFER, FramebufferID[0]); - } - - /*if (!Accelerated) - { - glReadBuffer(GL_COLOR_ATTACHMENT0); - glBindBuffer(GL_PIXEL_PACK_BUFFER, PixelbufferID); - glReadPixels(0, 0, 256< 8) Config::GL_ScaleFactor = 8; + + old_renderer = Config::_3DRenderer; + old_gldisplay = Config::ScreenUseGL; + old_threaded3D = Config::Threaded3D; + old_resolution = Config::GL_ScaleFactor; + old_antialias = Config::GL_Antialias; + + uiCheckboxSetChecked(cbGLDisplay, Config::ScreenUseGL); + uiCheckboxSetChecked(cbThreaded3D, Config::Threaded3D); + uiComboboxSetSelected(cbResolution, Config::GL_ScaleFactor-1); + uiCheckboxSetChecked(cbAntialias, Config::GL_Antialias); + uiRadioButtonsSetSelected(rbRenderer, Config::_3DRenderer); + UpdateControls(); uiControlShow(uiControl(win)); } diff --git a/src/libui_sdl/PlatformConfig.cpp b/src/libui_sdl/PlatformConfig.cpp index 065d9c2..f700ecb 100644 --- a/src/libui_sdl/PlatformConfig.cpp +++ b/src/libui_sdl/PlatformConfig.cpp @@ -40,9 +40,8 @@ int ScreenLayout; int ScreenSizing; int ScreenFilter; -int ScreenScale; +int ScreenUseGL; int ScreenRatio; -int ScreenScaleMode; int LimitFPS; @@ -105,9 +104,8 @@ ConfigEntry PlatformConfigFile[] = {"ScreenSizing", 0, &ScreenSizing, 0, NULL, 0}, {"ScreenFilter", 0, &ScreenFilter, 1, NULL, 0}, - {"ScreenScale", 0, &ScreenScale, 0, NULL, 0}, + {"ScreenUseGL", 0, &ScreenUseGL, 1, NULL, 0}, {"ScreenRatio", 0, &ScreenRatio, 0, NULL, 0}, - {"ScreenScaleMode", 0, &ScreenScaleMode, 0, NULL, 0}, {"LimitFPS", 0, &LimitFPS, 1, NULL, 0}, diff --git a/src/libui_sdl/PlatformConfig.h b/src/libui_sdl/PlatformConfig.h index 0cff1d2..013a0a7 100644 --- a/src/libui_sdl/PlatformConfig.h +++ b/src/libui_sdl/PlatformConfig.h @@ -48,9 +48,8 @@ extern int ScreenLayout; extern int ScreenSizing; extern int ScreenFilter; -extern int ScreenScale; +extern int ScreenUseGL; extern int ScreenRatio; -extern int ScreenScaleMode; extern int LimitFPS; diff --git a/src/libui_sdl/main.cpp b/src/libui_sdl/main.cpp index b499da7..f0d7b74 100644 --- a/src/libui_sdl/main.cpp +++ b/src/libui_sdl/main.cpp @@ -100,6 +100,9 @@ char PrevSRAMPath[1024]; // for savestate 'undo load' bool SavestateLoaded; +bool Screen_UseGL; +int _3DRenderer; + bool ScreenDrawInited = false; uiDrawBitmap* ScreenBitmap[2] = {NULL,NULL}; @@ -117,8 +120,7 @@ float GL_ScreenVertices[2 * 3*2 * 4]; // position/texcoord GLuint GL_ScreenTexture; bool GL_ScreenSizeDirty; -int ScreenScale[3]; -int ScreenScaleMode; +int GL_3DScale; int ScreenGap = 0; int ScreenLayout = 0; @@ -161,14 +163,14 @@ void GetSavestateName(int slot, char* filename, int len); -bool GLDrawing_Init() +bool GLScreen_Init() { if (!OpenGL_Init()) return false; if (!OpenGL_BuildShaderProgram(kScreenVS, kScreenFS, GL_ScreenShader, "ScreenShader")) return false; -printf("GL init looking good\n"); + GLuint uni_id; memset(&GL_ShaderConfig, 0, sizeof(GL_ShaderConfig)); @@ -211,11 +213,11 @@ printf("GL init looking good\n"); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8UI, 1024, 1536, 0, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, NULL); GL_ScreenSizeDirty = true; -printf("finished w/ err: %04X\n", glGetError()); + return true; } -void GLDrawing_DeInit() +void GLScreen_DeInit() { glDeleteTextures(1, &GL_ScreenTexture); @@ -225,7 +227,7 @@ void GLDrawing_DeInit() OpenGL_DeleteShaderProgram(GL_ScreenShader); } -void GLDrawing_DrawScreen() +void GLScreen_DrawScreen() { if (GL_ScreenSizeDirty) { @@ -233,8 +235,8 @@ void GLDrawing_DrawScreen() GL_ShaderConfig.uScreenSize[0] = WindowWidth; GL_ShaderConfig.uScreenSize[1] = WindowHeight; - GL_ShaderConfig.u3DScale = 1 << GPU3D::GetScale(); - + GL_ShaderConfig.u3DScale = GL_3DScale; +printf("updating GL scale: %d\n", GL_3DScale); glBindBuffer(GL_UNIFORM_BUFFER, GL_ShaderConfigUBO); void* unibuf = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY); if (unibuf) memcpy(unibuf, &GL_ShaderConfig, sizeof(GL_ShaderConfig)); @@ -257,8 +259,8 @@ void GLDrawing_DrawScreen() x1 = TopScreenRect.X + TopScreenRect.Width; y1 = TopScreenRect.Y + TopScreenRect.Height; - scwidth = 256;// << ScreenScale[0]; - scheight = 192;// << ScreenScale[0]; + scwidth = 256; + scheight = 192; switch (ScreenRotation) { @@ -303,8 +305,8 @@ void GLDrawing_DrawScreen() x1 = BottomScreenRect.X + BottomScreenRect.Width; y1 = BottomScreenRect.Y + BottomScreenRect.Height; - scwidth = 256;// << ScreenScale[1]; - scheight = 192;// << ScreenScale[1]; + scwidth = 256; + scheight = 192; switch (ScreenRotation) { @@ -376,7 +378,8 @@ void GLDrawing_DrawScreen() GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); glActiveTexture(GL_TEXTURE1); - GPU3D::SetupAccelFrame(); + if (_3DRenderer != 0) + GPU3D::GLRenderer::SetupAccelFrame(); glBindBuffer(GL_ARRAY_BUFFER, GL_ScreenVertexBufferID); glBindVertexArray(GL_ScreenVertexArrayID); @@ -384,7 +387,89 @@ void GLDrawing_DrawScreen() glFlush(); uiGLSwapBuffers(GLContext); - uiAreaQueueRedrawAll(MainDrawArea); +} + +void ScreenCreateArea(bool opengl) +{ + bool opengl_good = opengl; + if (opengl_good) + { + MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); + uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); + uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); + uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); + GLContext = uiAreaGetGLContext(MainDrawArea); + if (!GLContext) opengl_good = false; + } + + if (opengl_good) + { + uiGLMakeContextCurrent(GLContext); + if (!GLScreen_Init()) opengl_good = false; + } + + if (opengl_good) + { + //if (_3DRenderer != 0) + { + _3DRenderer = GPU3D::SetRenderer(_3DRenderer); + if (_3DRenderer != 0) + GPU3D::GLRenderer::SetDisplaySettings(Config::GL_ScaleFactor, Config::GL_Antialias); + else if (RunningSomething) + GPU3D::SoftRenderer::SetupRenderThread(); + } + uiGLMakeContextCurrent(NULL); + } + else + { + if (opengl) + { + uiWindowSetChild(MainWindow, NULL); + uiControlDestroy(uiControl(MainDrawArea)); + } + + Screen_UseGL = false; + + MainDrawArea = uiNewArea(&MainDrawAreaHandler); + uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); + uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); + uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); + ScreenDrawInited = false; + } + + uiControlShow(uiControl(MainWindow)); + uiControlSetFocus(uiControl(MainDrawArea)); +} + +void ScreenSetMethod(bool opengl) +{ + int oldstatus = EmuRunning; + EmuRunning = 3; + while (EmuStatus != 3); + + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + if (_3DRenderer != 0) GPU3D::GLRenderer::DeInit(); + else GPU3D::SoftRenderer::DeInit(); + GLScreen_DeInit(); + uiGLMakeContextCurrent(NULL); + } + else + { + if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); + if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); + } + + uiWindowSetChild(MainWindow, NULL); + uiControlDestroy(uiControl(MainDrawArea)); + + Screen_UseGL = Config::ScreenUseGL; + _3DRenderer = Config::_3DRenderer; + + ScreenCreateArea(opengl); + + EmuRunning = oldstatus; } void MicLoadWav(char* name) @@ -642,8 +727,11 @@ void FeedMicInput() int EmuThreadFunc(void* burp) { - uiGLMakeContextCurrent(GLContext); - GLDrawing_Init(); + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + GLScreen_Init(); + } NDS::Init(); @@ -652,13 +740,8 @@ int EmuThreadFunc(void* burp) MainScreenPos[2] = 0; AutoScreenSizing = 0; - // FIXME - ScreenScale[2] = Config::ScreenScale; - ScreenScale[0] = ScreenScale[2]; - ScreenScale[1] = ScreenScale[2]; - - int lastscale[2] = {ScreenScale[0], ScreenScale[1]}; - GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false); + GPU::SetDisplaySettings(_3DRenderer != 0); + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); Touching = false; KeyInputMask = 0xFFF; @@ -773,7 +856,7 @@ int EmuThreadFunc(void* burp) // microphone input FeedMicInput(); - uiGLMakeContextCurrent(GLContext); + if (Screen_UseGL) uiGLMakeContextCurrent(GLContext); // auto screen layout { @@ -804,22 +887,16 @@ int EmuThreadFunc(void* burp) } } - if (ScreenScale[0] != lastscale[0] || - ScreenScale[1] != lastscale[1]) - { - GPU::SetDisplaySettings(ScreenScale[0], ScreenScale[1], false); - ScreenDrawInited = false; - } - // emulate u32 nlines = NDS::RunFrame(); if (EmuRunning == 0) break; - GLDrawing_DrawScreen(); - - //uiAreaQueueRedrawAll(MainDrawArea); - //uiGLSwapBuffers(GLContext); + if (Screen_UseGL) + { + GLScreen_DrawScreen(); + } + uiAreaQueueRedrawAll(MainDrawArea); // framerate limiter based off SDL2_gfx float framerate = (1000.0f * nlines) / (60.0f * 263.0f); @@ -869,13 +946,16 @@ int EmuThreadFunc(void* burp) if (EmuRunning == 2) { - uiGLMakeContextCurrent(GLContext); - - //uiAreaQueueRedrawAll(MainDrawArea); - //uiGLSwapBuffers(GLContext); - GLDrawing_DrawScreen(); + if (Screen_UseGL) + { + uiGLMakeContextCurrent(GLContext); + GLScreen_DrawScreen(); + } + uiAreaQueueRedrawAll(MainDrawArea); } + if (Screen_UseGL) uiGLMakeContextCurrent(NULL); + EmuStatus = EmuRunning; SDL_Delay(100); @@ -889,7 +969,7 @@ int EmuThreadFunc(void* burp) NDS::DeInit(); Platform::LAN_DeInit(); - GLDrawing_DeInit(); + if (Screen_UseGL) GLScreen_DeInit(); return 44203; } @@ -897,22 +977,21 @@ int EmuThreadFunc(void* burp) void OnAreaDraw(uiAreaHandler* handler, uiArea* area, uiAreaDrawParams* params) { - // TODO: recreate bitmap if screen scale changed if (!ScreenDrawInited) { if (ScreenBitmap[0]) uiDrawFreeBitmap(ScreenBitmap[0]); if (ScreenBitmap[1]) uiDrawFreeBitmap(ScreenBitmap[1]); ScreenDrawInited = true; - ScreenBitmap[0] = uiDrawNewBitmap(params->Context, 256<Context, 256<Context, 256, 192); + ScreenBitmap[1] = uiDrawNewBitmap(params->Context, 256, 192); } if (!ScreenBitmap[0] || !ScreenBitmap[1]) return; if (!GPU::Framebuffer[0][0]) return; - uiRect top = {0, 0, 256< 8) GL_3DScale = 8; MainWindow = uiNewWindow("melonDS " MELONDS_VERSION, w, h, Config::WindowMaximized, 1, 1); uiWindowOnClosing(MainWindow, OnCloseWindow, NULL); @@ -2346,11 +2378,7 @@ int main(int argc, char** argv) MainDrawAreaHandler.Resize = OnAreaResize; ScreenDrawInited = false; - //MainDrawArea = uiNewArea(&MainDrawAreaHandler); - MainDrawArea = uiNewGLArea(&MainDrawAreaHandler, kGLVersions); - uiWindowSetChild(MainWindow, uiControl(MainDrawArea)); - uiControlSetMinSize(uiControl(MainDrawArea), 256, 384); - uiAreaSetBackgroundColor(MainDrawArea, 0, 0, 0); // TODO: make configurable? + ScreenCreateArea(Screen_UseGL); ScreenRotation = Config::ScreenRotation; ScreenGap = Config::ScreenGap; @@ -2377,15 +2405,6 @@ int main(int argc, char** argv) OnSetScreenRotation(MenuItem_ScreenRot[ScreenRotation], MainWindow, (void*)&kScreenRot[ScreenRotation]); - // TODO: fail gracefully, support older OpenGL, etc - GLContext = uiAreaGetGLContext(MainDrawArea); - uiGLMakeContextCurrent(GLContext); - - void* testor = uiGLGetProcAddress("glUseProgram"); - void* testor2 = uiGLGetProcAddress("glBindFramebuffer"); - printf("OPENGL: %p %p\n", testor, testor2); - uiGLMakeContextCurrent(NULL); - SDL_AudioSpec whatIwant, whatIget; memset(&whatIwant, 0, sizeof(SDL_AudioSpec)); whatIwant.freq = 47340; @@ -2454,8 +2473,6 @@ int main(int argc, char** argv) } } - uiControlShow(uiControl(MainWindow)); - uiControlSetFocus(uiControl(MainDrawArea)); uiMain(); EmuRunning = 0; -- cgit v1.2.3 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/GPU2D.h') 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 ea669190aa5084a699590d2f2fed92e848a9fd53 Mon Sep 17 00:00:00 2001 From: StapleButter Date: Thu, 30 May 2019 18:05:52 +0200 Subject: fix crash when using -O3. gcc will try to optimize the memfill with MMX opcodes, but those seem to crash if the memory isn't aligned to a 8-byte boundary. --- CMakeLists.txt | 2 +- src/GPU2D.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/GPU2D.h') diff --git a/CMakeLists.txt b/CMakeLists.txt index 7daf1a5..38d4707 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ else() endif() if(ENABLE_LTO) - add_compile_options(-O2 -flto) + add_compile_options(-O3 -flto) endif() add_compile_options(-fno-pic) diff --git a/src/GPU2D.h b/src/GPU2D.h index 21b43f1..57436c7 100644 --- a/src/GPU2D.h +++ b/src/GPU2D.h @@ -71,11 +71,11 @@ private: bool Accelerated; - u32 BGOBJLine[256*3]; + u32 BGOBJLine[256*3] __attribute__((aligned (8))); u32* _3DLine; - u8 WindowMask[256]; - u32 OBJLine[256]; + u8 WindowMask[256] __attribute__((aligned (8))); + u32 OBJLine[256] __attribute__((aligned (8))); u16 DispFIFO[16]; u32 DispFIFOReadPtr; -- cgit v1.2.3