Пример #1
0
void
GX2RSetAttributeBuffer(GX2RBuffer *buffer,
                       uint32_t index,
                       uint32_t stride,
                       uint32_t offset)
{
   auto bufferPtr = static_cast<uint8_t*>(buffer->buffer.get()) + offset;
   auto bufferSize = buffer->elemCount * buffer->elemSize;
   GX2SetAttribBuffer(index, bufferSize, stride, bufferPtr);
}
Пример #2
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;
}
Пример #3
0
static void* wiiu_gfx_init(const video_info_t* video,
                           const input_driver_t** input, void** input_data)
{
   int i;
   *input = NULL;
   *input_data = NULL;

   wiiu_video_t* wiiu = calloc(1, sizeof(*wiiu));

   if (!wiiu)
      return NULL;

   void* wiiuinput   = NULL;
   if (input && input_data)
   {
      wiiuinput = input_wiiu.init();
      *input = wiiuinput ? &input_wiiu : NULL;
      *input_data = wiiuinput;
   }

   /* video init */
   wiiu->cmd_buffer = MEM2_alloc(0x400000, 0x40);
   u32 init_attributes[] =
   {
      GX2_INIT_CMD_BUF_BASE, (u32)wiiu->cmd_buffer,
      GX2_INIT_CMD_BUF_POOL_SIZE, 0x400000,
      GX2_INIT_ARGC, 0,
      GX2_INIT_ARGV, 0,
      GX2_INIT_END
   };
   GX2Init(init_attributes);

   /* setup scanbuffers */
   u32 size = 0;
   u32 tmp = 0;
   wiiu->render_mode = wiiu_render_mode_map[GX2GetSystemTVScanMode()];
   GX2CalcTVSize(wiiu->render_mode.mode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &size, &tmp);
   wiiu->tv_scan_buffer = MEMBucket_alloc(size, GX2_SCAN_BUFFER_ALIGNMENT);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->tv_scan_buffer, size);
   GX2SetTVBuffer(wiiu->tv_scan_buffer, size, wiiu->render_mode.mode, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
                  GX2_BUFFERING_MODE_DOUBLE);

   GX2CalcDRCSize(GX2_DRC_RENDER_MODE_SINGLE, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8, GX2_BUFFERING_MODE_DOUBLE, &size,
                  &tmp);
   wiiu->drc_scan_buffer = MEMBucket_alloc(size, GX2_SCAN_BUFFER_ALIGNMENT);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->drc_scan_buffer, size);
   GX2SetDRCBuffer(wiiu->drc_scan_buffer, size, GX2_DRC_RENDER_MODE_SINGLE, GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8,
                   GX2_BUFFERING_MODE_DOUBLE);

   memset(&wiiu->color_buffer, 0, sizeof(GX2ColorBuffer));
   wiiu->color_buffer.surface.dim = GX2_SURFACE_DIM_TEXTURE_2D;
   wiiu->color_buffer.surface.width = wiiu->render_mode.width;
   wiiu->color_buffer.surface.height = wiiu->render_mode.height;
   wiiu->color_buffer.surface.depth = 1;
   wiiu->color_buffer.surface.mipLevels = 1;
   wiiu->color_buffer.surface.format = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
   wiiu->color_buffer.surface.use = GX2_SURFACE_USE_TEXTURE_COLOR_BUFFER_TV;
   wiiu->color_buffer.viewNumSlices = 1;
   GX2CalcSurfaceSizeAndAlignment(&wiiu->color_buffer.surface);
   GX2InitColorBufferRegs(&wiiu->color_buffer);

   wiiu->color_buffer.surface.image = MEM1_alloc(wiiu->color_buffer.surface.imageSize,
                                      wiiu->color_buffer.surface.alignment);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->color_buffer.surface.image, wiiu->color_buffer.surface.imageSize);

   wiiu->ctx_state = (GX2ContextState*)MEM2_alloc(sizeof(GX2ContextState), GX2_CONTEXT_STATE_ALIGNMENT);
   GX2SetupContextStateEx(wiiu->ctx_state, GX2_TRUE);

   GX2SetContextState(wiiu->ctx_state);
   GX2SetColorBuffer(&wiiu->color_buffer, GX2_RENDER_TARGET_0);
   GX2SetViewport(0.0f, 0.0f, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height, 0.0f, 1.0f);
   GX2SetScissor(0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);
   GX2SetDepthOnlyControl(GX2_DISABLE, GX2_DISABLE, GX2_COMPARE_FUNC_ALWAYS);
   GX2SetColorControl(GX2_LOGIC_OP_COPY, 1, GX2_DISABLE, GX2_ENABLE);
