void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc,float Gamma) { VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, fbWidth, fbHeight); if (m_virtualXFBList.end() == vxfb) { if (m_virtualXFBList.size() < MAX_VIRTUAL_XFB) { // create a new Virtual XFB and place it at the front of the list VirtualXFB v; memset(&v, 0, sizeof v); m_virtualXFBList.push_front(v); vxfb = m_virtualXFBList.begin(); } else { // Replace the last virtual XFB --vxfb; } } //else // replace existing virtual XFB // move this Virtual XFB to the front of the list. if (m_virtualXFBList.begin() != vxfb) m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, vxfb); unsigned int target_width, target_height; g_framebuffer_manager->GetTargetSize(&target_width, &target_height, sourceRc); // recreate if needed if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height)) { //delete vxfb->xfbSource; //vxfb->xfbSource = NULL; } if (!vxfb->xfbSource) { vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height); vxfb->xfbSource->texWidth = target_width; vxfb->xfbSource->texHeight = target_height; } vxfb->xfbSource->srcAddr = vxfb->xfbAddr = xfbAddr; vxfb->xfbSource->srcWidth = vxfb->xfbWidth = fbWidth; vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight; vxfb->xfbSource->sourceRc = g_renderer->ConvertEFBRectangle(sourceRc); // keep stale XFB data from being used ReplaceVirtualXFB(); g_renderer->ResetAPIState(); // reset any game specific settings // Copy EFB data to XFB and restore render target again vxfb->xfbSource->CopyEFB(Gamma); g_renderer->RestoreAPIState(); }
void FramebufferManagerBase::CopyToVirtualXFB(u32 xfbAddr, u32 fbStride, u32 fbHeight, const EFBRectangle& sourceRc, float Gamma) { if (!g_framebuffer_manager) return; VirtualXFBListType::iterator vxfb = FindVirtualXFB(xfbAddr, sourceRc.GetWidth(), fbHeight); if (m_virtualXFBList.end() == vxfb) { if (m_virtualXFBList.size() < MAX_VIRTUAL_XFB) { // create a new Virtual XFB and place it at the front of the list m_virtualXFBList.emplace_front(); vxfb = m_virtualXFBList.begin(); } else { // Replace the last virtual XFB --vxfb; } } //else // replace existing virtual XFB // move this Virtual XFB to the front of the list. if (m_virtualXFBList.begin() != vxfb) m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, vxfb); unsigned int target_width, target_height; g_framebuffer_manager->GetTargetSize(&target_width, &target_height); // recreate if needed if (vxfb->xfbSource && (vxfb->xfbSource->texWidth != target_width || vxfb->xfbSource->texHeight != target_height)) vxfb->xfbSource.reset(); if (!vxfb->xfbSource) { vxfb->xfbSource = g_framebuffer_manager->CreateXFBSource(target_width, target_height, m_EFBLayers); if (!vxfb->xfbSource) return; vxfb->xfbSource->texWidth = target_width; vxfb->xfbSource->texHeight = target_height; } vxfb->xfbSource->srcAddr = vxfb->xfbAddr = xfbAddr; vxfb->xfbSource->srcWidth = vxfb->xfbWidth = sourceRc.GetWidth(); vxfb->xfbSource->srcHeight = vxfb->xfbHeight = fbHeight; vxfb->xfbSource->sourceRc = g_renderer->ConvertEFBRectangle(sourceRc); // keep stale XFB data from being used ReplaceVirtualXFB(); // Copy EFB data to XFB and restore render target again vxfb->xfbSource->CopyEFB(Gamma); }