big commit, implemented depth textures with hardware support in D3D, so now they will be correct as in opengl. please test a lot because i only tested the ati path, nvidia path is "Theoretical" :).

Also reimplemented screen clearing as a color quad to support alpha blending when clearing as in the original hardware.
the funny thing is how is implemented peeking, as locking depth textures is not supported, implemented peeking copying the values form the depth texture to a r32f render target and then reading back the data.
please a lot of testing to this commit.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4599 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado 2009-11-22 02:37:00 +00:00
parent 7fa29f0b66
commit 19d7bb2c84
16 changed files with 288 additions and 223 deletions

View File

@ -453,10 +453,7 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, u32 HLSL)
WRITE(p, "uniform float4 "I_FOG"[2] : register(c%d);\n", C_FOG);
WRITE(p, "void main(\n");
WRITE(p, " out float4 ocol0 : COLOR0,\n");
if (HLSL == 1)
WRITE(p, " out float4 ocol1 : COLOR1,\n");
WRITE(p, " out float4 ocol0 : COLOR0,\n");
WRITE(p, " out float depth : DEPTH,\n");
// compute window position if needed because binding semantic WPOS is not widely supported
@ -541,13 +538,6 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, u32 HLSL)
WRITE(p, "depth = zCoord;\n");
if(HLSL == 1)
{
WRITE(p, "float4 EncodedDepth = frac(zCoord * float4(254.0f/255.0,254.0f,254.0f*255.0f,0.0f));\n");
WRITE(p, "EncodedDepth -= EncodedDepth.raag * float4(0.0f,1.0f/255.0f,1.0f/255.0f,0.0f);\n");
WRITE(p, "ocol1 = float4(EncodedDepth.rgb,1.0f);\n");
}
//if (bpmem.genMode.numindstages ) WRITE(p, "prev.rg = indtex0.xy;\nprev.b = 0;\n");
if (!WriteAlphaTest(p, HLSL))

View File

@ -115,12 +115,12 @@ void SetDepthMode(const BPCmd &bp)
{
D3D::SetRenderState(D3DRS_ZENABLE, TRUE);
D3D::SetRenderState(D3DRS_ZWRITEENABLE, bpmem.zmode.updateenable);
D3D::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]);
D3D::SetRenderState(D3DRS_ZFUNC, d3dCmpFuncs[bpmem.zmode.func]);
}
else
{
D3D::SetRenderState(D3DRS_ZENABLE, FALSE);
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // ??
D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE); // ??
}
}

View File

@ -476,6 +476,11 @@ void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Valu
}
}
void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type)
{
D3D::dev->SetSamplerState(Sampler, Type, m_SamplerStates[Sampler][Type]);
}
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
{
if (m_SamplerStates[Sampler][Type] != Value)

View File

@ -34,6 +34,8 @@ namespace D3D
// Z texture formats
#define FOURCC_INTZ ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z')))
#define FOURCC_RAWZ ((D3DFORMAT)(MAKEFOURCC('R','A','W','Z')))
#define FOURCC_DF24 ((D3DFORMAT)(MAKEFOURCC('D','F','2','4')))
#define FOURCC_DF16 ((D3DFORMAT)(MAKEFOURCC('D','F','1','6')))
// Depth buffer resolve:
#define FOURCC_RESZ ((D3DFORMAT)(MAKEFOURCC('R','E','S','Z')))
@ -74,6 +76,7 @@ void ShowD3DError(HRESULT err);
void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
void RefreshSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type);
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
void RefreshVertexDeclaration();
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);

View File

