this is EXPERIMENTAL. Implemented 3 different paths to use depth textures and allow peeking.
they are extremely hard/driver Dependant so your test is needed. there plugin will automatically select the path thats work for your hard, need that everyone post the messages that the video init throw (yes all will hate me for the messages) but is the only way to see what is the optimal path. in the next commit will clean the unused paths. i'm afraid thath the second path is Vista dependant (you need to include vista sdk to make it work). the third path use lockable depth buffer so there is no change in that. now peek color is fully working and is fast because the you never lock the the real color texture only the offscreen surface. please if someone knows a game that use peek color please test it. also fixed blending so SMS underwater must be fixed. this work with d3d teach me that i love opengl :) git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4393 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
9701b88be1
commit
56224bd966
|
@ -32,31 +32,6 @@ const bool renderFog = false;
|
|||
|
||||
using namespace D3D;
|
||||
|
||||
// State translation lookup tables
|
||||
static const D3DBLEND d3dSrcFactors[8] =
|
||||
{
|
||||
D3DBLEND_ZERO,
|
||||
D3DBLEND_ONE,
|
||||
D3DBLEND_DESTCOLOR,
|
||||
D3DBLEND_INVDESTCOLOR,
|
||||
D3DBLEND_SRCALPHA,
|
||||
D3DBLEND_INVSRCALPHA,
|
||||
D3DBLEND_DESTALPHA,
|
||||
D3DBLEND_INVDESTALPHA
|
||||
};
|
||||
|
||||
static const D3DBLEND d3dDestFactors[8] =
|
||||
{
|
||||
D3DBLEND_ZERO,
|
||||
D3DBLEND_ONE,
|
||||
D3DBLEND_SRCCOLOR,
|
||||
D3DBLEND_INVSRCCOLOR,
|
||||
D3DBLEND_SRCALPHA,
|
||||
D3DBLEND_INVSRCALPHA,
|
||||
D3DBLEND_DESTALPHA,
|
||||
D3DBLEND_INVDESTALPHA
|
||||
};
|
||||
|
||||
static const D3DCULL d3dCullModes[4] =
|
||||
{
|
||||
D3DCULL_NONE,
|
||||
|
@ -150,42 +125,7 @@ void SetDepthMode(const BPCmd &bp)
|
|||
|
||||
void SetBlendMode(const BPCmd &bp)
|
||||
{
|
||||
if (bp.changes & 1)
|
||||
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, bpmem.blendmode.blendenable);
|
||||
|
||||
D3DBLEND src = d3dSrcFactors[bpmem.blendmode.srcfactor];
|
||||
D3DBLEND dst = d3dDestFactors[bpmem.blendmode.dstfactor];
|
||||
|
||||
if (bp.changes & 0x700)
|
||||
D3D::SetRenderState(D3DRS_SRCBLEND, src);
|
||||
|
||||
if (bp.changes & 0xE0)
|
||||
{
|
||||
if (!bpmem.blendmode.subtract)
|
||||
{
|
||||
D3D::SetRenderState(D3DRS_DESTBLEND, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
|
||||
}
|
||||
}
|
||||
if (bp.changes & 0x800)
|
||||
{
|
||||
if (bpmem.blendmode.subtract)
|
||||
{
|
||||
D3D::SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
|
||||
D3D::SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
|
||||
}
|
||||
else
|
||||
{
|
||||
D3D::SetRenderState(D3DRS_SRCBLEND, src);
|
||||
D3D::SetRenderState(D3DRS_DESTBLEND, dst);
|
||||
}
|
||||
|
||||
D3D::SetRenderState(D3DRS_BLENDOP,
|
||||
bpmem.blendmode.subtract ? D3DBLENDOP_SUBTRACT : D3DBLENDOP_ADD);
|
||||
}
|
||||
Renderer::SetBlendMode(false);
|
||||
}
|
||||
void SetDitherMode(const BPCmd &bp)
|
||||
{
|
||||
|
|
|
@ -24,20 +24,33 @@ namespace FBManager
|
|||
{
|
||||
|
||||
static LPDIRECT3DTEXTURE9 s_efb_color_texture;
|
||||
static LPDIRECT3DTEXTURE9 s_efb_colorBuffer_texture;
|
||||
static LPDIRECT3DTEXTURE9 s_efb_depth_texture;
|
||||
static LPDIRECT3DTEXTURE9 s_efb_depthBuffer_texture;
|
||||
static LPDIRECT3DSURFACE9 s_efb_color_surface;
|
||||
static LPDIRECT3DSURFACE9 s_efb_depth_surface;
|
||||
|
||||
static LPDIRECT3DSURFACE9 s_efb_color_OffScreensurface;
|
||||
static LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;
|
||||
static LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;
|
||||
|
||||
static LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer;
|
||||
static LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;
|
||||
|
||||
|
||||
static D3DFORMAT s_efb_color_surface_Format;
|
||||
static D3DFORMAT s_efb_depth_surface_Format;
|
||||
#undef CHECK
|
||||
#define CHECK(hr) if (FAILED(hr)) { PanicAlert("FAIL: " __FUNCTION__); }
|
||||
#define CHECK(hr,Message) if (FAILED(hr)) { PanicAlert(__FUNCTION__ " FAIL: %s" ,Message); }
|
||||
|
||||
|
||||
|
||||
LPDIRECT3DSURFACE9 GetEFBColorRTSurface() { return s_efb_color_surface; }
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthRTSurface() { return s_efb_depth_surface; }
|
||||
LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface() { return s_efb_color_OffScreensurface; }
|
||||
LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface() { return s_efb_color_OffScreenReadBuffer; }
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface() { return s_efb_depth_OffScreenReadBuffer; }
|
||||
|
||||
LPDIRECT3DSURFACE9 GetEFBColorReadSurface() { return s_efb_color_ReadBuffer; }
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface() { return s_efb_depth_ReadBuffer; }
|
||||
|
||||
D3DFORMAT GetEFBDepthRTSurfaceFormat(){return s_efb_depth_surface_Format;}
|
||||
D3DFORMAT GetEFBColorRTSurfaceFormat(){return s_efb_color_surface_Format;}
|
||||
|
@ -47,11 +60,12 @@ LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc)
|
|||
return s_efb_color_texture;
|
||||
}
|
||||
|
||||
|
||||
LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle &sourceRc)
|
||||
{
|
||||
// Depth textures not supported under DX9. We're gonna fake this
|
||||
// with a secondary render target later.
|
||||
return NULL;
|
||||
return s_efb_depth_texture;
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,56 +73,171 @@ LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle &sourceRc)
|
|||
|
||||
void Create()
|
||||
{
|
||||
|
||||
// Simplest possible setup to start with.
|
||||
int target_width = Renderer::GetTargetWidth();
|
||||
int target_height = Renderer::GetTargetHeight();
|
||||
s_efb_color_surface_Format = D3DFMT_A8R8G8B8;
|
||||
//get the framebuffer texture
|
||||
HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, &s_efb_color_texture, NULL);
|
||||
CHECK(hr);
|
||||
|
||||
CHECK(hr,"Create Color Texture");
|
||||
//get the Surface
|
||||
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);
|
||||
CHECK(hr,"Get Color Surface");
|
||||
//create a one pixel texture to work as a buffer for peeking
|
||||
hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,
|
||||
D3DPOOL_DEFAULT, &s_efb_colorBuffer_texture, NULL);
|
||||
if (!FAILED(hr))
|
||||
{
|
||||
//get the surface for the peeking texture
|
||||
hr = s_efb_colorBuffer_texture->GetSurfaceLevel(0, &s_efb_color_ReadBuffer);
|
||||
CHECK(hr,"Get Color Pixel Surface");
|
||||
//create an offscreen surface that we can lock to retrieve the data
|
||||
hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &s_efb_color_OffScreenReadBuffer, NULL );
|
||||
CHECK(hr,"Create Color offScreen Surface");
|
||||
}
|
||||
|
||||
//Select Zbuffer format supported by hadware.
|
||||
if (g_ActiveConfig.bEFBAccessEnable)
|
||||
{
|
||||
s_efb_depth_surface_Format = D3DFMT_D32F_LOCKABLE;
|
||||
//depth format in prefered order
|
||||
D3DFORMAT *DepthTexFormats = new D3DFORMAT[7];
|
||||
DepthTexFormats[0] = (D3DFORMAT)MAKEFOURCC('D','F','2','4');
|
||||
DepthTexFormats[1] = (D3DFORMAT)MAKEFOURCC('I','N','T','Z');
|
||||
DepthTexFormats[2] = (D3DFORMAT)MAKEFOURCC('R','A','W','Z');
|
||||
DepthTexFormats[3] = (D3DFORMAT)MAKEFOURCC('D','F','1','6');
|
||||
DepthTexFormats[4] = D3DFMT_D32F_LOCKABLE;
|
||||
DepthTexFormats[5] = D3DFMT_D16_LOCKABLE;
|
||||
DepthTexFormats[6] = D3DFMT_D24X8;
|
||||
|
||||
for(int i = 0;i<4;i++)
|
||||
{
|
||||
s_efb_depth_surface_Format = DepthTexFormats[i];
|
||||
hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_DEPTHSTENCIL, s_efb_depth_surface_Format,
|
||||
D3DPOOL_DEFAULT, &s_efb_depth_texture, NULL);
|
||||
if (!FAILED(hr))
|
||||
break;
|
||||
|
||||
}
|
||||
CHECK(hr,"Create Depth Texture");
|
||||
if (!FAILED(hr))
|
||||
{
|
||||
//we found a dept texture suported by hardware so get the surface to draw to
|
||||
hr = s_efb_depth_texture->GetSurfaceLevel(0, &s_efb_depth_surface);
|
||||
CHECK(hr,"Get Depth Surface");
|
||||
//create a buffer texture for peeking
|
||||
hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_DEPTHSTENCIL, s_efb_depth_surface_Format,
|
||||
D3DPOOL_DEFAULT, &s_efb_depthBuffer_texture, NULL);
|
||||
CHECK(hr,"Create Depth Pixel Texture");
|
||||
if (!FAILED(hr))
|
||||
{
|
||||
//texture create correctly so get the surface
|
||||
hr = s_efb_depthBuffer_texture->GetSurfaceLevel(0, &s_efb_depth_ReadBuffer);
|
||||
CHECK(hr,"Get Depth Pixel Surface");
|
||||
// create an ofscren surface to grab the data
|
||||
hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, s_efb_depth_surface_Format, D3DPOOL_SYSTEMMEM, &s_efb_depth_OffScreenReadBuffer, NULL );
|
||||
CHECK(hr,"Create Depth offscreen Surface");
|
||||
if (FAILED(hr))
|
||||
{
|
||||
//no depth in system mem so try vista path to grab depth data
|
||||
//create a offscreen lockeable surface
|
||||
hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, D3DFMT_D32F_LOCKABLE, D3DPOOL_DEFAULT, &s_efb_depth_OffScreenReadBuffer, NULL );
|
||||
CHECK(hr,"Create Depth D3DFMT_D32F_LOCKABLE offscreen Surface");
|
||||
if(s_efb_depth_ReadBuffer)
|
||||
s_efb_depth_ReadBuffer->Release();
|
||||
//this is ugly but is a fast way to test wich path to proceed for peeking
|
||||
s_efb_depth_ReadBuffer = s_efb_depth_OffScreenReadBuffer;
|
||||
s_efb_depth_surface_Format = D3DFMT_D32F_LOCKABLE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!FAILED(hr))
|
||||
{
|
||||
//so far so god, texture depth works so return
|
||||
delete [] DepthTexFormats;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//no depth texture... cleanup
|
||||
if(s_efb_depth_ReadBuffer)
|
||||
s_efb_depth_ReadBuffer->Release();
|
||||
s_efb_depth_ReadBuffer = NULL;
|
||||
|
||||
if(s_efb_depth_OffScreenReadBuffer)
|
||||
s_efb_depth_OffScreenReadBuffer->Release();
|
||||
|
||||
if(s_efb_depth_surface)
|
||||
s_efb_depth_surface->Release();
|
||||
s_efb_depth_surface = NULL;
|
||||
|
||||
if(s_efb_depthBuffer_texture)
|
||||
s_efb_depthBuffer_texture->Release();
|
||||
s_efb_depthBuffer_texture=NULL;
|
||||
|
||||
if(s_efb_depth_texture)
|
||||
s_efb_depth_texture->Release();
|
||||
s_efb_depth_texture = NULL;
|
||||
}
|
||||
// no depth textures... try to create an lockable depth surface
|
||||
for(int i = 4;i<7;i++)
|
||||
{
|
||||
s_efb_depth_surface_Format = DepthTexFormats[i];
|
||||
hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, s_efb_depth_surface_Format,
|
||||
D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL);
|
||||
if (!FAILED(hr)) break;
|
||||
}
|
||||
s_efb_depth_ReadBuffer = s_efb_depth_surface;
|
||||
CHECK(hr,"CreateDepthStencilSurface");
|
||||
delete [] DepthTexFormats;
|
||||
}
|
||||
else
|
||||
{
|
||||
s_efb_depth_surface_Format = D3DFMT_D24S8;
|
||||
}
|
||||
hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, D3DFMT_D32F_LOCKABLE,
|
||||
s_efb_depth_surface_Format = D3DFMT_D24X8;
|
||||
hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, s_efb_depth_surface_Format,
|
||||
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);
|
||||
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);
|
||||
}
|
||||
CHECK(hr,"CreateDepthStencilSurface");
|
||||
}
|
||||
CHECK(hr);
|
||||
}
|
||||
|
||||
void Destroy()
|
||||
{
|
||||
if(s_efb_color_OffScreensurface)
|
||||
s_efb_color_OffScreensurface->Release();
|
||||
if(s_efb_depth_ReadBuffer)
|
||||
s_efb_depth_ReadBuffer->Release();
|
||||
s_efb_depth_ReadBuffer = NULL;
|
||||
|
||||
if(s_efb_depth_OffScreenReadBuffer)
|
||||
s_efb_depth_OffScreenReadBuffer->Release();
|
||||
|
||||
if(s_efb_depth_surface)
|
||||
s_efb_depth_surface->Release();
|
||||
s_efb_depth_surface = NULL;
|
||||
|
||||
if(s_efb_depthBuffer_texture)
|
||||
s_efb_depthBuffer_texture->Release();
|
||||
s_efb_depthBuffer_texture=NULL;
|
||||
|
||||
if(s_efb_depth_texture)
|
||||
s_efb_depth_texture->Release();
|
||||
s_efb_depth_texture = NULL;
|
||||
|
||||
if(s_efb_color_OffScreenReadBuffer )
|
||||
s_efb_color_OffScreenReadBuffer->Release();
|
||||
s_efb_color_OffScreenReadBuffer = NULL;
|
||||
|
||||
if(s_efb_color_ReadBuffer )
|
||||
s_efb_color_ReadBuffer->Release();
|
||||
s_efb_color_ReadBuffer = NULL;
|
||||
|
||||
if(s_efb_color_surface)
|
||||
s_efb_color_surface->Release();
|
||||
s_efb_color_surface = NULL;
|
||||
s_efb_color_surface = NULL;
|
||||
|
||||
if(s_efb_colorBuffer_texture)
|
||||
s_efb_colorBuffer_texture->Release();
|
||||
s_efb_colorBuffer_texture = NULL;
|
||||
|
||||
if(s_efb_color_texture)
|
||||
s_efb_color_texture->Release();
|
||||
|
|
|
@ -38,6 +38,10 @@ LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface();
|
|||
LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface();
|
||||
D3DFORMAT GetEFBDepthRTSurfaceFormat();
|
||||
D3DFORMAT GetEFBColorRTSurfaceFormat();
|
||||
LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
@ -59,10 +59,37 @@ static int s_recordHeight;
|
|||
static bool s_LastFrameDumped;
|
||||
static bool s_AVIDumping;
|
||||
|
||||
static u32 s_blendMode;
|
||||
|
||||
#define NUMWNDRES 6
|
||||
extern int g_Res[NUMWNDRES][2];
|
||||
char st[32768];
|
||||
|
||||
// State translation lookup tables
|
||||
static const D3DBLEND d3dSrcFactors[8] =
|
||||
{
|
||||
D3DBLEND_ZERO,
|
||||
D3DBLEND_ONE,
|
||||
D3DBLEND_DESTCOLOR,
|
||||
D3DBLEND_INVDESTCOLOR,
|
||||
D3DBLEND_SRCALPHA,
|
||||
D3DBLEND_INVSRCALPHA,
|
||||
D3DBLEND_DESTALPHA,
|
||||
D3DBLEND_INVDESTALPHA
|
||||
};
|
||||
|
||||
static const D3DBLEND d3dDestFactors[8] =
|
||||
{
|
||||
D3DBLEND_ZERO,
|
||||
D3DBLEND_ONE,
|
||||
D3DBLEND_SRCCOLOR,
|
||||
D3DBLEND_INVSRCCOLOR,
|
||||
D3DBLEND_SRCALPHA,
|
||||
D3DBLEND_INVSRCALPHA,
|
||||
D3DBLEND_DESTALPHA,
|
||||
D3DBLEND_INVDESTALPHA
|
||||
};
|
||||
|
||||
void SetupDeviceObjects()
|
||||
{
|
||||
D3D::font.Init();
|
||||
|
@ -100,7 +127,7 @@ bool Renderer::Init()
|
|||
h_temp = 480;
|
||||
}
|
||||
EmuWindow::SetSize(w_temp, h_temp);
|
||||
|
||||
s_blendMode = 0;
|
||||
int backbuffer_ms_mode = 0; // g_ActiveConfig.iMultisampleMode;
|
||||
|
||||
sscanf(g_Config.cFSResolution, "%dx%d", &w_temp, &h_temp);
|
||||
|
@ -441,24 +468,29 @@ void Renderer::SetColorMask()
|
|||
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||
{
|
||||
|
||||
//Get the working buffer and it's format
|
||||
//Get the working buffer
|
||||
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
||||
FBManager::GetEFBDepthRTSurface() : FBManager::GetEFBColorRTSurface();
|
||||
|
||||
//get the temporal buffer to move 1pixel data
|
||||
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
||||
FBManager::GetEFBDepthReadSurface() : FBManager::GetEFBColorReadSurface();
|
||||
//get the memory buffer that can be locked
|
||||
LPDIRECT3DSURFACE9 pOffScreenBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
||||
FBManager::GetEFBDepthRTSurface() : FBManager::GetEFBColorOffScreenRTSurface();
|
||||
|
||||
D3DLOCKED_RECT drect;
|
||||
|
||||
FBManager::GetEFBDepthOffScreenRTSurface() : FBManager::GetEFBColorOffScreenRTSurface();
|
||||
//get the buffer format
|
||||
D3DFORMAT BufferFormat = (type == PEEK_Z || type == POKE_Z) ?
|
||||
FBManager::GetEFBDepthRTSurfaceFormat() : FBManager::GetEFBColorRTSurfaceFormat();
|
||||
|
||||
D3DLOCKED_RECT drect;
|
||||
|
||||
|
||||
//Buffer not found alert
|
||||
if(!pBuffer) {
|
||||
PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB");
|
||||
return 0;
|
||||
}
|
||||
// Z buffer lock not suported: returning
|
||||
if((type == PEEK_Z || type == POKE_Z) && BufferFormat == D3DFMT_D24S8)
|
||||
if((type == PEEK_Z || type == POKE_Z) && BufferFormat == D3DFMT_D24X8)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -472,7 +504,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
|||
|
||||
TargetRectangle targetPixelRc = Renderer::ConvertEFBRectangle(efbPixelRc);
|
||||
|
||||
|
||||
u32 z = 0;
|
||||
float val = 0.0f;
|
||||
HRESULT hr;
|
||||
|
@ -484,19 +515,54 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
|||
|
||||
//lock the buffer
|
||||
|
||||
if(!(type == PEEK_Z || type == POKE_Z))
|
||||
if(!(BufferFormat == D3DFMT_D32F_LOCKABLE || BufferFormat == D3DFMT_D16_LOCKABLE))
|
||||
{
|
||||
hr = D3D::dev->StretchRect(pBuffer,&RectToLock,pOffScreenBuffer,&RectToLock, D3DTEXF_NONE);
|
||||
//the hard support stretchrect in both color and z so use it
|
||||
hr = D3D::dev->StretchRect(pBuffer,&RectToLock,RBuffer,NULL, D3DTEXF_NONE);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
PanicAlert("Unable to stretch data to buffer");
|
||||
return 0;
|
||||
}
|
||||
//retriebe the pixel data to the local memory buffer
|
||||
D3D::dev->GetRenderTargetData(RBuffer,pOffScreenBuffer);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
PanicAlert("Unable to copy data to mem buffer");
|
||||
return 0;
|
||||
}
|
||||
//change the rect to lock the entire one pixel buffer
|
||||
RectToLock.bottom = 1;
|
||||
RectToLock.left = 0;
|
||||
RectToLock.right = 1;
|
||||
RectToLock.top = 0;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
//like i say in FramebufferManager this is ugly... using the pointers to decide the peek path.. but it works:)
|
||||
if(BufferFormat == D3DFMT_D32F_LOCKABLE && RBuffer == pOffScreenBuffer)
|
||||
{
|
||||
//we are using vista path so use updateSurface to copy depth data
|
||||
hr = D3D::dev->UpdateSurface(pBuffer,&RectToLock,pOffScreenBuffer,NULL);
|
||||
if(FAILED(hr))
|
||||
{
|
||||
PanicAlert("Unable to update data to mem buffer");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//we are using lockable depth buffer so change the pointer to lock it directly
|
||||
pOffScreenBuffer = pBuffer;
|
||||
}
|
||||
}
|
||||
//the surface is good.. lock it
|
||||
if((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
|
||||
{
|
||||
PanicAlert("ERROR: %s", hr == D3DERR_WASSTILLDRAWING ? "Still drawing" :
|
||||
hr == D3DERR_INVALIDCALL ? "Invalid call" : "w00t");
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case PEEK_Z:
|
||||
|
@ -505,16 +571,19 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
|||
{
|
||||
case D3DFMT_D32F_LOCKABLE:
|
||||
val = ((float *)drect.pBits)[0];
|
||||
z = ((u32)(val * 0xffffff));// 0xFFFFFFFF;
|
||||
break;
|
||||
case (D3DFORMAT)MAKEFOURCC('D','F','1','6'):
|
||||
case D3DFMT_D16_LOCKABLE:
|
||||
val = ((float)((u16 *)drect.pBits)[0])/((float)0xFFFF);
|
||||
z = ((u32)(val * 0xffffff));
|
||||
break;
|
||||
default:
|
||||
val = 0;
|
||||
z = ((u32 *)drect.pBits)[0] >> 8;
|
||||
break;
|
||||
};
|
||||
// [0.0, 1.0] ==> [0, 0xFFFFFFFF]
|
||||
z = ((u32)(val * 0xffffff));// 0xFFFFFFFF;
|
||||
|
||||
break;
|
||||
}
|
||||
case POKE_Z:
|
||||
|
@ -535,17 +604,12 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
|||
}
|
||||
|
||||
|
||||
pBuffer->UnlockRect();
|
||||
pOffScreenBuffer->UnlockRect();
|
||||
|
||||
|
||||
// Scale the 32-bit value returned to a 24-bit
|
||||
// value (GC uses a 24-bit Z-buffer).
|
||||
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
|
||||
return z;//z >> 8;
|
||||
return z;
|
||||
|
||||
DEBUGGER_PAUSE_LOG_AT(NEXT_EFB_CMD,true,{printf("AccessEFB, type = %d",type);});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// mtx.m[0][3] = pMatrix[1]; // -0.5f/s_target_width; <-- fix d3d pixel center?
|
||||
|
@ -616,6 +680,45 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
|
|||
D3D::dev->Clear(0, NULL, clearflags, color,(z & 0xFFFFFF) / float(0xFFFFFF), 0);
|
||||
}
|
||||
|
||||
void Renderer::SetBlendMode(bool forceUpdate)
|
||||
{
|
||||
// blend mode bit mask
|
||||
// 0 - blend enable
|
||||
// 2 - reverse subtract enable (else add)
|
||||
// 3-5 - srcRGB function
|
||||
// 6-8 - dstRGB function
|
||||
|
||||
u32 newval = bpmem.blendmode.subtract << 2;
|
||||
|
||||
if (bpmem.blendmode.subtract) {
|
||||
newval |= 0x0049; // enable blending src 1 dst 1
|
||||
} else if (bpmem.blendmode.blendenable) {
|
||||
newval |= 1; // enable blending
|
||||
newval |= bpmem.blendmode.srcfactor << 3;
|
||||
newval |= bpmem.blendmode.dstfactor << 6;
|
||||
}
|
||||
|
||||
u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode;
|
||||
|
||||
if (changes & 1) {
|
||||
// blend enable change
|
||||
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, (newval & 1));
|
||||
|
||||
}
|
||||
|
||||
if (changes & 4) {
|
||||
// subtract enable change
|
||||
D3D::SetRenderState(D3DRS_BLENDOP, newval & 4 ? D3DBLENDOP_REVSUBTRACT : D3DBLENDOP_ADD);
|
||||
}
|
||||
|
||||
if (changes & 0x1F8) {
|
||||
// blend RGB change
|
||||
D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[(newval >> 3) & 7]);
|
||||
D3D::SetRenderState(D3DRS_DESTBLEND, d3dDestFactors[(newval >> 6) & 7]);
|
||||
}
|
||||
|
||||
s_blendMode = newval;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue