more bug fix in dx11:

fixed screen clearing and simplify drawClearQuad a little
put some nice code from dx11 that i like in dx9.
modify plugin spec preparing for implementing efb poke (is not used often but is a missing functionality so..)
please test.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5710 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado 2010-06-15 21:19:09 +00:00
parent 4464c11457
commit cb1694252b
13 changed files with 58 additions and 50 deletions

View File

@ -32,7 +32,7 @@ typedef void (__cdecl* TVideo_EnterLoop)();
typedef void (__cdecl* TVideo_ExitLoop)();
typedef void (__cdecl* TVideo_SetRendering)(bool bEnabled);
typedef void (__cdecl* TVideo_AddMessage)(const char* pstr, unsigned int milliseconds);
typedef u32 (__cdecl* TVideo_AccessEFB)(EFBAccessType, u32, u32);
typedef u32 (__cdecl* TVideo_AccessEFB)(EFBAccessType, u32, u32, u32);
typedef void (__cdecl* TVideo_Read16)(u16& _rReturnValue, const u32 _Address);
typedef void (__cdecl* TVideo_Write16)(const u16 _Data, const u32 _Address);
typedef void (__cdecl* TVideo_Read32)(u32& _rReturnValue, const u32 _Address);

View File

@ -136,10 +136,10 @@ u32 EFB_Read(const u32 addr)
int y = (addr >> 12) & 0x3ff;
if (addr & 0x00400000) {
var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(PEEK_Z, x, y);
var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(PEEK_Z, x, y, 0);
DEBUG_LOG(MEMMAP, "EFB Z Read @ %i, %i\t= 0x%08x", x, y, var);
} else {
var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(PEEK_COLOR, x, y);
var = CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(PEEK_COLOR, x, y, 0);
DEBUG_LOG(MEMMAP, "EFB Color Read @ %i, %i\t= 0x%08x", x, y, var);
}
@ -235,10 +235,10 @@ inline void WriteToHardware(u32 em_address, const T data, u32 effective_address,
int y = (em_address >> 12) & 0x3ff;
// TODO figure out a way to send data without falling into the template trap
if (em_address & 0x00400000) {
CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(POKE_Z, x, y);
CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(POKE_Z, x, y, (u32)data);
DEBUG_LOG(MEMMAP, "EFB Z Write %08x @ %i, %i", data, x, y);
} else {
CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(POKE_COLOR, x, y);
CPluginManager::GetInstance().GetVideo()->Video_AccessEFB(POKE_COLOR, x, y,(u32)data);
DEBUG_LOG(MEMMAP, "EFB Color Write %08x @ %i, %i", data, x, y);
}
return;

View File

@ -133,7 +133,7 @@ EXPORT void CALL Video_EndField();
// input: type of access (r/w, z/color, ...), x coord, y coord
// output: response to the access request (ex: peek z data at specified coord)
//
EXPORT u32 CALL Video_AccessEFB(EFBAccessType type, u32 x, u32 y);
EXPORT u32 CALL Video_AccessEFB(EFBAccessType type, u32 x, u32 y,u32 InputData);
// __________________________________________________________________________________________________
// Function: Video_Screenshot

View File

@ -77,7 +77,7 @@ EmuGfxState::EmuGfxState() : vertexshader(NULL), vsbytecode(NULL), pixelshader(N
depthdesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
// this probably must be changed once multisampling support gets added
rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0, false, false, false, false);
rastdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0, false, true, false, false);
pscbuf = NULL;
vscbuf = NULL;

View File