#if 1
   GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD,
                      GX2_ENABLE,          GX2_BLEND_MODE_SRC_ALPHA, GX2_BLEND_MODE_INV_SRC_ALPHA, GX2_BLEND_COMBINE_MODE_ADD);
#else
   GX2SetBlendControl(GX2_RENDER_TARGET_0, GX2_BLEND_MODE_ONE, GX2_BLEND_MODE_ZERO, GX2_BLEND_COMBINE_MODE_ADD,
                      GX2_DISABLE,         GX2_BLEND_MODE_ONE, GX2_BLEND_MODE_ZERO, GX2_BLEND_COMBINE_MODE_ADD);
#endif
   GX2SetCullOnlyControl(GX2_FRONT_FACE_CCW, GX2_DISABLE, GX2_DISABLE);
#ifdef GX2_CAN_ACCESS_DATA_SECTION
   wiiu->shader = &tex_shader;
#else
   /* init shader */
   //   wiiu->shader = MEM2_alloc(sizeof(*wiiu->shader), GX2_VERTEX_BUFFER_ALIGNMENT);
   wiiu->shader = MEM2_alloc(sizeof(tex_shader), 0x1000);
   memcpy(wiiu->shader, &tex_shader, sizeof(tex_shader));
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU, wiiu->shader, sizeof(tex_shader));

   wiiu->shader->vs.program = MEM2_alloc(wiiu->shader->vs.size, GX2_SHADER_ALIGNMENT);
   memcpy(wiiu->shader->vs.program, tex_shader.vs.program, wiiu->shader->vs.size);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->vs.program, wiiu->shader->vs.size);
   wiiu->shader->vs.attribVars = MEM2_alloc(wiiu->shader->vs.attribVarCount * sizeof(GX2AttribVar),
         GX2_SHADER_ALIGNMENT);
   memcpy(wiiu->shader->vs.attribVars, tex_shader.vs.attribVars ,
          wiiu->shader->vs.attribVarCount * sizeof(GX2AttribVar));

   wiiu->shader->ps.program = MEM2_alloc(wiiu->shader->ps.size, GX2_SHADER_ALIGNMENT);
   memcpy(wiiu->shader->ps.program, tex_shader.ps.program, wiiu->shader->ps.size);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->ps.program, wiiu->shader->ps.size);
   wiiu->shader->ps.samplerVars = MEM2_alloc(wiiu->shader->ps.samplerVarCount * sizeof(GX2SamplerVar),
         GX2_SHADER_ALIGNMENT);
   memcpy(wiiu->shader->ps.samplerVars, tex_shader.ps.samplerVars,
          wiiu->shader->ps.samplerVarCount * sizeof(GX2SamplerVar));

