diff options
Diffstat (limited to 'Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp')
| -rw-r--r-- | Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp | 243 |
1 files changed, 47 insertions, 196 deletions
diff --git a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp index 4f38b8c483..332c792d88 100644 --- a/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoDX11/Src/FramebufferManager.cpp @@ -24,7 +24,7 @@ #include "PixelShaderCache.h" #include "VertexShaderCache.h" -FramebufferManager g_framebufferManager; +FramebufferManager::Efb FramebufferManager::m_efb; D3DTexture2D* &FramebufferManager::GetEFBColorTexture() { return m_efb.color_tex; } ID3D11Texture2D* &FramebufferManager::GetEFBColorStagingBuffer() { return m_efb.color_staging_buf; } @@ -33,10 +33,17 @@ D3DTexture2D* &FramebufferManager::GetEFBDepthTexture() { return m_efb.depth_tex D3DTexture2D* &FramebufferManager::GetEFBDepthReadTexture() { return m_efb.depth_read_texture; } ID3D11Texture2D* &FramebufferManager::GetEFBDepthStagingBuffer() { return m_efb.depth_staging_buf; } -void FramebufferManager::Create() +FramebufferManager::FramebufferManager() { + m_efb.color_tex = NULL; + m_efb.color_staging_buf = NULL; + m_efb.depth_tex = NULL; + m_efb.depth_staging_buf = NULL; + m_efb.depth_read_texture = NULL; + unsigned int target_width = Renderer::GetFullTargetWidth(); unsigned int target_height = Renderer::GetFullTargetHeight(); + ID3D11Texture2D* buf; D3D11_TEXTURE2D_DESC texdesc; HRESULT hr; @@ -80,228 +87,72 @@ void FramebufferManager::Create() D3D::SetDebugObjectName((ID3D11DeviceChild*)m_efb.depth_staging_buf, "EFB depth staging texture (used for Renderer::AccessEFB)"); } -void FramebufferManager::Destroy() +FramebufferManager::~FramebufferManager() { SAFE_RELEASE(m_efb.color_tex); SAFE_RELEASE(m_efb.color_staging_buf); SAFE_RELEASE(m_efb.depth_tex); SAFE_RELEASE(m_efb.depth_staging_buf); SAFE_RELEASE(m_efb.depth_read_texture); - - for (VirtualXFBListType::iterator it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it) - SAFE_RELEASE(it->xfbSource.tex); - - m_virtualXFBList.clear(); - SAFE_RELEASE(m_realXFBSource.tex); } -void FramebufferManager::CopyToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void FramebufferManager::CopyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) { - copyToVirtualXFB(xfbAddr, fbWidth, fbHeight, sourceRc); + // TODO + PanicAlert("CopyToRealXFB not implemented, yet\n"); } -const XFBSource** FramebufferManager::GetXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) +XFBSourceBase* FramebufferManager::CreateXFBSource(unsigned int target_width, unsigned int target_height) { - return getVirtualXFBSource(xfbAddr, fbWidth, fbHeight, xfbCount); + return new XFBSource(D3DTexture2D::Create(target_width, target_height, + (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), + D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM)); } -FramebufferManager::VirtualXFBListType::iterator FramebufferManager::findVirtualXFB(u32 xfbAddr, u32 width, u32 height) +void FramebufferManager::GetTargetSize(unsigned int *width, unsigned int *height, const EFBRectangle& sourceRc) { - u32 srcLower = xfbAddr; - u32 srcUpper = xfbAddr + 2 * width * height; + const float scaleX = Renderer::GetXFBScaleX(); + const float scaleY = Renderer::GetXFBScaleY(); - VirtualXFBListType::iterator it; - for (it = m_virtualXFBList.begin(); it != m_virtualXFBList.end(); ++it) - { - u32 dstLower = it->xfbAddr; - u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; + TargetRectangle targetSource; - if (dstLower >= srcLower && dstUpper <= srcUpper) - return it; - } + targetSource.top = (int)(sourceRc.top *scaleY); + targetSource.bottom = (int)(sourceRc.bottom *scaleY); + targetSource.left = (int)(sourceRc.left *scaleX); + targetSource.right = (int)(sourceRc.right * scaleX); - // That address is not in the Virtual XFB list. - return m_virtualXFBList.end(); + *width = targetSource.right - targetSource.left; + *height = targetSource.bottom - targetSource.top; } -void FramebufferManager::replaceVirtualXFB() +void XFBSource::Draw(const MathUtil::Rectangle<float> &sourcerc, + const MathUtil::Rectangle<float> &drawrc, int width, int height) const { - VirtualXFBListType::iterator it = m_virtualXFBList.begin(); - - s32 srcLower = it->xfbAddr; - s32 srcUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; - s32 lineSize = 2 * it->xfbWidth; - - ++it; - - while (it != m_virtualXFBList.end()) - { - s32 dstLower = it->xfbAddr; - s32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; - - if (dstLower >= srcLower && dstUpper <= srcUpper) - { - // Invalidate the data - it->xfbAddr = 0; - it->xfbHeight = 0; - it->xfbWidth = 0; - } - else if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) - { - s32 upperOverlap = (srcUpper - dstLower) / lineSize; - s32 lowerOverlap = (dstUpper - srcLower) / lineSize; - - if (upperOverlap > 0 && lowerOverlap < 0) - { - it->xfbAddr += lineSize * upperOverlap; - it->xfbHeight -= upperOverlap; - } - else if (lowerOverlap > 0) - { - it->xfbHeight -= lowerOverlap; - } - } - - ++it; - } + D3D::drawShadedTexSubQuad(tex->GetSRV(), &sourcerc, + texWidth, texHeight, &drawrc, PixelShaderCache::GetColorCopyProgram(), + VertexShaderCache::GetSimpleVertexShader(), VertexShaderCache::GetSimpleInputLayout()); } -void FramebufferManager::copyToRealXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void XFBSource::DecodeToTexture(u32 xfbAddr, u32 fbWidth, u32 fbHeight) { - // TODO - PanicAlert("copyToRealXFB not implemented, yet\n"); + // TODO: + PanicAlert("RealXFB not implemented, yet\n"); } -void FramebufferManager::copyToVirtualXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRectangle& sourceRc) +void XFBSource::CopyEFB() { - D3DTexture2D* xfbTex; - HRESULT hr = 0; - - VirtualXFBListType::iterator it = findVirtualXFB(xfbAddr, fbWidth, fbHeight); - - if (it == m_virtualXFBList.end() && (int)m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) - { - // Replace the last virtual XFB (might cause glitches, but better than allocating 50 XFBs...) - // TODO: Reencode last virtual XFB to RAM to avoid glitches? - --it; - } - - float scaleX = Renderer::GetXFBScaleX(); - float scaleY = Renderer::GetXFBScaleY(); - TargetRectangle targetSource,efbSource; - efbSource = Renderer::ConvertEFBRectangle(sourceRc); - targetSource.top = (int)(sourceRc.top * scaleY); - targetSource.bottom = (int)(sourceRc.bottom * scaleY); - targetSource.left = (int)(sourceRc.left * scaleX); - targetSource.right = (int)(sourceRc.right * scaleX); - unsigned int target_width = targetSource.right - targetSource.left; - unsigned int target_height = targetSource.bottom - targetSource.top; - if (it != m_virtualXFBList.end()) - { - // Overwrite an existing Virtual XFB. - - it->xfbAddr = xfbAddr; - it->xfbWidth = fbWidth; - it->xfbHeight = fbHeight; - - it->xfbSource.srcAddr = xfbAddr; - it->xfbSource.srcWidth = fbWidth; - it->xfbSource.srcHeight = fbHeight; - - if (it->xfbSource.texWidth != target_width || it->xfbSource.texHeight != target_height || !(it->xfbSource.tex)) - { - SAFE_RELEASE(it->xfbSource.tex); - it->xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM); - if (it->xfbSource.tex == NULL) PanicAlert("Failed to create XFB texture\n"); - } - xfbTex = it->xfbSource.tex; - - it->xfbSource.texWidth = target_width; - it->xfbSource.texHeight = target_height; - - // move this Virtual XFB to the front of the list. - m_virtualXFBList.splice(m_virtualXFBList.begin(), m_virtualXFBList, it); - - // keep stale XFB data from being used - replaceVirtualXFB(); - } - else - { - // Create a new Virtual XFB and place it at the front of the list. - VirtualXFB newVirt; - - newVirt.xfbSource.tex = D3DTexture2D::Create(target_width, target_height, (D3D11_BIND_FLAG)(D3D11_BIND_RENDER_TARGET|D3D11_BIND_SHADER_RESOURCE), D3D11_USAGE_DEFAULT, DXGI_FORMAT_R8G8B8A8_UNORM); - if (newVirt.xfbSource.tex == NULL) PanicAlert("Failed to create a new virtual XFB"); - - newVirt.xfbAddr = xfbAddr; - newVirt.xfbWidth = fbWidth; - newVirt.xfbHeight = fbHeight; - - xfbTex = newVirt.xfbSource.tex; - newVirt.xfbSource.texWidth = target_width; - newVirt.xfbSource.texHeight = target_height; - - // Add the new Virtual XFB to the list - if (m_virtualXFBList.size() >= MAX_VIRTUAL_XFB) - { - // List overflowed; delete the oldest. - m_virtualXFBList.back().xfbSource.tex->Release(); - m_virtualXFBList.pop_back(); - WARN_LOG(VIDEO, "Virtual XFB list overflown, releasing oldest virtual XFB"); - } - m_virtualXFBList.push_front(newVirt); - } - if (!xfbTex->GetRTV()) return; - - Renderer::ResetAPIState(); // reset any game specific settings - // Copy EFB data to XFB and restore render target again - D3D11_RECT sourcerect = CD3D11_RECT(efbSource.left, efbSource.top, efbSource.right, efbSource.bottom); - D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)target_width, (float)target_height); + const D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)texWidth, (float)texHeight); + D3D::context->RSSetViewports(1, &vp); - D3D::context->OMSetRenderTargets(1, &xfbTex->GetRTV(), NULL); + D3D::context->OMSetRenderTargets(1, &tex->GetRTV(), NULL); D3D::SetLinearCopySampler(); - D3D::drawShadedTexQuad(GetEFBColorTexture()->GetSRV(), &sourcerect, - Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), - PixelShaderCache::GetColorCopyProgram(), VertexShaderCache::GetSimpleVertexShader(), - VertexShaderCache::GetSimpleInputLayout()); - D3D::context->OMSetRenderTargets(1, &GetEFBColorTexture()->GetRTV(), GetEFBDepthTexture()->GetDSV()); - Renderer::RestoreAPIState(); -} - -const XFBSource** FramebufferManager::getRealXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) -{ - PanicAlert("getRealXFBSource not implemented, yet\n"); - return NULL; -} - -const XFBSource** FramebufferManager::getVirtualXFBSource(u32 xfbAddr, u32 fbWidth, u32 fbHeight, u32 &xfbCount) -{ - xfbCount = 0; - - if (m_virtualXFBList.size() == 0) - { - // No Virtual XFBs available. - return NULL; - } - - u32 srcLower = xfbAddr; - u32 srcUpper = xfbAddr + 2 * fbWidth * fbHeight; - - VirtualXFBListType::iterator it; - for (it = m_virtualXFBList.end(); it != m_virtualXFBList.begin();) - { - --it; - - u32 dstLower = it->xfbAddr; - u32 dstUpper = it->xfbAddr + 2 * it->xfbWidth * it->xfbHeight; - - if (addrRangesOverlap(srcLower, srcUpper, dstLower, dstUpper)) - { - m_overlappingXFBArray[xfbCount] = &(it->xfbSource); - xfbCount++; - } - } - - return &m_overlappingXFBArray[0]; + + D3D::drawShadedTexQuad(FramebufferManager::GetEFBColorTexture()->GetSRV(), sourceRc.AsRECT(), + Renderer::GetFullTargetWidth(), Renderer::GetFullTargetHeight(), + PixelShaderCache::GetColorCopyProgram(), VertexShaderCache::GetSimpleVertexShader(), + VertexShaderCache::GetSimpleInputLayout()); + + D3D::context->OMSetRenderTargets(1, &FramebufferManager::GetEFBColorTexture()->GetRTV(), + FramebufferManager::GetEFBDepthTexture()->GetDSV()); } |