@ -398,12 +398,10 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
{
SaveRenderStates();
D3D::SetTexture(0, 0);
//float span = ((rSource->right-rSource->left - 1.0f) * (rDest->right - rDest->left))/(SourceWidth*((rDest->right - rDest->left)-1.0f));
float u1=((float)rSource->left+1.0f)/(float) SourceWidth;//*/((0.5f+rSource->left)/(float) SourceWidth)-(span*0.5f/(float)(rDest->right - rDest->left));
float u2=((float)rSource->right-1.0f)/(float) SourceWidth;;//*/u1+span;
//span = ((rSource->bottom-rSource->top - 1.0f) * (rDest->bottom - rDest->top))/(SourceHeight*((rDest->bottom - rDest->top)-1.0f));
float v1=((float)rSource->top+1.0f)/(float) SourceHeight;//*/((0.5f+rSource->top)/(float) SourceHeight)-(span*0.5f/(float)(rDest->bottom - rDest->top));
float v2=((float)rSource->bottom-1.0f)/(float) SourceHeight;//*/v1+span;
float u1=((float)rSource->left+1.0f)/(float) SourceWidth;
float u2=((float)rSource->right-1.0f)/(float) SourceWidth;
float v1=((float)rSource->top+1.0f)/(float) SourceHeight;
float v2=((float)rSource->bottom-1.0f)/(float) SourceHeight;
struct Q2DVertex { float x,y,z,rhw,u,v; } coords[4] = {
{(float)rDest->left-0.5f, (float)rDest->top-0.5f, 0.0f, 1.0f, u1, v1},
@ -411,28 +409,39 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
{(float)rDest->right-0.5f, (float)rDest->bottom-0.5f, 0.0f,1.0f, u2, v2},
{(float)rDest->left-0.5f, (float)rDest->bottom-0.5f, 0.0f,1.0f, u1, v2}
};
dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader);
dev->SetTexture(0, texture);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
HRESULT hr = 0;
hr = dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1);
hr = dev->SetVertexShader(Vshader);
hr = dev->SetPixelShader(PShader);
hr = dev->SetTexture(0, texture);
if(FAILED(hr))
{
PanicAlert("unable to set pixel shader");
}
hr = dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
if(FAILED(hr))
{
PanicAlert("unable to draw");
}
D3D::RefreshVertexDeclaration();
RestoreRenderStates();
}
void drawColoredQuad(const RECT *rDest, u32 Color)
void drawClearQuad(const RECT *rDest, u32 Color,float z,
IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader)
{
SaveRenderStates();
SaveRenderStates();
struct Q2DVertex { float x,y,z,rhw;u32 Color; } coords[4] = {
{(float)rDest->left-0.5f, (float)rDest->top-0.5f, 0.0f, 1.0f, Color},
{(float)rDest->right-0.5f, (float)rDest->top-0.5f, 0.0f,1.0f, Color},
{(float)rDest->right-0.5f, (float)rDest->bottom-0.5f, 0.0f,1.0f, Color},
{(float)rDest->left-0.5f, (float)rDest->bottom-0.5f, 0.0f,1.0f, Color}
{(float)rDest->left-0.5f, (float)rDest->top-0.5f, z, 1.0f, Color},
{(float)rDest->right-0.5f, (float)rDest->top-0.5f, z,1.0f, Color},
{(float)rDest->right-0.5f, (float)rDest->bottom-0.5f, z,1.0f, Color},
{(float)rDest->left-0.5f, (float)rDest->bottom-0.5f, z,1.0f, Color}
};
dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
dev->SetVertexShader(0);
dev->SetPixelShader(0);
dev->SetVertexShader(Vshader);
dev->SetPixelShader(PShader);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
D3D::RefreshVertexDeclaration();
RestoreRenderStates();

View File

@ -65,7 +65,9 @@ namespace D3D
const RECT *rDest,
IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader);
void drawColoredQuad(const RECT *rDest, u32 Color);
void drawClearQuad(const RECT *rDest, u32 Color,float z,
IDirect3DPixelShader9 *PShader,
IDirect3DVertexShader9 *Vshader);
void SaveRenderStates();
void RestoreRenderStates();
}

View File

@ -359,9 +359,6 @@ static void DX9DebuggerUpdateScreen()
D3D::dev->Present(NULL, NULL, NULL, NULL);
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1,FBManager::GetEFBDepthEncodedSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
D3D::dev->BeginScene();
}

View File

@ -26,10 +26,9 @@ namespace FBManager
static LPDIRECT3DTEXTURE9 s_efb_color_texture;//Texture thats contains the color data of the render target
static LPDIRECT3DTEXTURE9 s_efb_colorRead_texture;//1 pixel texture for temporal data store
static LPDIRECT3DTEXTURE9 s_efb_depth_texture;//Texture thats contains the depth data of the render target
static LPDIRECT3DTEXTURE9 s_efb_depthRead_texture;//1 pixel texture for temporal data store
static LPDIRECT3DTEXTURE9 s_efb_depthRead_texture;//4 pixel texture for temporal data store
static LPDIRECT3DSURFACE9 s_efb_depth_surface;//Depth Surface
static LPDIRECT3DSURFACE9 s_efb_depthColor_surface;//Depth, color encoded Surface
static LPDIRECT3DSURFACE9 s_efb_color_surface;//Color Surface
static LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;//Surface 0 of s_efb_colorRead_texture
static LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;//Surface 0 of s_efb_depthRead_texture
@ -39,7 +38,8 @@ static LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;//System memory Surfac
static D3DFORMAT s_efb_color_surface_Format;//Format of the color Surface
static D3DFORMAT s_efb_depth_surface_Format;//Format of the Depth color encoded Surface
static D3DFORMAT s_efb_depth_surface_Format;//Format of the Depth Surface
static D3DFORMAT s_efb_depth_ReadBuffer_Format;//Format of the Depth color Read Surface
#undef CHECK
#define CHECK(hr,Message) if (FAILED(hr)) { PanicAlert(__FUNCTION__ " FAIL: %s" ,Message); }
@ -54,11 +54,6 @@ LPDIRECT3DSURFACE9 GetEFBDepthRTSurface()
return s_efb_depth_surface;
}
LPDIRECT3DSURFACE9 GetEFBDepthEncodedSurface()
{
return s_efb_depthColor_surface;
}
LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface()
{
return s_efb_color_OffScreenReadBuffer;
@ -69,20 +64,20 @@ LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface()
}
LPDIRECT3DSURFACE9 GetEFBColorReadSurface()
{
{
return s_efb_color_ReadBuffer;
}
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface()
{
{
return s_efb_depth_ReadBuffer;
}
D3DFORMAT GetEFBDepthRTSurfaceFormat(){return s_efb_depth_surface_Format;}
D3DFORMAT GetEFBDepthReadSurfaceFormat(){return s_efb_depth_ReadBuffer_Format;}
D3DFORMAT GetEFBColorRTSurfaceFormat(){return s_efb_color_surface_Format;}
LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc)
{
return s_efb_color_texture;
@ -94,9 +89,10 @@ LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle &sourceRc)
return s_efb_depth_texture;
}
void Create()
{
{
// Simplest possible setup to start with.
int target_width = Renderer::GetTargetWidth();
int target_height = Renderer::GetTargetHeight();
@ -106,7 +102,7 @@ void Create()
D3DPOOL_DEFAULT, &s_efb_color_texture, NULL);
if(s_efb_color_texture)
{
s_efb_color_texture->GetSurfaceLevel(0,&s_efb_color_surface);
hr = s_efb_color_texture->GetSurfaceLevel(0,&s_efb_color_surface);
}
CHECK(hr,"Create Color Texture");
hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
@ -122,73 +118,64 @@ void Create()
//Select Zbuffer format supported by hadware.
if (g_ActiveConfig.bEFBAccessEnable)
{
if(D3D::GetCaps().NumSimultaneousRTs > 1)
{
hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, D3DFMT_D24X8,
D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL);
CHECK(hr,"CreateDepthStencilSurface");
D3DFORMAT *DepthTexFormats = new D3DFORMAT[3];
DepthTexFormats[0] = D3DFMT_R32F;
DepthTexFormats[1] = D3DFMT_A8R8G8B8;
{
D3DFORMAT *DepthTexFormats = new D3DFORMAT[5];
DepthTexFormats[0] = FOURCC_INTZ;
DepthTexFormats[1] = FOURCC_DF24;
DepthTexFormats[2] = FOURCC_RAWZ;
DepthTexFormats[3] = FOURCC_DF16;
DepthTexFormats[4] = D3DFMT_D24X8;
for(int i = 0;i<2;i++)
{
s_efb_depth_surface_Format = DepthTexFormats[i];
//get the framebuffer Depth texture
hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_depth_surface_Format,
D3DPOOL_DEFAULT, &s_efb_depth_texture, NULL);
if (!FAILED(hr)) break;
}
CHECK(hr,"Depth Color Texture");
//get the Surface
if(s_efb_depth_texture)
{
s_efb_depth_texture->GetSurfaceLevel(0,&s_efb_depthColor_surface);
}
//create a one pixel texture to work as a buffer for peeking
hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb_depth_surface_Format,
D3DPOOL_DEFAULT, &s_efb_depthRead_texture, NULL);
CHECK(hr,"Create Depth Read texture");
if(s_efb_depthRead_texture)
{
s_efb_depthRead_texture->GetSurfaceLevel(0,&s_efb_depth_ReadBuffer);
}
//create an offscreen surface that we can lock to retrieve 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");
delete [] DepthTexFormats;
for(int i = 0;i<5;i++)
{
s_efb_depth_surface_Format = DepthTexFormats[i];
//get the framebuffer Depth texture
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,"Depth Color Texture");
//get the Surface
if(s_efb_depth_texture)
{
s_efb_depth_texture->GetSurfaceLevel(0,&s_efb_depth_surface);
}
//create a 4x4 pixel texture to work as a buffer for peeking
if(s_efb_depth_surface_Format == FOURCC_RAWZ || s_efb_depth_surface_Format == D3DFMT_D24X8)
{
DepthTexFormats[0] = D3DFMT_A8R8G8B8;
}
else
{
//depth format in prefered order
D3DFORMAT *DepthTexFormats = new D3DFORMAT[3];
DepthTexFormats[0] = D3DFMT_D32F_LOCKABLE;
DepthTexFormats[1] = D3DFMT_D16_LOCKABLE;
DepthTexFormats[2] = D3DFMT_D24X8;
for(int i = 0;i<3;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;
s_efb_depth_OffScreenReadBuffer = s_efb_depth_surface;
//ULTRAAAAAAAAAAA ugly hack when no depth textures are supported
s_efb_depthColor_surface = s_efb_color_surface;
CHECK(hr,"CreateDepthStencilSurface");
delete [] DepthTexFormats;
DepthTexFormats[0] = D3DFMT_R32F;
}
DepthTexFormats[1] = D3DFMT_A8R8G8B8;
for(int i = 0;i<2;i++)
{
s_efb_depth_ReadBuffer_Format = DepthTexFormats[i];
//get the framebuffer Depth texture
hr = D3D::dev->CreateTexture(4, 4, 1, D3DUSAGE_RENDERTARGET, s_efb_depth_ReadBuffer_Format,
D3DPOOL_DEFAULT, &s_efb_depthRead_texture, NULL);
if (!FAILED(hr)) break;
}
CHECK(hr,"Create Depth Read texture");
if(s_efb_depthRead_texture)
{
s_efb_depthRead_texture->GetSurfaceLevel(0,&s_efb_depth_ReadBuffer);
}
//create an offscreen surface that we can lock to retrieve the data
hr = D3D::dev->CreateOffscreenPlainSurface(4, 4, s_efb_depth_ReadBuffer_Format, D3DPOOL_SYSTEMMEM, &s_efb_depth_OffScreenReadBuffer, NULL );
CHECK(hr,"Create Depth offScreen Surface");
delete [] DepthTexFormats;
}
else
{
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);
CHECK(hr,"CreateDepthStencilSurface");
//ULTRAAAAAAAAAAA ugly hack when no depth textures are supported
//s_efb_depthColor_surface = s_efb_color_surface;
CHECK(hr,"CreateDepthStencilSurface");
}
}
@ -199,10 +186,6 @@ if(s_efb_depth_surface)
s_efb_depth_surface->Release();
s_efb_depth_surface=NULL;
if(s_efb_depthColor_surface)
s_efb_depthColor_surface->Release();
s_efb_depthColor_surface=NULL;
if(s_efb_color_surface)
s_efb_color_surface->Release();
s_efb_color_surface=NULL;

