Пример #1
0
/** 
 * Renders external framebuffer (XFB)
 * @param src_rect Source rectangle in XFB to copy
 * @param dst_rect Destination rectangle in output framebuffer to copy to
 */
void RendererOpenGL::RenderXFB(const Rect& src_rect, const Rect& dst_rect) {

    FlipFramebuffer(LCD::GetFramebufferPointer(LCD::g_regs.framebuffer_top_left_1), m_xfb_top_flipped);
    FlipFramebuffer(LCD::GetFramebufferPointer(LCD::g_regs.framebuffer_sub_left_1), m_xfb_bottom_flipped);

    // Blit the top framebuffer
    // ------------------------

    // Update textures with contents of XFB in RAM - top
    glBindTexture(GL_TEXTURE_2D, m_xfb_texture_top);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
        GL_BGR, GL_UNSIGNED_BYTE, m_xfb_top_flipped);
    glBindTexture(GL_TEXTURE_2D, 0);

    // Render target is destination framebuffer
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]);
    glViewport(0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight);

    // Render source is our EFB
    glBindFramebuffer(GL_READ_FRAMEBUFFER, m_xfb_top);
    glReadBuffer(GL_COLOR_ATTACHMENT0);

    // Blit
    glBlitFramebuffer(src_rect.x0_, src_rect.y0_, src_rect.x1_, src_rect.y1_, 
                      dst_rect.x0_, dst_rect.y1_, dst_rect.x1_, dst_rect.y0_,
                      GL_COLOR_BUFFER_BIT, GL_LINEAR);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);

    // Blit the bottom framebuffer
    // ---------------------------

    // Update textures with contents of XFB in RAM - bottom
    glBindTexture(GL_TEXTURE_2D, m_xfb_texture_bottom);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, VideoCore::kScreenTopWidth, VideoCore::kScreenTopHeight,
        GL_RGB, GL_UNSIGNED_BYTE, m_xfb_bottom_flipped);
    glBindTexture(GL_TEXTURE_2D, 0);

    // Render target is destination framebuffer
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_fbo[kFramebuffer_VirtualXFB]);
    glViewport(0, 0,
        VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight);

    // Render source is our EFB
    glBindFramebuffer(GL_READ_FRAMEBUFFER, m_xfb_bottom);
    glReadBuffer(GL_COLOR_ATTACHMENT0);

    // Blit
    int offset = (VideoCore::kScreenTopWidth - VideoCore::kScreenBottomWidth) / 2;
    glBlitFramebuffer(0,0, VideoCore::kScreenBottomWidth, VideoCore::kScreenBottomHeight, 
                      offset, VideoCore::kScreenBottomHeight, VideoCore::kScreenBottomWidth + offset, 0,
                      GL_COLOR_BUFFER_BIT, GL_LINEAR);

    glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
}
Пример #2
0
/**
 * Renders external framebuffer (XFB)
 * @param src_rect Source rectangle in XFB to copy
 * @param dst_rect Destination rectangle in output framebuffer to copy to
 */
void RendererOpenGL::RenderXFB(const common::Rect& src_rect, const common::Rect& dst_rect) {
    const auto& framebuffer_top = GPU::g_regs.framebuffer_config[0];
    const auto& framebuffer_sub = GPU::g_regs.framebuffer_config[1];
    const u32 active_fb_top = (framebuffer_top.active_fb == 1)
                            ? Memory::PhysicalToVirtualAddress(framebuffer_top.address_left2)
                            : Memory::PhysicalToVirtualAddress(framebuffer_top.address_left1);
    const u32 active_fb_sub = (framebuffer_sub.active_fb == 1)
                            ? Memory::PhysicalToVirtualAddress(framebuffer_sub.address_left2)
                            : Memory::PhysicalToVirtualAddress(framebuffer_sub.address_left1);

    DEBUG_LOG(GPU, "RenderXFB: 0x%08x bytes from 0x%08x(%dx%d), fmt %x",
              framebuffer_top.stride * framebuffer_top.height,
              active_fb_top, (int)framebuffer_top.width,
              (int)framebuffer_top.height, (int)framebuffer_top.format);

    FlipFramebuffer(Memory::GetPointer(active_fb_top), screen_info.Top());
    FlipFramebuffer(Memory::GetPointer(active_fb_sub), screen_info.Bottom());

    for (int i = 0; i < 2; i++) {
        ScreenInfo* current_screen = &screen_info[i];

        glBindTexture(GL_TEXTURE_2D, current_screen->texture_id);

        // TODO: This should consider the GPU registers for framebuffer width, height and stride.
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, current_screen->width, current_screen->height,
                        GL_RGB, GL_UNSIGNED_BYTE, current_screen->flipped_xfb_data);
    }

    glBindTexture(GL_TEXTURE_2D, 0);

    // TODO(princesspeachum):
    // Only the subset src_rect of the GPU buffer
    // should be copied into the texture of the relevant screen.
    //
    // The method's parameters also only include src_rect and dest_rec for one screen,
    // so this may need to be changed (pair for each screen).
}