#endif
   wiiu->shader->fs.size = GX2CalcFetchShaderSizeEx(2, GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE);
   wiiu->shader->fs.program = MEM2_alloc(wiiu->shader->fs.size, GX2_SHADER_ALIGNMENT);
   GX2InitFetchShaderEx(&wiiu->shader->fs, (uint8_t*)wiiu->shader->fs.program,
                        sizeof(wiiu->shader->attribute_stream) /  sizeof(GX2AttribStream),
                        (GX2AttribStream*)&wiiu->shader->attribute_stream,
                        GX2_FETCH_SHADER_TESSELLATION_NONE, GX2_TESSELLATION_MODE_DISCRETE);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_SHADER, wiiu->shader->fs.program, wiiu->shader->fs.size);
   GX2SetVertexShader(&wiiu->shader->vs);
   GX2SetPixelShader(&wiiu->shader->ps);
   GX2SetFetchShader(&wiiu->shader->fs);

   wiiu->position = MEM2_alloc(4 * sizeof(*wiiu->position), GX2_VERTEX_BUFFER_ALIGNMENT);
   wiiu_set_position(wiiu->position, &wiiu->color_buffer, 0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);

   wiiu->tex_coord = MEM2_alloc(4 * sizeof(*wiiu->tex_coord), GX2_VERTEX_BUFFER_ALIGNMENT);
   wiiu_set_tex_coords(wiiu->tex_coord, &wiiu->texture, 0, 0, wiiu->texture.surface.width, wiiu->texture.surface.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);

   wiiu->menu.position = MEM2_alloc(4 * sizeof(*wiiu->menu.position), GX2_VERTEX_BUFFER_ALIGNMENT);
   wiiu_set_position(wiiu->menu.position, &wiiu->color_buffer, 0, 0, wiiu->color_buffer.surface.width, wiiu->color_buffer.surface.height);

   wiiu->menu.tex_coord = MEM2_alloc(4 * sizeof(*wiiu->menu.tex_coord), GX2_VERTEX_BUFFER_ALIGNMENT);
   wiiu_set_tex_coords(wiiu->menu.tex_coord, &wiiu->menu.texture, 0, 0, wiiu->menu.texture.surface.width, wiiu->menu.texture.surface.height);

   /* init frame texture */
   memset(&wiiu->texture, 0, sizeof(GX2Texture));
   wiiu->texture.surface.width    = video->input_scale * RARCH_SCALE_BASE;
   wiiu->texture.surface.height   = video->input_scale * RARCH_SCALE_BASE;
   wiiu->texture.surface.depth    = 1;
   wiiu->texture.surface.dim      = GX2_SURFACE_DIM_TEXTURE_2D;
   wiiu->texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
   wiiu->texture.viewNumSlices    = 1;
   wiiu->rgb32 = video->rgb32;
   if(wiiu->rgb32)
   {
      wiiu->texture.surface.format   = GX2_SURFACE_FORMAT_UNORM_R8_G8_B8_A8;
      wiiu->texture.compMap          = GX2_COMP_SEL(_G, _B, _A, _1);
   }
   else
   {
      wiiu->texture.surface.format   = GX2_SURFACE_FORMAT_UNORM_R5_G6_B5;
      wiiu->texture.compMap          = GX2_COMP_SEL(_B, _G, _R, _1);
   }
   GX2CalcSurfaceSizeAndAlignment(&wiiu->texture.surface);
   GX2InitTextureRegs(&wiiu->texture);

   wiiu->texture.surface.image = MEM2_alloc(wiiu->texture.surface.imageSize,
                                 wiiu->texture.surface.alignment);
   memset(wiiu->texture.surface.image, 0x0, wiiu->texture.surface.imageSize);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->texture.surface.image,
                 wiiu->texture.surface.imageSize);

   /* init menu texture */
   memset(&wiiu->menu.texture, 0, sizeof(GX2Texture));
   wiiu->menu.texture.surface.width    = 512;
   wiiu->menu.texture.surface.height   = 512;
   wiiu->menu.texture.surface.depth    = 1;
   wiiu->menu.texture.surface.dim      = GX2_SURFACE_DIM_TEXTURE_2D;
   wiiu->menu.texture.surface.format   = GX2_SURFACE_FORMAT_UNORM_R4_G4_B4_A4;
   wiiu->menu.texture.surface.tileMode = GX2_TILE_MODE_LINEAR_ALIGNED;
   wiiu->menu.texture.viewNumSlices    = 1;
   wiiu->menu.texture.compMap          = GX2_COMP_SEL(_A, _R, _G, _B);
   GX2CalcSurfaceSizeAndAlignment(&wiiu->menu.texture.surface);
   GX2InitTextureRegs(&wiiu->menu.texture);

   wiiu->menu.texture.surface.image = MEM2_alloc(wiiu->menu.texture.surface.imageSize,
                                      wiiu->menu.texture.surface.alignment);

   memset(wiiu->menu.texture.surface.image, 0x0, wiiu->menu.texture.surface.imageSize);
   GX2Invalidate(GX2_INVALIDATE_MODE_CPU_TEXTURE, wiiu->menu.texture.surface.image,
                 wiiu->menu.texture.surface.imageSize);

   /* init samplers */
   GX2InitSampler(&wiiu->sampler_nearest, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_POINT);
   GX2InitSampler(&wiiu->sampler_linear, GX2_TEX_CLAMP_MODE_CLAMP, GX2_TEX_XY_FILTER_MODE_LINEAR);

   /* set Texture and Sampler */
   GX2SetPixelTexture(&wiiu->texture, wiiu->shader->sampler.location);
   GX2SetPixelSampler(&wiiu->sampler_linear, wiiu->shader->sampler.location);

   /* clear leftover image */
   GX2ClearColor(&wiiu->color_buffer, 0.0f, 0.0f, 0.0f, 1.0f);
   GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_DRC);
   GX2CopyColorBufferToScanBuffer(&wiiu->color_buffer, GX2_SCAN_TARGET_TV);

   GX2SwapScanBuffers();
   GX2Flush();
   GX2WaitForVsync();

   GX2SetTVEnable(GX2_ENABLE);
   GX2SetDRCEnable(GX2_ENABLE);

   wiiu->keep_aspect   = true;
   wiiu->should_resize = true;
   wiiu->smooth        = video->smooth;
   wiiu->vsync         = video->vsync;
   GX2SetSwapInterval(!!video->vsync);

   wiiu->vp.x           = 0;
   wiiu->vp.y           = 0;
   wiiu->vp.width       = 854;
   wiiu->vp.height      = 480;
   wiiu->vp.full_width  = 854;
   wiiu->vp.full_height = 480;
   video_driver_set_size(&wiiu->vp.width, &wiiu->vp.height);

   float refresh_rate = 60.0f / 1.001f;
   driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &refresh_rate);

   return wiiu;
}