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
This commit is contained in:
parent
84c6135bfd
commit
0ac07e8aa8
|
@ -451,7 +451,9 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
|
||||||
|
|
||||||
WRITE(p, "void main(\n");
|
WRITE(p, "void main(\n");
|
||||||
|
|
||||||
WRITE(p, " out half4 ocol0 : COLOR0,\n");
|
WRITE(p, " out float4 ocol0 : COLOR0,\n");
|
||||||
|
if (HLSL)
|
||||||
|
WRITE(p, " out float4 ocol1 : COLOR1,\n");
|
||||||
WRITE(p, " out float depth : DEPTH,\n");
|
WRITE(p, " out float depth : DEPTH,\n");
|
||||||
|
|
||||||
// compute window position if needed because binding semantic WPOS is not widely supported
|
// compute window position if needed because binding semantic WPOS is not widely supported
|
||||||
|
@ -522,12 +524,20 @@ const char *GeneratePixelShader(u32 texture_mask, bool dstAlphaEnable, bool HLSL
|
||||||
|
|
||||||
// use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format...
|
// use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format...
|
||||||
if (bpmem.ztex2.op == ZTEXTURE_ADD)
|
if (bpmem.ztex2.op == ZTEXTURE_ADD)
|
||||||
WRITE(p, "depth = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w + zCoord);\n");
|
WRITE(p, "zCoord = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w + zCoord);\n");
|
||||||
else if (bpmem.ztex2.op == ZTEXTURE_REPLACE)
|
else if (bpmem.ztex2.op == ZTEXTURE_REPLACE)
|
||||||
WRITE(p, "depth = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w);\n");
|
WRITE(p, "zCoord = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w);\n");
|
||||||
else
|
|
||||||
WRITE(p, "depth = zCoord;\n");
|
WRITE(p, "depth = zCoord;\n");
|
||||||
|
|
||||||
|
if(HLSL)
|
||||||
|
{
|
||||||
|
//WRITE(p, "ocol1 = float4(1.0f/255.0f,2.0f/255.0f,3.0f/255.0f,0.0f);\n");
|
||||||
|
WRITE(p, "float4 EncodedDepth = frac(zCoord * float4(254.0f*255.0f,255.0f,254.0f/255.0f,254.0f*255.0f*255.0f));\n");
|
||||||
|
//WRITE(p, "EncodedDepth -= EncodedDepth.aarg * float4(1.0f/255.0f,1.0f/255.0f,1.0f/255.0f,0.0f);\n");
|
||||||
|
WRITE(p, "ocol1 = EncodedDepth;\n");
|
||||||
|
|
||||||
|
}
|
||||||
//if (bpmem.genMode.numindstages ) WRITE(p, "prev.rg = indtex0.xy;\nprev.b = 0;\n");
|
//if (bpmem.genMode.numindstages ) WRITE(p, "prev.rg = indtex0.xy;\nprev.b = 0;\n");
|
||||||
|
|
||||||
if (!WriteAlphaTest(p, HLSL))
|
if (!WriteAlphaTest(p, HLSL))
|
||||||
|
|
|
@ -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)
|
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl)
|
||||||
{
|
{
|
||||||
if (!decl) {
|
if (!decl) {
|
||||||
|
|
|
@ -63,7 +63,8 @@ int GetBackBufferWidth();
|
||||||
int GetBackBufferHeight();
|
int GetBackBufferHeight();
|
||||||
LPDIRECT3DSURFACE9 GetBackBufferSurface();
|
LPDIRECT3DSURFACE9 GetBackBufferSurface();
|
||||||
LPDIRECT3DSURFACE9 GetBackBufferDepthSurface();
|
LPDIRECT3DSURFACE9 GetBackBufferDepthSurface();
|
||||||
|
LPDIRECT3DVERTEXBUFFER9 GetquadVB();
|
||||||
|
LPDIRECT3DVERTEXDECLARATION9 GetBasicvertexDecl();
|
||||||
const D3DCAPS9 &GetCaps();
|
const D3DCAPS9 &GetCaps();
|
||||||
const char *PixelShaderVersionString();
|
const char *PixelShaderVersionString();
|
||||||
const char *VertexShaderVersionString();
|
const char *VertexShaderVersionString();
|
||||||
|
@ -74,6 +75,7 @@ void SetTexture(DWORD Stage, IDirect3DBaseTexture9 *pTexture);
|
||||||
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
|
void SetRenderState(D3DRENDERSTATETYPE State, DWORD Value);
|
||||||
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
|
void SetTextureStageState(DWORD Stage, D3DTEXTURESTAGESTATETYPE Type, DWORD Value);
|
||||||
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
|
void SetSamplerState(DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value);
|
||||||
|
void RefreshVertexDeclaration();
|
||||||
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
|
void SetVertexDeclaration(LPDIRECT3DVERTEXDECLARATION9 decl);
|
||||||
void ApplyCachedState();
|
void ApplyCachedState();
|
||||||
|
|
||||||
|
|
|
@ -208,10 +208,24 @@ void SaveRenderStates()
|
||||||
|
|
||||||
void RestoreRenderStates()
|
void RestoreRenderStates()
|
||||||
{
|
{
|
||||||
|
if(texture_old)
|
||||||
|
{
|
||||||
D3D::SetTexture(0, texture_old);
|
D3D::SetTexture(0, texture_old);
|
||||||
|
texture_old->Release();
|
||||||
|
texture_old = NULL;
|
||||||
|
}
|
||||||
|
if(ps_old)
|
||||||
|
{
|
||||||
dev->SetPixelShader(ps_old);
|
dev->SetPixelShader(ps_old);
|
||||||
|
ps_old->Release();
|
||||||
|
ps_old = NULL;
|
||||||
|
}
|
||||||
|
if(vs_old)
|
||||||
|
{
|
||||||
dev->SetVertexShader(vs_old);
|
dev->SetVertexShader(vs_old);
|
||||||
|
vs_old->Release();
|
||||||
|
vs_old = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
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();
|
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
|
} // namespace
|
||||||
|
|
|
@ -58,4 +58,13 @@ namespace D3D
|
||||||
extern CD3DFont font;
|
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 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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,34 +23,62 @@
|
||||||
namespace FBManager
|
namespace FBManager
|
||||||
{
|
{
|
||||||
|
|
||||||
static LPDIRECT3DTEXTURE9 s_efb_color_texture;
|
static LPDIRECT3DTEXTURE9 s_efb_color_texture;//Texture thats contains the color data of the render target
|
||||||
static LPDIRECT3DTEXTURE9 s_efb_colorBuffer_texture;
|
static LPDIRECT3DTEXTURE9 s_efb_colorRead_texture;//1 pixel texture for temporal data store
|
||||||
static LPDIRECT3DTEXTURE9 s_efb_depth_texture;
|
static LPDIRECT3DTEXTURE9 s_efb_depth_texture;//Texture thats contains the depth data of the render target
|
||||||
static LPDIRECT3DTEXTURE9 s_efb_depthBuffer_texture;
|
static LPDIRECT3DTEXTURE9 s_efb_depthRead_texture;//1 pixel texture for temporal data store
|
||||||
static LPDIRECT3DSURFACE9 s_efb_color_surface;
|
|
||||||
static LPDIRECT3DSURFACE9 s_efb_depth_surface;
|
|
||||||
|
|
||||||
static LPDIRECT3DSURFACE9 s_efb_color_ReadBuffer;
|
static LPDIRECT3DSURFACE9 s_efb_depth_surface;//Depth Surface
|
||||||
static LPDIRECT3DSURFACE9 s_efb_depth_ReadBuffer;
|
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_color_OffScreenReadBuffer;//System memory Surface that can be locked to retriebe the data
|
||||||
static LPDIRECT3DSURFACE9 s_efb_depth_OffScreenReadBuffer;
|
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_color_surface_Format;//Format of the color Surface
|
||||||
static D3DFORMAT s_efb_depth_surface_Format;
|
static D3DFORMAT s_efb_depth_surface_Format;//Format of the Depth color encoded Surface
|
||||||
#undef CHECK
|
#undef CHECK
|
||||||
#define CHECK(hr,Message) if (FAILED(hr)) { PanicAlert(__FUNCTION__ " FAIL: %s" ,Message); }
|
#define CHECK(hr,Message) if (FAILED(hr)) { PanicAlert(__FUNCTION__ " FAIL: %s" ,Message); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
LPDIRECT3DSURFACE9 GetEFBColorRTSurface() { return s_efb_color_surface; }
|
LPDIRECT3DSURFACE9 GetEFBColorRTSurface()
|
||||||
LPDIRECT3DSURFACE9 GetEFBDepthRTSurface() { return s_efb_depth_surface; }
|
{
|
||||||
LPDIRECT3DSURFACE9 GetEFBColorOffScreenRTSurface() { return s_efb_color_OffScreenReadBuffer; }
|
return s_efb_color_surface;
|
||||||
LPDIRECT3DSURFACE9 GetEFBDepthOffScreenRTSurface() { return s_efb_depth_OffScreenReadBuffer; }
|
}
|
||||||
|
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 GetEFBDepthRTSurfaceFormat(){return s_efb_depth_surface_Format;}
|
||||||
D3DFORMAT GetEFBColorRTSurfaceFormat(){return s_efb_color_surface_Format;}
|
D3DFORMAT GetEFBColorRTSurfaceFormat(){return s_efb_color_surface_Format;}
|
||||||
|
@ -63,14 +91,9 @@ LPDIRECT3DTEXTURE9 GetEFBColorTexture(const EFBRectangle& sourceRc)
|
||||||
|
|
||||||
LPDIRECT3DTEXTURE9 GetEFBDepthTexture(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;
|
return s_efb_depth_texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Create()
|
void Create()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -79,29 +102,55 @@ void Create()
|
||||||
int target_height = Renderer::GetTargetHeight();
|
int target_height = Renderer::GetTargetHeight();
|
||||||
s_efb_color_surface_Format = D3DFMT_A8R8G8B8;
|
s_efb_color_surface_Format = D3DFMT_A8R8G8B8;
|
||||||
//get the framebuffer texture
|
//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);
|
D3DPOOL_DEFAULT, &s_efb_color_texture, NULL);
|
||||||
CHECK(hr,"Create Color Texture");
|
if(s_efb_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))
|
|
||||||
{
|
{
|
||||||
//get the surface for the peeking texture
|
s_efb_color_texture->GetSurfaceLevel(0,&s_efb_color_surface);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
CHECK(hr,"Create Color Texture");
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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.
|
//Select Zbuffer format supported by hadware.
|
||||||
if (g_ActiveConfig.bEFBAccessEnable)
|
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];
|
D3DFORMAT *DepthTexFormats = new D3DFORMAT[3];
|
||||||
DepthTexFormats[0] = D3DFMT_D32F_LOCKABLE;
|
DepthTexFormats[0] = D3DFMT_D32F_LOCKABLE;
|
||||||
DepthTexFormats[1] = D3DFMT_D16_LOCKABLE;
|
DepthTexFormats[1] = D3DFMT_D16_LOCKABLE;
|
||||||
|
@ -116,7 +165,7 @@ void Create()
|
||||||
s_efb_depth_ReadBuffer = s_efb_depth_surface;
|
s_efb_depth_ReadBuffer = s_efb_depth_surface;
|
||||||
s_efb_depth_OffScreenReadBuffer = s_efb_depth_surface;
|
s_efb_depth_OffScreenReadBuffer = s_efb_depth_surface;
|
||||||
CHECK(hr,"CreateDepthStencilSurface");
|
CHECK(hr,"CreateDepthStencilSurface");
|
||||||
delete [] DepthTexFormats;
|
delete [] DepthTexFormats;*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -129,44 +178,51 @@ void Create()
|
||||||
|
|
||||||
void Destroy()
|
void Destroy()
|
||||||
{
|
{
|
||||||
if(s_efb_depth_ReadBuffer)
|
|
||||||
s_efb_depth_ReadBuffer->Release();
|
|
||||||
s_efb_depth_ReadBuffer = NULL;
|
|
||||||
|
|
||||||
if(s_efb_depth_OffScreenReadBuffer)
|
if(s_efb_depth_surface)
|
||||||
s_efb_depth_OffScreenReadBuffer->Release();
|
s_efb_depth_surface->Release();
|
||||||
|
s_efb_depth_surface=NULL;
|
||||||
|
|
||||||
if(s_efb_depth_surface)
|
if(s_efb_depthColor_surface)
|
||||||
s_efb_depth_surface->Release();
|
s_efb_depthColor_surface->Release();
|
||||||
s_efb_depth_surface = NULL;
|
s_efb_depthColor_surface=NULL;
|
||||||
|
|
||||||
if(s_efb_depthBuffer_texture)
|
if(s_efb_color_surface)
|
||||||
s_efb_depthBuffer_texture->Release();
|
s_efb_color_surface->Release();
|
||||||
s_efb_depthBuffer_texture=NULL;
|
s_efb_color_surface=NULL;
|
||||||
|
|
||||||
if(s_efb_depth_texture)
|
if(s_efb_color_ReadBuffer)
|
||||||
s_efb_depth_texture->Release();
|
s_efb_color_ReadBuffer->Release();
|
||||||
s_efb_depth_texture = NULL;
|
s_efb_color_ReadBuffer=NULL;
|
||||||
|
|
||||||
if(s_efb_color_OffScreenReadBuffer )
|
if(s_efb_depth_ReadBuffer)
|
||||||
s_efb_color_OffScreenReadBuffer->Release();
|
s_efb_depth_ReadBuffer->Release();
|
||||||
s_efb_color_OffScreenReadBuffer = NULL;
|
s_efb_depth_ReadBuffer=NULL;
|
||||||
|
|
||||||
if(s_efb_color_ReadBuffer )
|
if(s_efb_color_OffScreenReadBuffer)
|
||||||
s_efb_color_ReadBuffer->Release();
|
s_efb_color_OffScreenReadBuffer->Release();
|
||||||
s_efb_color_ReadBuffer = NULL;
|
s_efb_color_OffScreenReadBuffer=NULL;
|
||||||
|
|
||||||
if(s_efb_color_surface)
|
if(s_efb_depth_OffScreenReadBuffer)
|
||||||
s_efb_color_surface->Release();
|
s_efb_depth_OffScreenReadBuffer->Release();
|
||||||
s_efb_color_surface = NULL;
|
s_efb_depth_OffScreenReadBuffer=NULL;
|
||||||
|
|
||||||
if(s_efb_colorBuffer_texture)
|
if(s_efb_color_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->Release();
|
||||||
s_efb_color_texture = NULL;
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
|
@ -40,6 +40,7 @@ D3DFORMAT GetEFBDepthRTSurfaceFormat();
|
||||||
D3DFORMAT GetEFBColorRTSurfaceFormat();
|
D3DFORMAT GetEFBColorRTSurfaceFormat();
|
||||||
LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
|
LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
|
||||||
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
|
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
|
||||||
|
LPDIRECT3DSURFACE9 GetEFBDepthEncodedSurface();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,19 @@ PixelShaderCache::PSCache PixelShaderCache::PixelShaders;
|
||||||
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
|
const PixelShaderCache::PSCacheEntry *PixelShaderCache::last_entry;
|
||||||
static float lastPSconstants[C_COLORMATRIX+16][4];
|
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)
|
void SetPSConstant4f(int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
if( lastPSconstants[const_number][0] != f1 || lastPSconstants[const_number][1] != f2 ||
|
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()
|
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();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,6 +112,12 @@ void PixelShaderCache::Clear()
|
||||||
|
|
||||||
void PixelShaderCache::Shutdown()
|
void PixelShaderCache::Shutdown()
|
||||||
{
|
{
|
||||||
|
if(s_ColorMatrixProgram)
|
||||||
|
s_ColorMatrixProgram->Release();
|
||||||
|
s_ColorMatrixProgram = NULL;
|
||||||
|
if(s_ColorCopyProgram)
|
||||||
|
s_ColorCopyProgram->Release();
|
||||||
|
s_ColorCopyProgram=NULL;
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,6 +59,8 @@ public:
|
||||||
static void Clear();
|
static void Clear();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static bool SetShader(bool dstAlpha);
|
static bool SetShader(bool dstAlpha);
|
||||||
|
static LPDIRECT3DPIXELSHADER9 GetColorMatrixProgram();
|
||||||
|
static LPDIRECT3DPIXELSHADER9 GetColorCopyProgram();
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
static std::string GetCurrentShaderCode();
|
static std::string GetCurrentShaderCode();
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -63,6 +63,7 @@ static u32 s_blendMode;
|
||||||
|
|
||||||
char st[32768];
|
char st[32768];
|
||||||
|
|
||||||
|
|
||||||
// State translation lookup tables
|
// State translation lookup tables
|
||||||
static const D3DBLEND d3dSrcFactors[8] =
|
static const D3DBLEND d3dSrcFactors[8] =
|
||||||
{
|
{
|
||||||
|
@ -98,6 +99,7 @@ void SetupDeviceObjects()
|
||||||
PixelShaderManager::Dirty();
|
PixelShaderManager::Dirty();
|
||||||
|
|
||||||
// Tex and shader caches will recreate themselves over time.
|
// Tex and shader caches will recreate themselves over time.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Kill off all POOL_DEFAULT device objects.
|
// Kill off all POOL_DEFAULT device objects.
|
||||||
|
@ -159,15 +161,25 @@ bool Renderer::Init()
|
||||||
|
|
||||||
for (int stage = 0; stage < 8; stage++)
|
for (int stage = 0; stage < 8; stage++)
|
||||||
D3D::SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, g_ActiveConfig.iMaxAnisotropy);
|
D3D::SetSamplerState(stage, D3DSAMP_MAXANISOTROPY, g_ActiveConfig.iMaxAnisotropy);
|
||||||
|
D3DVIEWPORT9 vp;
|
||||||
D3D::dev->Clear(0, NULL, D3DCLEAR_ZBUFFER,D3DCOLOR_XRGB(255,255,255),1.0f,0);
|
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->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
|
||||||
|
|
||||||
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
|
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
|
||||||
|
D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
|
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::dev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x0, 1.0f, 0);
|
||||||
|
|
||||||
D3D::BeginFrame();
|
D3D::BeginFrame();
|
||||||
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
|
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
|
||||||
return true;
|
return true;
|
||||||
|
@ -209,9 +221,9 @@ void dumpMatrix(D3DXMATRIX &mtx)
|
||||||
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
TargetRectangle Renderer::ConvertEFBRectangle(const EFBRectangle& rc)
|
||||||
{
|
{
|
||||||
TargetRectangle result;
|
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.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;
|
result.bottom = (rc.bottom * s_target_height) / EFB_HEIGHT;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -261,31 +273,48 @@ void CheckForResize()
|
||||||
static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
|
static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
|
||||||
{
|
{
|
||||||
// Set the backbuffer as the rendering target
|
// Set the backbuffer as the rendering target
|
||||||
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
|
||||||
D3D::dev->SetDepthStencilSurface(NULL);
|
D3D::dev->SetDepthStencilSurface(NULL);
|
||||||
|
D3D::dev->SetRenderTarget(1, NULL);
|
||||||
|
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
|
||||||
|
|
||||||
// Blit our render target onto the backbuffer.
|
|
||||||
// TODO: Change to a quad so we can do post processing.
|
|
||||||
TargetRectangle src_rect, dst_rect;
|
TargetRectangle src_rect, dst_rect;
|
||||||
src_rect = Renderer::ConvertEFBRectangle(sourceRc);
|
src_rect = Renderer::ConvertEFBRectangle(sourceRc);
|
||||||
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
|
||||||
|
D3DVIEWPORT9 vp;
|
||||||
//LPD3DXSPRITE pSprite=NULL;
|
vp.X = 0;
|
||||||
//D3DXCreateSprite(D3D::dev, &pSprite);
|
vp.Y = 0;
|
||||||
//D3DXVECTOR3 pos(0,0,0);
|
vp.Width = s_backbuffer_width;
|
||||||
//EFBRectangle efbRect;
|
vp.Height = s_backbuffer_height;
|
||||||
//
|
vp.MinZ = 0.0f;
|
||||||
//pSprite->Begin(D3DXSPRITE_ALPHABLEND);
|
vp.MaxZ = 0.0f;
|
||||||
//pSprite->Draw(FBManager::GetEFBColorTexture(efbRect),NULL, NULL, &pos, 0xFFFFFFFF);
|
D3D::dev->SetViewport(&vp);
|
||||||
//pSprite->End();
|
|
||||||
//pSprite->Release();
|
|
||||||
|
|
||||||
D3D::dev->Clear(0,NULL, D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0);
|
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
|
EFBRectangle efbRect;
|
||||||
D3D::dev->StretchRect(FBManager::GetEFBColorRTSurface(), src_rect.AsRECT(),
|
|
||||||
D3D::GetBackBufferSurface(), dst_rect.AsRECT(),
|
|
||||||
D3DTEXF_LINEAR);
|
|
||||||
|
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
|
// Finish up the current frame, print some stats
|
||||||
if (g_ActiveConfig.bOverlayStats)
|
if (g_ActiveConfig.bOverlayStats)
|
||||||
|
@ -301,14 +330,11 @@ static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
|
||||||
|
|
||||||
OSD::DrawMessages();
|
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(0, FBManager::GetEFBColorRTSurface());
|
||||||
|
D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
|
||||||
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
|
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
|
||||||
|
|
||||||
|
VertexShaderManager::SetViewportChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -386,10 +412,11 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
D3D::EndFrame();
|
Renderer::ResetAPIState();
|
||||||
D3DDumpFrame();
|
D3DDumpFrame();
|
||||||
EFBTextureToD3DBackBuffer(sourceRc);
|
EFBTextureToD3DBackBuffer(sourceRc);
|
||||||
D3D::BeginFrame();
|
D3D::EndFrame();
|
||||||
|
|
||||||
|
|
||||||
DEBUGGER_LOG_AT((NEXT_XFB_CMD|NEXT_EFB_CMD|NEXT_FRAME),
|
DEBUGGER_LOG_AT((NEXT_XFB_CMD|NEXT_EFB_CMD|NEXT_FRAME),
|
||||||
{printf("StretchRect, EFB->XFB\n");});
|
{printf("StretchRect, EFB->XFB\n");});
|
||||||
|
@ -399,21 +426,12 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
|
||||||
xfbAddr, fbWidth, fbHeight,
|
xfbAddr, fbWidth, fbHeight,
|
||||||
sourceRc.left, sourceRc.top, sourceRc.right, sourceRc.bottom);}
|
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
|
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
|
// until the XFB pointer is updated by VI
|
||||||
D3D::SetRenderState(D3DRS_SCISSORTESTENABLE, true);
|
D3D::BeginFrame();
|
||||||
|
Renderer::RestoreAPIState();
|
||||||
|
UpdateViewport();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Renderer::SetScissorRect()
|
bool Renderer::SetScissorRect()
|
||||||
|
@ -432,10 +450,27 @@ bool Renderer::SetScissorRect()
|
||||||
rc.bottom = (int)(rc.bottom * yScale);
|
rc.bottom = (int)(rc.bottom * yScale);
|
||||||
|
|
||||||
if (rc.left < 0) rc.left = 0;
|
if (rc.left < 0) rc.left = 0;
|
||||||
|
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.right > s_target_width) rc.right = s_target_width;
|
||||||
if (rc.top < 0) rc.top = 0;
|
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;
|
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)
|
if (rc.right >= rc.left && rc.bottom >= rc.top)
|
||||||
{
|
{
|
||||||
D3D::dev->SetScissorRect(&rc);
|
D3D::dev->SetScissorRect(&rc);
|
||||||
|
@ -446,6 +481,7 @@ bool Renderer::SetScissorRect()
|
||||||
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 false;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::SetColorMask()
|
void Renderer::SetColorMask()
|
||||||
|
@ -460,10 +496,9 @@ void Renderer::SetColorMask()
|
||||||
|
|
||||||
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
{
|
{
|
||||||
|
|
||||||
//Get the working buffer
|
//Get the working buffer
|
||||||
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
LPDIRECT3DSURFACE9 pBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
||||||
FBManager::GetEFBDepthRTSurface() : FBManager::GetEFBColorRTSurface();
|
FBManager::GetEFBDepthEncodedSurface() : FBManager::GetEFBColorRTSurface();
|
||||||
//get the temporal buffer to move 1pixel data
|
//get the temporal buffer to move 1pixel data
|
||||||
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
LPDIRECT3DSURFACE9 RBuffer = (type == PEEK_Z || type == POKE_Z) ?
|
||||||
FBManager::GetEFBDepthReadSurface() : FBManager::GetEFBColorReadSurface();
|
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");
|
PanicAlert("No %s!", (type == PEEK_Z || type == POKE_Z) ? "Z-Buffer" : "Color EFB");
|
||||||
return 0;
|
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.
|
// Get the rectangular target region covered by the EFB pixel.
|
||||||
|
|
||||||
EFBRectangle efbPixelRc;
|
EFBRectangle efbPixelRc;
|
||||||
|
@ -506,11 +536,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
RectToLock.right = targetPixelRc.right;
|
RectToLock.right = targetPixelRc.right;
|
||||||
RectToLock.top = targetPixelRc.top;
|
RectToLock.top = targetPixelRc.top;
|
||||||
|
|
||||||
//lock the buffer
|
|
||||||
|
|
||||||
if(!(BufferFormat == D3DFMT_D32F_LOCKABLE || BufferFormat == D3DFMT_D16_LOCKABLE))
|
|
||||||
{
|
|
||||||
//the hard support stretchrect in both color and z so use it
|
|
||||||
hr = D3D::dev->StretchRect(pBuffer,&RectToLock,RBuffer,NULL, D3DTEXF_NONE);
|
hr = D3D::dev->StretchRect(pBuffer,&RectToLock,RBuffer,NULL, D3DTEXF_NONE);
|
||||||
if(FAILED(hr))
|
if(FAILED(hr))
|
||||||
{
|
{
|
||||||
|
@ -529,7 +554,7 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
RectToLock.left = 0;
|
RectToLock.left = 0;
|
||||||
RectToLock.right = 1;
|
RectToLock.right = 1;
|
||||||
RectToLock.top = 0;
|
RectToLock.top = 0;
|
||||||
}
|
|
||||||
//the surface is good.. lock it
|
//the surface is good.. lock it
|
||||||
if((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
|
if((hr = pOffScreenBuffer->LockRect(&drect, &RectToLock, D3DLOCK_READONLY)) != D3D_OK)
|
||||||
{
|
{
|
||||||
|
@ -541,24 +566,17 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
switch(type) {
|
switch(type) {
|
||||||
case PEEK_Z:
|
case PEEK_Z:
|
||||||
{
|
{
|
||||||
switch (BufferFormat)
|
static float ffrac = 255.0f/254.0f;
|
||||||
{
|
z = ((u32 *)drect.pBits)[0];
|
||||||
case D3DFMT_D32F_LOCKABLE:
|
float fvalue = (((float)(z & 0xFF)) / 255.0f) * ffrac;
|
||||||
val = ((float *)drect.pBits)[0];
|
fvalue += (((float)((z>>8) & 0xFF)) / 255.0f) * (ffrac/255.0f);
|
||||||
z = ((u32)(val * 0xffffff));// 0xFFFFFFFF;
|
fvalue += (((float)((z>>16) & 0xFF)) / 255.0f) * (ffrac/(255.0f*255.0f));
|
||||||
break;
|
fvalue += (((float)((z>>24) & 0xFF)) / 255.0f) * (ffrac/(255.0f*255.0f*255.0f));
|
||||||
case D3DFMT_D16_LOCKABLE:
|
if(fvalue>1.0f)fvalue=1.0f;
|
||||||
val = ((float)((u16 *)drect.pBits)[0])/((float)0xFFFF);
|
if(fvalue<0.0f)fvalue=0.0f;
|
||||||
z = ((u32)(val * 0xffffff));
|
z = ((u32)(fvalue * 0xffffff));
|
||||||
break;
|
|
||||||
default:
|
|
||||||
z = ((u32 *)drect.pBits)[0] >> 8;
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
// [0.0, 1.0] ==> [0, 0xFFFFFFFF]
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
case POKE_Z:
|
case POKE_Z:
|
||||||
// TODO: Get that Z value to poke from somewhere
|
// TODO: Get that Z value to poke from somewhere
|
||||||
//((float *)drect.pBits)[0] = val;
|
//((float *)drect.pBits)[0] = val;
|
||||||
|
@ -568,7 +586,6 @@ u32 Renderer::AccessEFB(EFBAccessType type, int x, int y)
|
||||||
case PEEK_COLOR:
|
case PEEK_COLOR:
|
||||||
z = ((u32 *)drect.pBits)[0];
|
z = ((u32 *)drect.pBits)[0];
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POKE_COLOR:
|
case POKE_COLOR:
|
||||||
// TODO: Get that ARGB value to poke from somewhere
|
// TODO: Get that ARGB value to poke from somewhere
|
||||||
//((float *)drect.pBits)[0] = val;
|
//((float *)drect.pBits)[0] = val;
|
||||||
|
@ -578,8 +595,6 @@ 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
|
// TODO: in RE0 this value is often off by one, which causes lighting to disappear
|
||||||
return z;
|
return z;
|
||||||
|
|
||||||
|
@ -605,6 +620,14 @@ void UpdateViewport()
|
||||||
vp.Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * MValueY);
|
vp.Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * MValueY);
|
||||||
vp.Width = (int)ceil(abs((int)(2 * xfregs.rawViewport[0])) * MValueX);
|
vp.Width = (int)ceil(abs((int)(2 * xfregs.rawViewport[0])) * MValueX);
|
||||||
vp.Height = (int)ceil(abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
|
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
|
//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.MinZ = 0.0f;//(xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777216.0f;
|
||||||
vp.MaxZ = 1.0f;//xfregs.rawViewport[5] / 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
|
// Flip/present backbuffer to frontbuffer here
|
||||||
D3D::Present();
|
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);
|
||||||
|
}
|
||||||
|
|
|
@ -27,7 +27,12 @@
|
||||||
|
|
||||||
#include "D3DBase.h"
|
#include "D3DBase.h"
|
||||||
#include "D3DTexture.h"
|
#include "D3DTexture.h"
|
||||||
|
#include "D3DUtil.h"
|
||||||
#include "FramebufferManager.h"
|
#include "FramebufferManager.h"
|
||||||
|
#include "PixelShaderCache.h"
|
||||||
|
#include "PixelShaderManager.h"
|
||||||
|
#include "VertexShaderManager.h"
|
||||||
|
#include "VertexShaderCache.h"
|
||||||
|
|
||||||
#include "Render.h"
|
#include "Render.h"
|
||||||
|
|
||||||
|
@ -257,9 +262,12 @@ TextureCache::TCacheEntry *TextureCache::Load(int stage, u32 address, int width,
|
||||||
return &entry;
|
return &entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef CHECK
|
||||||
|
#define CHECK(hr) if (FAILED(hr)) { PanicAlert(__FUNCTION__ " FAIL"); }
|
||||||
// EXTREMELY incomplete.
|
// EXTREMELY incomplete.
|
||||||
void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, bool bIsIntensityFmt, u32 copyfmt, int bScaleByHalf, const EFBRectangle &source_rect)
|
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_w = source_rect.GetWidth();
|
||||||
int efb_h = source_rect.GetHeight();
|
int efb_h = source_rect.GetHeight();
|
||||||
|
|
||||||
|
@ -271,19 +279,20 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
|
||||||
iter = textures.find(address);
|
iter = textures.find(address);
|
||||||
if (iter != textures.end())
|
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
|
// Remove it and recreate it as a render target
|
||||||
iter->second.texture->Release();
|
iter->second.texture->Release();
|
||||||
iter->second.texture = 0;
|
iter->second.texture = 0;
|
||||||
textures.erase(iter);
|
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.frameCount = frameCount;
|
||||||
entry.w = tex_w;
|
entry.w = tex_w;
|
||||||
entry.h = tex_h;
|
entry.h = tex_h;
|
||||||
|
entry.fmt = copyfmt;
|
||||||
|
|
||||||
D3D::dev->CreateTexture(tex_w, tex_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0);
|
hr = D3D::dev->CreateTexture(tex_w, tex_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0);
|
||||||
|
CHECK(hr);
|
||||||
textures[address] = entry;
|
textures[address] = entry;
|
||||||
tex = entry.texture;
|
tex = entry.texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
have_texture:
|
have_texture:
|
||||||
TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
/*TargetRectangle targetSource = Renderer::ConvertEFBRectangle(source_rect);
|
||||||
RECT source_rc;
|
RECT source_rc;
|
||||||
source_rc.left = targetSource.left;
|
source_rc.left = targetSource.left;
|
||||||
source_rc.top = targetSource.top;
|
source_rc.top = targetSource.top;
|
||||||
|
@ -317,8 +328,162 @@ have_texture:
|
||||||
srcSurface = FBManager::GetEFBColorRTSurface();
|
srcSurface = FBManager::GetEFBColorRTSurface();
|
||||||
D3D::dev->StretchRect(srcSurface, &source_rc, destSurface, &dest_rc, D3DTEXF_LINEAR);
|
D3D::dev->StretchRect(srcSurface, &source_rc, destSurface, &dest_rc, D3DTEXF_LINEAR);
|
||||||
destSurface->Release();
|
destSurface->Release();
|
||||||
|
return;*/
|
||||||
|
float colmat[16]= {0.0f};
|
||||||
|
float fConstAdd[4] = {0.0f};
|
||||||
|
|
||||||
DEBUGGER_LOG_AT((NEXT_XFB_CMD|NEXT_EFB_CMD|NEXT_FRAME|NEXT_NEW_TEXTURE|NEXT_FLUSH),
|
if (bFromZBuffer)
|
||||||
{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);
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,13 @@ const VertexShaderCache::VSCacheEntry *VertexShaderCache::last_entry;
|
||||||
|
|
||||||
static float GC_ALIGNED16(lastVSconstants[C_FOGPARAMS+8][4]);
|
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)
|
void SetVSConstant4f(int const_number, float f1, float f2, float f3, float f4)
|
||||||
{
|
{
|
||||||
if (lastVSconstants[const_number][0] != f1 ||
|
if (lastVSconstants[const_number][0] != f1 ||
|
||||||
|
@ -121,6 +128,21 @@ void SetMultiVSConstant4fv(int const_number, int count, const float *f)
|
||||||
|
|
||||||
void VertexShaderCache::Init()
|
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();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,6 +160,8 @@ void VertexShaderCache::Clear()
|
||||||
|
|
||||||
void VertexShaderCache::Shutdown()
|
void VertexShaderCache::Shutdown()
|
||||||
{
|
{
|
||||||
|
if(SimpleVertexSahder)
|
||||||
|
SimpleVertexSahder->Release();
|
||||||
Clear();
|
Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ public:
|
||||||
static void Cleanup();
|
static void Cleanup();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
static bool SetShader(u32 components);
|
static bool SetShader(u32 components);
|
||||||
|
static LPDIRECT3DVERTEXSHADER9 GetSimpleVertexSahder();
|
||||||
#if defined(_DEBUG) || defined(DEBUGFAST)
|
#if defined(_DEBUG) || defined(DEBUGFAST)
|
||||||
static std::string GetCurrentShaderCode();
|
static std::string GetCurrentShaderCode();
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue