Well this commit has 2 parts:

first part if fixing, fixed, i thing, the flickering that everyone has reported, at least in my case i only have flickering in the one texture in one game and now is fixed. The other fix is not for an reported issue, is more a correctness fix, running dolphin with pix to review debug errors, result in a ton of warnings and error, now with this commit, at least for ati, there no more error or warnings, this means, correct management and state change, no accurate emulation, for this still a lot of work to do.
for this part of the commit please give me feedback and let me know of remaining issues

Te second part is the partial implementation of efb to ram copy in d3d, this won't brake anything because is commented but i commit this to ask for help from ector and donko in some errors remaining in the implementation related to differences between opengl an d3d.
if you want to test this you have to uncomment line 150 to 155 of bpstruct.cpp

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@4594 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado
2009-11-20 18:46:30 +00:00
parent 47f3c5bc31
commit 802c112ad9
9 changed files with 324 additions and 277 deletions

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9.00"
Version="9,00"
Name="Plugin_VideoDX9"
ProjectGUID="{636FAD5F-02D1-4E9A-BE67-FB8EA99B9A18}"
RootNamespace="Plugin_VideoDX9"
@ -1276,6 +1276,14 @@
RelativePath=".\Src\D3DUtil.h"
>
</File>
<File
RelativePath=".\Src\TextureConverter.cpp"
>
</File>
<File
RelativePath=".\Src\TextureConverter.h"
>
</File>
</Filter>
<Filter
Name="UI"

View File

@ -24,6 +24,7 @@
#include "VertexShaderManager.h"
#include "Utils.h"
#include "debugger/debugger.h"
#include "TextureConverter.h"
bool textureChanged[8];
@ -145,24 +146,24 @@ void CopyEFB(const BPCmd &bp, const EFBRectangle &rc, const u32 &address, const
{
if (!g_ActiveConfig.bEFBCopyDisable)
{
//if (g_ActiveConfig.bCopyEFBToRAM)
//uncomment this to see the efb to ram work in progress
/*if (g_ActiveConfig.bCopyEFBToRAM)
{
// To RAM, not implemented yet
//TextureConverter::EncodeToRam(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
//else // To D3D Texture
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
DEBUGGER_PAUSE_LOG_AT(NEXT_EFB_CMD,false,
{printf("EFB to texture: addr = %08X\n",address);});
TextureConverter::EncodeToRam(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
}
else // To D3D Texture*/
{
TextureCache::CopyRenderTargetToTexture(address, fromZBuffer, isIntensityFmt, copyfmt, scaleByHalf, rc);
}
}
}
void ClearScreen(const BPCmd &bp, const EFBRectangle &rc)
{
// TODO: Scale EFBRectangle correctly
// it seems that the GC is able to alpha blend on color-fill
// we cant do that so if alpha is != 255 we skip it
VertexShaderManager::SetViewportChanged();
bool colorEnable = bpmem.blendmode.colorupdate;
bool alphaEnable = (bpmem.zcontrol.pixel_format == PIXELFMT_RGBA6_Z24 && bpmem.blendmode.alphaupdate);

View File

@ -189,9 +189,9 @@ const int TS[6][2] =
static DWORD RS_old[6];
static DWORD TS_old[6];
static LPDIRECT3DBASETEXTURE9 texture_old;
static LPDIRECT3DPIXELSHADER9 ps_old;
static LPDIRECT3DVERTEXSHADER9 vs_old;
static LPDIRECT3DBASETEXTURE9 texture_old = NULL;
static LPDIRECT3DPIXELSHADER9 ps_old = NULL;
static LPDIRECT3DVERTEXSHADER9 vs_old = NULL;
void SaveRenderStates()
{
@ -397,7 +397,7 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
IDirect3DVertexShader9 *Vshader)
{
SaveRenderStates();
D3D::SetTexture(0, 0);
//float span = ((rSource->right-rSource->left - 1.0f) * (rDest->right - rDest->left))/(SourceWidth*((rDest->right - rDest->left)-1.0f));
float u1=((float)rSource->left+1.0f)/(float) SourceWidth;//*/((0.5f+rSource->left)/(float) SourceWidth)-(span*0.5f/(float)(rDest->right - rDest->left));
float u2=((float)rSource->right-1.0f)/(float) SourceWidth;;//*/u1+span;
@ -419,6 +419,24 @@ void drawShadedTexQuad(IDirect3DTexture9 *texture,
D3D::RefreshVertexDeclaration();
RestoreRenderStates();
}
}
void drawColoredQuad(const RECT *rDest, u32 Color)
{
SaveRenderStates();
struct Q2DVertex { float x,y,z,rhw;u32 Color; } coords[4] = {
{(float)rDest->left-0.5f, (float)rDest->top-0.5f, 0.0f, 1.0f, Color},
{(float)rDest->right-0.5f, (float)rDest->top-0.5f, 0.0f,1.0f, Color},
{(float)rDest->right-0.5f, (float)rDest->bottom-0.5f, 0.0f,1.0f, Color},
{(float)rDest->left-0.5f, (float)rDest->bottom-0.5f, 0.0f,1.0f, Color}
};
dev->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE);
dev->SetVertexShader(0);
dev->SetPixelShader(0);
dev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, coords, sizeof(Q2DVertex));
D3D::RefreshVertexDeclaration();
RestoreRenderStates();
}
} // namespace

