From 41cc224ca110f331f4f83e4edf0ee96a3a3a4e76 Mon Sep 17 00:00:00 2001 From: Rodolfo Osvaldo Bogado Date: Thu, 8 Oct 2009 00:35:47 +0000 Subject: [PATCH] added a more "correct" Color peeking, you can't lock the drawing surface so the correct way is to use and offscreen surface and use StretchRect to copy the data, then lock the offscreen surface and read the data. this is experimental so please test it a lot. the bad news is you can do this only for the color surface, the z-fuffer remain slow to read and only from lockable formats. the good news are the same code should work for mltisampled surfaced. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4384 8ced0084-cf51-0410-be5f-012b33b47a6e --- .../Src/FramebufferManager.cpp | 30 +++++++++++++++---- .../Plugin_VideoDX9/Src/FramebufferManager.h | 2 ++ Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 21 +++++++++---- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp index 089e181f96..05b2f09932 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp @@ -18,6 +18,7 @@ #include "D3DBase.h" #include "Render.h" #include "FramebufferManager.h" +#include "VideoConfig.h" namespace FBManager { @@ -25,6 +26,10 @@ namespace FBManager static LPDIRECT3DTEXTURE9 s_efb_color_texture; static LPDIRECT3DSURFACE9 s_efb_color_surface; static LPDIRECT3DSURFACE9 s_efb_depth_surface; + +static LPDIRECT3DSURFACE9 s_efb_color_OffScreensurface; + + static D3DFORMAT s_efb_color_surface_Format; static D3DFORMAT s_efb_depth_surface_Format; #undef CHECK @@ -32,6 +37,8 @@ static D3DFORMAT s_efb_depth_surface_Format; LPDIRECT3DSURFACE9 GetEFBColorRTSurface() { return s_efb_color_surface; } LPDIRECT3DSURFACE9 GetEFBDepthRTSurface() { return s_efb_depth_surface; } +LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface() { return s_efb_color_OffScreensurface; } + D3DFORMAT GetEFBDepthRTSurfaceFormat(){return s_efb_depth_surface_Format;} D3DFORMAT GetEFBColorRTSurfaceFormat(){return s_efb_color_surface_Format;} @@ -61,29 +68,40 @@ void Create() CHECK(hr); hr = s_efb_color_texture->GetSurfaceLevel(0, &s_efb_color_surface); + CHECK(hr); + hr = D3D::dev->CreateOffscreenPlainSurface(target_width, target_height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &s_efb_color_OffScreensurface, NULL ); CHECK(hr); - //Select Zbuffer format supported by hadware. - s_efb_depth_surface_Format = D3DFMT_D32F_LOCKABLE; + if (g_ActiveConfig.bEFBAccessEnable) + { + s_efb_depth_surface_Format = D3DFMT_D32F_LOCKABLE; + } + else + { + s_efb_depth_surface_Format = D3DFMT_D24S8; + } hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, D3DFMT_D32F_LOCKABLE, - D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL); + D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL); if (FAILED(hr)) { s_efb_depth_surface_Format = D3DFMT_D16_LOCKABLE; hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, D3DFMT_D16_LOCKABLE, - D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL); + D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL); if(FAILED(hr)) { s_efb_depth_surface_Format = D3DFMT_D24S8; hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, D3DFMT_D24S8, - D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL); + D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL); } - } + } CHECK(hr); } void Destroy() { + if(s_efb_color_OffScreensurface) + s_efb_color_OffScreensurface->Release(); + if(s_efb_depth_surface) s_efb_depth_surface->Release(); s_efb_depth_surface = NULL; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h index 3fa298c16c..59dbd62604 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h +++ b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h @@ -34,6 +34,8 @@ LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle& sourceRc); LPDIRECT3DSURFACE9 GetEFBColorRTSurface(); LPDIRECT3DSURFACE9 GetEFBDepthRTSurface(); +LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface(); +LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface(); D3DFORMAT GetEFBDepthRTSurfaceFormat(); D3DFORMAT GetEFBColorRTSurfaceFormat(); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 801f982e72..7cf3b803d4 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -444,6 +444,10 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y) //Get the working buffer and it's format LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ? FBManager::GetEFBDepthRTSurface() : FBManager::GetEFBColorRTSurface(); + + LPDIRECT3DSURFACE9 pOffScreenBuffer = (type == PEEK_Z || type == POKE_Z) ? + FBManager::GetEFBDepthRTSurface() : FBManager::GetEFBColorOffScreenRTSurface(); + D3DLOCKED_RECT drect; D3DFORMAT BufferFormat = (type == PEEK_Z || type == POKE_Z) ? @@ -469,10 +473,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y) TargetRectangle targetPixelRc = Renderer::ConvertEFBRectangle(efbPixelRc); - // Sample from the center of the target region. - int srcX = (targetPixelRc.left + targetPixelRc.right) / 2; - int srcY = (targetPixelRc.top + targetPixelRc.bottom) / 2; - u32 z = 0; float val = 0.0f; HRESULT hr; @@ -483,7 +483,18 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y) RectToLock.top = targetPixelRc.top; //lock the buffer - if((hr = pBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK) + + if(!(type == PEEK_Z || type == POKE_Z)) + { + hr = D3D::dev->StretchRect(pBuffer,&RectToLock,pOffScreenBuffer,&RectToLock, D3DTEXF_NONE); + if(FAILED(hr)) + { + PanicAlert("Unable to copy data to mem buffer"); + return 0; + } + } + + if((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK) PanicAlert("ERROR: %s", hr == D3DERR_WASSTILLDRAWING ? "Still drawing" : hr == D3DERR_INVALIDCALL ? "Invalid call" : "w00t");