View File

@ -38,9 +38,10 @@ LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface();
LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface();
D3DFORMAT GetEFBDepthRTSurfaceFormat();
D3DFORMAT GetEFBColorRTSurfaceFormat();
D3DFORMAT GetEFBDepthReadSurfaceFormat();
LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
LPDIRECT3DSURFACE9 GetEFBDepthEncodedSurface();

View File

@ -36,6 +36,8 @@ static float lastPSconstants[C_COLORMATRIX+16][4];
static LPDIRECT3DPIXELSHADER9 s_ColorMatrixProgram = 0;
static LPDIRECT3DPIXELSHADER9 s_ColorCopyProgram = 0;
static LPDIRECT3DPIXELSHADER9 s_ClearProgram = 0;
static LPDIRECT3DPIXELSHADER9 s_ClearZProgram = 0;
static LPDIRECT3DPIXELSHADER9 s_DepthMatrixProgram = 0;
@ -54,6 +56,11 @@ LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram()
return s_ColorCopyProgram;
}
LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetClearProgram()
{
return s_ClearProgram;
}
void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{
if( lastPSconstants[const_number][0] != f1 || lastPSconstants[const_number][1] != f2 ||
@ -99,6 +106,14 @@ void PixelShaderCache::Init()
" in float3 uv0 : TEXCOORD0){\n"
"ocol0 = tex2D(samp0,uv0.xy);\n"
"}\n");
char pclearprog[1024];
sprintf(pclearprog,"void main(\n"
"out float4 ocol0 : COLOR0,\n"
" in float4 incol0 : COLOR0){\n"
"ocol0 = incol0;\n"
"}\n");
char pdmatrixprog[1024];
sprintf(pdmatrixprog,"uniform sampler samp0 : register(s0);\n"
"uniform float4 cColMatrix[5] : register(c%d);\n"
@ -106,15 +121,15 @@ void PixelShaderCache::Init()
"out float4 ocol0 : COLOR0,\n"
" in float3 uv0 : TEXCOORD0){\n"
"float4 texcol = tex2D(samp0,uv0.xy);\n"
"float4 EncodedDepth = frac(texcol.r * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
"EncodedDepth -= EncodedDepth.raag * float4(0.0f,1.0f/255.0f,1.0f/255.0f,0.0f);\n"
"texcol = float4(EncodedDepth.rgb,1.0f);\n"
"float4 EncodedDepth = frac((texcol.r * (16777215.0f/16777216.0f)) * float4(1.0f,255.0f,255.0f*255.0f,255.0f*255.0f*255.0f));\n"
"texcol = float4((EncodedDepth.rgb * (16777216.0f/16777215.0f)),1.0f);\n"
"ocol0 = float4(dot(texcol,cColMatrix[0]),dot(texcol,cColMatrix[1]),dot(texcol,cColMatrix[2]),dot(texcol,cColMatrix[3])) + cColMatrix[4];\n"
"}\n",C_COLORMATRIX);
s_ColorMatrixProgram = D3D::CompilePixelShader(pmatrixprog, (int)strlen(pmatrixprog));
s_ColorCopyProgram = D3D::CompilePixelShader(pcopyprog, (int)strlen(pcopyprog));
s_DepthMatrixProgram = D3D::CompilePixelShader(pdmatrixprog, (int)strlen(pdmatrixprog));
s_ClearProgram = D3D::CompilePixelShader(pclearprog, (int)strlen(pclearprog));
Clear();
}
@ -141,6 +156,10 @@ void PixelShaderCache::Shutdown()
if(s_DepthMatrixProgram)
s_DepthMatrixProgram->Release();
s_DepthMatrixProgram = NULL;
if(s_ClearProgram)
s_ClearProgram->Release();
s_ClearProgram=NULL;
Clear();
}
@ -181,7 +200,7 @@ bool PixelShaderCache::SetShader(bool dstAlpha)
return false;
}
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), dstAlpha, (D3D::GetCaps().NumSimultaneousRTs > 1)? 1 : 2);
const char *code = GeneratePixelShader(PixelShaderManager::GetTextureMask(), dstAlpha, /*(D3D::GetCaps().NumSimultaneousRTs > 1)? 1 :*/ 2);
LPDIRECT3DPIXELSHADER9 shader = D3D::CompilePixelShader(code, (int)strlen(code));
// Make an entry in the table

