X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=pcsx_rearmed.git;a=blobdiff_plain;f=plugins%2Fgpu_unai%2Fgpu.cpp;h=a7cf495a67c3311af1d5307e745aab4da39d972d;hp=ba32d1806351ccae174f69ba6dcf6d25f7f7ff22;hb=55b0eeea6028e00741e620d28ab3211c49b8515f;hpb=86aad47b0418b1715a4d223adf8f59aa92619d15 diff --git a/plugins/gpu_unai/gpu.cpp b/plugins/gpu_unai/gpu.cpp index ba32d180..a7cf495a 100644 --- a/plugins/gpu_unai/gpu.cpp +++ b/plugins/gpu_unai/gpu.cpp @@ -18,29 +18,35 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307 USA. * ***************************************************************************/ -#include "gpu.h" #include "port.h" +#include "gpu.h" #include "profiler.h" #include "debug.h" int skipCount = 2; /* frame skip (0,1,2,3...) */ -int skCount=0; /* internal frame skip */ +int skCount = 0; /* internal frame skip */ int linesInterlace = 0; /* internal lines interlace */ int linesInterlace_user = 0; /* Lines interlace */ -bool isSkip=false; /* skip frame (info coming from GPU) */ -bool skipFrame=false; /* skip frame (according to frame skip) */ +bool isSkip = false; /* skip frame (info coming from GPU) */ +bool wasSkip = false; +bool skipFrame = false; /* skip frame (according to frame skip) */ bool alt_fps = false; /* Alternative FPS algorithm */ bool show_fps = false; /* Show FPS statistics */ -bool isPAL=false; /* PAL video timing */ +bool isPAL = false; /* PAL video timing */ bool progressInterlace_flag = false; /* Progressive interlace flag */ bool progressInterlace = false; /* Progressive interlace option*/ bool frameLimit = false; /* frames to wait */ + bool light = true; /* lighting */ bool blend = true; /* blending */ +bool FrameToRead = false; /* load image in progress */ +bool FrameToWrite = false; /* store image in progress */ +bool fb_dirty = false; bool enableAbbeyHack = false; /* Abe's Odyssey hack */ + u8 BLEND_MODE; u8 TEXT_MODE; u8 Masking; @@ -58,9 +64,6 @@ s32 px,py; s32 x_end,y_end; u16* pvram; -u32 FrameToRead; -u32 FrameToWrite; - u32 GP0; s32 PacketCount; s32 PacketIndex; @@ -92,7 +95,8 @@ u32 lInc; u32 tInc, tMsk; GPUPacket PacketBuffer; -u16 GPU_FrameBuffer[FRAME_BUFFER_SIZE/2]; // FRAME_BUFFER_SIZE is defined in bytes +// FRAME_BUFFER_SIZE is defined in bytes; 512K is guard memory for out of range reads +u16 GPU_FrameBuffer[(FRAME_BUFFER_SIZE+512*1024)/2] __attribute__((aligned(2048))); u32 GPU_GP1; /////////////////////////////////////////////////////////////////////////////// @@ -180,6 +184,14 @@ long GPU_freeze(unsigned int bWrite, GPUFreeze_t* p2) if (bWrite) { p2->GPU_gp1 = GPU_GP1; + memset(p2->Control, 0, sizeof(p2->Control)); + // save resolution and registers for P.E.Op.S. compatibility + p2->Control[3] = (3 << 24) | ((GPU_GP1 >> 23) & 1); + p2->Control[4] = (4 << 24) | ((GPU_GP1 >> 29) & 3); + p2->Control[5] = (5 << 24) | (DisplayArea[0] | (DisplayArea[1] << 10)); + p2->Control[6] = (6 << 24) | (2560 << 12); + p2->Control[7] = (7 << 24) | (DisplayArea[4] | (DisplayArea[5] << 10)); + p2->Control[8] = (8 << 24) | ((GPU_GP1 >> 17) & 0x3f) | ((GPU_GP1 >> 10) & 0x40); memcpy(p2->FrameBuffer, (u16*)GPU_FrameBuffer, FRAME_BUFFER_SIZE); return (1); } @@ -187,6 +199,10 @@ long GPU_freeze(unsigned int bWrite, GPUFreeze_t* p2) { GPU_GP1 = p2->GPU_gp1; memcpy((u16*)GPU_FrameBuffer, p2->FrameBuffer, FRAME_BUFFER_SIZE); + GPU_writeStatus((5 << 24) | p2->Control[5]); + GPU_writeStatus((7 << 24) | p2->Control[7]); + GPU_writeStatus((8 << 24) | p2->Control[8]); + gpuSetTexture(GPU_GP1); return (1); } return (0); @@ -269,7 +285,7 @@ void GPU_writeDataMem(u32* dmaAddress, s32 dmaCount) pvram += 1024; if (++py>=y_end) { - FrameToWrite = 0; + FrameToWrite = false; GPU_GP1 &= ~0x08000000; break; } @@ -282,7 +298,7 @@ void GPU_writeDataMem(u32* dmaAddress, s32 dmaCount) pvram += 1024; if (++py>=y_end) { - FrameToWrite = 0; + FrameToWrite = false; GPU_GP1 &= ~0x08000000; break; } @@ -298,6 +314,7 @@ void GPU_writeDataMem(u32* dmaAddress, s32 dmaCount) } GPU_GP1 = (GPU_GP1 | 0x14000000) & ~0x60000000; + fb_dirty = true; pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE); pcsx4all_prof_resume(PCSX4ALL_PROF_CPU); } @@ -315,7 +332,7 @@ INLINE int CheckForEndlessLoop(u32 *laddr) } /////////////////////////////////////////////////////////////////////////////// -void GPU_dmaChain(u32* baseAddr, u32 dmaVAddr) +long GPU_dmaChain(u32* baseAddr, u32 dmaVAddr) { #ifdef DEBUG_ANALYSIS dbg_anacnt_GPU_dmaChain++; @@ -323,6 +340,7 @@ void GPU_dmaChain(u32* baseAddr, u32 dmaVAddr) pcsx4all_prof_start_with_pause(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE); u32 data, *address, count, offset; unsigned int DMACommandCounter = 0; + long dma_words = 0; GPU_GP1 &= ~0x14000000; lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=(u32*)0x1fffff; @@ -339,9 +357,12 @@ void GPU_dmaChain(u32* baseAddr, u32 dmaVAddr) else dmaVAddr = 0x1FFFFF; if(count>0) GPU_writeDataMem(address,count); + dma_words += 1 + count; } GPU_GP1 = (GPU_GP1 | 0x14000000) & ~0x60000000; pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE); + + return dma_words; } /////////////////////////////////////////////////////////////////////////////// @@ -365,7 +386,7 @@ void GPU_writeData(u32 data) pvram += 1024; if (++py>=y_end) { - FrameToWrite = 0; + FrameToWrite = false; GPU_GP1 &= ~0x08000000; } } @@ -379,7 +400,7 @@ void GPU_writeData(u32 data) pvram += 1024; if (++py>=y_end) { - FrameToWrite = 0; + FrameToWrite = false; GPU_GP1 &= ~0x08000000; } } @@ -390,6 +411,7 @@ void GPU_writeData(u32 data) gpuCheckPacket(data); } GPU_GP1 |= 0x14000000; + fb_dirty = true; pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_HW_WRITE); pcsx4all_prof_resume(PCSX4ALL_PROF_CPU); @@ -431,7 +453,7 @@ void GPU_readDataMem(u32* dmaAddress, s32 dmaCount) pvram += 1024; if (++py>=y_end) { - FrameToRead = 0; + FrameToRead = false; GPU_GP1 &= ~0x08000000; break; } @@ -464,7 +486,7 @@ u32 GPU_readData(void) pvram += 1024; if (++py>=y_end) { - FrameToRead = 0; + FrameToRead = false; GPU_GP1 &= ~0x08000000; } } @@ -476,7 +498,7 @@ u32 GPU_readData(void) pvram +=1024; if (++py>=y_end) { - FrameToRead = 0; + FrameToRead = false; GPU_GP1 &= ~0x08000000; } } @@ -512,11 +534,11 @@ void GPU_writeStatus(u32 data) break; case 0x01: GPU_GP1 &= ~0x08000000; - PacketCount = FrameToRead = FrameToWrite = 0; + PacketCount = 0; FrameToRead = FrameToWrite = false; break; case 0x02: GPU_GP1 &= ~0x08000000; - PacketCount = FrameToRead = FrameToWrite = 0; + PacketCount = 0; FrameToRead = FrameToWrite = false; break; case 0x03: GPU_GP1 = (GPU_GP1 & ~0x00800000) | ((data & 1) << 23); @@ -529,10 +551,17 @@ void GPU_writeStatus(u32 data) case 0x05: DisplayArea[0] = (data & 0x000003FF); //(short)(data & 0x3ff); DisplayArea[1] = ((data & 0x0007FC00)>>10); //(data & 0x000FFC00) >> 10; //(short)((data>>10)&0x1ff); + fb_dirty = true; + wasSkip = isSkip; + if (isSkip) + isSkip = false; + else + isSkip = skipFrame; break; case 0x07: DisplayArea[4] = data & 0x000003FF; //(short)(data & 0x3ff); DisplayArea[5] = (data & 0x000FFC00) >> 10; //(short)((data>>10) & 0x3ff); + fb_dirty = true; break; case 0x08: { @@ -543,6 +572,7 @@ void GPU_writeStatus(u32 data) DisplayArea[3] = VerticalResolution[(GPU_GP1 >> 19) & 3]; isPAL = (data & 0x08) ? true : false; // if 1 - PAL mode, else NTSC } + fb_dirty = true; break; case 0x10: switch (data & 0xffff) { @@ -570,6 +600,8 @@ void GPU_writeStatus(u32 data) pcsx4all_prof_resume(PCSX4ALL_PROF_CPU); } +#ifndef REARMED + // Blitting functions #include "gpu_blit.h" @@ -612,71 +644,16 @@ INLINE void gpuVideoOutput(void) int incY = (h0==480) ? 2 : 1; h0=(h0==480 ? 2048 : 1024); - if (!progressInterlace) - { - const int li=linesInterlace; - switch ( w0 ) - { - case 256: - for(int y1=y0+h1; y0=1000000) @@ -835,6 +812,156 @@ void GPU_updateLace(void) isSkip=true; } } + fb_dirty=false; pcsx4all_prof_end_with_resume(PCSX4ALL_PROF_GPU,PCSX4ALL_PROF_COUNTERS); } + +#else + +#include "../../frontend/plugin_lib.h" +#include "../../frontend/cspace.h" + +extern "C" { + +static const struct rearmed_cbs *cbs; +static void *screen_buf; +static s16 old_res_horz, old_res_vert, old_rgb24; + +static void blit(void) +{ + s16 isRGB24 = (GPU_GP1 & 0x00200000) ? 1 : 0; + s16 h0, x0, y0, w0, h1; + u16 *srcs; + u8 *dest; + + x0 = DisplayArea[0] & ~1; // alignment needed by blitter + y0 = DisplayArea[1]; + srcs = &((u16*)GPU_FrameBuffer)[FRAME_OFFSET(x0,y0)]; + + w0 = DisplayArea[2]; + h0 = DisplayArea[3]; // video mode + + h1 = DisplayArea[5] - DisplayArea[4]; // display needed + if (h0 == 480) h1 = Min2(h1*2,480); + + if (h1 <= 0) + return; + + if (w0 != old_res_horz || h1 != old_res_vert || isRGB24 != old_rgb24) + { + old_res_horz = w0; + old_res_vert = h1; + old_rgb24 = (s16)isRGB24; + screen_buf = cbs->pl_vout_set_mode(w0, h1, isRGB24 ? 24 : 16); + } + dest = (u8 *)screen_buf; + + if (isRGB24) + { +#ifndef MAEMO + for (; h1-- > 0; dest += w0 * 3, srcs += 1024) + { + bgr888_to_rgb888(dest, srcs, w0 * 3); + } +#else + for (; h1-- > 0; dest += w0 * 2, srcs += 1024) + { + bgr888_to_rgb565(dest, srcs, w0 * 3); + } +#endif + } + else + { + for (; h1-- > 0; dest += w0 * 2, srcs += 1024) + { + bgr555_to_rgb565(dest, srcs, w0 * 2); + } + } + + screen_buf = cbs->pl_vout_flip(); +} + +static void blit_raw(void) +{ + s16 isRGB24 = (GPU_GP1 & 0x00200000) ? 1 : 0; + s16 h0, w0, h1; + + w0 = DisplayArea[2]; + h0 = DisplayArea[3]; // video mode + h1 = DisplayArea[5] - DisplayArea[4]; // display needed + if (h0 == 480) h1 = Min2(h1*2,480); + + if (h1 <= 0) + return; + + if (w0 != old_res_horz || h1 != old_res_vert || isRGB24 != old_rgb24) + { + old_res_horz = w0; + old_res_vert = h1; + old_rgb24 = (s16)isRGB24; + screen_buf = cbs->pl_vout_set_mode(w0, h1, isRGB24 ? 24 : 16); + } + cbs->pl_vout_raw_flip(DisplayArea[0], DisplayArea[1]); +} + +void GPU_updateLace(void) +{ + // Interlace bit toggle + GPU_GP1 ^= 0x80000000; + + if (!fb_dirty || (GPU_GP1&0x08800000)) + return; + + if (!wasSkip) { + if (cbs->pl_vout_raw_flip != NULL) + blit_raw(); + else + blit(); + fb_dirty = false; + skCount = 0; + } + else { + skCount++; + if (skCount >= 8) + wasSkip = isSkip = 0; + } + + skipFrame = cbs->fskip_advice || cbs->frameskip == 1; +} + +long GPUopen(unsigned long *, char *, char *) +{ + cbs->pl_vout_open(); + screen_buf = cbs->pl_vout_flip(); + return 0; +} + +long GPUclose(void) +{ + cbs->pl_vout_close(); + return 0; +} + +long GPUfreeze(unsigned int ulGetFreezeData, GPUFreeze_t* p2) +{ + if (ulGetFreezeData > 1) + return 0; + + return GPU_freeze(ulGetFreezeData, p2); +} + +void GPUrearmedCallbacks(const struct rearmed_cbs *cbs_) +{ + enableAbbeyHack = cbs_->gpu_unai.abe_hack; + light = !cbs_->gpu_unai.no_light; + blend = !cbs_->gpu_unai.no_blend; + if (cbs_->pl_vout_set_raw_vram) + cbs_->pl_vout_set_raw_vram((void *)GPU_FrameBuffer); + + cbs = cbs_; +} + +} /* extern "C" */ + +#endif