@ -420,7 +420,7 @@ ID3D11Buffer* clearvb = NULL;
typedef struct { float x,y,z,u,v; } STQVertex;
typedef struct { float x,y,z,u,v; } STSQVertex;
typedef struct { float x,y,z; float col[4];} ClearVertex;
typedef struct { float x,y,z; u32 col;} ClearVertex;
void InitUtils()
{
@ -575,16 +575,11 @@ void drawClearQuad(u32 Color, float z, ID3D11PixelShader* PShader, ID3D11VertexS
if (lastcol != Color || lastz != z)
{
float col[4];
col[0] = (float)((Color & 0xFF) << 24);
col[1] = (float)((Color & 0xFF00) << 8);
col[2] = (float)((Color & 0xFF0000) >> 8);
col[3] = (float)((Color & 0xFF000000) >> 24);
ClearVertex coords[4] = {
{-1.0f, 1.0f, z, {col[0],col[1],col[2],col[3]}},
{ 1.0f, 1.0f, z, {col[0],col[1],col[2],col[3]}},
{-1.0f, -1.0f, z, {col[0],col[1],col[2],col[3]}},
{ 1.0f, -1.0f, z, {col[0],col[1],col[2],col[3]}},
{-1.0f, 1.0f, z, Color},
{ 1.0f, 1.0f, z, Color},
{-1.0f, -1.0f, z, Color},
{ 1.0f, -1.0f, z, Color},
};
D3D11_MAPPED_SUBRESOURCE map;

View File

@ -240,19 +240,20 @@ void SetupDeviceObjects()
D3D11_DEPTH_STENCIL_DESC ddesc;
ddesc.DepthEnable = FALSE;
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ZERO;
ddesc.DepthFunc = D3D11_COMPARISON_ALWAYS;
ddesc.StencilEnable = FALSE;
ddesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
ddesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;
D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[0]);
ddesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
ddesc.DepthEnable = TRUE;
D3D::device->CreateDepthStencilState(&ddesc, &cleardepthstates[1]);
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[0], "depth state for Renderer::ClearScreen (depth buffer disabled)");
D3D::SetDebugObjectName((ID3D11DeviceChild*)cleardepthstates[1], "depth state for Renderer::ClearScreen (depth buffer enabled)");
// TODO: once multisampling gets implemented, this might need to be changed
D3D11_RASTERIZER_DESC rdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, false, false, false);
D3D11_RASTERIZER_DESC rdesc = CD3D11_RASTERIZER_DESC(D3D11_FILL_SOLID, D3D11_CULL_NONE, false, 0, 0.f, 0.f, false, true, false, false);
D3D::device->CreateRasterizerState(&rdesc, &clearraststate);
D3D::SetDebugObjectName((ID3D11DeviceChild*)clearraststate, "rasterizer state for Renderer::ClearScreen");
@ -739,15 +740,15 @@ 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
D3D11_VIEWPORT vp = CD3D11_VIEWPORT(0.f, 0.f, (float)Renderer::GetFullTargetWidth(), (float)Renderer::GetFullTargetHeight());
D3D::context->RSSetViewports(1, &vp);
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
// update the view port for clearing the picture
D3D11_VIEWPORT vp = CD3D11_VIEWPORT((float)targetRc.left, (float)targetRc.top, (float)targetRc.GetWidth(), (float)targetRc.GetHeight(),
0.f,
1.f);
D3D::context->RSSetViewports(1, &vp);
// always set the scissor in case it was set by the game and has not been reset
// TODO: Do we really need to set the scissor rect? Why not just disable scissor testing?
D3D11_RECT sirc = CD3D11_RECT(targetRc.left, targetRc.top, targetRc.right, targetRc.bottom);
D3D11_RECT sirc = CD3D11_RECT(targetRc.left, targetRc.top, targetRc.right, targetRc.bottom);
D3D::context->RSSetScissorRects(1, &sirc);
D3D::context->OMSetDepthStencilState(cleardepthstates[zEnable], 0);
D3D::context->RSSetState(clearraststate);
@ -984,6 +985,7 @@ void Renderer::RestoreAPIState()
if (bpmem.zmode.updateenable) D3D::gfxstate->depthdesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
SetColorMask();
SetLogicOpMode();
D3D::gfxstate->ApplyState();
}
void Renderer::SetGenerationMode()

View File