View File

@ -62,6 +62,8 @@ public:
static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram();
static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram();
static LPDIRECT3DPIXELSHADER9 GetDepthMatrixProgram();
static LPDIRECT3DPIXELSHADER9 GetClearProgram();
#if defined(_DEBUG) || defined(DEBUGFAST)
static std::string GetCurrentShaderCode();
#endif

View File

@ -174,8 +174,6 @@ bool Renderer::Init()
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
vp.Width = s_target_width;
vp.Height = s_target_height;
@ -322,7 +320,7 @@ static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
sourcerect.right = src_rect.right;
sourcerect.top = src_rect.top;
D3D::drawShadedTexQuad(read_texture,&sourcerect,Renderer::GetTargetWidth(),Renderer::GetTargetHeight(),&destinationrect,PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexSahder());
D3D::drawShadedTexQuad(read_texture,&sourcerect,Renderer::GetTargetWidth(),Renderer::GetTargetHeight(),&destinationrect,PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexShader());
// Finish up the current frame, print some stats
if (g_ActiveConfig.bOverlayStats)
@ -416,8 +414,6 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
Renderer::ResetAPIState();
// Set the backbuffer as the rendering target
D3D::dev->SetDepthStencilSurface(NULL);
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, NULL);
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3DDumpFrame();
@ -438,8 +434,6 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
D3D::BeginFrame();
Renderer::RestoreAPIState();
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
UpdateViewport();
VertexShaderManager::SetViewportChanged();
@ -478,11 +472,11 @@ bool Renderer::SetScissorRect()
else
{
WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
/*rc.left = 0;
rc.left = 0;
rc.top = 0;
rc.right = GetTargetWidth();
rc.bottom = GetTargetHeight();
D3D::dev->SetScissorRect(&rc);*/
D3D::dev->SetScissorRect(&rc);
return false;
}
return false;
@ -502,7 +496,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
{
//Get the working buffer
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
FBManager::GetEFBDepthEncodedSurface() : FBManager::GetEFBColorRTSurface();
FBManager::GetEFBDepthRTSurface() : FBManager::GetEFBColorRTSurface();
//get the temporal buffer to move 1pixel data
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
FBManager::GetEFBDepthReadSurface() : FBManager::GetEFBColorReadSurface();
@ -512,6 +506,8 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
//get the buffer format
D3DFORMAT BufferFormat = (type == PEEK_Z || type == POKE_Z) ?
FBManager::GetEFBDepthRTSurfaceFormat() : FBManager::GetEFBColorRTSurfaceFormat();
D3DFORMAT ReadBufferFormat = (type == PEEK_Z || type == POKE_Z) ?
FBManager::GetEFBDepthReadSurfaceFormat() : BufferFormat;
D3DLOCKED_RECT drect;
if(!g_ActiveConfig.bEFBAccessEnable || BufferFormat == D3DFMT_D24X8)
@ -539,28 +535,95 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
RectToLock.bottom = targetPixelRc.bottom;
RectToLock.left = targetPixelRc.left;
RectToLock.right = targetPixelRc.right;
RectToLock.top = targetPixelRc.top;
if(BufferFormat != D3DFMT_D32F_LOCKABLE && BufferFormat != D3DFMT_D16_LOCKABLE)
RectToLock.top = targetPixelRc.top;
if(type == PEEK_Z)
{
RECT PixelRect;
PixelRect.bottom = 4;
PixelRect.left = 0;
PixelRect.right = 4;
PixelRect.top = 0;
RectToLock.bottom+=2;
RectToLock.right+=1;
RectToLock.top-=1;
RectToLock.left-=2;
if((RectToLock.bottom - RectToLock.top) > 4)
RectToLock.bottom--;
if((RectToLock.right - RectToLock.left) > 4)
RectToLock.left++;
ResetAPIState(); // reset any game specific settings
hr =D3D::dev->SetDepthStencilSurface(NULL);
hr = D3D::dev->SetRenderTarget(0, RBuffer);
if(FAILED(hr))
{
PanicAlert("unable to set pixel render buffer");
return 0;
}
D3DVIEWPORT9 vp;
// Stretch picture with increased internal resolution
vp.X = 0;
vp.Y = 0;
vp.Width = 4;
vp.Height = 4;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
hr = D3D::dev->SetViewport(&vp);
if(FAILED(hr))
{
PanicAlert("unable to set pixel viewport");
return 0;
}
float colmat[16]= {0.0f};
float fConstAdd[4] = {0.0f};
colmat[0] = colmat[5] = colmat[10] = 1.0f;
PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
EFBRectangle source_rect;
LPDIRECT3DTEXTURE9 read_texture = FBManager::GetEFBDepthTexture(source_rect);
D3D::dev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
D3D::dev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
D3D::dev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
D3D::drawShadedTexQuad(read_texture,&RectToLock, Renderer::GetTargetWidth() , Renderer::GetTargetHeight(),&PixelRect,(BufferFormat == FOURCC_RAWZ)?PixelShaderCache::GetColorMatrixProgram():PixelShaderCache::GetDepthMatrixProgram(),VertexShaderCache::GetSimpleVertexShader());
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MIPFILTER);
hr = D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
hr = D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
UpdateViewport();
RestoreAPIState();
RectToLock.bottom = 4;
RectToLock.left = 0;
RectToLock.right = 4;
RectToLock.top = 0;
}
else
{
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;
}
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;
}
//the surface is good.. lock it
if((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
@ -573,31 +636,21 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
switch(type) {
case PEEK_Z:
{
switch (BufferFormat)
switch (ReadBufferFormat)
{
case D3DFMT_D32F_LOCKABLE:
val = ((float *)drect.pBits)[0];
break;
case D3DFMT_D16_LOCKABLE:
val = ((float)((u16 *)drect.pBits)[0])/((float)0xFFFF);
break;
case D3DFMT_R32F:
val = ((float *)drect.pBits)[0] * (255.0f/254.0f);
val = ((float *)drect.pBits)[6];
break;
default:
float ffrac = 1.0f/254.0f;
z = ((u32 *)drect.pBits)[0];
float ffrac = 1.0f/255.0f;
z = ((u32 *)drect.pBits)[6];
val = ((float)((z>>16) & 0xFF)) * ffrac;
ffrac*= 1 / 255.0f;
val += ((float)((z>>8) & 0xFF)) * ffrac;
ffrac*= 1 / 255.0f;
val += ((float)(z & 0xFF)) * ffrac;
//ffrac*= 1 / 255.0f;
//val += ((float)((z>>24) & 0xFF)) * ffrac;
val += ((float)(z & 0xFF)) * ffrac;
break;
};
if(val>1.0f)val=1.0f;
if(val<0.0f)val=0.0f;
z = ((u32)(val * 0xffffff));
}
break;
@ -664,41 +717,30 @@ void UpdateViewport()
}
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
{
DWORD clearflags = 0;
if(colorEnable)
{
clearflags |= D3DCLEAR_TARGET;
}
if (zEnable)
{
clearflags |= D3DCLEAR_ZBUFFER;
}
if(clearflags)
{
// Update the view port for clearing the picture
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = Renderer::GetTargetWidth();
vp.Height = Renderer::GetTargetHeight();
vp.MinZ = 0.0;
vp.MaxZ = 1.0;
D3D::dev->SetViewport(&vp);
{
// Update the view port for clearing the picture
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = Renderer::GetTargetWidth();
vp.Height = Renderer::GetTargetHeight();
vp.MinZ = 0.0;
vp.MaxZ = 1.0;
D3D::dev->SetViewport(&vp);
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
// Always set the scissor in case it was set by the game and has not been reset
RECT sirc;
sirc.left = targetRc.left;
sirc.top = targetRc.top;
sirc.right = targetRc.right;
sirc.bottom = targetRc.bottom;
D3D::dev->SetScissorRect(&sirc);
D3D::dev->Clear(0, NULL, clearflags, color,(z & 0xFFFFFF) / float(0xFFFFFF), 0);
SetScissorRect();
VertexShaderManager::SetViewportChanged();
}
// Always set the scissor in case it was set by the game and has not been reset
RECT sirc;
sirc.left = targetRc.left;
sirc.top = targetRc.top;
sirc.right = targetRc.right;
sirc.bottom = targetRc.bottom;
D3D::dev->SetScissorRect(&sirc);
D3D::drawClearQuad(&sirc,color,(z & 0xFFFFFF) / float(0xFFFFFF),PixelShaderCache::GetClearProgram(),VertexShaderCache::GetSimpleVertexShader());
//D3D::dev->Clear(0, NULL, clearflags, color,(z & 0xFFFFFF) / float(0xFFFFFF), 0);
SetScissorRect();
VertexShaderManager::SetViewportChanged();
}
void Renderer::SetBlendMode(bool forceUpdate)

View File

@ -341,29 +341,29 @@ have_texture:
{
case 0: // Z4
case 1: // Z8
colmat[0] = colmat[4] = colmat[8] = colmat[12] = 255.0f/254.0f;
colmat[0] = colmat[4] = colmat[8] = colmat[12] =1.0f;
break;
case 3: // Z16 //?
colmat[1] = colmat[5] = colmat[9] = colmat[12] = 255.0f/254.0f;
colmat[1] = colmat[5] = colmat[9] = colmat[12] = 1.0f;
case 11: // Z16 (reverse order)
colmat[0] = colmat[4] = colmat[8] = colmat[13] = 255.0f/254.0f;
colmat[0] = colmat[4] = colmat[8] = colmat[13] = 1.0f;
break;
case 6: // Z24X8
colmat[0] = colmat[5] = colmat[10] = 255.0f/254.0f;
colmat[0] = colmat[5] = colmat[10] = 1.0f;
break;
case 9: // Z8M
colmat[1] = colmat[5] = colmat[9] = colmat[13] = 255.0f/254.0f;
colmat[1] = colmat[5] = colmat[9] = colmat[13] = 1.0f;
break;
case 10: // Z8L
colmat[2] = colmat[6] = colmat[10] = colmat[14] = 255.0f/254.0f;
colmat[2] = colmat[6] = colmat[10] = colmat[14] = 1.0f;
break;
case 12: // Z16L
colmat[2] = colmat[6] = colmat[10] = colmat[13] = 255.0f/254.0f;
colmat[2] = colmat[6] = colmat[10] = colmat[13] = 1.0f;
break;
default:
ERROR_LOG(VIDEO, "Unknown copy zbuf format: 0x%x", copyfmt);
colmat[2] = colmat[5] = colmat[8] = 255.0f/254.0f;
colmat[2] = colmat[5] = colmat[8] = 1.0f;
break;
}
}
@ -448,8 +448,6 @@ have_texture:
LPDIRECT3DSURFACE9 Rendersurf = NULL;
tex->GetSurfaceLevel(0,&Rendersurf);
D3D::dev->SetDepthStencilSurface(NULL);
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, NULL);
D3D::dev->SetRenderTarget(0, Rendersurf);
D3DVIEWPORT9 vp;
@ -476,12 +474,22 @@ have_texture:
sourcerect.left = targetSource.left;
sourcerect.right = targetSource.right;
sourcerect.top = targetSource.top;
D3D::drawShadedTexQuad(read_texture,&sourcerect, Renderer::GetTargetWidth() , Renderer::GetTargetHeight(),&destrect,(FBManager::GetEFBDepthRTSurfaceFormat() == D3DFMT_R32F && bFromZBuffer)? PixelShaderCache::GetDepthMatrixProgram(): PixelShaderCache::GetColorMatrixProgram(),VertexShaderCache::GetSimpleVertexSahder());
if(bFromZBuffer)
{
D3D::dev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
D3D::dev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
D3D::dev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
}
D3DFORMAT bformat = FBManager::GetEFBDepthRTSurfaceFormat();
D3D::drawShadedTexQuad(read_texture,&sourcerect, Renderer::GetTargetWidth() , Renderer::GetTargetHeight(),&destrect,((bformat != FOURCC_RAWZ && bformat != D3DFMT_D24X8) && bFromZBuffer)? PixelShaderCache::GetDepthMatrixProgram(): PixelShaderCache::GetColorMatrixProgram(),VertexShaderCache::GetSimpleVertexShader());
if(bFromZBuffer)
{
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MIPFILTER);
}
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
VertexShaderManager::SetViewportChanged();
Renderer::RestoreAPIState();

