mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
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, " 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");
|
||||
|
||||
// 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...
|
||||
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)
|
||||
WRITE(p, "depth = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w);\n");
|
||||
else
|
||||
WRITE(p, "depth = zCoord;\n");
|
||||
WRITE(p, "zCoord = frac(dot("I_ZBIAS"[0].xyzw, textemp.xyzw) + "I_ZBIAS"[1].w);\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 (!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)
|
||||
{
|
||||
if (!decl) {
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
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))
|
||||
if(s_efb_color_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_color_texture->GetSurfaceLevel(0,&s_efb_color_surface);
|
||||
}
|
||||
CHECK(hr,"Create Color Texture");
|
||||
hr = D3D::dev->CreateTexture(1, 1, 1, D3DUSAGE_RENDERTARGET, s_efb_color_surface_Format,
|
||||
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.
|
||||
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
|
@ -40,6 +40,7 @@ D3DFORMAT GetEFBDepthRTSurfaceFormat();
|
||||
D3DFORMAT GetEFBColorRTSurfaceFormat();
|
||||
LPDIRECT3DSURFACE9 GetEFBColorReadSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthReadSurface();
|
||||
LPDIRECT3DSURFACE9 GetEFBDepthEncodedSurface();
|
||||
|
||||
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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};
|
||||
|
||||
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);
|
||||
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;
|
||||
|
||||
|
||||
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 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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user