static void FillAndWait(u8* buffer, u32 value, u32 size, u32 control, bool first_engine = true) { if (first_engine) { GX_MemoryFill((u32*)buffer, value, (u32*)(buffer + size), control, 0, 0, 0, 0); gspWaitForPSC0(); } else { GX_MemoryFill(0, 0, 0, control, (u32*)buffer, value, (u32*)(buffer + size), control); gspWaitForPSC1(); } GSPGPU_InvalidateDataCache(buffer, size); }
void gfxLoadBorder(u8* imgData, int imgWidth, int imgHeight) { if(imgData == NULL || (borderInit && (borderWidth != imgWidth || borderHeight != imgHeight))) { if(borderInit) { C3D_TexDelete(&borderTexture); borderInit = false; } borderWidth = 0; borderHeight = 0; gpuBorderWidth = 0; gpuBorderHeight = 0; if(imgData == NULL) { return; } } // Adjust the texture to power-of-two dimensions. borderWidth = imgWidth; borderHeight = imgHeight; gpuBorderWidth = (int) pow(2, ceil(log(borderWidth) / log(2))); gpuBorderHeight = (int) pow(2, ceil(log(borderHeight) / log(2))); // Create the texture. if(!borderInit && !C3D_TexInit(&borderTexture, gpuBorderWidth, gpuBorderHeight, GPU_RGBA8)) { return; } C3D_TexSetFilter(&borderTexture, GPU_LINEAR, GPU_LINEAR); // Copy the texture to a power-of-two sized buffer. u32* imgBuffer = (u32*) imgData; u32* temp = (u32*) linearAlloc(gpuBorderWidth * gpuBorderHeight * sizeof(u32)); for(int x = 0; x < borderWidth; x++) { for(int y = 0; y < borderHeight; y++) { temp[y * gpuBorderWidth + x] = imgBuffer[y * borderWidth + x]; } } GSPGPU_FlushDataCache(temp, gpuBorderWidth * gpuBorderHeight * sizeof(u32)); if(R_SUCCEEDED(GX_DisplayTransfer(temp, (u32) GX_BUFFER_DIM(gpuBorderWidth, gpuBorderHeight), (u32*) borderTexture.data, (u32) GX_BUFFER_DIM(gpuBorderWidth, gpuBorderHeight), GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)))) { gspWaitForPPF(); } linearFree(temp); GSPGPU_InvalidateDataCache(borderTexture.data, borderTexture.size); borderInit = true; }
static void svchax_gspwn(u32 dst, u32 src, u32 size, u8* flush_buffer) { extern Handle gspEvents[GSPEVENT_MAX]; memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); GSPGPU_InvalidateDataCache(dst, size); GSPGPU_FlushDataCache(src, size); memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); svcClearEvent(gspEvents[GSPEVENT_PPF]); GX_TextureCopy(src, 0, dst, 0, size, 8); svcWaitSynchronization(gspEvents[GSPEVENT_PPF], U64_MAX); memcpy(flush_buffer, flush_buffer + 0x4000, 0x4000); }
void gfxDrawScreen() { int screenTexSize = 256; u32* transferBuffer = screenBuffer; GPU_TEXTURE_FILTER_PARAM filter = GPU_NEAREST; if(scaleMode != 0 && scaleFilter != 0) { filter = GPU_LINEAR; if(scaleFilter == 2) { screenTexSize = 512; transferBuffer = scale2xBuffer; gfxScale2xRGBA8888(screenBuffer, 256, scale2xBuffer, 512, 256, 224); } } if(!screenInit || screenTexture.width != screenTexSize || screenTexture.height != screenTexSize) { if(screenInit) { C3D_TexDelete(&screenTexture); screenInit = false; } screenInit = C3D_TexInit(&screenTexture, screenTexSize, screenTexSize, GPU_RGBA8); } C3D_TexSetFilter(&screenTexture, filter, filter); GSPGPU_FlushDataCache(transferBuffer, screenTexSize * screenTexSize * sizeof(u32)); if(R_SUCCEEDED(GX_DisplayTransfer(transferBuffer, (u32) GX_BUFFER_DIM(screenTexSize, screenTexSize), (u32*) screenTexture.data, (u32) GX_BUFFER_DIM(screenTexSize, screenTexSize), GX_TRANSFER_FLIP_VERT(1) | GX_TRANSFER_OUT_TILED(1) | GX_TRANSFER_RAW_COPY(0) | GX_TRANSFER_IN_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_OUT_FORMAT(GX_TRANSFER_FMT_RGBA8) | GX_TRANSFER_SCALING(GX_TRANSFER_SCALE_NO)))) { gspWaitForPPF(); } GSPGPU_InvalidateDataCache(screenTexture.data, screenTexture.size); if(!C3D_FrameBegin(0)) { return; } C3D_RenderTarget* target = gameScreen == 0 ? targetTop : targetBottom; C3D_FrameDrawOn(target); C3D_FVUnifMtx4x4(GPU_VERTEX_SHADER, shaderInstanceGetUniformLocation(program.vertexShader, "projection"), gameScreen == 0 ? &projectionTop : &projectionBottom); u16 viewportWidth = target->renderBuf.colorBuf.height; u16 viewportHeight = target->renderBuf.colorBuf.width; // Draw the screen. if(screenInit) { // Calculate the VBO dimensions. int screenWidth = 256; int screenHeight = 224; if(scaleMode == 1) { screenWidth *= 1.25f; screenHeight *= 1.25f; } else if(scaleMode == 2) { screenWidth *= 1.50f; screenHeight *= 1.50f; } else if(scaleMode == 3) { screenWidth *= viewportHeight / (float) screenHeight; screenHeight = viewportHeight; } else if(scaleMode == 4) { screenWidth = viewportWidth; screenHeight = viewportHeight; } // Calculate VBO points. const float x1 = ((int) viewportWidth - screenWidth) / 2.0f; const float y1 = ((int) viewportHeight - screenHeight) / 2.0f; const float x2 = x1 + screenWidth; const float y2 = y1 + screenHeight; static const float baseTX2 = 256.0f / 256.0f; static const float baseTY2 = 224.0f / 256.0f; static const float baseFilterMod = 0.25f / 256.0f; float tx2 = baseTX2; float ty2 = baseTY2; if(scaleMode != 0 && scaleFilter == 1) { tx2 -= baseFilterMod; ty2 -= baseFilterMod; } C3D_TexBind(0, &screenTexture); C3D_ImmDrawBegin(GPU_TRIANGLES); C3D_ImmSendAttrib(x1, y1, 0.5f, 0.0f); C3D_ImmSendAttrib(0, 0, 0.0f, 0.0f); C3D_ImmSendAttrib(x2, y2, 0.5f, 0.0f); C3D_ImmSendAttrib(tx2, ty2, 0.0f, 0.0f); C3D_ImmSendAttrib(x2, y1, 0.5f, 0.0f); C3D_ImmSendAttrib(tx2, 0, 0.0f, 0.0f); C3D_ImmSendAttrib(x1, y1, 0.5f, 0.0f); C3D_ImmSendAttrib(0, 0, 0.0f, 0.0f); C3D_ImmSendAttrib(x1, y2, 0.5f, 0.0f); C3D_ImmSendAttrib(0, ty2, 0.0f, 0.0f); C3D_ImmSendAttrib(x2, y2, 0.5f, 0.0f); C3D_ImmSendAttrib(tx2, ty2, 0.0f, 0.0f); C3D_ImmDrawEnd(); } // Draw the border. if(borderInit && scaleMode != 4) { // Calculate VBO points. int scaledBorderWidth = borderWidth; int scaledBorderHeight = borderHeight; if(borderScaleMode == 1) { if(scaleMode == 1) { scaledBorderWidth *= 1.25f; scaledBorderHeight *= 1.25f; } else if(scaleMode == 2) { scaledBorderWidth *= 1.50f; scaledBorderHeight *= 1.50f; } else if(scaleMode == 3) { scaledBorderWidth *= viewportHeight / 224.0f; scaledBorderHeight *= viewportHeight / 224.0f; } else if(scaleMode == 4) { scaledBorderWidth *= viewportWidth / 256.0f; scaledBorderHeight *= viewportHeight / 224.0f; } } const float x1 = ((int) viewportWidth - scaledBorderWidth) / 2.0f; const float y1 = ((int) viewportHeight - scaledBorderHeight) / 2.0f; const float x2 = x1 + scaledBorderWidth; const float y2 = y1 + scaledBorderHeight; float tx2 = (float) borderWidth / (float) gpuBorderWidth; float ty2 = (float) borderHeight / (float) gpuBorderHeight; C3D_TexBind(0, &borderTexture); C3D_ImmDrawBegin(GPU_TRIANGLES); C3D_ImmSendAttrib(x1, y1, 0.5f, 0.0f); C3D_ImmSendAttrib(0, 0, 0.0f, 0.0f); C3D_ImmSendAttrib(x2, y2, 0.5f, 0.0f); C3D_ImmSendAttrib(tx2, ty2, 0.0f, 0.0f); C3D_ImmSendAttrib(x2, y1, 0.5f, 0.0f); C3D_ImmSendAttrib(tx2, 0, 0.0f, 0.0f); C3D_ImmSendAttrib(x1, y1, 0.5f, 0.0f); C3D_ImmSendAttrib(0, 0, 0.0f, 0.0f); C3D_ImmSendAttrib(x1, y2, 0.5f, 0.0f); C3D_ImmSendAttrib(0, ty2, 0.0f, 0.0f); C3D_ImmSendAttrib(x2, y2, 0.5f, 0.0f); C3D_ImmSendAttrib(tx2, ty2, 0.0f, 0.0f); C3D_ImmDrawEnd(); } C3D_FrameEnd(0); }
void draw_startup() { Result ret; FILE *f = NULL; u8* bufAdr = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); u8* gfxtopadr = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); MVDSTD_Config config; char str[256]; int i, j; u32 cnt=0; for(i=0;i<320;i++) { for(j=0;j<240;j++) { u32 v=(j+i*240)*3; bufAdr[v]=(pcCos(i+cnt)+4096)/32; bufAdr[v+1]=(pcCos(j-256+cnt)+4096)/64; bufAdr[v+2]=(pcCos(i+128-cnt)+4096)/32; } } f = fopen("sdmc:/mvd_indata.bin", "r"); if(f) { fread(inaddr, 1, 0x46500, f); fclose(f); } else { memcpy(inaddr, bufAdr, 320*240*3); } memset(gfxtopadr, 0, 0x46500); GSPGPU_FlushDataCache(inaddr, 0x46500); printstring("mvd example\n"); ret = mvdstdInit(MVDMODE_COLORFORMATCONV, MVD_INPUT_YUYV422, MVD_OUTPUT_RGB565, 0); memset(str, 0, 256); snprintf(str, sizeof(str)-1, "mvdstdInit(): 0x%08x\n", (unsigned int)ret); printstring(str); if(ret>=0) { mvdstdGenerateDefaultConfig(&config, 320, 240, 320, 240, (u32*)inaddr, (u32*)outaddr, (u32*)&outaddr[0x12c00]); ret = mvdstdProcessFrame(&config, NULL, 0, 0); memset(str, 0, 256); snprintf(str, sizeof(str)-1, "mvdstdProcessFrame(): 0x%08x\n", (unsigned int)ret); printstring(str); } svcSleepThread(1000000000);//Not sure how to determine when frame processing finishes. GSPGPU_InvalidateDataCache(outaddr, 0x100000); f = fopen("sdmc:/mvd_outdata.bin", "w"); if(f) { fwrite(outaddr, 1, 0x100000, f); fclose(f); } f = fopen("sdmc:/mvd_log", "w"); if(f) { fwrite(logstring, 1, strlen(logstring), f); fclose(f); } memcpy(gfxtopadr, outaddr, 0x46500); mvdstdExit(); gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForVBlank(); }