View File

@ -189,21 +189,21 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
tempTexture->GetSurfaceLevel(0,&Rendersurf);
hr = D3D::dev->SetDepthStencilSurface(NULL);
if(D3D::GetCaps().NumSimultaneousRTs > 1)
hr = D3D::dev->SetRenderTarget(1, NULL);
hr = D3D::dev->SetRenderTarget(0, Rendersurf);
/*if (linearFilter)
if (linearFilter)
{
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
D3D::dev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
D3D::dev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
D3D::dev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
}
else
{
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}*/
D3D::dev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
D3D::dev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
D3D::dev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);
}
D3DVIEWPORT9 vp;
@ -227,14 +227,14 @@ void EncodeToRamUsingShader(LPDIRECT3DPIXELSHADER9 shader, LPDIRECT3DTEXTURE9 sr
// Draw...
D3D::drawShadedTexQuad(srcTexture,&SrcRect,srcTextureWidth,srcTextureHeight,&DstRect,shader,VertexShaderCache::GetSimpleVertexSahder());
D3D::drawShadedTexQuad(srcTexture,&SrcRect,srcTextureWidth,srcTextureHeight,&DstRect,shader,VertexShaderCache::GetSimpleVertexShader());
hr = D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
if(D3D::GetCaps().NumSimultaneousRTs > 1)
hr = D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
hr = D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
VertexShaderManager::SetViewportChanged();
Renderer::RestoreAPIState();
D3D::RefreshSamplerState(0, D3DSAMP_MINFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MAGFILTER);
D3D::RefreshSamplerState(0, D3DSAMP_MIPFILTER);
// .. and then readback the results.
// TODO: make this less slow.

View File

@ -35,11 +35,11 @@ const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
static float GC_ALIGNED16(lastVSconstants[C_FOGPARAMS+8][4]);
static LPDIRECT3DVERTEXSHADER9 SimpleVertexSahder;
static LPDIRECT3DVERTEXSHADER9 SimpleVertexShader;
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexSahder()
LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexShader()
{
return SimpleVertexSahder;
return SimpleVertexShader;
}
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4)
@ -132,17 +132,21 @@ void VertexShaderCache::Init()
sprintf(vSimpleProg,"struct VSOUTPUT\n"
"{\n"
"float4 vPosition : POSITION;\n"
"float4 Color : COLOR0;\n"
"float4 vTexCoord : TEXCOORD0;\n"
"float4 vTexCoord1 : TEXCOORD1;\n"
"};\n"
"VSOUTPUT main( float4 inPosition : POSITION, float4 inUV : TEXCOORD0)\n"
"VSOUTPUT main( float4 inPosition : POSITION, float4 inUV : TEXCOORD0,float4 inColor : COLOR0)\n"
"{\n"
"VSOUTPUT OUT = (VSOUTPUT)0;\n"
"OUT.vPosition = inPosition;\n"
"OUT.Color = inColor;\n"
"OUT.vTexCoord = inUV;\n"
"OUT.vTexCoord1 = inPosition.zzzz;\n"
"return OUT;\n"
"}\n");
SimpleVertexSahder = D3D::CompileVertexShader(vSimpleProg, (int)strlen(vSimpleProg));
SimpleVertexShader = D3D::CompileVertexShader(vSimpleProg, (int)strlen(vSimpleProg));
Clear();
}
@ -160,8 +164,8 @@ void VertexShaderCache::Clear()
void VertexShaderCache::Shutdown()
{
if(SimpleVertexSahder)
SimpleVertexSahder->Release();
if(SimpleVertexShader)
SimpleVertexShader->Release();
Clear();
}

View File

@ -56,7 +56,7 @@ public:
static void Cleanup();
static void Shutdown();
static bool SetShader(u32 components);
static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexSahder();
static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexShader();
#if defined(_DEBUG) || defined(DEBUGFAST)
static std::string GetCurrentShaderCode();
#endif