summaryrefslogtreecommitdiff
path: root/Source/Plugins
diff options
context:
space:
mode:
authorRodolfo Osvaldo Bogado <rodolfoosvaldobogado@gmail.com>2009-11-08 20:35:11 +0000
committerRodolfo Osvaldo Bogado <rodolfoosvaldobogado@gmail.com>2009-11-08 20:35:11 +0000
commit0ac07e8aa8edfd28c1ca5c357fdd9f17a2a2dbde (patch)
tree16eef889bc0ffa56b8b91a5d92fa58d91a4d036a /Source/Plugins
parent84c6135bfdfdb48455271cf4656481f845143327 (diff)
Big Commit this will break a lot, fix a lot, but i thing is a good step:
Implemented all the correct format conversions in efb to texture copy. replaced all the stretcrect calls with quad draws this must improve speed a bit. A BIGGGGGGGGGG cleanup in the code and reorganization. reimplemented zpeek using a secondary render target ( this still is buggy so many issues left) please a lot off feedback. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4520 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Plugins')
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp8
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h4
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp55
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h9
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp200
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h1
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp38
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h2
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/Render.cpp253
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp191
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp24
-rw-r--r--Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h1
12 files changed, 594 insertions, 192 deletions
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
index deda094ffe..8536198d65 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.cpp
@@ -485,6 +485,14 @@ void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value)
}
}
+void RefreshVertexDeclaration()
+{
+ if (m_VtxDecl)
+ {
+ D3D::dev->SetVertexDeclaration(m_VtxDecl);
+ }
+}
+
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl)
{
if (!decl) {
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
index 40ab5c6237..d34b4e91d5 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DBase.h
@@ -63,7 +63,8 @@ int GetBackBufferWidth();
int GetBackBufferHeight();
LPDIRECT3DSURFACE9 GetBackBufferSurface();
LPDIRECT3DSURFACE9 GetBackBufferDepthSurface();
-
+LPDIRECT3DVERTEXBUFFER9 GetquadVB();
+LPDIRECT3DVERTEXDECLARATION9 GetBasicvertexDecl();
const D3DCAPS9 &GetCaps();
const char *PixelShaderVersionString();
const char *VertexShaderVersionString();
@@ -74,6 +75,7 @@ void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
+void RefreshVertexDeclaration();
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
void ApplyCachedState();
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp
index a1b30a3dc2..3e6fb7e4b2 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.cpp
@@ -208,10 +208,24 @@ void SaveRenderStates()
void RestoreRenderStates()
{
- D3D::SetTexture(0, texture_old);
-
- dev->SetPixelShader(ps_old);
- dev->SetVertexShader(vs_old);
+ if(texture_old)
+ {
+ D3D::SetTexture(0, texture_old);
+ texture_old->Release();
+ texture_old = NULL;
+ }
+ if(ps_old)
+ {
+ dev->SetPixelShader(ps_old);
+ ps_old->Release();
+ ps_old = NULL;
+ }
+ if(vs_old)
+ {
+ dev->SetVertexShader(vs_old);
+ vs_old->Release();
+ vs_old = NULL;
+ }
for (int i = 0; i < 6; i++)
{
@@ -374,4 +388,37 @@ void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1, float v
RestoreRenderStates();
}
+void drawShadedTexQuad(IDirect3DTexture9 *texture,
+ const RECT *rSource,
+ int SourceWidth,
+ int SourceHeight,
+ const RECT *rDest,
+ IDirect3DPixelShader9 *PShader,
+ IDirect3DVertexShader9 *Vshader)
+{
+ SaveRenderStates();
+
+ float span = ((rSource->right-rSource->left - 1.0f) * (rDest->right - rDest->left))/(SourceWidth*((rDest->right - rDest->left)-1.0f));
+ float u1=((0.5f+rSource->left)/(float) SourceWidth)-(span*0.5f/(float)(rDest->right - rDest->left));
+ float u2=u1+span;
+ span = ((rSource->bottom-rSource->top - 1.0f) * (rDest->bottom - rDest->top))/(SourceHeight*((rDest->bottom - rDest->top)-1.0f));
+ float v1=((0.5f+rSource->top)/(float) SourceHeight)-(span*0.5f/(float)(rDest->bottom - rDest->top));
+ float v2=v1+span;
+
+ struct Q2DVertex { float x,y,z,rhw,u,v; } coords[4] = {
+ {(float)rDest->left-1.0f, (float)rDest->top-1.0f, 0.0f, 1.0f, u1, v1},
+ {(float)rDest->right, (float)rDest->top-1.0f, 0.0f,1.0f, u2, v1},
+ {(float)rDest->right, (float)rDest->bottom, 0.0f,1.0f, u2, v2},
+ {(float)rDest->left-1.0f, (float)rDest->bottom, 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));
+ D3D::RefreshVertexDeclaration();
+ RestoreRenderStates();
+
+}
+
} // namespace
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h
index dc59ff3b6d..e61f6b06e1 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/D3DUtil.h
@@ -58,4 +58,13 @@ namespace D3D
extern CD3DFont font;
void quad2d(float x1, float y1, float x2, float y2, u32 color, float u1=0, float v1=0, float u2=1, float v2=1);
+ void drawShadedTexQuad(IDirect3DTexture9 *texture,
+ const RECT *rSource,
+ int SourceWidth,
+ int SourceHeight,
+ const RECT *rDest,
+ IDirect3DPixelShader9 *PShader,
+ IDirect3DVertexShader9 *Vshader);
+ void SaveRenderStates();
+ void RestoreRenderStates();
}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp
index f9d73bc169..c0772b2b4d 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.cpp
@@ -23,34 +23,62 @@
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 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 LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;
-static LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;
+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
-static LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer;
-static LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;
+static LPDIRECT3DSURFACE9 s_efb_color_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
+static LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
-static D3DFORMAT s_efb_color_surface_Format;
-static D3DFORMAT s_efb_depth_surface_Format;
+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
#undef CHECK
#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_OffScreenReadBuffer; }
-LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface() { return s_efb_depth_OffScreenReadBuffer; }
+LPDIRECT3DSURFACE9 GetEFBColorRTSurface()
+{
+ return s_efb_color_surface;
+}
+LPDIRECT3DSURFACE9 GetEFBDepthRTSurface()
+{
+ return s_efb_depth_surface;
+}
+
+LPDIRECT3DSURFACE9 GetEFBDepthEncodedSurface()
+{
+ return s_efb_depthColor_surface;
+}
+
+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;
+}
-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;}
@@ -63,14 +91,9 @@ LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc)
LPDIRECT3DTEXTURE9 GetEFBDepthTexture(const EFBRectangle &sourceRc)
{
- // Depth textures not supported under DX9. We're gonna fake this
- // with a secondary render target later.
return s_efb_depth_texture;
}
-
-
-
void Create()
{
@@ -79,29 +102,55 @@ void Create()
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,
+ HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
D3DPOOL_DEFAULT, &s_efb_color_texture, NULL);
+ if(s_efb_color_texture)
+ {
+ s_efb_color_texture->GetSurfaceLevel(0,&s_efb_color_surface);
+ }
CHECK(hr,"Create Color Texture");
- //get the Surface
- hr = s_efb_color_texture->GetSurfaceLevel(0, &s_efb_color_surface);
- 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))
+ hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
+ D3DPOOL_DEFAULT, &s_efb_colorRead_texture, NULL);
+ CHECK(hr,"Create Color Read Texture");
+ if(s_efb_colorRead_texture)
{
- //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");
+ s_efb_colorRead_texture->GetSurfaceLevel(0,&s_efb_color_ReadBuffer);
}
+ //create an offscreen surface that we can lock to retrieve the data
+ hr = D3D::dev->CreateOffscreenPlainSurface(1, 1, s_efb_color_surface_Format, D3DPOOL_SYSTEMMEM, &s_efb_color_OffScreenReadBuffer, NULL );
+ CHECK(hr,"Create Color offScreen Surface");
//Select Zbuffer format supported by hadware.
if (g_ActiveConfig.bEFBAccessEnable)
{
- //depth format in prefered order
+
+ hr = D3D::dev->CreateDepthStencilSurface(target_width, target_height, D3DFMT_D24X8,
+ D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL);
+ CHECK(hr,"CreateDepthStencilSurface");
+
+ s_efb_depth_surface_Format = D3DFMT_A8R8G8B8;
+ //get the framebuffer Depth texture
+ HRESULT hr = D3D::dev->CreateTexture(target_width, target_height, 1, D3DUSAGE_RENDERTARGET, s_efb_depth_surface_Format,
+ D3DPOOL_DEFAULT, &s_efb_depth_texture, NULL);
+ 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");
+
+ /*//depth format in prefered order
D3DFORMAT *DepthTexFormats = new D3DFORMAT[3];
DepthTexFormats[0] = D3DFMT_D32F_LOCKABLE;
DepthTexFormats[1] = D3DFMT_D16_LOCKABLE;
@@ -116,7 +165,7 @@ void Create()
s_efb_depth_ReadBuffer = s_efb_depth_surface;
s_efb_depth_OffScreenReadBuffer = s_efb_depth_surface;
CHECK(hr,"CreateDepthStencilSurface");
- delete [] DepthTexFormats;
+ delete [] DepthTexFormats;*/
}
else
{
@@ -129,44 +178,51 @@ void Create()
void Destroy()
{
- 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_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_depthColor_surface)
+s_efb_depthColor_surface->Release();
+s_efb_depthColor_surface=NULL;
- if(s_efb_depth_texture)
- s_efb_depth_texture->Release();
- s_efb_depth_texture = NULL;
+if(s_efb_color_surface)
+s_efb_color_surface->Release();
+s_efb_color_surface=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_ReadBuffer)
+s_efb_color_ReadBuffer->Release();
+s_efb_color_ReadBuffer=NULL;
+
+if(s_efb_depth_ReadBuffer)
+s_efb_depth_ReadBuffer->Release();
+s_efb_depth_ReadBuffer=NULL;
+
+if(s_efb_color_OffScreenReadBuffer)
+s_efb_color_OffScreenReadBuffer->Release();
+s_efb_color_OffScreenReadBuffer=NULL;
+
+if(s_efb_depth_OffScreenReadBuffer)
+s_efb_depth_OffScreenReadBuffer->Release();
+s_efb_depth_OffScreenReadBuffer=NULL;
+
+if(s_efb_color_texture)
+ s_efb_color_texture->Release();
+s_efb_color_texture=NULL;
+
+if(s_efb_colorRead_texture)
+s_efb_colorRead_texture->Release();
+s_efb_colorRead_texture=NULL;
+
+if(s_efb_depth_texture)
+s_efb_depth_texture->Release();
+s_efb_depth_texture=NULL;
+
+if(s_efb_depthRead_texture)
+s_efb_depthRead_texture->Release();
+s_efb_depthRead_texture=NULL;
- if(s_efb_color_surface)
- s_efb_color_surface->Release();
- 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();
- s_efb_color_texture = NULL;
}
} // namespace \ No newline at end of file
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h
index ddf8377df5..a1b36ac44a 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/FramebufferManager.h
@@ -40,6 +40,7 @@ D3DFORMAT GetEFBDepthRTSurfaceFormat();
D3DFORMAT GetEFBColorRTSurfaceFormat();
LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
+LPDIRECT3DSURFACE9 GetEFBDepthEncodedSurface();
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp
index dafed61dfb..b762d85993 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.cpp
@@ -34,6 +34,19 @@ PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
static float lastPSconstants[C_COLORMATRIX+16][4];
+static LPDIRECT3DPIXELSHADER9 s_ColorMatrixProgram = 0;
+static LPDIRECT3DPIXELSHADER9 s_ColorCopyProgram = 0;
+
+LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorMatrixProgram()
+{
+ return s_ColorMatrixProgram;
+}
+
+LPDIRECT3DPIXELSHADER9 PixelShaderCache::GetColorCopyProgram()
+{
+ return s_ColorCopyProgram;
+}
+
void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{
if( lastPSconstants[const_number][0] != f1 || lastPSconstants[const_number][1] != f2 ||
@@ -63,6 +76,25 @@ void SetPSConstant4fv(int const_number, const float *f)
void PixelShaderCache::Init()
{
+ char pmatrixprog[1024];
+ sprintf(pmatrixprog,"uniform sampler samp0 : register(s0);\n"
+ "uniform float4 cColMatrix[5] : register(c%d);\n"
+ "void main(\n"
+ "out float4 ocol0 : COLOR0,\n"
+ " in float3 uv0 : TEXCOORD0){\n"
+ "float4 texcol = tex2D(samp0,uv0.xy);\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);
+ char pcopyprog[1024];
+ sprintf(pcopyprog,"uniform sampler samp0 : register(s0);\n"
+ "void main(\n"
+ "out float4 ocol0 : COLOR0,\n"
+ " in float3 uv0 : TEXCOORD0){\n"
+ "ocol0 = tex2D(samp0,uv0.xy);\n"
+ "}\n");
+
+ s_ColorMatrixProgram = D3D::CompilePixelShader(pmatrixprog, (int)strlen(pmatrixprog));
+ s_ColorCopyProgram = D3D::CompilePixelShader(pcopyprog, (int)strlen(pcopyprog));
Clear();
}
@@ -80,6 +112,12 @@ void PixelShaderCache::Clear()
void PixelShaderCache::Shutdown()
{
+ if(s_ColorMatrixProgram)
+ s_ColorMatrixProgram->Release();
+ s_ColorMatrixProgram = NULL;
+ if(s_ColorCopyProgram)
+ s_ColorCopyProgram->Release();
+ s_ColorCopyProgram=NULL;
Clear();
}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h
index b9e84b45bd..c227128151 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/PixelShaderCache.h
@@ -59,6 +59,8 @@ public:
static void Clear();
static void Shutdown();
static bool SetShader(bool dstAlpha);
+ static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram();
+ static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram();
#if defined(_DEBUG) || defined(DEBUGFAST)
static std::string GetCurrentShaderCode();
#endif
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
index 1c5a564778..1b40fd91ca 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp
@@ -63,6 +63,7 @@ static u32 s_blendMode;
char st[32768];
+
// State translation lookup tables
static const D3DBLEND d3dSrcFactors[8] =
{
@@ -98,6 +99,7 @@ void SetupDeviceObjects()
PixelShaderManager::Dirty();
// Tex and shader caches will recreate themselves over time.
+
}
// Kill off all POOL_DEFAULT device objects.
@@ -159,15 +161,25 @@ bool Renderer::Init()
for (int stage = 0; stage < 8; stage++)
D3D::SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, g_ActiveConfig.iMaxAnisotropy);
-
- D3D::dev->Clear(0, NULL, D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(255,255,255),1.0f,0);
+ D3DVIEWPORT9 vp;
+ vp.X = 0;
+ vp.Y = 0;
+ vp.Width = s_backbuffer_width;
+ vp.Height = s_backbuffer_height;
+ vp.MinZ = 0.0f;
+ vp.MaxZ = 0.0f;
+ D3D::dev->SetViewport(&vp);
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
-
+
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
+ D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
-
+ vp.Width = s_target_width;
+ vp.Height = s_target_height;
+ vp.MinZ = 0.0f;
+ vp.MaxZ = 0.0f;
+ D3D::dev->SetViewport(&vp);
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0, 1.0f, 0);
-
D3D::BeginFrame();
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
return true;
@@ -209,9 +221,9 @@ void dumpMatrix(D3DXMATRIX &mtx)
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
{
TargetRectangle result;
- result.left = (rc.left * s_target_width) / EFB_WIDTH;
+ result.left = (rc.left * s_target_width) / EFB_WIDTH ;
result.top = (rc.top * s_target_height) / EFB_HEIGHT;
- result.right = (rc.right * s_target_width) / EFB_WIDTH;
+ result.right = (rc.right * s_target_width) / EFB_WIDTH ;
result.bottom = (rc.bottom * s_target_height) / EFB_HEIGHT;
return result;
}
@@ -261,32 +273,49 @@ void CheckForResize()
static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
{
// Set the backbuffer as the rendering target
- D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3D::dev->SetDepthStencilSurface(NULL);
-
- // Blit our render target onto the backbuffer.
- // TODO: Change to a quad so we can do post processing.
+ D3D::dev->SetRenderTarget(1, NULL);
+ D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
+
TargetRectangle src_rect, dst_rect;
src_rect = Renderer::ConvertEFBRectangle(sourceRc);
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
-
- //LPD3DXSPRITE pSprite=NULL;
- //D3DXCreateSprite(D3D::dev, &pSprite);
- //D3DXVECTOR3 pos(0,0,0);
- //EFBRectangle efbRect;
- //
- //pSprite->Begin(D3DXSPRITE_ALPHABLEND);
- //pSprite->Draw(FBManager::GetEFBColorTexture(efbRect),NULL, NULL, &pos, 0xFFFFFFFF);
- //pSprite->End();
- //pSprite->Release();
+ D3DVIEWPORT9 vp;
+ vp.X = 0;
+ vp.Y = 0;
+ vp.Width = s_backbuffer_width;
+ vp.Height = s_backbuffer_height;
+ vp.MinZ = 0.0f;
+ vp.MaxZ = 0.0f;
+ D3D::dev->SetViewport(&vp);
D3D::dev->Clear(0,NULL, D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
+ vp.X = dst_rect.left;
+ vp.Y = dst_rect.top;
+ vp.Width = dst_rect.right - dst_rect.left;
+ vp.Height = dst_rect.bottom - dst_rect.top;
+ vp.MinZ = 0.0f;
+ vp.MaxZ = 0.0f;
+ D3D::dev->SetViewport(&vp);
- // todo, to draw the EFB texture to the backbuffer instead of StretchRect
- D3D::dev->StretchRect(FBManager::GetEFBColorRTSurface(), src_rect.AsRECT(),
- D3D::GetBackBufferSurface(), dst_rect.AsRECT(),
- D3DTEXF_LINEAR);
-
+ EFBRectangle efbRect;
+
+
+
+ LPDIRECT3DTEXTURE9 read_texture = FBManager::GetEFBColorTexture(efbRect);
+ RECT destinationrect;
+ destinationrect.bottom = dst_rect.bottom;
+ destinationrect.left = dst_rect.left;
+ destinationrect.right = dst_rect.right;
+ destinationrect.top = dst_rect.top;
+ RECT sourcerect;
+ sourcerect.bottom = src_rect.bottom;
+ sourcerect.left = src_rect.left;
+ sourcerect.right = src_rect.right;
+ sourcerect.top = src_rect.top;
+
+ D3D::drawShadedTexQuad(read_texture,&sourcerect,Renderer::GetTargetWidth(),Renderer::GetTargetHeight(),&destinationrect,PixelShaderCache::GetColorCopyProgram(),VertexShaderCache::GetSimpleVertexSahder());
+
// Finish up the current frame, print some stats
if (g_ActiveConfig.bOverlayStats)
{
@@ -301,14 +330,11 @@ static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
OSD::DrawMessages();
- // u32 clearColor = (bpmem.clearcolorAR << 16) | bpmem.clearcolorGB;
-
- // Clear the render target. We probably don't need to do this every frame.
- //D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 1.0f, 0);
-
- // Set rendering target back to the EFB rendering texture
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
+ D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
+
+ VertexShaderManager::SetViewportChanged();
}
@@ -386,10 +412,11 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
return;
}
- D3D::EndFrame();
+ Renderer::ResetAPIState();
D3DDumpFrame();
EFBTextureToD3DBackBuffer(sourceRc);
- D3D::BeginFrame();
+ D3D::EndFrame();
+
DEBUGGER_LOG_AT((NEXT_XFB_CMD|NEXT_EFB_CMD|NEXT_FRAME),
{printf("StretchRect, EFB->XFB\n");});
@@ -399,21 +426,12 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
xfbAddr, fbWidth, fbHeight,
sourceRc.left, sourceRc.top, sourceRc.right, sourceRc.bottom);}
);
-
-
- RECT rc;
- rc.left = 0;
- rc.top = 0;
- rc.right = (LONG)s_target_width;
- rc.bottom = (LONG)s_target_height;
- D3D::dev->SetScissorRect(&rc);
- D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, false);
-
- UpdateViewport();
-
Swap(0,FIELD_PROGRESSIVE,0,0); // we used to swap the buffer here, now we will wait
- // until the XFB pointer is updated by VI
- D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
+ // until the XFB pointer is updated by VI
+ D3D::BeginFrame();
+ Renderer::RestoreAPIState();
+ UpdateViewport();
+
}
bool Renderer::SetScissorRect()
@@ -432,10 +450,27 @@ bool Renderer::SetScissorRect()
rc.bottom = (int)(rc.bottom * yScale);
if (rc.left < 0) rc.left = 0;
- if (rc.right > s_target_width) rc.right = s_target_width;
+ if (rc.right < 0) rc.right = 0;
+ if (rc.left > s_target_width) rc.left = s_target_width;
+ if (rc.right > s_target_width) rc.right = s_target_width;
if (rc.top < 0) rc.top = 0;
+ if (rc.bottom < 0) rc.bottom = 0;
+ if (rc.top > s_target_height) rc.top = s_target_height;
if (rc.bottom > s_target_height) rc.bottom = s_target_height;
-
+ /*LONG temprc = 0;
+ if(rc.right < rc.left)
+ {
+ temprc = rc.right;
+ rc.right = rc.left;
+ rc.left = temprc;
+ }
+ if(rc.bottom < rc.top)
+ {
+ temprc = rc.bottom;
+ rc.bottom = rc.top;
+ rc.top = temprc;
+ }
+ D3D::dev->SetScissorRect(&rc);*/
if (rc.right >= rc.left && rc.bottom >= rc.top)
{
D3D::dev->SetScissorRect(&rc);
@@ -443,9 +478,10 @@ bool Renderer::SetScissorRect()
}
else
{
- WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
+ WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
return false;
}
+ return true;
}
void Renderer::SetColorMask()
@@ -460,10 +496,9 @@ void Renderer::SetColorMask()
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
{
-
//Get the working buffer
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
- FBManager::GetEFBDepthRTSurface() : FBManager::GetEFBColorRTSurface();
+ FBManager::GetEFBDepthEncodedSurface() : FBManager::GetEFBColorRTSurface();
//get the temporal buffer to move 1pixel data
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
FBManager::GetEFBDepthReadSurface() : FBManager::GetEFBColorReadSurface();
@@ -482,11 +517,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
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_D24X8)
- {
- return 0;
- }
// Get the rectangular target region covered by the EFB pixel.
EFBRectangle efbPixelRc;
@@ -506,30 +536,25 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
RectToLock.right = targetPixelRc.right;
RectToLock.top = targetPixelRc.top;
- //lock the buffer
-
- if(!(BufferFormat == D3DFMT_D32F_LOCKABLE || BufferFormat == D3DFMT_D16_LOCKABLE))
+ hr = D3D::dev->StretchRect(pBuffer,&RectToLock,RBuffer,NULL, D3DTEXF_NONE);
+ if(FAILED(hr))
{
- //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;
- }
+ 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;
+
//the surface is good.. lock it
if((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
{
@@ -540,25 +565,18 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
switch(type) {
case PEEK_Z:
- {
- switch (BufferFormat)
{
- case D3DFMT_D32F_LOCKABLE:
- val = ((float *)drect.pBits)[0];
- z = ((u32)(val * 0xffffff));// 0xFFFFFFFF;
- break;
- case D3DFMT_D16_LOCKABLE:
- val = ((float)((u16 *)drect.pBits)[0])/((float)0xFFFF);
- z = ((u32)(val * 0xffffff));
- break;
- default:
- z = ((u32 *)drect.pBits)[0] >> 8;
- break;
- };
- // [0.0, 1.0] ==> [0, 0xFFFFFFFF]
-
- break;
+ static float ffrac = 255.0f/254.0f;
+ z = ((u32 *)drect.pBits)[0];
+ float fvalue = (((float)(z & 0xFF)) / 255.0f) * ffrac;
+ fvalue += (((float)((z>>8) & 0xFF)) / 255.0f) * (ffrac/255.0f);
+ fvalue += (((float)((z>>16) & 0xFF)) / 255.0f) * (ffrac/(255.0f*255.0f));
+ fvalue += (((float)((z>>24) & 0xFF)) / 255.0f) * (ffrac/(255.0f*255.0f*255.0f));
+ if(fvalue>1.0f)fvalue=1.0f;
+ if(fvalue<0.0f)fvalue=0.0f;
+ z = ((u32)(fvalue * 0xffffff));
}
+ break;
case POKE_Z:
// TODO: Get that Z value to poke from somewhere
//((float *)drect.pBits)[0] = val;
@@ -568,7 +586,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
case PEEK_COLOR:
z = ((u32 *)drect.pBits)[0];
break;
-
case POKE_COLOR:
// TODO: Get that ARGB value to poke from somewhere
//((float *)drect.pBits)[0] = val;
@@ -577,9 +594,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
}
- pOffScreenBuffer->UnlockRect();
-
-
+ pOffScreenBuffer->UnlockRect();
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
return z;
@@ -605,6 +620,14 @@ void UpdateViewport()
vp.Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * MValueY);
vp.Width = (int)ceil(abs((int)(2 * xfregs.rawViewport[0])) * MValueX);
vp.Height = (int)ceil(abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
+ if(vp.X < 0) vp.X = 0;
+ if(vp.Y < 0) vp.Y = 0;
+ if(vp.X > s_target_width) vp.X = s_target_width;
+ if(vp.Y > s_target_height) vp.Y = s_target_height;
+ if(vp.Width < 0) vp.Width = 0;
+ if(vp.Height < 0) vp.Height = 0;
+ if(vp.Width > (s_target_width - vp.X)) vp.Width = s_target_width - vp.X;
+ if(vp.Height > (s_target_height - vp.Y)) vp.Height = s_target_height - vp.Y;
//some games set invalids values for z min and z max so fix them to the max an min alowed and let the shaders do this work
vp.MinZ = 0.0f;//(xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
vp.MaxZ = 1.0f;//xfregs.rawViewport[5] / 16777216.0f;
@@ -719,3 +742,29 @@ void Renderer::Swap(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
// Flip/present backbuffer to frontbuffer here
D3D::Present();
}
+
+void Renderer::ResetAPIState()
+{
+ D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE);
+ D3D::SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
+ D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE);
+ D3D::SetRenderState(D3DRS_ZENABLE, FALSE);
+ D3D::SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
+ DWORD color_mask = D3DCOLORWRITEENABLE_ALPHA| D3DCOLORWRITEENABLE_RED | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_BLUE;
+ D3D::SetRenderState(D3DRS_COLORWRITEENABLE, color_mask);
+}
+
+void Renderer::RestoreAPIState()
+{
+ // Gets us back into a more game-like state.
+
+ UpdateViewport();
+
+ if (bpmem.zmode.testenable) D3D::SetRenderState(D3DRS_ZENABLE, TRUE);
+ if (bpmem.zmode.updateenable) D3D::SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
+
+ D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE);
+ SetScissorRect();
+ SetColorMask();
+ SetBlendMode(true);
+}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
index db4f5d0247..3f51af74f7 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/TextureCache.cpp
@@ -27,7 +27,12 @@
#include "D3DBase.h"
#include "D3DTexture.h"
+#include "D3DUtil.h"
#include "FramebufferManager.h"
+#include "PixelShaderCache.h"
+#include "PixelShaderManager.h"
+#include "VertexShaderManager.h"
+#include "VertexShaderCache.h"
#include "Render.h"
@@ -257,9 +262,12 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
return &entry;
}
+#undef CHECK
+#define CHECK(hr) if (FAILED(hr)) { PanicAlert(__FUNCTION__ " FAIL"); }
// EXTREMELY incomplete.
void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect)
{
+ HRESULT hr = S_OK;
int efb_w = source_rect.GetWidth();
int efb_h = source_rect.GetHeight();
@@ -271,19 +279,20 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
iter = textures.find(address);
if (iter != textures.end())
{
- if (!iter->second.isRenderTarget)
+ if (iter->second.isRenderTarget && iter->second.w == tex_w && iter->second.h == tex_h)
+ {
+
+ tex = iter->second.texture;
+ iter->second.frameCount = frameCount;
+ goto have_texture;
+ }
+ else
{
// Remove it and recreate it as a render target
iter->second.texture->Release();
iter->second.texture = 0;
textures.erase(iter);
}
- else
- {
- tex = iter->second.texture;
- iter->second.frameCount = frameCount;
- goto have_texture;
- }
}
{
@@ -293,14 +302,16 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
entry.frameCount = frameCount;
entry.w = tex_w;
entry.h = tex_h;
-
- D3D::dev->CreateTexture(tex_w, tex_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0);
+ entry.fmt = copyfmt;
+
+ hr = D3D::dev->CreateTexture(tex_w, tex_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0);
+ CHECK(hr);
textures[address] = entry;
tex = entry.texture;
}
have_texture:
- TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
+ /*TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
RECT source_rc;
source_rc.left = targetSource.left;
source_rc.top = targetSource.top;
@@ -317,8 +328,162 @@ have_texture:
srcSurface = FBManager::GetEFBColorRTSurface();
D3D::dev->StretchRect(srcSurface, &source_rc, destSurface, &dest_rc, D3DTEXF_LINEAR);
destSurface->Release();
+ return;*/
+ float colmat[16]= {0.0f};
+ float fConstAdd[4] = {0.0f};
+
+ if (bFromZBuffer)
+ {
+ switch(copyfmt)
+ {
+ case 0: // Z4
+ case 1: // Z8
+ colmat[2] = colmat[6] = colmat[10] = colmat[14] = 1;
+ break;
+
+ case 3: // Z16 //?
+ colmat[1] = colmat[5] = colmat[9] = colmat[14] = 1;
+ case 11: // Z16 (reverse order)
+ colmat[2] = colmat[6] = colmat[10] = colmat[13] = 1;
+ break;
+ case 6: // Z24X8
+ colmat[0] = 1;
+ colmat[5] = 1;
+ colmat[10] = 1;
+ colmat[15] = 1;
+ break;
+ case 9: // Z8M
+ colmat[1] = colmat[5] = colmat[9] = colmat[13] = 1;
+ break;
+ case 10: // Z8L
+ colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1;
+ break;
+ case 12: // Z16L
+ colmat[0] = colmat[4] = colmat[8] = colmat[13] = 1;
+ break;
+ default:
+ ERROR_LOG(VIDEO, "Unknown copy zbuf format: 0x%x", copyfmt);
+ colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1;
+ break;
+ }
+ }
+ else if (bIsIntensityFmt)
+ {
+ fConstAdd[0] = fConstAdd[1] = fConstAdd[2] = 16.0f/255.0f;
+ switch (copyfmt)
+ {
+ case 0: // I4
+ case 1: // I8
+ case 2: // IA4
+ case 3: // IA8
+ // TODO - verify these coefficients
+ colmat[0] = 0.257f; colmat[1] = 0.504f; colmat[2] = 0.098f;
+ colmat[4] = 0.257f; colmat[5] = 0.504f; colmat[6] = 0.098f;
+ colmat[8] = 0.257f; colmat[9] = 0.504f; colmat[10] = 0.098f;
+
+ if (copyfmt < 2)
+ {
+ fConstAdd[3] = 16.0f / 255.0f;
+ colmat[12] = 0.257f; colmat[13] = 0.504f; colmat[14] = 0.098f;
+ }
+ else// alpha
+ colmat[15] = 1;
+
+ break;
+ default:
+ ERROR_LOG(VIDEO, "Unknown copy intensity format: 0x%x", copyfmt);
+ colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1;
+ break;
+ }
+ }
+ else
+ {
+ switch (copyfmt)
+ {
+ case 0: // R4
+ case 8: // R8
+ colmat[0] = colmat[4] = colmat[8] = colmat[12] = 1;
+ break;
+ case 2: // RA4
+ case 3: // RA8
+ colmat[0] = colmat[4] = colmat[8] = colmat[15] = 1;
+ break;
+
+ case 7: // A8
+ colmat[3] = colmat[7] = colmat[11] = colmat[15] = 1;
+ break;
+ case 9: // G8
+ colmat[1] = colmat[5] = colmat[9] = colmat[13] = 1;
+ break;
+ case 10: // B8
+ colmat[2] = colmat[6] = colmat[10] = colmat[14] = 1;
+ break;
+ case 11: // RG8
+ colmat[0] = colmat[4] = colmat[8] = colmat[13] = 1;
+ break;
+ case 12: // GB8
+ colmat[1] = colmat[5] = colmat[9] = colmat[14] = 1;
+ break;
+
+ case 4: // RGB565
+ colmat[0] = colmat[5] = colmat[10] = 1;
+ fConstAdd[3] = 1; // set alpha to 1
+ break;
+ case 5: // RGB5A3
+ case 6: // RGBA8
+ colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1;
+ break;
+
+ default:
+ ERROR_LOG(VIDEO, "Unknown copy color format: 0x%x", copyfmt);
+ colmat[0] = colmat[5] = colmat[10] = colmat[15] = 1;
+ break;
+ }
+ }
+ // Make sure to resolve anything we need to read from.
+ LPDIRECT3DTEXTURE9 read_texture = bFromZBuffer ? FBManager::GetEFBDepthTexture(source_rect) : FBManager::GetEFBColorTexture(source_rect);
+
+ // We have to run a pixel shader, for color conversion.
+ Renderer::ResetAPIState(); // reset any game specific settings
+ LPDIRECT3DSURFACE9 Rendersurf = NULL;
+ hr = tex->GetSurfaceLevel(0,&Rendersurf);
+ CHECK(hr);
+ D3D::dev->SetDepthStencilSurface(NULL);
+ D3D::dev->SetRenderTarget(1, NULL);
+ D3D::dev->SetRenderTarget(0, Rendersurf);
+
+ D3DVIEWPORT9 vp;
+
+ // Stretch picture with increased internal resolution
+ vp.X = 0;
+ vp.Y = 0;
+ vp.Width = tex_w;
+ vp.Height = tex_h;
+ vp.MinZ = 0.0f;
+ vp.MaxZ = 1.0f;
+ hr = D3D::dev->SetViewport(&vp);
+ CHECK(hr);
+ RECT destrect;
+ destrect.bottom = tex_h;
+ destrect.left = 0;
+ destrect.right = tex_w;
+ destrect.top = 0;
+
- DEBUGGER_LOG_AT((NEXT_XFB_CMD|NEXT_EFB_CMD|NEXT_FRAME|NEXT_NEW_TEXTURE|NEXT_FLUSH),
- {printf("StretchRect, EFB (%d,%d) -> Texture at 0x%08X (%d,%d)\n",efb_w,efb_h,address,tex_w,tex_h);});
- DEBUGGER_PAUSE_AT((NEXT_EFB_CMD|NEXT_NEW_TEXTURE),false);
+ PixelShaderManager::SetColorMatrix(colmat, fConstAdd); // set transformation
+ //TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
+ RECT sourcerect;
+ sourcerect.bottom = source_rect.bottom;
+ sourcerect.left = source_rect.left;
+ sourcerect.right = source_rect.right;
+ sourcerect.top = source_rect.top;
+
+ D3D::drawShadedTexQuad(read_texture,&sourcerect, EFB_WIDTH , EFB_HEIGHT,&destrect,PixelShaderCache::GetColorMatrixProgram(),NULL);
+
+ D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
+ D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
+ D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
+ VertexShaderManager::SetViewportChanged();
+ Renderer::RestoreAPIState();
+ Rendersurf->Release();
}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp
index 6a09e86fc9..6153402e6b 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.cpp
@@ -35,6 +35,13 @@ const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
static float GC_ALIGNED16(lastVSconstants[C_FOGPARAMS+8][4]);
+static LPDIRECT3DVERTEXSHADER9 SimpleVertexSahder;
+
+LPDIRECT3DVERTEXSHADER9 VertexShaderCache::GetSimpleVertexSahder()
+{
+ return SimpleVertexSahder;
+}
+
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4)
{
if (lastVSconstants[const_number][0] != f1 ||
@@ -121,6 +128,21 @@ void SetMultiVSConstant4fv(int const_number, int count, const float *f)
void VertexShaderCache::Init()
{
+ char vSimpleProg[1024];
+ sprintf(vSimpleProg,"struct VSOUTPUT\n"
+ "{\n"
+ "float4 vPosition : POSITION;\n"
+ "float4 vTexCoord : TEXCOORD0;\n"
+ "};\n"
+ "VSOUTPUT main( float4 inPosition : POSITION, float4 inUV : TEXCOORD0)\n"
+ "{\n"
+ "VSOUTPUT OUT = (VSOUTPUT)0;\n"
+ "OUT.vPosition = inPosition;\n"
+ "OUT.vTexCoord = inUV;\n"
+ "return OUT;\n"
+ "}\n");
+
+ SimpleVertexSahder = D3D::CompileVertexShader(vSimpleProg, (int)strlen(vSimpleProg));
Clear();
}
@@ -138,6 +160,8 @@ void VertexShaderCache::Clear()
void VertexShaderCache::Shutdown()
{
+ if(SimpleVertexSahder)
+ SimpleVertexSahder->Release();
Clear();
}
diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h
index 8fc5d0cf56..f6ad37f1ab 100644
--- a/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h
+++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexShaderCache.h
@@ -56,6 +56,7 @@ public:
static void Cleanup();
static void Shutdown();
static bool SetShader(u32 components);
+ static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexSahder();
#if defined(_DEBUG) || defined(DEBUGFAST)
static std::string GetCurrentShaderCode();
#endif