View File

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

View File

@ -188,7 +188,7 @@ void Create()
D3DMULTISAMPLE_NONE, 0, FALSE, &s_efb_depth_surface, NULL);
CHECK(hr,"CreateDepthStencilSurface");
//ULTRAAAAAAAAAAA ugly hack when no depth textures are supported
s_efb_depthColor_surface = s_efb_color_surface;
//s_efb_depthColor_surface = s_efb_color_surface;
}
}

View File

@ -41,6 +41,7 @@
#include "OnScreenDisplay.h"
#include "FramebufferManager.h"
#include "Fifo.h"
#include "TextureConverter.h"
#include "debugger/debugger.h"
@ -97,7 +98,7 @@ void SetupDeviceObjects()
VertexShaderManager::Dirty();
PixelShaderManager::Dirty();
TextureConverter::Init();
// Tex and shader caches will recreate themselves over time.
}
@ -114,6 +115,7 @@ void TeardownDeviceObjects()
VertexLoaderManager::Shutdown();
VertexShaderCache::Clear();
PixelShaderCache::Clear();
TextureConverter::Shutdown();
}
bool Renderer::Init()
@ -167,7 +169,7 @@ bool Renderer::Init()
vp.Width = s_backbuffer_width;
vp.Height = s_backbuffer_height;
vp.MinZ = 0.0f;
vp.MaxZ = 0.0f;
vp.MaxZ = 1.0f;
D3D::dev->SetViewport(&vp);
D3D::dev->Clear(0, NULL, D3DCLEAR_TARGET, 0x0, 0, 0);
@ -177,8 +179,6 @@ bool Renderer::Init()
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();
@ -273,12 +273,6 @@ void CheckForResize()
static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
{
// Set the backbuffer as the rendering target
D3D::dev->SetDepthStencilSurface(NULL);
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, NULL);
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
TargetRectangle src_rect, dst_rect;
src_rect = Renderer::ConvertEFBRectangle(sourceRc);
ComputeDrawRectangle(s_backbuffer_width, s_backbuffer_height, false, &dst_rect);
@ -288,21 +282,33 @@ static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
vp.Width = s_backbuffer_width;
vp.Height = s_backbuffer_height;
vp.MinZ = 0.0f;
vp.MaxZ = 0.0f;
vp.MaxZ = 1.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;
int X = dst_rect.left;
int Y = dst_rect.top;
int Width = dst_rect.right - dst_rect.left;
int Height = dst_rect.bottom - dst_rect.top;
if(X < 0) X = 0;
if(Y < 0) Y = 0;
if(X > s_backbuffer_width) X = s_backbuffer_width;
if(Y > s_backbuffer_height) Y = s_backbuffer_height;
if(Width < 0) Width = 0;
if(Height < 0) Height = 0;
if(Width > (s_backbuffer_width - X)) Width = s_backbuffer_width - X;
if(Height > (s_backbuffer_height - Y)) Height = s_backbuffer_height - Y;
vp.X = X;
vp.Y = Y;
vp.Width = Width;
vp.Height = Height;
vp.MinZ = 0.0f;
vp.MaxZ = 0.0f;
vp.MaxZ = 1.0f;
D3D::dev->SetViewport(&vp);
EFBRectangle efbRect;
EFBRectangle efbRect;
LPDIRECT3DTEXTURE9 read_texture = FBManager::GetEFBColorTexture(efbRect);
RECT destinationrect;
@ -331,13 +337,6 @@ static void EFBTextureToD3DBackBuffer(const EFBRectangle& sourceRc)
}
OSD::DrawMessages();
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
VertexShaderManager::SetViewportChanged();
}
@ -414,8 +413,13 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
DEBUGGER_PAUSE_LOG_AT(NEXT_XFB_CMD,false,{printf("RenderToXFB - disabled");});
return;
}
Renderer::ResetAPIState();
// Set the backbuffer as the rendering target
D3D::dev->SetDepthStencilSurface(NULL);
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, NULL);
D3D::dev->SetRenderTarget(0, D3D::GetBackBufferSurface());
D3DDumpFrame();
EFBTextureToD3DBackBuffer(sourceRc);
D3D::EndFrame();
@ -433,7 +437,12 @@ void Renderer::RenderToXFB(u32 xfbAddr, u32 fbWidth, u32 fbHeight, const EFBRect
// until the XFB pointer is updated by VI
D3D::BeginFrame();
Renderer::RestoreAPIState();
UpdateViewport();
D3D::dev->SetRenderTarget(0, FBManager::GetEFBColorRTSurface());
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, FBManager::GetEFBDepthEncodedSurface());
D3D::dev->SetDepthStencilSurface(FBManager::GetEFBDepthRTSurface());
UpdateViewport();
VertexShaderManager::SetViewportChanged();
}
@ -460,20 +469,7 @@ bool Renderer::SetScissorRect()
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);
@ -482,14 +478,14 @@ bool Renderer::SetScissorRect()
else
{
WARN_LOG(VIDEO, "Bad scissor rectangle: %i %i %i %i", rc.left, rc.top, rc.right, rc.bottom);
rc.left = 0;
/*rc.left = 0;
rc.top = 0;
rc.right = GetTargetWidth();
rc.bottom = GetTargetHeight();
D3D::dev->SetScissorRect(&rc);
D3D::dev->SetScissorRect(&rc);*/
return false;
}
return true;
return false;
}
void Renderer::SetColorMask()
@ -644,18 +640,23 @@ void UpdateViewport()
D3DVIEWPORT9 vp;
// Stretch picture with increased internal resolution
vp.X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * MValueX);
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;
int X = (int)(ceil(xfregs.rawViewport[3] - xfregs.rawViewport[0] - (scissorXOff)) * MValueX);
int Y = (int)(ceil(xfregs.rawViewport[4] + xfregs.rawViewport[1] - (scissorYOff)) * MValueY);
int Width = (int)ceil(abs((int)(2 * xfregs.rawViewport[0])) * MValueX);
int Height = (int)ceil(abs((int)(2 * xfregs.rawViewport[1])) * MValueY);
if(X < 0) X = 0;
if(Y < 0) Y = 0;
if(X > s_target_width) X = s_target_width;
if(Y > s_target_height) Y = s_target_height;
if(Width < 0) Width = 0;
if(Height < 0) Height = 0;
if(Width > (s_target_width - X)) Width = s_target_width - X;
if(Height > (s_target_height - Y)) Height = s_target_height - Y;
vp.X = X;
vp.Y = Y;
vp.Width = Width;
vp.Height = Height;
//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;
@ -664,28 +665,6 @@ void UpdateViewport()
void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaEnable, bool zEnable, u32 color, u32 z)
{
// Update the view port for clearing the picture
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = Renderer::GetTargetWidth();
vp.Height = Renderer::GetTargetHeight();
vp.MinZ = 0.0;
vp.MaxZ = 1.0;
D3D::dev->SetViewport(&vp);
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
// Always set the scissor in case it was set by the game and has not been reset
RECT sirc;
sirc.left = targetRc.left;
sirc.top = targetRc.top;
sirc.right = targetRc.right;
sirc.bottom = targetRc.bottom;
D3D::dev->SetScissorRect(&sirc);
VertexShaderManager::SetViewportChanged();
DWORD clearflags = 0;
if(colorEnable)
{
@ -695,8 +674,31 @@ void Renderer::ClearScreen(const EFBRectangle& rc, bool colorEnable, bool alphaE
{
clearflags |= D3DCLEAR_ZBUFFER;
}
if(clearflags)
{
// Update the view port for clearing the picture
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = Renderer::GetTargetWidth();
vp.Height = Renderer::GetTargetHeight();
vp.MinZ = 0.0;
vp.MaxZ = 1.0;
D3D::dev->SetViewport(&vp);
D3D::dev->Clear(0, NULL, clearflags, color,(z & 0xFFFFFF) / float(0xFFFFFF), 0);
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
// Always set the scissor in case it was set by the game and has not been reset
RECT sirc;
sirc.left = targetRc.left;
sirc.top = targetRc.top;
sirc.right = targetRc.right;
sirc.bottom = targetRc.bottom;
D3D::dev->SetScissorRect(&sirc);
D3D::dev->Clear(0, NULL, clearflags, color,(z & 0xFFFFFF) / float(0xFFFFFF), 0);
SetScissorRect();
VertexShaderManager::SetViewportChanged();
}
}
void Renderer::SetBlendMode(bool forceUpdate)

View File

@ -288,12 +288,8 @@ 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();
@ -330,8 +326,7 @@ void TextureCache::CopyRenderTargetToTexture(u32 address, bool bFromZBuffer, boo
entry.h = tex_h;
entry.fmt = copyfmt;
hr = D3D::dev->CreateTexture(tex_w, tex_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0);
CHECK(hr);
D3D::dev->CreateTexture(tex_w, tex_h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &entry.texture, 0);
textures[address] = entry;
tex = entry.texture;
}
@ -451,8 +446,7 @@ have_texture:
// 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);
tex->GetSurfaceLevel(0,&Rendersurf);
D3D::dev->SetDepthStencilSurface(NULL);
if(D3D::GetCaps().NumSimultaneousRTs > 1)
D3D::dev->SetRenderTarget(1, NULL);
@ -467,8 +461,7 @@ have_texture:
vp.Height = tex_h;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
hr = D3D::dev->SetViewport(&vp);
CHECK(hr);
D3D::dev->SetViewport(&vp);
RECT destrect;
destrect.bottom = tex_h;
destrect.left = 0;