Exemplo n.º 1
0
static bool wiiu_gfx_frame(void* data, const void* frame,
                           unsigned width, unsigned height, uint64_t frame_count,
                           unsigned pitch, const char* msg)
{
   (void)msg;
   int i;

   wiiu_video_t* wiiu = (wiiu_video_t*) data;

   if (!width || !height)
   {
      GX2WaitForVsync();
      return true;
   }

   if(wiiu->vsync)
   {
      uint32_t swap_count;
      uint32_t flip_count;
      OSTime last_flip;
      OSTime last_vsync;

      GX2GetSwapStatus(&swap_count, &flip_count, &last_flip, &last_vsync);

      if(wiiu->last_vsync >= last_vsync)
      {
         GX2WaitForVsync();
         wiiu->last_vsync = last_vsync + ms_to_ticks(17);
      }
      else
         wiiu->last_vsync = last_vsync;
   }
   GX2WaitForFlip();

   static u32 lastTick , currentTick;
   currentTick = OSGetSystemTick();
   u32 diff = currentTick - lastTick;
   static float fps;
   static u32 frames;
   frames++;
   if(diff > wiiu_timer_clock)
   {
      fps = (float)frames * ((float) wiiu_timer_clock / (float) diff);
      lastTick = currentTick;
      frames = 0;
   }
#if 0
   static u32 last_frame_tick;
   if (!(wiiu->menu.enable))
      printf("\r frame time : %10.6f ms            \n", (float)(currentTick - last_frame_tick) * 1000.0f / (float)wiiu_timer_clock);
   last_frame_tick = currentTick;
#endif
   printf("\rfps: %8.8f frames : %5i", fps, wiiu->frames++);
   fflush(stdout);

   static struct retro_perf_counter gfx_frame_perf = {0};
   performance_counter_init(&gfx_frame_perf, "gfx_frame");
   performance_counter_start(&gfx_frame_perf);

   if (wiiu->should_resize)
      wiiu_gfx_update_viewport(wiiu);

   GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
   /* can't call GX2ClearColor after GX2SetContextState for whatever reason */
   GX2SetContextState(wiiu->ctx_state);

   if(frame)
   {
      if (width > wiiu->texture.surface.width)
         width = wiiu->texture.surface.width;

      if (height > wiiu->texture.surface.height)
         height = wiiu->texture.surface.height;

      wiiu->width = width;
      wiiu->height = height;
      if(wiiu->rgb32)
      {
         const uint32_t* src = frame;
         uint32_t* dst = (uint32_t*)wiiu->texture.surface.image;

         for (i = 0; i < height; i++)
         {
            int j;
            for(j = 0; j < width; j++)
               dst[j] = src[j];
            dst += wiiu->texture.surface.pitch;
            src += pitch / 4;
         }
      }
      else
      {
         const uint16_t* src = frame;
         uint16_t* dst = (uint16_t*)wiiu->texture.surface.image;

         for (i = 0; i < height; i++)
         {
            int j;
            for(j = 0; j < width; j++)
               dst[j] = __builtin_bswap16(src[j]);
            dst += wiiu->texture.surface.pitch;
            src += pitch / 2;
         }
      }


      GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
                    wiiu->texture.surface.imageSize);
      wiiu_set_tex_coords(wiiu->tex_coord, &wiiu->texture, 0, 0, width, height);
   }

   GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->position), sizeof(*wiiu->position), wiiu->position);
   GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->tex_coord), sizeof(*wiiu->tex_coord), wiiu->tex_coord);

   GX2SetPixelTexture(&wiiu->texture, wiiu->shader->sampler.location);
   GX2SetPixelSampler(wiiu->smooth? &wiiu->sampler_linear : &wiiu->sampler_nearest,
                      wiiu->shader->sampler.location);

   GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);

   if (wiiu->menu.enable)
   {
      GX2SetAttribBuffer(0, 4 * sizeof(*wiiu->menu.position), sizeof(*wiiu->menu.position), wiiu->menu.position);
      GX2SetAttribBuffer(1, 4 * sizeof(*wiiu->menu.tex_coord), sizeof(*wiiu->menu.tex_coord), wiiu->menu.tex_coord);

      GX2SetPixelTexture(&wiiu->menu.texture, wiiu->shader->sampler.location);
      GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);

      GX2DrawEx(GX2_PRIMITIVE_MODE_QUADS, 4, 0, 1);
      GX2DrawDone();
   }

   GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_DRC);
   GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_TV);

   GX2SwapScanBuffers();
   GX2Flush();
   performance_counter_stop(&gfx_frame_perf);

   return true;
}
Exemplo n.º 2
0
static bool cg_d3d9_renderchain_read_viewport(void *data, uint8_t *buffer)
{
   unsigned width, height;
   D3DLOCKED_RECT rect;
   LPDIRECT3DSURFACE target = NULL;
   LPDIRECT3DSURFACE dest   = NULL;
   bool ret                 = true;
   d3d_video_t *d3d         = (d3d_video_t*)data;
   LPDIRECT3DDEVICE d3dr    = (LPDIRECT3DDEVICE)d3d->dev;
   static struct retro_perf_counter d3d_read_viewport = {0};

   video_driver_get_size(&width, &height);

   performance_counter_init(&d3d_read_viewport, "d3d_read_viewport");
   performance_counter_start(&d3d_read_viewport);

   (void)data;
   (void)buffer;

   if (FAILED(d3d->d3d_err = d3dr->GetRenderTarget(0, &target)))
   {
      ret = false;
      goto end;
   }

   if (FAILED(d3d->d3d_err = d3dr->CreateOffscreenPlainSurface(
               width, height,
               D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM,
               &dest, NULL)))
   {
      ret = false;
      goto end;
   }

   if (FAILED(d3d->d3d_err = d3dr->GetRenderTargetData(target, dest)))
   {
      ret = false;
      goto end;
   }

   if (SUCCEEDED(dest->LockRect(&rect, NULL, D3DLOCK_READONLY)))
   {
      unsigned x, y;
      unsigned pitchpix       = rect.Pitch / 4;
      const uint32_t *pixels  = (const uint32_t*)rect.pBits;

      pixels                 += d3d->final_viewport.X;
      pixels                 += (d3d->final_viewport.Height - 1) * pitchpix;
      pixels                 -= d3d->final_viewport.Y * pitchpix;

      for (y = 0; y < d3d->final_viewport.Height; y++, pixels -= pitchpix)
      {
         for (x = 0; x < d3d->final_viewport.Width; x++)
         {
            *buffer++ = (pixels[x] >>  0) & 0xff;
            *buffer++ = (pixels[x] >>  8) & 0xff;
            *buffer++ = (pixels[x] >> 16) & 0xff;
         }
      }

      dest->UnlockRect();
   }
Exemplo n.º 3
0
static bool video_thread_frame(void *data, const void *frame_,
      unsigned width, unsigned height, uint64_t frame_count,
      unsigned pitch, const char *msg)
{
   unsigned copy_stride;
   static struct retro_perf_counter thr_frame = {0};
   const uint8_t *src                  = NULL;
   uint8_t *dst                        = NULL;
   thread_video_t *thr                 = (thread_video_t*)data;

   /* If called from within read_viewport, we're actually in the 
    * driver thread, so just render directly. */
   if (thr->frame.within_thread)
   {
      thread_update_driver_state(thr);

      if (thr->driver && thr->driver->frame)
         return thr->driver->frame(thr->driver_data, frame_,
               width, height, frame_count, pitch, msg);
      return false;
   }

   performance_counter_init(&thr_frame, "thr_frame");
   performance_counter_start(&thr_frame);

   copy_stride = width * (thr->info.rgb32 
         ? sizeof(uint32_t) : sizeof(uint16_t));

   src = (const uint8_t*)frame_;
   dst = thr->frame.buffer;

   slock_lock(thr->lock);

   if (!thr->nonblock)
   {
      settings_t *settings = config_get_ptr();

      retro_time_t target_frame_time = (retro_time_t)
         roundf(1000000 / settings->video.refresh_rate);
      retro_time_t target = thr->last_time + target_frame_time;

      /* Ideally, use absolute time, but that is only a good idea on POSIX. */
      while (thr->frame.updated)
      {
         retro_time_t current = cpu_features_get_time_usec();
         retro_time_t delta   = target - current;

         if (delta <= 0)
            break;

         if (!scond_wait_timeout(thr->cond_cmd, thr->lock, delta))
            break;
      }
   }

   /* Drop frame if updated flag is still set, as thread is 
    * still working on last frame. */
   if (!thr->frame.updated)
   {
      if (src)
      {
         unsigned h;
         for (h = 0; h < height; h++, src += pitch, dst += copy_stride)
            memcpy(dst, src, copy_stride);
      }

      thr->frame.updated = true;
      thr->frame.width  = width;
      thr->frame.height = height;
      thr->frame.count  = frame_count;
      thr->frame.pitch  = copy_stride;

      if (msg)
         strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg));
      else
         *thr->frame.msg = '\0';

      scond_signal(thr->cond_thread);

#if defined(HAVE_MENU)
      if (thr->texture.enable)
      {
         while (thr->frame.updated)
            scond_wait(thr->cond_cmd, thr->lock);
      }
#endif
      thr->hit_count++;
   }
   else
      thr->miss_count++;

   slock_unlock(thr->lock);

   performance_counter_stop(&thr_frame);

   thr->last_time = cpu_features_get_time_usec();
   return true;
}
Exemplo n.º 4
0
static bool ctr_frame(void* data, const void* frame,
      unsigned width, unsigned height, 
      uint64_t frame_count,
      unsigned pitch, const char* msg)
{
   uint32_t diff;
   static uint64_t currentTick,lastTick;
   ctr_video_t       *ctr  = (ctr_video_t*)data;
   settings_t   *settings  = config_get_ptr();
   static float        fps = 0.0;
   static int total_frames = 0;
   static int       frames = 0;
   static struct retro_perf_counter ctrframe_f = {0};
   uint32_t state_tmp;
   touchPosition state_tmp_touch;

   extern bool select_pressed;

   if (!width || !height)
   {
      gspWaitForEvent(GSPGPU_EVENT_VBlank0, true);
      return true;
   }

   if(!aptMainLoop())
   {
      command_event(CMD_EVENT_QUIT, NULL);
      return true;
   }

   if (select_pressed)
   {
      command_event(CMD_EVENT_QUIT, NULL);
      return true;
   }

   state_tmp = hidKeysDown();
   hidTouchRead(&state_tmp_touch);
   if((state_tmp & KEY_TOUCH) && (state_tmp_touch.py < 120))
   {
      Handle lcd_handle;
      u8 not_2DS;
      extern PrintConsole* currentConsole;

      gfxBottomFramebuffers[0] = ctr->lcd_buttom_on ? (u8*)ctr->empty_framebuffer:
                                                      (u8*)currentConsole->frameBuffer;

      CFGU_GetModelNintendo2DS(&not_2DS);
      if(not_2DS && srvGetServiceHandle(&lcd_handle, "gsp::Lcd") >= 0)
      {
         u32 *cmdbuf = getThreadCommandBuffer();
         cmdbuf[0] = ctr->lcd_buttom_on? 0x00120040:  0x00110040;
         cmdbuf[1] = 2;
         svcSendSyncRequest(lcd_handle);
         svcCloseHandle(lcd_handle);
      }

      ctr->lcd_buttom_on = !ctr->lcd_buttom_on;
   }

   svcWaitSynchronization(gspEvents[GSPGPU_EVENT_P3D], 20000000);
   svcClearEvent(gspEvents[GSPGPU_EVENT_P3D]);
   svcWaitSynchronization(gspEvents[GSPGPU_EVENT_PPF], 20000000);
   svcClearEvent(gspEvents[GSPGPU_EVENT_PPF]);

   frames++;

   if (ctr->vsync)
      svcWaitSynchronization(gspEvents[GSPGPU_EVENT_VBlank0], U64_MAX);

   svcClearEvent(gspEvents[GSPGPU_EVENT_VBlank0]);

   currentTick = svcGetSystemTick();
   diff        = currentTick - lastTick;
   if(diff > CTR_CPU_TICKS_PER_SECOND)
   {
      fps = (float)frames * ((float) CTR_CPU_TICKS_PER_SECOND / (float) diff);
      lastTick = currentTick;
      frames = 0;
   }


//#define CTR_INSPECT_MEMORY_USAGE

#ifdef CTR_INSPECT_MEMORY_USAGE
   uint32_t ctr_get_stack_usage(void);
   void ctr_linear_get_stats(void);
   extern u32 __linear_heap_size;
   extern u32 __heap_size;

   MemInfo mem_info;
   PageInfo page_info;
   u32 query_addr = 0x08000000;
   printf(PRINTFPOS(0,0));
   while (query_addr < 0x40000000)
   {
      svcQueryMemory(&mem_info, &page_info, query_addr);
      printf("0x%08X --> 0x%08X (0x%08X) \n", mem_info.base_addr, mem_info.base_addr + mem_info.size, mem_info.size);
      query_addr = mem_info.base_addr + mem_info.size;
      if(query_addr == 0x1F000000)
         query_addr = 0x30000000;
   }
//   static u32* dummy_pointer;
//   if(total_frames == 500)
//      dummy_pointer = malloc(0x2000000);
//   if(total_frames == 1000)
//      free(dummy_pointer);


   printf("========================================");
   printf("0x%08X 0x%08X 0x%08X\n", __heap_size, gpuCmdBufOffset, (__linear_heap_size - linearSpaceFree()));
   printf("fps: %8.4f frames: %i (%X)\n", fps, total_frames++, (__linear_heap_size - linearSpaceFree()));
   printf("========================================");
   u32 app_memory = *((u32*)0x1FF80040);
   u64 mem_used;
   svcGetSystemInfo(&mem_used, 0, 1);
   printf("total mem : 0x%08X          \n", app_memory);
   printf("used: 0x%08X free: 0x%08X      \n", (u32)mem_used, app_memory - (u32)mem_used);
   static u32 stack_usage = 0;
   extern u32 __stack_bottom;
   if(!(total_frames & 0x3F))
      stack_usage = ctr_get_stack_usage();
   printf("stack total:0x%08X used: 0x%08X\n", 0x10000000 - __stack_bottom, stack_usage);

   printf("========================================");
   ctr_linear_get_stats();
   printf("========================================");

#else
   printf(PRINTFPOS(29,0)"fps: %8.4f frames: %i\r", fps, total_frames++);
#endif
   fflush(stdout);

   performance_counter_init(&ctrframe_f, "ctrframe_f");
   performance_counter_start(&ctrframe_f);

   if (ctr->should_resize)
      ctr_update_viewport(ctr);

   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);

   GPUCMD_SetBufferOffset(0);

   if (width > ctr->texture_width)
      width = ctr->texture_width;
   if (height > ctr->texture_height)
      height = ctr->texture_height;

   if(frame)
   {
      if(((((u32)(frame)) >= 0x14000000 && ((u32)(frame)) < 0x40000000)) /* frame in linear memory */
         && !((u32)frame & 0x7F)                                         /* 128-byte aligned */
         && !(pitch & 0xF)                                               /* 16-byte aligned */
         && (pitch > 0x40))
      {
         /* can copy the buffer directly with the GPU */
//         GSPGPU_FlushDataCache(frame, pitch * height);
         ctrGuSetCommandList_First(true,(void*)frame, pitch * height,0,0,0,0);
         ctrGuCopyImage(true, frame, pitch / (ctr->rgb32? 4: 2), height, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, false,
                        ctr->texture_swizzled, ctr->texture_width, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565,  true);
      }
      else
      {
         int i;
         uint8_t      *dst = (uint8_t*)ctr->texture_linear;
         const uint8_t *src = frame;

         for (i = 0; i < height; i++)
         {
            memcpy(dst, src, width * (ctr->rgb32? 4: 2));
            dst += ctr->texture_width * (ctr->rgb32? 4: 2);
            src += pitch;
         }
         GSPGPU_FlushDataCache(ctr->texture_linear,
                               ctr->texture_width * ctr->texture_height * (ctr->rgb32? 4: 2));

         ctrGuCopyImage(false, ctr->texture_linear, ctr->texture_width, ctr->texture_height, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565, false,
                        ctr->texture_swizzled, ctr->texture_width, ctr->rgb32 ? CTRGU_RGBA8: CTRGU_RGB565,  true);

      }

      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));
      ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->scale_vector, 1);
   }

   ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->texture_swizzled), ctr->texture_width, ctr->texture_height,
                  (ctr->smooth? GPU_TEXTURE_MAG_FILTER(GPU_LINEAR)  | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR)
                              : GPU_TEXTURE_MAG_FILTER(GPU_NEAREST) | GPU_TEXTURE_MIN_FILTER(GPU_NEAREST)) |
                  GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE),
                  ctr->rgb32 ? GPU_RGBA8: GPU_RGB565);

   ctr_check_3D_slider(ctr);

   /* ARGB --> RGBA */
   if (ctr->rgb32)
   {
      GPU_SetTexEnv(0,
                    GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, 0),
                    GPU_TEVSOURCES(GPU_PRIMARY_COLOR, GPU_PRIMARY_COLOR, 0),
                    GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_G, 0, 0),
                    GPU_TEVOPERANDS(0, 0, 0),
                    GPU_MODULATE, GPU_MODULATE,
                    0x0000FF);
      GPU_SetTexEnv(1,
                    GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_PREVIOUS),
                    GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0),
                    GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_B, 0, 0),
                    GPU_TEVOPERANDS(0, 0, 0),
                    GPU_MULTIPLY_ADD, GPU_MODULATE,
                    0x00FF00);
      GPU_SetTexEnv(2,
                    GPU_TEVSOURCES(GPU_TEXTURE0, GPU_CONSTANT, GPU_PREVIOUS),
                    GPU_TEVSOURCES(GPU_PREVIOUS, GPU_PREVIOUS, 0),
                    GPU_TEVOPERANDS(GPU_TEVOP_RGB_SRC_ALPHA, 0, 0),
                    GPU_TEVOPERANDS(0, 0, 0),
                    GPU_MULTIPLY_ADD, GPU_MODULATE,
                    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);

   if (ctr->video_mode == CTR_VIDEO_MODE_3D)
   {
      if (ctr->menu_texture_enable)
      {
         ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(&ctr->frame_coords[1]));
         GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);
         ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(&ctr->frame_coords[2]));
      }
      else
      {
         ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords));
         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);
   }
   else
      ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->frame_coords));

   GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, 1);

   /* restore */
   if (ctr->rgb32)
   {
      GPU_SetTexEnv(0, GPU_TEXTURE0, GPU_TEXTURE0, 0, 0, GPU_REPLACE, GPU_REPLACE, 0);
      GPU_SetTexEnv(1, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0);
      GPU_SetTexEnv(2, GPU_PREVIOUS, GPU_PREVIOUS, 0, 0, 0, 0, 0);
   }

   if (ctr->menu_texture_enable)
   {

      GSPGPU_FlushDataCache(ctr->menu.texture_linear,
                            ctr->menu.texture_width * ctr->menu.texture_height * sizeof(uint16_t));

      ctrGuCopyImage(false, ctr->menu.texture_linear, ctr->menu.texture_width, ctr->menu.texture_height, CTRGU_RGBA4444,false,
                     ctr->menu.texture_swizzled, ctr->menu.texture_width, CTRGU_RGBA4444,  true);

      ctrGuSetTexture(GPU_TEXUNIT0, VIRT_TO_PHYS(ctr->menu.texture_swizzled), ctr->menu.texture_width, ctr->menu.texture_height,
                     GPU_TEXTURE_MAG_FILTER(GPU_LINEAR) | GPU_TEXTURE_MIN_FILTER(GPU_LINEAR) |
                     GPU_TEXTURE_WRAP_S(GPU_CLAMP_TO_EDGE) | GPU_TEXTURE_WRAP_T(GPU_CLAMP_TO_EDGE),
                     GPU_RGBA4);

      ctrGuSetVertexShaderFloatUniform(0, (float*)&ctr->menu.scale_vector, 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);

      ctrGuSetAttributeBuffersAddress(VIRT_TO_PHYS(ctr->menu.frame_coords));
      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);
      }
   }

   GPU_FinishDrawing();
   GPUCMD_Finalize();
   ctrGuFlushAndRun(true);

   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;

   performance_counter_stop(&ctrframe_f);

   return true;
}
Exemplo n.º 5
0
/**
 * check_rewind:
 * @pressed              : was rewind key pressed or held?
 *
 * Checks if rewind toggle/hold was being pressed and/or held.
 **/