@ -141,7 +141,7 @@ void VertexShaderCache::Init()
const D3D11_INPUT_ELEMENT_DESC clearelems[2] =
{
{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
{ "COLOR", 0, DXGI_FORMAT_B8G8R8A8_UNORM, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
};
ID3D10Blob* blob;

View File

@ -392,6 +392,7 @@ static struct
EFBAccessType type;
u32 x;
u32 y;
u32 Data;
} s_accessEFBArgs;
static u32 s_AccessEFBResult = 0;
@ -406,14 +407,14 @@ void VideoFifo_CheckEFBAccess()
}
}
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y)
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
{
if (s_PluginInitialized)
{
s_accessEFBArgs.type = type;
s_accessEFBArgs.x = x;
s_accessEFBArgs.y = y;
s_accessEFBArgs.Data = InputData;
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
if (g_VideoInitialize.bOnThread)

View File

@ -892,17 +892,17 @@ 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
TargetRectangle targetRc = Renderer::ConvertEFBRectangle(rc);
D3DVIEWPORT9 vp;
vp.X = 0;
vp.Y = 0;
vp.Width = Renderer::GetFullTargetWidth();
vp.Height = Renderer::GetFullTargetHeight();
vp.X = targetRc.left;
vp.Y = targetRc.top;
vp.Width = targetRc.GetWidth();
vp.Height = targetRc.GetHeight();
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;
@ -927,35 +927,42 @@ void Renderer::SetBlendMode(bool forceUpdate)
// 2 - reverse subtract enable (else add)
// 3-5 - srcRGB function
// 6-8 - dstRGB function
#define BLEND_ENABLE_MASK 1
#define BLENDOP_SHIFT 2
#define BLENDOP_MASK 4
#define SRCFACTOR_SHIFT 3
#define DESTFACTOR_SHIFT 6
#define FACTOR_MASK 7
if (bpmem.blendmode.logicopenable && bpmem.blendmode.logicmode != 3)
return;
u32 newval = bpmem.blendmode.subtract << 2;
u32 newval = bpmem.blendmode.subtract << BLENDOP_SHIFT;
if (bpmem.blendmode.subtract) {
newval |= 0x0049; // enable blending src 1 dst 1
newval |= BLEND_ENABLE_MASK | (1 << SRCFACTOR_SHIFT) | (1 << DESTFACTOR_SHIFT);
} else if (bpmem.blendmode.blendenable) {
newval |= 1; // enable blending
newval |= bpmem.blendmode.srcfactor << 3;
newval |= bpmem.blendmode.dstfactor << 6;
newval |= BLEND_ENABLE_MASK; // enable blending
newval |= bpmem.blendmode.srcfactor << SRCFACTOR_SHIFT;
newval |= bpmem.blendmode.dstfactor << DESTFACTOR_SHIFT;
}
u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode;
if (changes & 1) {
if (changes & BLEND_ENABLE_MASK) {
// blend enable change
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, (newval & 1));
D3D::SetRenderState(D3DRS_ALPHABLENDENABLE, (newval & BLEND_ENABLE_MASK));
}
if (changes & 4) {
if (changes & BLENDOP_MASK) {
// subtract enable change
D3D::SetRenderState(D3DRS_BLENDOP, newval & 4 ? D3DBLENDOP_REVSUBTRACT : D3DBLENDOP_ADD);
D3D::SetRenderState(D3DRS_BLENDOP, newval & BLENDOP_MASK ? D3DBLENDOP_REVSUBTRACT : D3DBLENDOP_ADD);
}
if (changes & 0x1F8) {
// blend RGB change
D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[(newval >> 3) & 7]);
D3D::SetRenderState(D3DRS_DESTBLEND, d3dDestFactors[(newval >> 6) & 7]);
D3D::SetRenderState(D3DRS_SRCBLEND, d3dSrcFactors[(newval >> SRCFACTOR_SHIFT) & FACTOR_MASK]);
D3D::SetRenderState(D3DRS_DESTBLEND, d3dDestFactors[(newval >> DESTFACTOR_SHIFT) & FACTOR_MASK]);
}
s_blendMode = newval;

View File

@ -451,6 +451,7 @@ static struct
EFBAccessType type;
u32 x;
u32 y;
u32 Data;
} s_accessEFBArgs;
static u32 s_AccessEFBResult = 0;
@ -465,13 +466,14 @@ void VideoFifo_CheckEFBAccess()
}
}
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y)
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y,u32 InputData)
{
if (s_PluginInitialized)
{
s_accessEFBArgs.type = type;
s_accessEFBArgs.x = x;
s_accessEFBArgs.y = y;
s_accessEFBArgs.Data = InputData;
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);

View File

@ -768,7 +768,7 @@ bool Renderer::SetScissorRect()
// Check that the coordinates are good
if (rc_right >= rc_left && rc_bottom >= rc_top)
if (rc_right != rc_left && rc_bottom != rc_top)
{
glScissor(
(int)(rc_left * EFBxScale), // x = 0 for example

View File

@ -431,6 +431,7 @@ static struct
EFBAccessType type;
u32 x;
u32 y;
u32 Data;
} s_accessEFBArgs;
static u32 s_AccessEFBResult = 0;
@ -445,14 +446,14 @@ void VideoFifo_CheckEFBAccess()
}
}
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y)
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
{
if (s_PluginInitialized)
{
s_accessEFBArgs.type = type;
s_accessEFBArgs.x = x;
s_accessEFBArgs.y = y;
s_accessEFBArgs.Data = InputData;
Common::AtomicStoreRelease(s_efbAccessRequested, TRUE);
if (g_VideoInitialize.bOnThread)

View File

@ -120,7 +120,7 @@ void Video_EndField()
{
}
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y)
u32 Video_AccessEFB(EFBAccessType type, u32 x, u32 y, u32 InputData)
{
u32 value = 0;