X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=plugins%2Fgpu_unai%2Fgpulib_if.cpp;h=e84eff5f4e9a2475670342584a1d5c1dab405778;hb=43047988e507799d7d5bbcd926c5d0b5b94fcdc1;hp=78870de1f7c91164c3bf3877cc11d96211230a82;hpb=ab323c13064ac483e66682556ae3bf387df0f29d;p=pcsx_rearmed.git diff --git a/plugins/gpu_unai/gpulib_if.cpp b/plugins/gpu_unai/gpulib_if.cpp index 78870de1..e84eff5f 100644 --- a/plugins/gpu_unai/gpulib_if.cpp +++ b/plugins/gpu_unai/gpulib_if.cpp @@ -51,6 +51,158 @@ ///////////////////////////////////////////////////////////////////////////// +#define DOWNSCALE_VRAM_SIZE (1024 * 512 * 2 * 2 + 4096) + +INLINE void scale_640_to_320(uint16_t *dest, const uint16_t *src, bool isRGB24) { + size_t uCount = 320; + + if(isRGB24) { + const uint8_t* src8 = (const uint8_t *)src; + uint8_t* dst8 = (uint8_t *)dest; + + do { + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8; + src8 += 4; + } while(--uCount); + } else { + const uint16_t* src16 = src; + uint16_t* dst16 = dest; + + do { + *dst16++ = *src16; + src16 += 2; + } while(--uCount); + } +} + +INLINE void scale_512_to_320(uint16_t *dest, const uint16_t *src, bool isRGB24) { + size_t uCount = 64; + + if(isRGB24) { + const uint8_t* src8 = (const uint8_t *)src; + uint8_t* dst8 = (uint8_t *)dest; + + do { + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8; + src8 += 4; + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8; + src8 += 4; + *dst8++ = *src8++; + *dst8++ = *src8++; + *dst8++ = *src8; + src8 += 4; + } while(--uCount); + } else { + const uint16_t* src16 = src; + uint16_t* dst16 = dest; + + do { + *dst16++ = *src16++; + *dst16++ = *src16; + src16 += 2; + *dst16++ = *src16++; + *dst16++ = *src16; + src16 += 2; + *dst16++ = *src16; + src16 += 2; + } while(--uCount); + } +} + +static uint16_t *get_downscale_buffer(int *x, int *y, int *w, int *h, int *vram_h) +{ + uint16_t *dest = gpu_unai.downscale_vram; + const uint16_t *src = gpu_unai.vram; + bool isRGB24 = (gpu_unai.GPU_GP1 & 0x00200000 ? true : false); + int stride = 1024, dstride = 1024, lines = *h, orig_w = *w; + + // PS1 fb read wraps around (fixes black screen in 'Tobal no. 1') + unsigned int fb_mask = 1024 * 512 - 1; + + if (*h > 240) { + *h /= 2; + stride *= 2; + lines = *h; + + // Ensure start at a non-skipped line + while (*y & gpu_unai.ilace_mask) ++*y; + } + + unsigned int fb_offset_src = (*y * dstride + *x) & fb_mask; + unsigned int fb_offset_dest = fb_offset_src; + + if (*w == 512 || *w == 640) { + *w = 320; + } + + switch(orig_w) { + case 640: + do { + scale_640_to_320(dest + fb_offset_dest, src + fb_offset_src, isRGB24); + fb_offset_src = (fb_offset_src + stride) & fb_mask; + fb_offset_dest = (fb_offset_dest + dstride) & fb_mask; + } while(--lines); + + break; + case 512: + do { + scale_512_to_320(dest + fb_offset_dest, src + fb_offset_src, isRGB24); + fb_offset_src = (fb_offset_src + stride) & fb_mask; + fb_offset_dest = (fb_offset_dest + dstride) & fb_mask; + } while(--lines); + break; + default: + size_t size = isRGB24 ? *w * 3 : *w * 2; + + do { + memcpy(dest + fb_offset_dest, src + fb_offset_src, size); + fb_offset_src = (fb_offset_src + stride) & fb_mask; + fb_offset_dest = (fb_offset_dest + dstride) & fb_mask; + } while(--lines); + break; + } + + return gpu_unai.downscale_vram; +} + +static void map_downscale_buffer(void) +{ + if (gpu_unai.downscale_vram) + return; + + gpu_unai.downscale_vram = (uint16_t*)gpu.mmap(DOWNSCALE_VRAM_SIZE); + + if (gpu_unai.downscale_vram == NULL) { + fprintf(stderr, "failed to map downscale buffer\n"); + gpu.get_downscale_buffer = NULL; + } + else { + gpu.get_downscale_buffer = get_downscale_buffer; + } +} + +static void unmap_downscale_buffer(void) +{ + if (gpu_unai.downscale_vram == NULL) + return; + + gpu.munmap(gpu_unai.downscale_vram, DOWNSCALE_VRAM_SIZE); + gpu_unai.downscale_vram = NULL; + gpu.get_downscale_buffer = NULL; +} + int renderer_init(void) { memset((void*)&gpu_unai, 0, sizeof(gpu_unai)); @@ -94,11 +246,16 @@ int renderer_init(void) SetupLightLUT(); SetupDitheringConstants(); + if (gpu_unai.config.scale_hires) { + map_downscale_buffer(); + } + return 0; } void renderer_finish(void) { + unmap_downscale_buffer(); } void renderer_notify_res_change(void) @@ -227,6 +384,9 @@ int do_cmd_list(u32 *list, int list_len, int *last_cmd) #ifdef HAVE_PRE_ARMV7 /* XXX */ gpu_unai.ilace_mask |= gpu.status.interlace; #endif + if (gpu_unai.config.scale_hires) { + gpu_unai.ilace_mask |= gpu.status.interlace; + } for (; list < list_end; list += 1 + len) { @@ -632,6 +792,14 @@ void renderer_set_config(const struct rearmed_cbs *cbs) gpu_unai.config.fast_lighting = cbs->gpu_unai.fast_lighting; gpu_unai.config.blending = cbs->gpu_unai.blending; gpu_unai.config.dithering = cbs->gpu_unai.dithering; + gpu_unai.config.scale_hires = cbs->gpu_unai.scale_hires; + + gpu.state.downscale_enable = gpu_unai.config.scale_hires; + if (gpu_unai.config.scale_hires) { + map_downscale_buffer(); + } else { + unmap_downscale_buffer(); + } } // vim:shiftwidth=2:expandtab