From da132f1f1c06dbb61424c98b851d81c051804269 Mon Sep 17 00:00:00 2001 From: rogerman Date: Mon, 14 Sep 2015 18:33:33 +0000 Subject: [PATCH] GPU: - More code cleanup. --- desmume/src/GPU.cpp | 392 ++++++++++++++++++++++---------------------- desmume/src/GPU.h | 228 +++++++++++++++----------- desmume/src/MMU.cpp | 48 +++--- 3 files changed, 357 insertions(+), 311 deletions(-) diff --git a/desmume/src/GPU.cpp b/desmume/src/GPU.cpp index 08380366f..608713bfa 100644 --- a/desmume/src/GPU.cpp +++ b/desmume/src/GPU.cpp @@ -221,8 +221,8 @@ bool gpu_loadstate(EMUFILE* is, int size) //subEngine->refreshAffineStartRegs(-1,-1); } - mainEngine->ParseAllRegisters(); - subEngine->ParseAllRegisters(); + mainEngine->ParseAllRegisters(); + subEngine->ParseAllRegisters(); return !is->fail(); } @@ -319,7 +319,7 @@ void GPUEngineBase::_Reset_Base() memset(this->_sprColor, 0, sizeof(this->_sprColor)); memset(this->_sprAlpha, 0, sizeof(this->_sprAlpha)); - memset(this->_sprType, 0, sizeof(this->_sprType)); + memset(this->_sprType, OBJMode_Normal, sizeof(this->_sprType)); memset(this->_sprPrio, 0x7F, sizeof(this->_sprPrio)); memset(this->_sprNum, 0, sizeof(this->_sprNum)); @@ -362,11 +362,6 @@ void GPUEngineBase::_Reset_Base() this->_needUpdateWINH[0] = true; this->_needUpdateWINH[1] = true; - this->_dispMode = GPUDisplayMode_Off; - this->_vramBlock = 0; - this->_VRAMaddrNative = (u16 *)MMU.ARM9_LCD; - this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer(); - this->isCustomRenderingNeeded = false; this->is3DEnabled = false; this->vramBGLayer = VRAM_NO_3D_USAGE; @@ -383,8 +378,6 @@ void GPUEngineBase::_Reset_Base() this->_sprBoundary = 0; this->_sprBMPBoundary = 0; - this->_sprBMPMode = 0; - this->_sprEnable = 0; this->_WIN0_ENABLED = 0; this->_WIN1_ENABLED = 0; @@ -542,6 +535,7 @@ void GPUEngineBase::SetupFinalPixelBlitter() } //Sets up LCD control variables for Display Engines A and B for quick reading +template void GPUEngineBase::ParseReg_DISPCNT() { const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT; @@ -552,30 +546,11 @@ void GPUEngineBase::ParseReg_DISPCNT() this->SetupFinalPixelBlitter(); - this->_dispMode = (GPUDisplayMode)( DISPCNT.DisplayMode & ((this->_engineID == GPUEngineID_Sub)?1:3) ); - this->_vramBlock = DISPCNT.VRAM_Block; - - switch (this->_dispMode) + if (ENGINEID == GPUEngineID_Main) { - case GPUDisplayMode_Off: // Display Off - break; - - case GPUDisplayMode_Normal: // Display BG and OBJ layers - break; - - case GPUDisplayMode_VRAM: // Display framebuffer - { - this->_VRAMaddrNative = (u16 *)MMU.ARM9_LCD + (this->_vramBlock * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH); - this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer() + (this->_vramBlock * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * GPU->GetCustomFramebufferWidth()); - break; - } - - case GPUDisplayMode_MainMemory: // Display from Main RAM - // nothing to be done here - // see GPU_RenderLine who gets data from FIFO. - break; + ((GPUEngineA *)this)->UpdateSelectedVRAMBlock(); } - + if (DISPCNT.OBJ_Tile_mapping) { //1-d sprite mapping boundaries: @@ -596,20 +571,18 @@ void GPUEngineBase::ParseReg_DISPCNT() this->_spriteRenderMode = SpriteRenderMode_Sprite2D; } - if (DISPCNT.OBJ_BMP_1D_Bound && (this->_engineID == GPUEngineID_Main)) + if (DISPCNT.OBJ_BMP_1D_Bound && (ENGINEID == GPUEngineID_Main)) this->_sprBMPBoundary = 8; else this->_sprBMPBoundary = 7; - - this->_sprEnable = DISPCNT.OBJ_Enable; - this->ParseReg_BGnCNT(); - this->ParseReg_BGnCNT(); - this->ParseReg_BGnCNT(); - this->ParseReg_BGnCNT(); + this->ParseReg_BGnCNT(); + this->ParseReg_BGnCNT(); + this->ParseReg_BGnCNT(); + this->ParseReg_BGnCNT(); } -template +template void GPUEngineBase::ParseReg_BGnCNT() { const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT; @@ -617,7 +590,7 @@ void GPUEngineBase::ParseReg_BGnCNT() this->ResortBGLayers(); - if (this->_engineID == GPUEngineID_Sub) + if (ENGINEID == GPUEngineID_Sub) { this->_BG_tile_ram[LAYERID] = MMU_BBG; this->_BG_bmp_ram[LAYERID] = MMU_BBG; @@ -654,7 +627,7 @@ void GPUEngineBase::ParseReg_BGnCNT() if (mode == BGType_AffineExt) { //see: http://nocash.emubase.de/gbatek.htm#dsvideobgmodescontrol - const u8 affineModeSelection = (BGnCNT.Palette_256 << 1) | (BGnCNT.CharacBase_Block & 1); + const u8 affineModeSelection = (BGnCNT.PaletteMode << 1) | (BGnCNT.CharacBase_Block & 1); switch (affineModeSelection) { case 0: @@ -988,7 +961,7 @@ FORCEINLINE FASTCALL bool GPUEngineBase::_master_setFinalBGColor(const size_t sr } template -FORCEINLINE FASTCALL void GPUEngineBase::_master_setFinalOBJColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const u8 type) +FORCEINLINE FASTCALL void GPUEngineBase::_master_setFinalOBJColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const OBJMode objMode) { bool windowEffectSatisfied = true; @@ -1005,7 +978,7 @@ FORCEINLINE FASTCALL void GPUEngineBase::_master_setFinalOBJColor(const size_t s //if the window effect is satisfied, then we can do color effects to modify the color if (windowEffectSatisfied) { - const bool isObjTranslucentType = type == GPU_OBJ_MODE_Transparent || type == GPU_OBJ_MODE_Bitmap; + const bool isObjTranslucentType = (objMode == OBJMode_Transparent) || (objMode == OBJMode_Bitmap); const GPULayerID dstLayerID = (GPULayerID)dstLayerIDLine[dstX]; const bool firstTargetSatisfied = (this->_IORegisterMap->BLDCNT.OBJ_Target1 != 0); const bool secondTargetSatisfied = (dstLayerID != GPULayerID_OBJ) && this->_blend2[dstLayerID]; @@ -1114,18 +1087,18 @@ FORCEINLINE void GPUEngineBase::_SetFinalColor3D(const size_t srcX, const size_t }; } -FORCEINLINE void GPUEngineBase::_SetFinalColorSprite(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const u8 type) +FORCEINLINE void GPUEngineBase::_SetFinalColorSprite(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const OBJMode objMode) { switch (this->_finalColorSpriteFuncID) { - case 0x0: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break; - case 0x1: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break; - case 0x2: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break; - case 0x3: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break; - case 0x4: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break; - case 0x5: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break; - case 0x6: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break; - case 0x7: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, type); break; + case 0x0: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break; + case 0x1: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break; + case 0x2: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break; + case 0x3: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break; + case 0x4: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break; + case 0x5: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break; + case 0x6: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break; + case 0x7: this->_master_setFinalOBJColor(srcX, dstX, dstColorLine, dstLayerIDLine, src, alpha, objMode); break; }; } @@ -1376,7 +1349,7 @@ void GPUEngineBase::_RenderLine_TextBG(u16 XBG, u16 YBG, u16 LG) xoff = XBG; - if (!BGnCNT.Palette_256) // color: 16 palette entries + if (BGnCNT.PaletteMode == PaletteMode_16x16) // color: 16 palette entries { const u16 *pal = this->_paletteBG; @@ -1869,12 +1842,12 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u u32 srcadr; // Check if sprite is disabled before everything - if (spriteInfo.RotScale == 2) + if (spriteInfo.RotScale == 0 && spriteInfo.Disable != 0) continue; prio = spriteInfo.Priority; - if (spriteInfo.RotScale & 1) + if (spriteInfo.RotScale != 0) { s32 fieldX, fieldY, auxX, auxY, realX, realY, offset; u8 blockparameter; @@ -1896,7 +1869,7 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u fieldY = sprSize.y; // If we are using double size mode, double our control vars - if (spriteInfo.RotScale & 2) + if (spriteInfo.DoubleSize != 0) { fieldX <<= 1; fieldY <<= 1; @@ -1913,10 +1886,10 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u if ((sprX == GPU_FRAMEBUFFER_NATIVE_WIDTH) || (sprX + fieldX <= 0)) continue; - cost += sprSize.x*2 + 10; + cost += (sprSize.x * 2) + 10; // Get which four parameter block is assigned to this sprite - blockparameter = (spriteInfo.RotScalIndex + (spriteInfo.HFlip<< 3) + (spriteInfo.VFlip << 4))*4; + blockparameter = (spriteInfo.RotScaleIndex + (spriteInfo.HFlip << 3) + (spriteInfo.VFlip << 4)) * 4; // Get rotation/scale parameters dx = LE_TO_LOCAL_16((s16)this->_oamList[blockparameter+0].attr3); @@ -1947,7 +1920,7 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u } // If we are using 1 palette of 256 colours - if (spriteInfo.Depth) + if (spriteInfo.PaletteMode == PaletteMode_1x256) { src = (u8 *)MMU_gpu_map(this->_sprMem + (spriteInfo.TileIndex << this->_sprBoundary)); @@ -2097,20 +2070,20 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u { if (MODE == SpriteRenderMode_Sprite2D) { - if (spriteInfo.Depth) + if (spriteInfo.PaletteMode == PaletteMode_1x256) src = (u8 *)MMU_gpu_map(this->_sprMem + ((spriteInfo.TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8)); else src = (u8 *)MMU_gpu_map(this->_sprMem + ((spriteInfo.TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*4)); } else { - if (spriteInfo.Depth) + if (spriteInfo.PaletteMode == PaletteMode_1x256) src = (u8 *)MMU_gpu_map(this->_sprMem + (spriteInfo.TileIndex<_sprBoundary) + ((y>>3)*sprSize.x*8) + ((y&0x7)*8)); else src = (u8 *)MMU_gpu_map(this->_sprMem + (spriteInfo.TileIndex<_sprBoundary) + ((y>>3)*sprSize.x*4) + ((y&0x7)*4)); } - this->_RenderSpriteWin(src, (spriteInfo.Depth != 0), lg, sprX, x, xdir); + this->_RenderSpriteWin(src, (spriteInfo.PaletteMode == PaletteMode_1x256), lg, sprX, x, xdir); } else if (spriteInfo.Mode == 3) //sprite is in BMP format { @@ -2122,7 +2095,7 @@ void GPUEngineBase::_SpriteRenderPerform(u16 *dst, u8 *dst_alpha, u8 *typeTab, u this->_RenderSpriteBMP(i, l, dst, srcadr, dst_alpha, typeTab, prioTab, prio, lg, sprX, x, xdir, spriteInfo.PaletteIndex); } - else if (spriteInfo.Depth) //256 colors + else if (spriteInfo.PaletteMode == PaletteMode_1x256) //256 colors { if (MODE == SpriteRenderMode_Sprite2D) srcadr = this->_sprMem + ((spriteInfo.TileIndex)<<5) + ((y>>3)<<10) + ((y&0x7)*8); @@ -2389,7 +2362,7 @@ void GPUEngineBase::UpdateVRAM3DUsageProperties_OBJLayer(const size_t bankIndex, { const OAMAttributes &spriteInfo = this->_oamList[spriteIndex]; - if ( (spriteInfo.RotScale != 2) && ((spriteInfo.RotScale & 1) == 0) && (spriteInfo.Mode == 3) && (spriteInfo.PaletteIndex != 0) ) + if ( ((spriteInfo.RotScale != 0) || (spriteInfo.Disable == 0)) && (spriteInfo.Mode == 3) && (spriteInfo.PaletteIndex != 0) ) { const u32 vramAddress = ((spriteInfo.TileIndex & 0x1F) << 5) + ((spriteInfo.TileIndex & ~0x1F) << 7); const SpriteSize sprSize = GPUEngineBase::_sprSizeTab[spriteInfo.Size][spriteInfo.Shape]; @@ -2439,7 +2412,7 @@ void GPUEngineBase::ModeRenderDebug(const size_t targetScanline, const GPULayerI } template -void GPUEngineBase::HandleDisplayModeOff(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount) +void GPUEngineBase::_HandleDisplayModeOff(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount) { // In this display mode, the display is cleared to white. if (ISCUSTOMRENDERINGNEEDED) @@ -2453,102 +2426,11 @@ void GPUEngineBase::HandleDisplayModeOff(u16 *dstColorLine, const size_t l, cons } template -void GPUEngineBase::HandleDisplayModeNormal(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount) +void GPUEngineBase::_HandleDisplayModeNormal(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount) { //do nothing: it has already been generated into the right place } -template -void GPUEngineBase::HandleDisplayModeVRAM(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount) -{ - if (!ISCUSTOMRENDERINGNEEDED) - { - const u16 *src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH); -#ifdef LOCAL_LE - memcpy(dstColorLine, src, GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)); -#else - for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++) - { - dstColorLine[x] = LE_TO_LOCAL_16(src[x]); - } -#endif - } - else - { - const VRAM3DUsageProperties &vramUsageProperty = GPU->GetVRAM3DUsageProperties(); - const GPUEngineA *mainEngine = GPU->GetEngineMain(); - - if (vramUsageProperty.isBlockUsed[mainEngine->GetVRAMBlock()] && (vramUsageProperty.blockIndexDisplayVRAM == mainEngine->GetVRAMBlock())) - { - const u16 *src = this->_VRAMaddrCustom + (_gpuDstLineIndex[l] * dstLineWidth); -#ifdef LOCAL_LE - memcpy(dstColorLine, src, dstLineWidth * dstLineCount * sizeof(u16)); -#else - for (size_t x = 0; x < dstLineWidth * dstLineCount; x++) - { - dstColorLine[x] = LE_TO_LOCAL_16(src[x]); - } -#endif - } - else - { - const u16 *src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH); - - for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++) - { - const u16 color = LE_TO_LOCAL_16(src[x]); - - for (size_t p = 0; p < _gpuDstPitchCount[x]; p++) - { - dstColorLine[_gpuDstPitchIndex[x] + p] = color; - } - } - - for (size_t line = 1; line < dstLineCount; line++) - { - memcpy(dstColorLine + (line * dstLineWidth), dstColorLine, dstLineWidth * sizeof(u16)); - } - } - } -} - -template -void GPUEngineBase::HandleDisplayModeMainMemory(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount) -{ - //this has not been tested since the dma timing for dispfifo was changed around the time of - //newemuloop. it may not work. - -#ifdef ENABLE_SSE2 - const __m128i fifoMask = _mm_set1_epi32(0x7FFF7FFF); - for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(__m128i); i++) - { - __m128i fifoColor = _mm_set_epi32(DISP_FIFOrecv(), DISP_FIFOrecv(), DISP_FIFOrecv(), DISP_FIFOrecv()); - fifoColor = _mm_shuffle_epi32(fifoColor, 0x1B); // We need to shuffle the four FIFO values back into the correct order, since they were originally loaded in reverse order. - _mm_store_si128((__m128i *)dstColorLine + i, _mm_and_si128(fifoColor, fifoMask)); - } -#else - for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++) - { - ((u32 *)dstColorLine)[i] = DISP_FIFOrecv() & 0x7FFF7FFF; - } -#endif - if (ISCUSTOMRENDERINGNEEDED) - { - for (size_t i = GPU_FRAMEBUFFER_NATIVE_WIDTH - 1; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i--) - { - for (size_t p = _gpuDstPitchCount[i] - 1; p < _gpuDstPitchCount[i]; p--) - { - dstColorLine[_gpuDstPitchIndex[i] + p] = dstColorLine[i]; - } - } - - for (size_t line = 1; line < dstLineCount; line++) - { - memcpy(dstColorLine + (line * dstLineWidth), dstColorLine, dstLineWidth * sizeof(u16)); - } - } -} - void GPUEngineBase::ParseReg_MOSAIC() { const u8 bgMosaicH = this->_IORegisterMap->MOSAIC.BG_MosaicH; @@ -2634,7 +2516,6 @@ void GPUEngineBase::SetCustomFramebufferSize(size_t w, size_t h) this->_workingDstColorBuffer = newWorkingScanline; this->_dstLayerID = newBGPixels; - this->_VRAMaddrCustom = GPU->GetCustomVRAMBuffer() + (this->_vramBlock * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w); this->customBuffer = GPU->GetCustomFramebuffer(this->_targetDisplayID); free_aligned(oldWorkingScanline); @@ -2704,10 +2585,11 @@ void GPUEngineBase::REG_DISPx_pack_test() printf("\t%02x\n", (u32)((uintptr_t)(&r->DISP_MMEM_FIFO) - (uintptr_t)r) ); } +template void GPUEngineBase::ParseAllRegisters() { - this->ParseReg_DISPCNT(); - // No need to call ParseReg_BGnCNT(), since it is + this->ParseReg_DISPCNT(); + // No need to call ParseReg_BGnCNT(), since it is // already called by ParseReg_DISPCNT(). this->ParseReg_BGnX(); @@ -2730,10 +2612,16 @@ GPUEngineA::GPUEngineA() _engineID = GPUEngineID_Main; _IORegisterMap = (GPU_IOREG *)MMU.ARM9_REG; _paletteBG = (u16 *)MMU.ARM9_VMEM; - _paletteOBJ = (u16 *)(MMU.ARM9_VMEM + 0x200); + _paletteOBJ = (u16 *)(MMU.ARM9_VMEM + ADDRESS_STEP_512B); _oamList = (OAMAttributes *)(MMU.ARM9_OAM); _sprMem = MMU_AOBJ; + _VRAMNativeBlockPtr[0] = (u16 *)MMU.ARM9_LCD; + _VRAMNativeBlockPtr[1] = _VRAMNativeBlockPtr[0] + (1 * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH); + _VRAMNativeBlockPtr[2] = _VRAMNativeBlockPtr[0] + (2 * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH); + _VRAMNativeBlockPtr[3] = _VRAMNativeBlockPtr[0] + (3 * GPU_VRAM_BLOCK_LINES * GPU_FRAMEBUFFER_NATIVE_WIDTH); + _VRAMaddrNative = _VRAMNativeBlockPtr[0]; + _3DFramebufferRGBA6665 = (FragmentColor *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(FragmentColor)); _3DFramebufferRGBA5551 = (u16 *)malloc_alignedCacheLine(GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT * sizeof(u16)); gfx3d_Update3DFramebuffers(_3DFramebufferRGBA6665, _3DFramebufferRGBA5551); @@ -2832,16 +2720,6 @@ void GPUEngineA::ParseReg_DISPCAPCNT() this->dispCapCnt.srcA, this->dispCapCnt.srcB);*/ } -GPUDisplayMode GPUEngineA::GetDisplayMode() const -{ - return this->_dispMode; -} - -u8 GPUEngineA::GetVRAMBlock() const -{ - return this->_vramBlock; -} - FragmentColor* GPUEngineA::Get3DFramebufferRGBA6665() const { return this->_3DFramebufferRGBA6665; @@ -2852,6 +2730,13 @@ u16* GPUEngineA::Get3DFramebufferRGBA5551() const return this->_3DFramebufferRGBA5551; } +void GPUEngineA::UpdateSelectedVRAMBlock() +{ + const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT; + this->_VRAMaddrNative = this->_VRAMNativeBlockPtr[DISPCNT.VRAM_Block]; + this->_VRAMaddrCustom = this->_VRAMCustomBlockPtr[DISPCNT.VRAM_Block]; +} + void GPUEngineA::SetCustomFramebufferSize(size_t w, size_t h) { this->GPUEngineBase::SetCustomFramebufferSize(w, h); @@ -2865,6 +2750,13 @@ void GPUEngineA::SetCustomFramebufferSize(size_t w, size_t h) this->_3DFramebufferRGBA5551 = newColorRGBA5551; gfx3d_Update3DFramebuffers(this->_3DFramebufferRGBA6665, this->_3DFramebufferRGBA5551); + const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT; + this->_VRAMCustomBlockPtr[0] = GPU->GetCustomVRAMBuffer(); + this->_VRAMCustomBlockPtr[1] = this->_VRAMCustomBlockPtr[0] + (1 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w); + this->_VRAMCustomBlockPtr[2] = this->_VRAMCustomBlockPtr[0] + (2 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w); + this->_VRAMCustomBlockPtr[3] = this->_VRAMCustomBlockPtr[0] + (3 * _gpuCaptureLineIndex[GPU_VRAM_BLOCK_LINES] * w); + this->_VRAMaddrCustom = this->_VRAMCustomBlockPtr[DISPCNT.VRAM_Block]; + free_aligned(oldColorRGBA6665Buffer); free_aligned(oldColorRGBA5551Buffer); } @@ -2936,8 +2828,10 @@ void GPUEngineA::RenderLine(const u16 l, bool skip) this->_SetupWindows<0>(); this->_SetupWindows<1>(); + const GPUDisplayMode displayMode = (GPUDisplayMode)this->_IORegisterMap->DISPCNT.DisplayMode; + //generate the 2d engine output - if (this->_dispMode == GPUDisplayMode_Normal) + if (displayMode == GPUDisplayMode_Normal) { //optimization: render straight to the output buffer when thats what we are going to end up displaying anyway this->_currentDstColor = dstColorLine; @@ -2950,22 +2844,22 @@ void GPUEngineA::RenderLine(const u16 l, bool skip) this->_RenderLine_Layer(l, this->_currentDstColor, dstLineWidth, dstLineCount); - switch (this->_dispMode) + switch (displayMode) { case GPUDisplayMode_Off: // Display Off(Display white) - this->HandleDisplayModeOff(dstColorLine, l, dstLineWidth, dstLineCount); + this->_HandleDisplayModeOff(dstColorLine, l, dstLineWidth, dstLineCount); break; case GPUDisplayMode_Normal: // Display BG and OBJ layers - this->HandleDisplayModeNormal(dstColorLine, l, dstLineWidth, dstLineCount); + this->_HandleDisplayModeNormal(dstColorLine, l, dstLineWidth, dstLineCount); break; case GPUDisplayMode_VRAM: // Display vram framebuffer - this->HandleDisplayModeVRAM(dstColorLine, l, dstLineWidth, dstLineCount); + this->_HandleDisplayModeVRAM(dstColorLine, l, dstLineWidth, dstLineCount); break; case GPUDisplayMode_MainMemory: // Display memory FIFO - this->HandleDisplayModeMainMemory(dstColorLine, l, dstLineWidth, dstLineCount); + this->_HandleDisplayModeMainMemory(dstColorLine, l, dstLineWidth, dstLineCount); break; } @@ -3078,7 +2972,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t // init background color & priorities memset(this->_sprAlpha, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); - memset(this->_sprType, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); + memset(this->_sprType, OBJMode_Normal, GPU_FRAMEBUFFER_NATIVE_WIDTH); memset(this->_sprPrio, 0x7F, GPU_FRAMEBUFFER_NATIVE_WIDTH); memset(this->_sprWin, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); @@ -3167,7 +3061,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t } #ifndef DISABLE_MOSAIC - if (BGnCNT.Mosaic_Enable != 0) + if (BGnCNT.Mosaic != 0) { switch (layerID) { @@ -3225,7 +3119,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t layerIDLine, (useCustomVRAM) ? srcLine[dstX] : this->_sprColor[srcX], this->_sprAlpha[srcX], - this->_sprType[srcX]); + (OBJMode)this->_sprType[srcX]); } } @@ -3246,7 +3140,7 @@ void GPUEngineA::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t layerIDLine, this->_sprColor[srcX], this->_sprAlpha[srcX], - this->_sprType[srcX]); + (OBJMode)this->_sprType[srcX]); } } } @@ -3789,12 +3683,103 @@ void GPUEngineA::_RenderLine_DispCapture_Blend(const u16 *__restrict srcA, const } } +template +void GPUEngineA::_HandleDisplayModeVRAM(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount) +{ + if (!ISCUSTOMRENDERINGNEEDED) + { + const u16 *src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH); +#ifdef LOCAL_LE + memcpy(dstColorLine, src, GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16)); +#else + for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++) + { + dstColorLine[x] = LE_TO_LOCAL_16(src[x]); + } +#endif + } + else + { + const IOREG_DISPCNT &DISPCNT = this->_IORegisterMap->DISPCNT; + const VRAM3DUsageProperties &vramUsageProperty = GPU->GetVRAM3DUsageProperties(); + + if (vramUsageProperty.isBlockUsed[DISPCNT.VRAM_Block] && (vramUsageProperty.blockIndexDisplayVRAM == DISPCNT.VRAM_Block)) + { + const u16 *src = this->_VRAMaddrCustom + (_gpuDstLineIndex[l] * dstLineWidth); +#ifdef LOCAL_LE + memcpy(dstColorLine, src, dstLineWidth * dstLineCount * sizeof(u16)); +#else + for (size_t x = 0; x < dstLineWidth * dstLineCount; x++) + { + dstColorLine[x] = LE_TO_LOCAL_16(src[x]); + } +#endif + } + else + { + const u16 *src = this->_VRAMaddrNative + (l * GPU_FRAMEBUFFER_NATIVE_WIDTH); + + for (size_t x = 0; x < GPU_FRAMEBUFFER_NATIVE_WIDTH; x++) + { + const u16 color = LE_TO_LOCAL_16(src[x]); + + for (size_t p = 0; p < _gpuDstPitchCount[x]; p++) + { + dstColorLine[_gpuDstPitchIndex[x] + p] = color; + } + } + + for (size_t line = 1; line < dstLineCount; line++) + { + memcpy(dstColorLine + (line * dstLineWidth), dstColorLine, dstLineWidth * sizeof(u16)); + } + } + } +} + +template +void GPUEngineA::_HandleDisplayModeMainMemory(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount) +{ + //this has not been tested since the dma timing for dispfifo was changed around the time of + //newemuloop. it may not work. + +#ifdef ENABLE_SSE2 + const __m128i fifoMask = _mm_set1_epi32(0x7FFF7FFF); + for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(__m128i); i++) + { + __m128i fifoColor = _mm_set_epi32(DISP_FIFOrecv(), DISP_FIFOrecv(), DISP_FIFOrecv(), DISP_FIFOrecv()); + fifoColor = _mm_shuffle_epi32(fifoColor, 0x1B); // We need to shuffle the four FIFO values back into the correct order, since they were originally loaded in reverse order. + _mm_store_si128((__m128i *)dstColorLine + i, _mm_and_si128(fifoColor, fifoMask)); + } +#else + for (size_t i = 0; i < GPU_FRAMEBUFFER_NATIVE_WIDTH * sizeof(u16) / sizeof(u32); i++) + { + ((u32 *)dstColorLine)[i] = DISP_FIFOrecv() & 0x7FFF7FFF; + } +#endif + if (ISCUSTOMRENDERINGNEEDED) + { + for (size_t i = GPU_FRAMEBUFFER_NATIVE_WIDTH - 1; i < GPU_FRAMEBUFFER_NATIVE_WIDTH; i--) + { + for (size_t p = _gpuDstPitchCount[i] - 1; p < _gpuDstPitchCount[i]; p--) + { + dstColorLine[_gpuDstPitchIndex[i] + p] = dstColorLine[i]; + } + } + + for (size_t line = 1; line < dstLineCount; line++) + { + memcpy(dstColorLine + (line * dstLineWidth), dstColorLine, dstLineWidth * sizeof(u16)); + } + } +} + GPUEngineB::GPUEngineB() { _engineID = GPUEngineID_Sub; _IORegisterMap = (GPU_IOREG *)(&MMU.ARM9_REG[REG_DISPB]); _paletteBG = (u16 *)(MMU.ARM9_VMEM + ADDRESS_STEP_1KB); - _paletteOBJ = (u16 *)(MMU.ARM9_VMEM + ADDRESS_STEP_1KB + 0x200); + _paletteOBJ = (u16 *)(MMU.ARM9_VMEM + ADDRESS_STEP_1KB + ADDRESS_STEP_512B); _oamList = (OAMAttributes *)(MMU.ARM9_OAM + ADDRESS_STEP_1KB); _sprMem = MMU_BOBJ; } @@ -3898,8 +3883,10 @@ void GPUEngineB::RenderLine(const u16 l, bool skip) this->_SetupWindows<0>(); this->_SetupWindows<1>(); + const GPUDisplayMode displayMode = (GPUDisplayMode)(this->_IORegisterMap->DISPCNT.DisplayMode & 0x01); + //generate the 2d engine output - if (this->_dispMode == GPUDisplayMode_Normal) + if (displayMode == GPUDisplayMode_Normal) { //optimization: render straight to the output buffer when thats what we are going to end up displaying anyway this->_currentDstColor = dstColorLine; @@ -3912,14 +3899,14 @@ void GPUEngineB::RenderLine(const u16 l, bool skip) this->_RenderLine_Layer(l, this->_currentDstColor, dstLineWidth, dstLineCount); - switch (this->_dispMode) + switch (displayMode) { case GPUDisplayMode_Off: // Display Off(Display white) - this->HandleDisplayModeOff(dstColorLine, l, dstLineWidth, dstLineCount); + this->_HandleDisplayModeOff(dstColorLine, l, dstLineWidth, dstLineCount); break; case GPUDisplayMode_Normal: // Display BG and OBJ layers - this->HandleDisplayModeNormal(dstColorLine, l, dstLineWidth, dstLineCount); + this->_HandleDisplayModeNormal(dstColorLine, l, dstLineWidth, dstLineCount); break; default: @@ -4009,7 +3996,7 @@ void GPUEngineB::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t // init background color & priorities memset(this->_sprAlpha, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); - memset(this->_sprType, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); + memset(this->_sprType, OBJMode_Normal, GPU_FRAMEBUFFER_NATIVE_WIDTH); memset(this->_sprPrio, 0x7F, GPU_FRAMEBUFFER_NATIVE_WIDTH); memset(this->_sprWin, 0, GPU_FRAMEBUFFER_NATIVE_WIDTH); @@ -4061,7 +4048,7 @@ void GPUEngineB::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t const IOREG_BGnCNT &BGnCNT = this->_IORegisterMap->BGnCNT[layerID]; #ifndef DISABLE_MOSAIC - if (BGnCNT.Mosaic_Enable != 0) + if (BGnCNT.Mosaic != 0) { switch (layerID) { @@ -4119,7 +4106,7 @@ void GPUEngineB::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t layerIDLine, (useCustomVRAM) ? srcLine[dstX] : this->_sprColor[srcX], this->_sprAlpha[srcX], - this->_sprType[srcX]); + (OBJMode)this->_sprType[srcX]); } } @@ -4140,7 +4127,7 @@ void GPUEngineB::_RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t layerIDLine, this->_sprColor[srcX], this->_sprAlpha[srcX], - this->_sprType[srcX]); + (OBJMode)this->_sprType[srcX]); } } } @@ -4178,8 +4165,6 @@ GPUSubsystem::GPUSubsystem() _displayInfo.nativeBuffer[1] = _nativeFramebuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT); _displayInfo.customBuffer[0] = _customFramebuffer; _displayInfo.customBuffer[1] = _customFramebuffer + (GPU_FRAMEBUFFER_NATIVE_WIDTH * GPU_FRAMEBUFFER_NATIVE_HEIGHT); - - ClearWithColor(0x8000); _displayInfo.didPerformCustomRender[0] = false; _displayInfo.didPerformCustomRender[1] = false; @@ -4189,6 +4174,8 @@ GPUSubsystem::GPUSubsystem() _displayInfo.renderedHeight[1] = GPU_FRAMEBUFFER_NATIVE_HEIGHT; _displayInfo.renderedBuffer[0] = _displayInfo.nativeBuffer[0]; _displayInfo.renderedBuffer[1] = _displayInfo.nativeBuffer[1]; + + ClearWithColor(0x8000); } GPUSubsystem::~GPUSubsystem() @@ -4246,9 +4233,11 @@ void GPUSubsystem::Reset() void GPUSubsystem::UpdateVRAM3DUsageProperties() { + const IOREG_DISPCNT &mainDISPCNT = this->_engineMain->GetIORegisterMap().DISPCNT; + this->_VRAM3DUsage.blockIndexDisplayVRAM = VRAM_NO_3D_USAGE; - this->_engineMain->is3DEnabled = (this->_engineMain->GetIORegisterMap().DISPCNT.BG0_Enable == 1) && (this->_engineMain->GetIORegisterMap().DISPCNT.BG0_3D == 1); + this->_engineMain->is3DEnabled = (mainDISPCNT.BG0_Enable == 1) && (mainDISPCNT.BG0_3D == 1); this->_engineMain->isCustomRenderingNeeded = false; this->_engineMain->vramBlockBGIndex = VRAM_NO_3D_USAGE; this->_engineMain->vramBlockOBJIndex = VRAM_NO_3D_USAGE; @@ -4314,7 +4303,7 @@ void GPUSubsystem::UpdateVRAM3DUsageProperties() case VramConfiguration::LCDC: { - if ((this->_engineMain->GetDisplayMode() == GPUDisplayMode_VRAM) && (this->_engineMain->GetVRAMBlock() == i)) + if ((mainDISPCNT.DisplayMode == GPUDisplayMode_VRAM) && (mainDISPCNT.VRAM_Block == i)) { this->_VRAM3DUsage.blockIndexDisplayVRAM = i; } @@ -4610,6 +4599,19 @@ void NDSDisplay::SetEngineByID(const GPUEngineID theID) this->_gpu->SetDisplayByID(this->_ID); } +template void GPUEngineBase::ParseReg_DISPCNT(); +template void GPUEngineBase::ParseReg_DISPCNT(); + +template void GPUEngineBase::ParseReg_BGnCNT(); +template void GPUEngineBase::ParseReg_BGnCNT(); +template void GPUEngineBase::ParseReg_BGnCNT(); +template void GPUEngineBase::ParseReg_BGnCNT(); + +template void GPUEngineBase::ParseReg_BGnCNT(); +template void GPUEngineBase::ParseReg_BGnCNT(); +template void GPUEngineBase::ParseReg_BGnCNT(); +template void GPUEngineBase::ParseReg_BGnCNT(); + template void GPUEngineBase::ParseReg_WINnH<0>(); template void GPUEngineBase::ParseReg_WINnH<1>(); diff --git a/desmume/src/GPU.h b/desmume/src/GPU.h index 2afb02c95..82721ac58 100644 --- a/desmume/src/GPU.h +++ b/desmume/src/GPU.h @@ -47,6 +47,28 @@ bool gpu_loadstate(EMUFILE* is, int size); typedef void (*rot_fun)(GPUEngineBase *gpu, const s32 auxX, const s32 auxY, const int lg, const u32 map, const u32 tile, const u16 *pal, const size_t i); +enum PaletteMode +{ + PaletteMode_16x16 = 0, + PaletteMode_1x256 = 1 +}; + +enum OBJMode +{ + OBJMode_Normal = 0, + OBJMode_Transparent = 1, + OBJMode_Window = 2, + OBJMode_Bitmap = 3 +}; + +enum OBJShape +{ + OBJShape_Square = 0, + OBJShape_Horizontal = 1, + OBJShape_Vertical = 2, + OBJShape_Prohibited = 3 +}; + union FragmentColor { u32 color; @@ -169,10 +191,10 @@ typedef union struct { #ifdef LOCAL_LE - u8 Priority:2; // 0- 1: 0..3=high..low + u8 Priority:2; // 0- 1: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority u8 CharacBase_Block:4; // 2- 5: individual character base offset (n*16KB) - u8 Mosaic_Enable:1; // 6: 0=disable, 1=Enable mosaic - u8 Palette_256:1; // 7: 0=16x16, 1=1*256 palette + u8 Mosaic:1; // 6: Mosaic render: 0=Disable, 1=Enable + u8 PaletteMode:1; // 7: Color/palette mode; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors u8 ScreenBase_Block:5; // 8-12: individual screen base offset (text n*2KB, BMP n*16KB) u8 PaletteSet_Wrap:1; // 13: BG0 extended palette set 0=set0, 1=set2 @@ -184,10 +206,10 @@ typedef union // bmp : 128x128 256x256 512x256 512x512 // large : 512x1024 1024x512 - - #else - u8 Palette_256:1; // 7: 0=16x16, 1=1*256 palette - u8 Mosaic_Enable:1; // 6: 0=disable, 1=Enable mosaic + u8 PaletteMode:1; // 7: Color/palette mode; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors + u8 Mosaic:1; // 6: Mosaic render: 0=Disable, 1=Enable u8 CharacBase_Block:4; // 2- 5: individual character base offset (n*16KB) - u8 Priority:2; // 0- 1: 0..3=high..low + u8 Priority:2; // 0- 1: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority u8 ScreenSize:2; // 14-15: text : 256x256 512x256 256x512 512x512 // x/rot/s : 128x128 256x256 512x512 1024x1024 @@ -785,72 +807,96 @@ typedef union i.bits.blue = w.bits.blue; \ i.bits.alpha = w.bits.alpha; - - - // (00: Normal, 01: Transparent, 10: Object window, 11: Bitmap) -enum GPU_OBJ_MODE -{ - GPU_OBJ_MODE_Normal = 0, - GPU_OBJ_MODE_Transparent = 1, - GPU_OBJ_MODE_Window = 2, - GPU_OBJ_MODE_Bitmap = 3 -}; - typedef union { u16 attr[4]; struct { -#ifdef LOCAL_BE - //attr0 - unsigned Shape:2; - unsigned Depth:1; - unsigned Mosaic:1; - unsigned Mode:2; - unsigned RotScale:2; - unsigned Y:8; +#ifdef LOCAL_LE + union + { + u16 attr0; + + struct + { + u16 Y:8; // 0- 7: Sprite Y-coordinate; 0...255 + u16 RotScale:1; // 8: Perform rotation/scaling; 0=Disable, 1=Enable + u16 Disable:1; // 9: OBJ disable flag, only if Bit8 is cleared; 0=Perform render, 1=Do not perform render + u16 Mode:2; // 10-11: OBJ mode; 0=Normal, 1=Transparent, 2=Window, 3=Bitmap + u16 Mosaic:1; // 12: Mosaic render: 0=Disable, 1=Enable + u16 PaletteMode:1; // 13: Color/palette select; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors + u16 Shape:2; // 14-15: OBJ shape; 0=Square, 1=Horizontal, 2=Vertical, 3=Prohibited + }; + + struct + { + u16 :8; + u16 :1; + u16 DoubleSize:1; // 9: Perform double-size render, only if Bit8 is set; 0=Disable, 1=Enable + u16 :6; + }; + }; - //attr1 - unsigned Size:2; - unsigned VFlip:1; - unsigned HFlip:1; - unsigned RotScalIndex:3; - signed X:9; + s16 X:9; // 16-24: Sprite X-coordinate; 0...511 + u16 RotScaleIndex:3; // 25-27: Rotation/scaling parameter selection; 0...31 + u16 HFlip:1; // 28: Flip sprite horizontally; 0=Normal, 1=Flip + u16 VFlip:1; // 29: Flip sprite vertically; 0=Normal, 1=Flip + u16 Size:2; // 30-31: OBJ size, interacts with Bit 14-15 + // + // Size| Square | Horizontal | Vertical + // 0: 8x8 16x8 8x16 + // 1: 16x16 32x8 8x32 + // 2: 32x32 32x16 16x32 + // 3: 64x64 64x32 32x64 - //attr2 - unsigned PaletteIndex:4; - unsigned Priority:2; - unsigned TileIndex:10; - - //attr3 - unsigned attr3:16; // Whenever this is used, you will need to explicitly convert endianness. + u16 TileIndex:10; // 32-41: Tile index; 0...1023 + u16 Priority:2; // 42-43: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority + u16 PaletteIndex:4; // 44-47: Palette index; 0...15 #else - //attr0 - unsigned Y:8; - unsigned RotScale:2; - unsigned Mode:2; - unsigned Mosaic:1; - unsigned Depth:1; - unsigned Shape:2; + union + { + u16 attr0; + + struct + { + u16 Shape:2; // 14-15: OBJ shape; 0=Square, 1=Horizontal, 2=Vertical, 3=Prohibited + u16 PaletteMode:1; // 13: Color/palette select; 0=16 palettes of 16 colors each, 1=Single palette of 256 colors + u16 Mosaic:1; // 12: Mosaic render: 0=Disable, 1=Enable + u16 Mode:2; // 10-11: OBJ mode; 0=Normal, 1=Transparent, 2=Window, 3=Bitmap + u16 Disable:1; // 9: OBJ disable flag, only if Bit8 is cleared; 0=Perform render, 1=Do not perform render + u16 RotScale:1; // 8: Perform rotation/scaling; 0=Disable, 1=Enable + u16 Y:8; // 0- 7: Sprite Y-coordinate; 0...255 + }; + + struct + { + u16 :6; + u16 DoubleSize:1; // 9: Perform double-size render, only if Bit8 is set; 0=Disable, 1=Enable + u16 :1; + u16 :8; + }; + }; - //attr1 - signed X:9; - unsigned RotScalIndex:3; - unsigned HFlip:1; - unsigned VFlip:1; - unsigned Size:2; + u16 Size:2; // 30-31: OBJ size, interacts with Bit 14-15 + // + // Size| Square | Horizontal | Vertical + // 0: 8x8 16x8 8x16 + // 1: 16x16 32x8 8x32 + // 2: 32x32 32x16 16x32 + // 3: 64x64 64x32 32x64 + u16 VFlip:1; // 29: Flip sprite vertically; 0=Normal, 1=Flip + u16 HFlip:1; // 28: Flip sprite horizontally; 0=Normal, 1=Flip + u16 RotScaleIndex:3; // 25-27: Rotation/scaling parameter selection; 0...31 + s16 X:9; // 16-24: Sprite X-coordinate; 0...511 - //attr2 - unsigned TileIndex:10; - unsigned Priority:2; - unsigned PaletteIndex:4; - - //attr3 - unsigned attr3:16; // Whenever this is used, you will need to explicitly convert endianness. + u16 PaletteIndex:4; // 44-47: Palette index; 0...15 + u16 Priority:2; // 42-43: Rendering priority; 0...3, where 0 is highest priority and 3 is lowest priority + u16 TileIndex:10; // 32-41: Tile index; 0...1023 #endif + + u16 attr3:16; // 48-63: Whenever this is used, you will need to explicitly convert endianness. }; - } OAMAttributes; enum SpriteRenderMode @@ -1044,8 +1090,6 @@ protected: u8 _sprBoundary; u8 _sprBMPBoundary; - u8 _sprBMPMode; - u32 _sprEnable; bool _blend2[8]; @@ -1057,20 +1101,14 @@ protected: u32 _BG_bmp_ram[4]; u32 _BG_tile_ram[4]; u32 _BG_map_ram[4]; - BGType _BGTypes[4]; - GPUDisplayMode _dispMode; - u8 _vramBlock; - CACHE_ALIGN u8 _sprNum[256]; CACHE_ALIGN u8 _h_win[2][GPU_FRAMEBUFFER_NATIVE_WIDTH]; const u8 *_curr_win[2]; NDSDisplayID _targetDisplayID; - u16 *_VRAMaddrNative; - u16 *_VRAMaddrCustom; - + int _finalColorBckFuncID; int _finalColor3DFuncID; int _finalColorSpriteFuncID; @@ -1123,6 +1161,9 @@ protected: template void _RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t dstLineWidth, const size_t dstLineCount); template void _RenderLine_MasterBrightness(u16 *dstColorLine, const size_t dstLineWidth, const size_t dstLineCount); + template void _HandleDisplayModeOff(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); + template void _HandleDisplayModeNormal(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); + template void _UpdateWINH(); template void _SetupWindows(); template void _ModeRender(); @@ -1134,11 +1175,11 @@ protected: FORCEINLINE FASTCALL void _master_setFinal3dColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const FragmentColor src); template - FORCEINLINE FASTCALL void _master_setFinalOBJColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const u8 type); + FORCEINLINE FASTCALL void _master_setFinalOBJColor(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const OBJMode objMode); template void _SetFinalColorBG(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, u16 src); void _SetFinalColor3D(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const FragmentColor src); - void _SetFinalColorSprite(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const u8 type); + void _SetFinalColorSprite(const size_t srcX, const size_t dstX, u16 *dstColorLine, u8 *dstLayerIDLine, const u16 src, const u8 alpha, const OBJMode objMode); u16 _FinalColorBlend(const u16 colA, const u16 colB); FORCEINLINE u16 _FinalColorBlendFunc(const u16 colA, const u16 colB, const TBlendTable *blendTable); @@ -1162,8 +1203,8 @@ public: void ResortBGLayers(); void SetupFinalPixelBlitter(); - void ParseReg_DISPCNT(); - template void ParseReg_BGnCNT(); + template void ParseReg_DISPCNT(); + template void ParseReg_BGnCNT(); template void ParseReg_BGnX(); template void ParseReg_BGnY(); template void ParseReg_WINnH(); @@ -1173,7 +1214,7 @@ public: void ParseReg_BLDY(); void ParseReg_MASTER_BRIGHT(); - void ParseAllRegisters(); + template void ParseAllRegisters(); template void RenderLine(const u16 l, bool skip); @@ -1219,11 +1260,6 @@ public: void SpriteRender(u16 *dst, u8 *dst_alpha, u8 *typeTab, u8 *prioTab); void SpriteRenderDebug(const size_t targetScanline, u16 *dst, u8 *dst_alpha, u8 *typeTab, u8 *prioTab); void ModeRenderDebug(const size_t targetScanline, const GPULayerID layerID, u16 *dstLineColor); - - template void HandleDisplayModeOff(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); - template void HandleDisplayModeNormal(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); - template void HandleDisplayModeVRAM(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); - template void HandleDisplayModeMainMemory(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); int GetFinalColorBckFuncID() const; void SetFinalColorBckFuncID(int funcID); @@ -1241,10 +1277,19 @@ public: class GPUEngineA : public GPUEngineBase { +private: + GPUEngineA(); + ~GPUEngineA(); + protected: FragmentColor *_3DFramebufferRGBA6665; u16 *_3DFramebufferRGBA5551; + u16 *_VRAMaddrNative; + u16 *_VRAMaddrCustom; + u16 *_VRAMNativeBlockPtr[4]; + u16 *_VRAMCustomBlockPtr[4]; + template void _RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t dstLineWidth, const size_t dstLineCount); template void _RenderLine_DisplayCapture(const u16 l); void _RenderLine_DispCapture_FIFOToBuffer(u16 *fifoLineBuffer); @@ -1264,6 +1309,10 @@ protected: template void _RenderLine_DispCapture_Blend(const u16 *__restrict srcA, const u16 *__restrict srcB, u16 *__restrict dst, const size_t captureLengthExt, const size_t l); + template void _HandleDisplayModeVRAM(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); + template void _HandleDisplayModeMainMemory(u16 *dstColorLine, const size_t l, const size_t dstLineWidth, const size_t dstLineCount); + + public: DISPCAPCNT_parsed dispCapCnt; @@ -1272,21 +1321,20 @@ public: virtual void Reset(); void ParseReg_DISPCAPCNT(); - GPUDisplayMode GetDisplayMode() const; - u8 GetVRAMBlock() const; + void UpdateSelectedVRAMBlock(); FragmentColor* Get3DFramebufferRGBA6665() const; u16* Get3DFramebufferRGBA5551() const; virtual void SetCustomFramebufferSize(size_t w, size_t h); template void RenderLine(const u16 l, bool skip); - -private: - GPUEngineA(); - ~GPUEngineA(); }; class GPUEngineB : public GPUEngineBase { +private: + GPUEngineB(); + ~GPUEngineB(); + protected: template void _RenderLine_Layer(const u16 l, u16 *dstColorLine, const size_t dstLineWidth, const size_t dstLineCount); @@ -1296,10 +1344,6 @@ public: virtual void Reset(); template void RenderLine(const u16 l, bool skip); - -private: - GPUEngineB(); - ~GPUEngineB(); }; class NDSDisplay @@ -1323,6 +1367,9 @@ public: class GPUSubsystem { private: + GPUSubsystem(); + ~GPUSubsystem(); + GPUEngineA *_engineMain; GPUEngineB *_engineSub; NDSDisplay *_displayMain; @@ -1338,9 +1385,6 @@ private: NDSDisplayInfo _displayInfo; - GPUSubsystem(); - ~GPUSubsystem(); - public: static GPUSubsystem* Allocate(); void FinalizeAndDeallocate(); @@ -1380,7 +1424,7 @@ public: // frontend becomes responsible for calling GetDisplayInfo() and reading the native // and custom buffers properly for each display. If a single buffer is still needed // for certain cases, then the frontend must manually call - // GPUEngineBase::BlitNativeToCustomFramebuffer() for each GPU before reading the + // GPUEngineBase::BlitNativeToCustomFramebuffer() for each engine before reading the // master framebuffer. bool GetWillAutoBlitNativeToCustomBuffer() const; void SetWillAutoBlitNativeToCustomBuffer(const bool willAutoBlit); diff --git a/desmume/src/MMU.cpp b/desmume/src/MMU.cpp index 292eefe08..9c5daee69 100644 --- a/desmume/src/MMU.cpp +++ b/desmume/src/MMU.cpp @@ -3565,36 +3565,36 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) { case REG_DISPA_DISPCNT: T1WriteWord(MMU.ARM9_REG, 0x0000, val); - mainEngine->ParseReg_DISPCNT(); + mainEngine->ParseReg_DISPCNT(); return; case REG_DISPA_DISPCNT+2: T1WriteWord(MMU.ARM9_REG, 0x0002, val); - mainEngine->ParseReg_DISPCNT(); + mainEngine->ParseReg_DISPCNT(); return; case REG_DISPA_BG0CNT: //GPULOG("MAIN BG0 SETPROP 16B %08X\r\n", val); T1WriteWord(MMU.ARM9_REG, 0x0008, val); - mainEngine->ParseReg_BGnCNT(); + mainEngine->ParseReg_BGnCNT(); return; case REG_DISPA_BG1CNT: //GPULOG("MAIN BG1 SETPROP 16B %08X\r\n", val); T1WriteWord(MMU.ARM9_REG, 0x000A, val); - mainEngine->ParseReg_BGnCNT(); + mainEngine->ParseReg_BGnCNT(); return; case REG_DISPA_BG2CNT: //GPULOG("MAIN BG2 SETPROP 16B %08X\r\n", val); T1WriteWord(MMU.ARM9_REG, 0x000C, val); - mainEngine->ParseReg_BGnCNT(); + mainEngine->ParseReg_BGnCNT(); return; case REG_DISPA_BG3CNT: //GPULOG("MAIN BG3 SETPROP 16B %08X\r\n", val); T1WriteWord(MMU.ARM9_REG, 0x000E, val); - mainEngine->ParseReg_BGnCNT(); + mainEngine->ParseReg_BGnCNT(); return; case REG_DISPA_BG2XL: @@ -3708,36 +3708,36 @@ void FASTCALL _MMU_ARM9_write16(u32 adr, u16 val) case REG_DISPB_DISPCNT: T1WriteWord(MMU.ARM9_REG, 0x1000, val); - subEngine->ParseReg_DISPCNT(); + subEngine->ParseReg_DISPCNT(); return; case REG_DISPB_DISPCNT+2: T1WriteWord(MMU.ARM9_REG, 0x1002, val); - subEngine->ParseReg_DISPCNT(); + subEngine->ParseReg_DISPCNT(); return; case REG_DISPB_BG0CNT: //GPULOG("SUB BG0 SETPROP 16B %08X\r\n", val); T1WriteWord(MMU.ARM9_REG, 0x1008, val); - subEngine->ParseReg_BGnCNT(); + subEngine->ParseReg_BGnCNT(); return; case REG_DISPB_BG1CNT: //GPULOG("SUB BG1 SETPROP 16B %08X\r\n", val); T1WriteWord(MMU.ARM9_REG, 0x100A, val); - subEngine->ParseReg_BGnCNT(); + subEngine->ParseReg_BGnCNT(); return; case REG_DISPB_BG2CNT: //GPULOG("SUB BG2 SETPROP 16B %08X\r\n", val); T1WriteWord(MMU.ARM9_REG, 0x100C, val); - subEngine->ParseReg_BGnCNT(); + subEngine->ParseReg_BGnCNT(); return; case REG_DISPB_BG3CNT: //GPULOG("SUB BG3 SETPROP 16B %08X\r\n", val); T1WriteWord(MMU.ARM9_REG, 0x100E, val); - subEngine->ParseReg_BGnCNT(); + subEngine->ParseReg_BGnCNT(); return; case REG_DISPB_BG2XL: @@ -4110,20 +4110,20 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) { case REG_DISPA_DISPCNT: T1WriteLong(MMU.ARM9_REG, 0x0000, val); - mainEngine->ParseReg_DISPCNT(); + mainEngine->ParseReg_DISPCNT(); //GPULOG("MAIN INIT 32B %08X\r\n", val); return; case REG_DISPA_BG0CNT: T1WriteLong(MMU.ARM9_REG, 0x0008, val); - mainEngine->ParseReg_BGnCNT(); - mainEngine->ParseReg_BGnCNT(); + mainEngine->ParseReg_BGnCNT(); + mainEngine->ParseReg_BGnCNT(); return; case REG_DISPA_BG2CNT: T1WriteLong(MMU.ARM9_REG, 0x000C, val); - mainEngine->ParseReg_BGnCNT(); - mainEngine->ParseReg_BGnCNT(); + mainEngine->ParseReg_BGnCNT(); + mainEngine->ParseReg_BGnCNT(); return; case REG_DISPA_BG2XL: @@ -4197,20 +4197,20 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) case REG_DISPB_DISPCNT: T1WriteLong(MMU.ARM9_REG, 0x1000, val); - subEngine->ParseReg_DISPCNT(); + subEngine->ParseReg_DISPCNT(); //GPULOG("SUB INIT 32B %08X\r\n", val); return; case REG_DISPB_BG0CNT: T1WriteLong(MMU.ARM9_REG, 0x1008, val); - subEngine->ParseReg_BGnCNT(); - subEngine->ParseReg_BGnCNT(); + subEngine->ParseReg_BGnCNT(); + subEngine->ParseReg_BGnCNT(); return; case REG_DISPB_BG2CNT: T1WriteLong(MMU.ARM9_REG, 0x100C, val); - subEngine->ParseReg_BGnCNT(); - subEngine->ParseReg_BGnCNT(); + subEngine->ParseReg_BGnCNT(); + subEngine->ParseReg_BGnCNT(); return; case REG_DISPB_BG2XL: @@ -4321,12 +4321,12 @@ void FASTCALL _MMU_ARM9_write32(u32 adr, u32 val) return; // Fog Color - Parameters:4b - case 0x04000358: + case eng_3D_FOG_COLOR: HostWriteLong(MMU.ARM9_REG, 0x0358, val); gfx3d_glFogColor(val); return; - case 0x0400035C: + case eng_3D_FOG_OFFSET: HostWriteLong(MMU.ARM9_REG, 0x035C, val); gfx3d_glFogOffset(val); return;