From 27fc306b19bca6cc59b8ebbfae8b089d3e51f86e Mon Sep 17 00:00:00 2001 From: aliaspider Date: Sun, 17 Apr 2016 13:23:56 +0100 Subject: [PATCH 1/4] (3DS) refactor shaders. --- gfx/drivers/ctr_sprite.gsh | 38 +++++++++++++++++++------------------- gfx/drivers/ctr_sprite.vsh | 1 - 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/gfx/drivers/ctr_sprite.gsh b/gfx/drivers/ctr_sprite.gsh index 8309157aa3..c70a622141 100644 --- a/gfx/drivers/ctr_sprite.gsh +++ b/gfx/drivers/ctr_sprite.gsh @@ -2,17 +2,21 @@ .entry main_gsh ; Constants -.constf _01N1 (0.0, 1.0, -1.0, 1.0) -.alias _0000 _01N1.xxxx -.alias _1111 _01N1.yyyy -.alias _0101 _01N1.xyxy -.alias _N1N1 _01N1.zwzw +.constf _N1N1 (-1.0, 1.0, -1.0, 1.0) ; Inputs -.alias sprite_coords v0 -.alias tex_size v1 -.alias top_left sprite_coords.xyxy -.alias bottom_right sprite_coords.zwzw +.alias sprite_coords v0 +.alias tex_frame_coords v1 ;(0.0, 1.0, w/tex_w, 1.0 - h/tex_h) + +.alias top_left sprite_coords.xy ; real: top_right +.alias bottom_right sprite_coords.zw ; real: bottom_left +.alias top_right sprite_coords.zy ; real: bottom_right +.alias bottom_left sprite_coords.xw ; real: top_left + +.alias tex_top_left tex_frame_coords.xy +.alias tex_bottom_right tex_frame_coords.zw +.alias tex_top_right tex_frame_coords.xw +.alias tex_bottom_left tex_frame_coords.zy ; Outputs .out pos position @@ -22,29 +26,25 @@ setemit 0 mov pos.xy, top_left.xy mov pos.zw, _N1N1 - mov texcoord.xy, tex_size.xy + mov texcoord.xy, tex_top_left.xy emit setemit 1 - mov pos.x, top_left.x - mov pos.y, bottom_right.y + mov pos.xy, bottom_left.xy mov pos.zw, _N1N1 - mov texcoord.x, tex_size.z - mov texcoord.y, tex_size.y + mov texcoord.xy, tex_bottom_left.xy emit setemit 2, prim inv mov pos.xy, bottom_right.xy mov pos.zw, _N1N1 - mov texcoord.xy, tex_size.zw + mov texcoord.xy, tex_bottom_right.xy emit setemit 1, prim - mov pos.x, bottom_right.x - mov pos.y, top_left.y + mov pos.xy, top_right.xy mov pos.zw, _N1N1 - mov texcoord.x, tex_size.x - mov texcoord.y, tex_size.w + mov texcoord.xy, tex_top_right.xy emit end diff --git a/gfx/drivers/ctr_sprite.vsh b/gfx/drivers/ctr_sprite.vsh index fc1a5259a6..69714d7742 100644 --- a/gfx/drivers/ctr_sprite.vsh +++ b/gfx/drivers/ctr_sprite.vsh @@ -19,7 +19,6 @@ ; Output .out pos position .out texcoord texcoord0 -.out color color .proc main_vsh From a609a748dbfbc42df0bf71eec19dace26db62325 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Sun, 17 Apr 2016 13:27:55 +0100 Subject: [PATCH 2/4] (3DS) move shaders to a subdirectory. --- Makefile.ctr | 7 +------ gfx/drivers/{ => ctr_shaders}/ctr_sprite.gsh | 0 gfx/drivers/{ => ctr_shaders}/ctr_sprite.vsh | 0 3 files changed, 1 insertion(+), 6 deletions(-) rename gfx/drivers/{ => ctr_shaders}/ctr_sprite.gsh (100%) rename gfx/drivers/{ => ctr_shaders}/ctr_sprite.vsh (100%) diff --git a/Makefile.ctr b/Makefile.ctr index e6d6a36a5a..be92bf934e 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -26,7 +26,7 @@ APP_USE_SVCHAX = 0 include ctr/Makefile.cores OBJS := -OBJS += gfx/drivers/ctr_sprite.o +OBJS += gfx/drivers/ctr_shaders/ctr_sprite.o OBJS += ctr/ctr_system.o OBJS += ctr/ctr_memory.o OBJS += ctr/ctr_linear.o @@ -325,11 +325,6 @@ $(TARGET): $(TARGET_3DSX) $(TARGET_3DS) $(TARGET_CIA) $(TARGET).3dsx: $(TARGET).elf $(TARGET).elf: $(OBJS) libretro_ctr.a -ctr_sprite_shader_shbin.h: gfx/drivers/ctr_sprite.o -gfx/drivers/ctr_gfx.c: ctr_sprite_shader_shbin.h -griffin/griffin.o: gfx/drivers/ctr_gfx.c - - PREFIX := $(DEVKITARM)/bin/arm-none-eabi- CC := $(PREFIX)gcc diff --git a/gfx/drivers/ctr_sprite.gsh b/gfx/drivers/ctr_shaders/ctr_sprite.gsh similarity index 100% rename from gfx/drivers/ctr_sprite.gsh rename to gfx/drivers/ctr_shaders/ctr_sprite.gsh diff --git a/gfx/drivers/ctr_sprite.vsh b/gfx/drivers/ctr_shaders/ctr_sprite.vsh similarity index 100% rename from gfx/drivers/ctr_sprite.vsh rename to gfx/drivers/ctr_shaders/ctr_sprite.vsh From 1465cf1ffc1106bdd47ee154025160ea07216406 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Sun, 17 Apr 2016 15:30:44 +0100 Subject: [PATCH 3/4] (3DS) allow setting a start offset in the texture --- gfx/drivers/ctr_gfx.c | 37 ++++++++++++++++---------- gfx/drivers/ctr_shaders/ctr_sprite.vsh | 3 +-- 2 files changed, 24 insertions(+), 16 deletions(-) diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 1f488d764c..48d84c7a0b 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -49,7 +49,7 @@ typedef struct typedef struct { s16 x0, y0, x1, y1; - s16 u, v; + s16 u0, v0, u1, v1; } ctr_vertex_t; typedef struct ctr_video @@ -147,12 +147,14 @@ static void ctr_update_viewport(ctr_video_t* ctr) float height = ctr->vp.full_height; settings_t *settings = config_get_ptr(); + float desired_aspect = video_driver_get_aspect_ratio(); + if(ctr->rotation & 0x1) + desired_aspect = 1.0 / desired_aspect; + if (settings->video.scale_integer) { video_viewport_get_scaled_integer(&ctr->vp, ctr->vp.full_width, - ctr->vp.full_height, video_driver_get_aspect_ratio(), ctr->keep_aspect); - width = ctr->vp.width; - height = ctr->vp.height; + ctr->vp.full_height, desired_aspect, ctr->keep_aspect); } else if (ctr->keep_aspect) { @@ -173,7 +175,6 @@ static void ctr_update_viewport(ctr_video_t* ctr) #endif { float delta; - float desired_aspect = video_driver_get_aspect_ratio(); if (fabsf(device_aspect - desired_aspect) < 0.0001f) { @@ -279,8 +280,10 @@ static void* ctr_init(const video_info_t* video, ctr->frame_coords->y0 = 0; ctr->frame_coords->x1 = CTR_TOP_FRAMEBUFFER_WIDTH; ctr->frame_coords->y1 = CTR_TOP_FRAMEBUFFER_HEIGHT; - ctr->frame_coords->u = CTR_TOP_FRAMEBUFFER_WIDTH; - ctr->frame_coords->v = CTR_TOP_FRAMEBUFFER_HEIGHT; + ctr->frame_coords->u0 = 0; + ctr->frame_coords->v0 = 0; + ctr->frame_coords->u1 = CTR_TOP_FRAMEBUFFER_WIDTH; + ctr->frame_coords->v1 = CTR_TOP_FRAMEBUFFER_HEIGHT; GSPGPU_FlushDataCache(ctr->frame_coords, sizeof(ctr_vertex_t)); ctr->menu.texture_width = 512; @@ -296,8 +299,10 @@ static void* ctr_init(const video_info_t* video, ctr->menu.frame_coords->y0 = 0; ctr->menu.frame_coords->x1 = CTR_TOP_FRAMEBUFFER_WIDTH - 40; ctr->menu.frame_coords->y1 = CTR_TOP_FRAMEBUFFER_HEIGHT; - ctr->menu.frame_coords->u = CTR_TOP_FRAMEBUFFER_WIDTH - 80; - ctr->menu.frame_coords->v = CTR_TOP_FRAMEBUFFER_HEIGHT; + ctr->menu.frame_coords->u0 = 0; + ctr->menu.frame_coords->v0 = 0; + ctr->menu.frame_coords->u1 = CTR_TOP_FRAMEBUFFER_WIDTH - 80; + ctr->menu.frame_coords->v1 = CTR_TOP_FRAMEBUFFER_HEIGHT; GSPGPU_FlushDataCache(ctr->menu.frame_coords, sizeof(ctr_vertex_t)); ctr_set_scale_vector(&ctr->scale_vector, @@ -348,7 +353,7 @@ static void* ctr_init(const video_info_t* video, ctrGuSetAttributeBuffers(2, VIRT_TO_PHYS(ctr->menu.frame_coords), CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 0 | - CTRGU_ATTRIBFMT(GPU_SHORT, 2) << 4, + CTRGU_ATTRIBFMT(GPU_SHORT, 4) << 4, sizeof(ctr_vertex_t)); GPUCMD_Finalize(); ctrGuFlushAndRun(true); @@ -563,8 +568,10 @@ static bool ctr_frame(void* data, const void* frame, } - ctr->frame_coords->u = width; - ctr->frame_coords->v = height; + ctr->frame_coords->u0 = 0; + ctr->frame_coords->v0 = 0; + ctr->frame_coords->u1 = width; + ctr->frame_coords->v1 = height; GSPGPU_FlushDataCache(ctr->frame_coords, sizeof(ctr_vertex_t)); ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords)); @@ -730,8 +737,10 @@ static void ctr_set_texture_frame(void* data, const void* frame, bool rgb32, ctr->menu.frame_coords->y0 = (CTR_TOP_FRAMEBUFFER_HEIGHT - height) / 2; ctr->menu.frame_coords->x1 = ctr->menu.frame_coords->x0 + width; ctr->menu.frame_coords->y1 = ctr->menu.frame_coords->y0 + height; - ctr->menu.frame_coords->u = width; - ctr->menu.frame_coords->v = height; + ctr->menu.frame_coords->u0 = 0; + ctr->menu.frame_coords->v0 = 0; + ctr->menu.frame_coords->u1 = width; + ctr->menu.frame_coords->v1 = height; GSPGPU_FlushDataCache(ctr->menu.frame_coords, sizeof(ctr_vertex_t)); } diff --git a/gfx/drivers/ctr_shaders/ctr_sprite.vsh b/gfx/drivers/ctr_shaders/ctr_sprite.vsh index 69714d7742..fc0a62f098 100644 --- a/gfx/drivers/ctr_shaders/ctr_sprite.vsh +++ b/gfx/drivers/ctr_shaders/ctr_sprite.vsh @@ -24,8 +24,7 @@ mul r0, viewport_scale, pos_in.yxwz add pos, _1111, r0 - mul r1.zw, texture_scale, texcoord_in.xyxy - mov r1.xy, _0000 + mul r1, texture_scale, texcoord_in add texcoord, _0101, r1 end From 4994de806a2d41b5dc61cf5a0df64e6f5d55c5d7 Mon Sep 17 00:00:00 2001 From: aliaspider Date: Sun, 17 Apr 2016 20:10:21 +0100 Subject: [PATCH 4/4] (3DS) add more display modes for the top screen that can be controlled by the 3D slider. --- Makefile.ctr | 2 +- ctr/ctr_svchax.c | 46 ++++++++ frontend/drivers/platform_ctr.c | 28 ++++- gfx/drivers/ctr_gfx.c | 179 ++++++++++++++++++++++++++++---- gfx/drivers/ctr_gu.h | 6 +- 5 files changed, 236 insertions(+), 25 deletions(-) diff --git a/Makefile.ctr b/Makefile.ctr index be92bf934e..8aa1e34742 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -21,7 +21,7 @@ APP_RSF = ctr/tools/template.rsf APP_SYSTEM_MODE = 64MB APP_SYSTEM_MODE_EXT = 124MB APP_BIG_TEXT_SECTION = 0 -APP_USE_SVCHAX = 0 +APP_USE_SVCHAX = 1 include ctr/Makefile.cores diff --git a/ctr/ctr_svchax.c b/ctr/ctr_svchax.c index cadea4ecc5..1baae59619 100644 --- a/ctr/ctr_svchax.c +++ b/ctr/ctr_svchax.c @@ -45,6 +45,27 @@ static u32 svc_7b(backdoor_fn entry_fn, ...) // can pass up to two arguments to return 0; } +static __attribute__((naked)) +u32 k_get_PA(u32* addr) +{ + __asm__ volatile( + "mov r1, r0 \n\t" + "mcr p15, 0, r0, c7, c8, 1 \n\t" + "mrc p15, 0, r0, c7, c4, 0 \n\t" + "mov r0, r0, LSR#12 \n\t" + "mov r0, r0, LSL#12 \n\t" + "mov r1, r1, LSL#20 \n\t" + "orr r0, r1, LSR#20 \n\t" + "bx lr \n\t" + ); + return 0; +} + +u32 get_PA(u32 addr) +{ + return svc_7b((backdoor_fn)k_get_PA, addr); +} + static void k_enable_all_svcs(u32 isNew3DS) { u32* thread_ACL = *(*(u32***)CURRENT_KTHREAD + 0x22) - 0x6; @@ -505,3 +526,28 @@ Result svchax_init(bool patch_srv) return 0; } + +Result ctr_set_parallax_layer(bool state) +{ + static u32 parallax_layer_kaddr = 0; + + if(!__ctr_svchax) + return -1; + + if(!parallax_layer_kaddr) + { + for (parallax_layer_kaddr = 0xfffc0000; parallax_layer_kaddr < 0xfffe0000; parallax_layer_kaddr += 0x2000) + { + if (get_PA(parallax_layer_kaddr) == 0x10202000) + break; + else + svcSleepThread(10000); + } + } + + write_kaddr(parallax_layer_kaddr, state? 0x00010001: 0x0); +#if 0 + printf("set layer : %s\n", state?"ON" : "OFF"); +#endif + return 0; +} diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 82932495db..e6bb6af735 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -112,6 +112,8 @@ static void frontend_ctr_deinit(void *data) cfguExit(); ndspExit(); csndExit(); + gfxTopRightFramebuffers[0] = NULL; + gfxTopRightFramebuffers[1] = NULL; gfxExit(); #endif } @@ -174,6 +176,8 @@ static void ctr_check_dspfirm(void) __attribute__((weak)) Result svchax_init(bool patch_srv); __attribute__((weak)) u32 __ctr_patch_services; +void gfxSetFramebufferInfo(gfxScreen_t screen, u8 id); + static void frontend_ctr_init(void *data) { #ifndef IS_SALAMANDER @@ -183,7 +187,29 @@ static void frontend_ctr_init(void *data) *verbose = true; gfxInit(GSP_BGR8_OES,GSP_RGB565_OES,false); - gfxSet3D(false); + + u32 topSize = 400 * 240 * 3; + u32 bottomSize = 320 * 240 * 2; + linearFree(gfxTopLeftFramebuffers[0]); + linearFree(gfxTopLeftFramebuffers[1]); + linearFree(gfxBottomFramebuffers[0]); + linearFree(gfxBottomFramebuffers[1]); + linearFree(gfxTopRightFramebuffers[0]); + linearFree(gfxTopRightFramebuffers[1]); + + gfxTopLeftFramebuffers[0]=linearAlloc(topSize * 2); + gfxTopRightFramebuffers[0] = gfxTopLeftFramebuffers[0] + topSize; + + gfxTopLeftFramebuffers[1]=linearAlloc(topSize * 2); + gfxTopRightFramebuffers[1] = gfxTopLeftFramebuffers[1] + topSize; + + gfxBottomFramebuffers[0]=linearAlloc(bottomSize); + gfxBottomFramebuffers[1]=linearAlloc(bottomSize); + + gfxSetFramebufferInfo(GFX_TOP, 0); + gfxSetFramebufferInfo(GFX_BOTTOM, 0); + + gfxSet3D(true); consoleInit(GFX_BOTTOM, NULL); /* enable access to all service calls when possible. */ diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 48d84c7a0b..ebb8cee4f4 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -30,10 +30,17 @@ #include "../../retroarch.h" #include "../../performance.h" -#define CTR_TOP_FRAMEBUFFER_WIDTH 400 -#define CTR_TOP_FRAMEBUFFER_HEIGHT 240 -#define CTR_GPU_FRAMEBUFFER ((void*)0x1F119400) -#define CTR_GPU_DEPTHBUFFER ((void*)0x1F370800) +#define CTR_TOP_FRAMEBUFFER_WIDTH 400 +#define CTR_TOP_FRAMEBUFFER_HEIGHT 240 +#define CTR_TOP_FRAMEBUFFER_SIZE (CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * 4) + +#define CTR_VRAM_START 0x1F000000 +#define CTR_TOP_FRAMEBUFFER ((void*)CTR_VRAM_START) +#define CTR_TOP_FRAMEBUFFER_LEFT ((void*)CTR_TOP_FRAMEBUFFER) +#define CTR_TOP_FRAMEBUFFER_RIGHT ((void*)((u32)CTR_TOP_FRAMEBUFFER_LEFT + CTR_TOP_FRAMEBUFFER_SIZE)) + +#define CTR_GPU_DEPTHBUFFER ((void*)(CTR_TOP_FRAMEBUFFER_RIGHT + CTR_TOP_FRAMEBUFFER_SIZE)) + extern const u8 ctr_sprite_shbin[]; extern const u32 ctr_sprite_shbin_size; @@ -52,6 +59,14 @@ typedef struct s16 u0, v0, u1, v1; } ctr_vertex_t; +typedef enum +{ + CTR_VIDEO_MODE_NORMAL, + CTR_VIDEO_MODE_800x240, + CTR_VIDEO_MODE_400x240, + CTR_VIDEO_MODE_3D +}ctr_video_mode_enum; + typedef struct ctr_video { struct @@ -93,8 +108,57 @@ typedef struct ctr_video void* empty_framebuffer; aptHookCookie lcd_aptHook; + ctr_video_mode_enum video_mode; + int current_buffer_top; } ctr_video_t; +static INLINE void ctr_check_3D_slider(ctr_video_t* ctr) +{ + float slider_val = *(float*)0x1FF81080; + ctr_video_mode_enum old_mode = ctr->video_mode; + + if (slider_val == 0.0) + ctr->video_mode = CTR_VIDEO_MODE_NORMAL; + else if (slider_val < 0.1) + ctr->video_mode = CTR_VIDEO_MODE_800x240; + else if (slider_val < 0.6) + ctr->video_mode = CTR_VIDEO_MODE_400x240; + else + ctr->video_mode = CTR_VIDEO_MODE_3D; + + if (old_mode != ctr->video_mode) + { + switch (ctr->video_mode) + { + case CTR_VIDEO_MODE_800x240: + case CTR_VIDEO_MODE_400x240: + if (ctr_set_parallax_layer(false)) + ctr->video_mode = CTR_VIDEO_MODE_3D; + break; + case CTR_VIDEO_MODE_3D: + ctr_set_parallax_layer(true); + break; + default: + break; + } + } + + if (ctr->video_mode == CTR_VIDEO_MODE_3D) + { + s16 offset = (slider_val - 0.6) * 10.0; + ctr->menu.frame_coords[1] = ctr->menu.frame_coords[0]; + ctr->menu.frame_coords[2] = ctr->menu.frame_coords[0]; + + ctr->menu.frame_coords[1].x0 += offset; + ctr->menu.frame_coords[1].x1 += offset; + ctr->menu.frame_coords[2].x0 -= offset; + ctr->menu.frame_coords[2].x1 -= offset; + + GSPGPU_FlushDataCache(ctr->menu.frame_coords, 3 * sizeof(ctr_vertex_t)); + + } +} + static INLINE void ctr_set_scale_vector(ctr_scale_vector_t* vec, int viewport_width, int viewport_height, int texture_width, int texture_height) @@ -249,9 +313,6 @@ static void* ctr_init(const video_info_t* video, if (!ctr) return NULL; -// gfxInitDefault(); -// gfxSet3D(false); - memset(ctr, 0, sizeof(ctr_video_t)); @@ -293,7 +354,7 @@ static void* ctr_init(const video_info_t* video, ctr->menu.texture_swizzled = linearMemAlign(ctr->menu.texture_width * ctr->menu.texture_height * sizeof(uint16_t), 128); - ctr->menu.frame_coords = linearAlloc(sizeof(ctr_vertex_t)); + ctr->menu.frame_coords = linearAlloc(3 * sizeof(ctr_vertex_t)); ctr->menu.frame_coords->x0 = 40; ctr->menu.frame_coords->y0 = 0; @@ -317,13 +378,9 @@ static void* ctr_init(const video_info_t* video, shaderProgramUse(&ctr->shader); GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), - VIRT_TO_PHYS(CTR_GPU_FRAMEBUFFER), + VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, CTR_TOP_FRAMEBUFFER_WIDTH); -// GPU_SetViewport(NULL, -// VIRT_TO_PHYS(CTR_GPU_FRAMEBUFFER), -// 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, CTR_TOP_FRAMEBUFFER_WIDTH); - GPU_DepthMap(-1.0f, 0.0f); GPU_SetFaceCulling(GPU_CULL_NONE); GPU_SetStencilTest(false, GPU_ALWAYS, 0x00, 0xFF, 0x00); @@ -371,6 +428,7 @@ static void* ctr_init(const video_info_t* video, ctr->smooth = video->smooth; ctr->vsync = video->vsync; ctr->lcd_buttom_on = true; + ctr->current_buffer_top = 0; ctr->empty_framebuffer = linearAlloc(320 * 240 * 2); memset(ctr->empty_framebuffer, 0, 320 * 240 * 2); @@ -443,6 +501,8 @@ static bool ctr_frame(void* data, const void* frame, ctr->lcd_buttom_on = !ctr->lcd_buttom_on; } + ctr_check_3D_slider(ctr); + svcWaitSynchronization(gspEvents[GSPGPU_EVENT_P3D], 20000000); svcClearEvent(gspEvents[GSPGPU_EVENT_P3D]); svcWaitSynchronization(gspEvents[GSPGPU_EVENT_PPF], 20000000); @@ -522,8 +582,8 @@ static bool ctr_frame(void* data, const void* frame, if (ctr->should_resize) ctr_update_viewport(ctr); - ctrGuSetMemoryFill(true, (u32*)CTR_GPU_FRAMEBUFFER, 0x00000000, - (u32*)(CTR_GPU_FRAMEBUFFER + CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * sizeof(uint32_t)), + ctrGuSetMemoryFill(true, (u32*)CTR_TOP_FRAMEBUFFER, 0x00000000, + (u32*)(CTR_TOP_FRAMEBUFFER + 2 * CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * sizeof(uint32_t)), 0x201, (u32*)CTR_GPU_DEPTHBUFFER, 0x00000000, (u32*)(CTR_GPU_DEPTHBUFFER + CTR_TOP_FRAMEBUFFER_WIDTH * CTR_TOP_FRAMEBUFFER_HEIGHT * sizeof(uint32_t)), 0x201); @@ -610,8 +670,22 @@ static bool ctr_frame(void* data, const void* frame, 0xFF0000); } + GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), + VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER), + 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, + ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); + GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); + if(ctr->video_mode == CTR_VIDEO_MODE_3D) + { + GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), + VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER_RIGHT), + 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, + CTR_TOP_FRAMEBUFFER_WIDTH); + GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); + } + /* restore */ if (ctr->rgb32) { @@ -634,20 +708,83 @@ static bool ctr_frame(void* data, const void* frame, GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE), GPU_RGBA4); - - ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->menu.frame_coords)); ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->menu.scale_vector, 1); - GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); + GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), + VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER), + 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, + ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); + + if (ctr->video_mode == CTR_VIDEO_MODE_3D) + { + ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(&ctr->menu.frame_coords[1])); + GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); + + GPU_SetViewport(VIRT_TO_PHYS(CTR_GPU_DEPTHBUFFER), + VIRT_TO_PHYS(CTR_TOP_FRAMEBUFFER_RIGHT), + 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, + CTR_TOP_FRAMEBUFFER_WIDTH); + ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(&ctr->menu.frame_coords[2])); + GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); + } + else + { + + ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->menu.frame_coords)); + GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1); + } } GPU_FinishDrawing(); GPUCMD_Finalize(); ctrGuFlushAndRun(true); - ctrGuDisplayTransfer(true, CTR_GPU_FRAMEBUFFER, 240,400, CTRGU_RGBA8, - gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), 240,400,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); + ctrGuDisplayTransfer(true, CTR_TOP_FRAMEBUFFER, + 240, + ctr->video_mode == CTR_VIDEO_MODE_800x240 ? 800 : 400, + CTRGU_RGBA8, + gfxTopLeftFramebuffers[ctr->current_buffer_top], 240,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); + + + if ((ctr->video_mode == CTR_VIDEO_MODE_400x240) || (ctr->video_mode == CTR_VIDEO_MODE_3D)) + ctrGuDisplayTransfer(true, CTR_TOP_FRAMEBUFFER_RIGHT, + 240, + 400, + CTRGU_RGBA8, + gfxTopRightFramebuffers[ctr->current_buffer_top], 240,CTRGU_RGB8, CTRGU_MULTISAMPLE_NONE); + + + // Swap buffers : + ctr->current_buffer_top ^= 1; + extern GSPGPU_FramebufferInfo topFramebufferInfo; + extern u8* gfxSharedMemory; + extern u8 gfxThreadID; + + topFramebufferInfo.active_framebuf=ctr->current_buffer_top; + topFramebufferInfo.framebuf0_vaddr=(u32*)gfxTopLeftFramebuffers[ctr->current_buffer_top]; + if(ctr->video_mode == CTR_VIDEO_MODE_800x240) + { + topFramebufferInfo.framebuf1_vaddr=(u32*)(gfxTopLeftFramebuffers[ctr->current_buffer_top] + 240 * 3); + topFramebufferInfo.framebuf_widthbytesize = 240 * 3 * 2; + } + else + { + topFramebufferInfo.framebuf1_vaddr=(u32*)gfxTopRightFramebuffers[ctr->current_buffer_top]; + topFramebufferInfo.framebuf_widthbytesize = 240 * 3; + } + + + topFramebufferInfo.format=(1<<8)|(1<<5)|GSP_BGR8_OES; + topFramebufferInfo.framebuf_dispselect=ctr->current_buffer_top; + topFramebufferInfo.unk=0x00000000; + + u8* framebufferInfoHeader=gfxSharedMemory+0x200+gfxThreadID*0x80; + GSPGPU_FramebufferInfo* framebufferInfo=(GSPGPU_FramebufferInfo*)&framebufferInfoHeader[0x4]; + framebufferInfoHeader[0x0] ^= 1; + framebufferInfo[framebufferInfoHeader[0x0]] = topFramebufferInfo; + framebufferInfoHeader[0x1]=1; + + - gfxSwapBuffersGpu(); retro_perf_stop(&ctrframe_f); return true; diff --git a/gfx/drivers/ctr_gu.h b/gfx/drivers/ctr_gu.h index 2a7d37384b..cb4683af45 100644 --- a/gfx/drivers/ctr_gu.h +++ b/gfx/drivers/ctr_gu.h @@ -67,6 +67,8 @@ extern u32 gpuCmdBufOffset; extern u32 __linear_heap_size; extern u32 __linear_heap; +Result ctr_set_parallax_layer(bool state); + __attribute__((always_inline)) static INLINE void ctrGuSetTexture(GPU_TEXUNIT unit, u32* data, u16 width, u16 height, u32 param, GPU_TEXCOLOR colorType) @@ -177,13 +179,13 @@ __attribute__((always_inline)) static INLINE Result ctrGuDisplayTransfer (bool queued, void* src, int src_w, int src_h, int src_fmt, - void* dst, int dst_w, int dst_h, int dst_fmt, int multisample_lvl) + void* dst, int dst_w, int dst_fmt, int multisample_lvl) { u32 gxCommand[0x8]; gxCommand[0]=0x03 | (queued? 0x01000000 : 0x0); //CommandID gxCommand[1]=(u32)src; gxCommand[2]=(u32)dst; - gxCommand[3]=CTRGU_SIZE(dst_w, dst_h); + gxCommand[3]=CTRGU_SIZE(dst_w, 0); gxCommand[4]=CTRGU_SIZE(src_w, src_h); gxCommand[5]=(src_fmt << 8) | (dst_fmt << 12) | multisample_lvl; gxCommand[6]=gxCommand[7]=0x0;