void state_manager_check_rewind(bool pressed)
{
   static bool first    = true;
   settings_t *settings = config_get_ptr();

   if (state_manager_frame_is_reversed())
   {
      audio_driver_frame_is_reverse();
      state_manager_set_frame_is_reversed(false);
   }

   if (first)
   {
      first = false;
      return;
   }

   if (!rewind_state.state)
      return;

   if (pressed)
   {
      const void *buf    = NULL;

      if (state_manager_pop(rewind_state.state, &buf))
      {
         retro_ctx_serialize_info_t serial_info;

         state_manager_set_frame_is_reversed(true);

         audio_driver_setup_rewind();

         runloop_msg_queue_push(
               msg_hash_to_str(MSG_REWINDING), 0,
               runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL) 
               ? 1 : 30, true);

         serial_info.data_const = buf;
         serial_info.size       = rewind_state.size;

         core_unserialize(&serial_info);

         if (bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
            bsv_movie_ctl(BSV_MOVIE_CTL_FRAME_REWIND, NULL);
      }
      else
         runloop_msg_queue_push(
               msg_hash_to_str(MSG_REWIND_REACHED_END),
               0, 30, true);
   }
   else
   {
      static unsigned cnt      = 0;

      cnt = (cnt + 1) % (settings->rewind_granularity ?
            settings->rewind_granularity : 1); /* Avoid possible SIGFPE. */

      if ((cnt == 0) || bsv_movie_ctl(BSV_MOVIE_CTL_IS_INITED, NULL))
      {
         retro_ctx_serialize_info_t serial_info;
         static struct retro_perf_counter rewind_serialize = {0};
         void *state = NULL;

         state_manager_push_where(rewind_state.state, &state);

         performance_counter_init(&rewind_serialize, "rewind_serialize");
         performance_counter_start(&rewind_serialize);

         serial_info.data = state;
         serial_info.size = rewind_state.size;

         core_serialize(&serial_info);

         performance_counter_stop(&rewind_serialize);

         state_manager_push_do(rewind_state.state);
      }
   }

   core_set_rewind_callbacks();
}
Exemplo n.º 6
0
static void state_manager_push_do(state_manager_t *state)
{
#if STRICT_BUF_SIZE
   memcpy(state->nextblock, state->debugblock, state->debugsize);
#endif

   static struct retro_perf_counter gen_deltas = {0};
   uint8_t *swap = NULL;

   if (state->thisblock_valid)
   {
      const uint8_t *oldb, *newb;
      uint8_t *compressed;
      size_t headpos, tailpos, remaining;
      if (state->capacity < sizeof(size_t) + state->maxcompsize)
         return;

recheckcapacity:;

      headpos = state->head - state->data;
      tailpos = state->tail - state->data;
      remaining = (tailpos + state->capacity -
            sizeof(size_t) - headpos - 1) % state->capacity + 1;

      if (remaining <= state->maxcompsize)
      {
         state->tail = state->data + read_size_t(state->tail);
         state->entries--;
         goto recheckcapacity;
      }

      performance_counter_init(&gen_deltas, "gen_deltas");
      performance_counter_start(&gen_deltas);

      oldb        = state->thisblock;
      newb        = state->nextblock;
      compressed  = state->head + sizeof(size_t);

      compressed += state_manager_raw_compress(oldb, newb,
            state->blocksize, compressed);

      if (compressed - state->data + state->maxcompsize > state->capacity)
      {
         compressed = state->data;
         if (state->tail == state->data + sizeof(size_t))
            state->tail = state->data + read_size_t(state->tail);
      }
      write_size_t(compressed, state->head-state->data);
      compressed += sizeof(size_t);
      write_size_t(state->head, compressed-state->data);
      state->head = compressed;

      performance_counter_stop(&gen_deltas);
   }
   else
      state->thisblock_valid = true;

   swap             = state->thisblock;
   state->thisblock = state->nextblock;
   state->nextblock = swap;

   state->entries++;
}