this commit is divided in 4 parts:

1 - Optimize pixelshadergen to avoid redundant register overflow math, with this if a game don't need this will be not applied.
this must bring some fill rate back and improve speed a little in fill rate limited systems.
2- some corrections to vertexshadergen to avoid uninitialized texture coordinates, dono if is the correct way to fix it but t least it will make house of the dead overkill playable in dx11.
the bad thing: still missing geometri in dx9, in dx11 it works exactly as on opengl.
3 - some optimization made to improve fps a little wih the latests changes made to fifo.
* back to the original code in beginfield as now it will work right.
* check for efb access more often as a lot of time is lost waiting for efb access
4 - apply a little fix for missing textures in nvidia opengl tanks to  Wagnard28 for finding that nvidia does not like invalid shader id :)
please test for any regression

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@5812 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
Rodolfo Osvaldo Bogado 2010-06-29 14:40:37 +00:00
parent 4afe48a0fb
commit d511b50612
11 changed files with 213 additions and 145 deletions

View File

@ -22,7 +22,7 @@ static const char ID[4] = {'D', 'C', 'A', 'C'};
// Update this to the current SVN revision every time you change shader generation code. // Update this to the current SVN revision every time you change shader generation code.
// We don't automatically get this from SVN_REV because that would mean regenerating the // We don't automatically get this from SVN_REV because that would mean regenerating the
// shader cache for every revision, graphics-related or not, which is simply annoying. // shader cache for every revision, graphics-related or not, which is simply annoying.
const int version = 5691; const int version = 5812;
LinearDiskCache::LinearDiskCache() LinearDiskCache::LinearDiskCache()
: file_(NULL), num_entries_(0) { : file_(NULL), num_entries_(0) {

View File

@ -729,7 +729,7 @@ void UpdateParameters()
TargetRefreshRate = PAL_FIELD_RATE; TargetRefreshRate = PAL_FIELD_RATE;
// AyuanX: Some games are pretty sensitive to this value // AyuanX: Some games are pretty sensitive to this value
// So we have to make it run a little faster to prevent potential time out // So we have to make it run a little faster to prevent potential time out
TicksPerFrame = SystemTimers::GetTicksPerSecond() / (PAL_FIELD_RATE + 1); TicksPerFrame = SystemTimers::GetTicksPerSecond() / (PAL_FIELD_RATE + 1);
s_lineCount = m_DisplayControlRegister.NIN ? PAL_LINE_COUNT : (PAL_LINE_COUNT+1)/2; s_lineCount = m_DisplayControlRegister.NIN ? PAL_LINE_COUNT : (PAL_LINE_COUNT+1)/2;
//s_upperFieldBegin = PAL_UPPER_BEGIN; //s_upperFieldBegin = PAL_UPPER_BEGIN;
//s_lowerFieldBegin = PAL_LOWER_BEGIN; //s_lowerFieldBegin = PAL_LOWER_BEGIN;
@ -800,19 +800,16 @@ void Update()
{ {
// Progressive // Progressive
NewVBeamPos = s_lineCount + 1; NewVBeamPos = s_lineCount + 1;
BeginField(FIELD_PROGRESSIVE);
} }
else if (m_VBeamPos == s_lineCount) else if (m_VBeamPos == s_lineCount)
{ {
// Interlace Upper // Interlace Upper
NewVBeamPos = s_lineCount * 2; NewVBeamPos = s_lineCount * 2;
BeginField(FIELD_UPPER);
} }
else else
{ {
// Interlace Lower // Interlace Lower
NewVBeamPos = s_lineCount; NewVBeamPos = s_lineCount;
BeginField(FIELD_LOWER);
} }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
@ -821,8 +818,25 @@ void Update()
m_InterruptRegister[i].IR_INT = 1; m_InterruptRegister[i].IR_INT = 1;
} }
UpdateInterrupts(); UpdateInterrupts();
if (m_DisplayControlRegister.NIN)
{
// Progressive
BeginField(FIELD_PROGRESSIVE);
}
else if (m_VBeamPos == s_lineCount)
{
// Interlace Upper
BeginField(FIELD_UPPER);
}
else
{
// Interlace Lower
BeginField(FIELD_LOWER);
}
m_VBeamPos = (NewVBeamPos > s_lineCount) ? 1 : NewVBeamPos; m_VBeamPos = (NewVBeamPos > s_lineCount) ? 1 : NewVBeamPos;
Core::VideoThrottle(); Core::VideoThrottle();
} }

View File

@ -345,6 +345,15 @@ static char swapModeTable[4][5];
static char text[16384]; static char text[16384];
struct RegisterState
{
bool ColorNeedOverflowControl;
bool AlphaNeedOverflowControl;
bool AuxStored;
};
static RegisterState RegisterStates[4];
static void BuildSwapModeTable() static void BuildSwapModeTable()
{ {
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
@ -383,21 +392,10 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, API_
} }
// Declare samplers // Declare samplers
if (texture_mask) if (texture_mask && ApiType == API_OPENGL)
{ {
if (ApiType == API_D3D11) WRITE(p, "uniform samplerRECT ");
{ bool bfirst = true;
WRITE(p, "sampler ");
}
else if (ApiType == API_D3D9)
{
WRITE(p, "uniform sampler ");
}
else
{
WRITE(p, "uniform samplerRECT ");
}
bool bfirst = true;
for (int i = 0; i < 8; ++i) for (int i = 0; i < 8; ++i)
{ {
if (texture_mask & (1<<i)) if (texture_mask & (1<<i))
@ -406,21 +404,7 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, API_
bfirst = false; bfirst = false;
} }
} }
WRITE(p, ";\n"); WRITE(p, ";\n");
if(ApiType == API_D3D11)
{
bfirst = true;
WRITE(p, "Texture2D ");
for (int i = 0; i < 8; ++i)
{
if (texture_mask & (1<<i))
{
WRITE(p, "%s Tex%d : register(t%d)", bfirst?"":",", i, i);
bfirst = false;
}
}
WRITE(p, ";\n");
}
} }
if (texture_mask != 0xff) if (texture_mask != 0xff)
@ -549,19 +533,39 @@ const char *GeneratePixelShaderCode(u32 texture_mask, bool dstAlphaEnable, API_
} }
} }
RegisterStates[0].AlphaNeedOverflowControl = false;
RegisterStates[0].ColorNeedOverflowControl = false;
RegisterStates[0].AuxStored = false;
for(int i = 0 ; i < 4 ; i++)
{
RegisterStates[i].AlphaNeedOverflowControl = true;
RegisterStates[i].ColorNeedOverflowControl = true;
RegisterStates[i].AuxStored = false;
}
for (int i = 0; i < numStages; i++) for (int i = 0; i < numStages; i++)
WriteStage(p, i, texture_mask,ApiType); //build the equation for this stage WriteStage(p, i, texture_mask,ApiType); //build the equation for this stage
if(numStages) if(numStages)
{ {
// The results of the last texenv stage are put onto the screen, // The results of the last texenv stage are put onto the screen,
// regardless of the used destination register // regardless of the used destination register
WRITE(p, "prev.rgb = %s;\n",tevCOutputTable[bpmem.combiners[numStages-1].colorC.dest]); if(bpmem.combiners[numStages - 1].colorC.dest != 0)
WRITE(p, "prev.a = %s;\n",tevAOutputTable[bpmem.combiners[numStages-1].alphaC.dest]); {
bool retrieveFromAuxRegister = !RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl && RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].AuxStored;
WRITE(p, "prev.rgb = %s%s;\n", retrieveFromAuxRegister ? "c" : "" ,tevCOutputTable[bpmem.combiners[numStages - 1].colorC.dest]);
RegisterStates[0].ColorNeedOverflowControl = RegisterStates[bpmem.combiners[numStages - 1].colorC.dest].ColorNeedOverflowControl;
}
if(bpmem.combiners[numStages - 1].alphaC.dest != 0)
{
bool retrieveFromAuxRegister = !RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AlphaNeedOverflowControl && RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AuxStored;
WRITE(p, "prev.a = %s%s;\n", retrieveFromAuxRegister ? "c" : "" ,tevAOutputTable[bpmem.combiners[numStages - 1].alphaC.dest]);
RegisterStates[0].AlphaNeedOverflowControl = RegisterStates[bpmem.combiners[numStages - 1].alphaC.dest].AlphaNeedOverflowControl;
}
} }
// emulation of unisgned 8 overflow when casting if needed
// emulation of unisgned 8 overflow when casting if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); WRITE(p, "prev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
if (!WriteAlphaTest(p, ApiType)) if (!WriteAlphaTest(p, ApiType))
{ {
@ -782,7 +786,19 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
|| ac.a == TEVALPHAARG_APREV || ac.a == TEVALPHAARG_APREV
|| ac.b == TEVALPHAARG_APREV || ac.b == TEVALPHAARG_APREV
|| ac.c == TEVALPHAARG_APREV) || ac.c == TEVALPHAARG_APREV)
WRITE(p, "cprev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); {
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
{
WRITE(p, "cprev = frac(4.0f + prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[0].AlphaNeedOverflowControl = false;
RegisterStates[0].ColorNeedOverflowControl = false;
}
else
{
WRITE(p, "cprev = prev;\n");
}
RegisterStates[0].AuxStored = true;
}
if(cc.a == TEVCOLORARG_C0 if(cc.a == TEVCOLORARG_C0
|| cc.a == TEVCOLORARG_A0 || cc.a == TEVCOLORARG_A0
@ -793,7 +809,20 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
|| ac.a == TEVALPHAARG_A0 || ac.a == TEVALPHAARG_A0
|| ac.b == TEVALPHAARG_A0 || ac.b == TEVALPHAARG_A0
|| ac.c == TEVALPHAARG_A0) || ac.c == TEVALPHAARG_A0)
WRITE(p, "cc0 = frac(4.0f + c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); {
if(RegisterStates[1].AlphaNeedOverflowControl || RegisterStates[1].ColorNeedOverflowControl)
{
WRITE(p, "cc0 = frac(4.0f + c0 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[1].AlphaNeedOverflowControl = false;
RegisterStates[1].ColorNeedOverflowControl = false;
}
else
{
WRITE(p, "cc0 = c0;\n");
}
RegisterStates[1].AuxStored = true;
}
if(cc.a == TEVCOLORARG_C1 if(cc.a == TEVCOLORARG_C1
|| cc.a == TEVCOLORARG_A1 || cc.a == TEVCOLORARG_A1
@ -804,7 +833,19 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
|| ac.a == TEVALPHAARG_A1 || ac.a == TEVALPHAARG_A1
|| ac.b == TEVALPHAARG_A1 || ac.b == TEVALPHAARG_A1
|| ac.c == TEVALPHAARG_A1) || ac.c == TEVALPHAARG_A1)
WRITE(p, "cc1 = frac(4.0f + c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); {
if(RegisterStates[2].AlphaNeedOverflowControl || RegisterStates[2].ColorNeedOverflowControl)
{
WRITE(p, "cc1 = frac(4.0f + c1 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[2].AlphaNeedOverflowControl = false;
RegisterStates[2].ColorNeedOverflowControl = false;
}
else
{
WRITE(p, "cc1 = c1;\n");
}
RegisterStates[2].AuxStored = true;
}
if(cc.a == TEVCOLORARG_C2 if(cc.a == TEVCOLORARG_C2
|| cc.a == TEVCOLORARG_A2 || cc.a == TEVCOLORARG_A2
@ -815,8 +856,22 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
|| ac.a == TEVALPHAARG_A2 || ac.a == TEVALPHAARG_A2
|| ac.b == TEVALPHAARG_A2 || ac.b == TEVALPHAARG_A2
|| ac.c == TEVALPHAARG_A2) || ac.c == TEVALPHAARG_A2)
WRITE(p, "cc2 = frac(4.0f + c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n"); {
if(RegisterStates[3].AlphaNeedOverflowControl || RegisterStates[3].ColorNeedOverflowControl)
{
WRITE(p, "cc2 = frac(4.0f + c2 * (255.0f/256.0f)) * (256.0f/255.0f);\n");
RegisterStates[3].AlphaNeedOverflowControl = false;
RegisterStates[3].ColorNeedOverflowControl = false;
}
else
{
WRITE(p, "cc2 = c2;\n");
}
RegisterStates[3].AuxStored = true;
}
RegisterStates[cc.dest].ColorNeedOverflowControl = (cc.clamp == 0);
RegisterStates[cc.dest].AuxStored = false;
if (cc.clamp) if (cc.clamp)
WRITE(p, "%s=saturate(", tevCOutputTable[cc.dest]); WRITE(p, "%s=saturate(", tevCOutputTable[cc.dest]);
else else
@ -863,6 +918,8 @@ static void WriteStage(char *&p, int n, u32 texture_mask, API_TYPE ApiType)
WRITE(p,")"); WRITE(p,")");
WRITE(p,";\n"); WRITE(p,";\n");
RegisterStates[ac.dest].AlphaNeedOverflowControl = (ac.clamp == 0);
RegisterStates[ac.dest].AuxStored = false;
// combine the alpha channel // combine the alpha channel
if (ac.clamp) if (ac.clamp)
WRITE(p, "%s=saturate(", tevAOutputTable[ac.dest]); WRITE(p, "%s=saturate(", tevAOutputTable[ac.dest]);

View File

@ -332,7 +332,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
// zero left over channels // zero left over channels
for (int i = xfregs.nNumChans; i < 2; ++i) for (int i = xfregs.nNumChans; i < 2; ++i)
WRITE(p, "o.colors[%d] = float4(0.0f,0.0f,0.0f,0.0f);\n", i); WRITE(p, "o.colors[%d] = float4(0.0f,0.0f,0.0f,1.0f);\n", i);
// special case if only pos and tex coord 0 and tex coord input is AB11 // special case if only pos and tex coord 0 and tex coord input is AB11
// donko - this has caused problems in some games. removed for now. // donko - this has caused problems in some games. removed for now.
@ -349,6 +349,7 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
TexMtxInfo& texinfo = xfregs.texcoords[i].texmtxinfo; TexMtxInfo& texinfo = xfregs.texcoords[i].texmtxinfo;
WRITE(p, "{\n"); WRITE(p, "{\n");
WRITE(p, "coord = float4(0.0f,0.0f,1.0f,1.0f);\n");
switch (texinfo.sourcerow) { switch (texinfo.sourcerow) {
case XF_SRCGEOM_INROW: case XF_SRCGEOM_INROW:
_assert_( texinfo.inputform == XF_TEXINPUT_ABC1 ); _assert_( texinfo.inputform == XF_TEXINPUT_ABC1 );
@ -384,7 +385,26 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
// firs transformation // firs transformation
switch (texinfo.texgentype) { switch (texinfo.texgentype) {
case XF_TEXGEN_REGULAR: case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) {
// transform the light dir into tangent space
WRITE(p, "ldir = normalize("I_LIGHTS".lights[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift);
WRITE(p, "o.tex%d.xyz = coord.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift);
}
else _assert_(0); // should have normals
break;
case XF_TEXGEN_COLOR_STRGBC0:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
WRITE(p, "o.tex%d.xyz = float3(o.colors[0].x, o.colors[0].y, 1);\n", i);
break;
case XF_TEXGEN_COLOR_STRGBC1:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
WRITE(p, "o.tex%d.xyz = float3(o.colors[1].x, o.colors[1].y, 1);\n", i);
break;
case XF_TEXGEN_REGULAR:
default:
if (components & (VB_HAS_TEXMTXIDX0<<i)) { if (components & (VB_HAS_TEXMTXIDX0<<i)) {
if (texinfo.projection == XF_TEXPROJ_STQ ) if (texinfo.projection == XF_TEXPROJ_STQ )
WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+1].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+2].t));\n", i, i, i, i); WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+1].t), dot(coord, "I_TRANSFORMMATRICES".T[tex%d.z+2].t));\n", i, i, i, i);
@ -399,24 +419,6 @@ const char *GenerateVertexShaderCode(u32 components, API_TYPE api_type)
WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TEXMATRICES".T[%d].t), dot(coord, "I_TEXMATRICES".T[%d].t), 1);\n", i, 3*i, 3*i+1); WRITE(p, "o.tex%d.xyz = float3(dot(coord, "I_TEXMATRICES".T[%d].t), dot(coord, "I_TEXMATRICES".T[%d].t), 1);\n", i, 3*i, 3*i+1);
} }
break; break;
case XF_TEXGEN_EMBOSS_MAP: // calculate tex coords into bump map
if (components & (VB_HAS_NRM1|VB_HAS_NRM2)) {
// transform the light dir into tangent space
WRITE(p, "ldir = normalize("I_LIGHTS".lights[%d].pos.xyz - pos.xyz);\n", texinfo.embosslightshift);
WRITE(p, "o.tex%d.xyz = o.tex%d.xyz + float3(dot(ldir, _norm1), dot(ldir, _norm2), 0.0f);\n", i, texinfo.embosssourceshift);
}
else _assert_(0); // should have normals
break;
case XF_TEXGEN_COLOR_STRGBC0:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
WRITE(p, "o.tex%d.xyz = float3(o.colors[0].x, o.colors[0].y, 1);\n", i);
break;
case XF_TEXGEN_COLOR_STRGBC1:
_assert_(texinfo.sourcerow == XF_SRCCOLORS_INROW);
WRITE(p, "o.tex%d.xyz = float3(o.colors[1].x, o.colors[1].y, 1);\n", i);
break;
} }
if (xfregs.bEnableDualTexTransform && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types? if (xfregs.bEnableDualTexTransform && texinfo.texgentype == XF_TEXGEN_REGULAR) { // only works for regular tex gen types?

View File

@ -21,7 +21,7 @@
#include "D3DBase.h" #include "D3DBase.h"
#include "D3DShader.h" #include "D3DShader.h"
#include "D3DUtil.h" #include "D3DUtil.h"
#include "Fifo.h"
#include "Statistics.h" #include "Statistics.h"
#include "Profiler.h" #include "Profiler.h"
#include "FBManager.h" #include "FBManager.h"
@ -304,6 +304,7 @@ void Flush()
if (LocalVBuffer == s_pCurBufferPointer) return; if (LocalVBuffer == s_pCurBufferPointer) return;
if (Flushed) return; if (Flushed) return;
Flushed=true; Flushed=true;
VideoFifo_CheckEFBAccess();
DVSTARTPROFILE(); DVSTARTPROFILE();

View File

@ -71,7 +71,6 @@ static bool s_PluginInitialized = false;
volatile u32 s_swapRequested = FALSE; volatile u32 s_swapRequested = FALSE;
static u32 s_efbAccessRequested = FALSE; static u32 s_efbAccessRequested = FALSE;
static volatile u32 s_FifoShuttingDown = FALSE; static volatile u32 s_FifoShuttingDown = FALSE;
static bool ForceSwap = true;
static volatile struct static volatile struct
{ {
@ -234,7 +233,6 @@ void Video_Prepare()
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
ForceSwap = true;
Renderer::Init(); Renderer::Init();
TextureCache::Init(); TextureCache::Init();
BPInit(); BPInit();
@ -307,16 +305,16 @@ void Video_SetRendering(bool bEnabled)
Fifo_SetRendering(bEnabled); Fifo_SetRendering(bEnabled);
} }
// run from the graphics thread // Run from the graphics thread (from Fifo.cpp)
void VideoFifo_CheckSwapRequest() void VideoFifo_CheckSwapRequest()
{ {
if (Common::AtomicLoadAcquire(s_swapRequested)) if(g_ActiveConfig.bUseXFB)
{ {
if (ForceSwap || g_ActiveConfig.bUseXFB) if (Common::AtomicLoadAcquire(s_swapRequested))
{ {
Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight); Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight);
Common::AtomicStoreRelease(s_swapRequested, FALSE);
} }
Common::AtomicStoreRelease(s_swapRequested, FALSE);
} }
} }
@ -325,33 +323,29 @@ inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
return !((aLower >= bUpper) || (bLower >= aUpper)); return !((aLower >= bUpper) || (bLower >= aUpper));
} }
// Run from the graphics thread // Run from the graphics thread (from Fifo.cpp)
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
{ {
if (Common::AtomicLoadAcquire(s_swapRequested) && g_ActiveConfig.bUseXFB) if (g_ActiveConfig.bUseXFB)
{ {
u32 aLower = xfbAddr; if(Common::AtomicLoadAcquire(s_swapRequested))
u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight; {
u32 bLower = s_beginFieldArgs.xfbAddr; u32 aLower = xfbAddr;
u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight; u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
u32 bLower = s_beginFieldArgs.xfbAddr;
u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight;
if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
} }
ForceSwap = false; }
} }
// Run from the CPU thread (from VideoInterface.cpp) // Run from the CPU thread (from VideoInterface.cpp)
void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
{ {
if (s_PluginInitialized && g_ActiveConfig.bUseXFB) if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
{ {
s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth;
s_beginFieldArgs.fbHeight = fbHeight;
Common::AtomicStoreRelease(s_swapRequested, TRUE);
if (g_VideoInitialize.bOnThread) if (g_VideoInitialize.bOnThread)
{ {
while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown) while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown)
@ -359,7 +353,13 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
Common::YieldCPU(); Common::YieldCPU();
} }
else else
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth;
s_beginFieldArgs.fbHeight = fbHeight;
Common::AtomicStoreRelease(s_swapRequested, TRUE);
} }
} }

View File

@ -19,7 +19,7 @@
#include "FileUtil.h" #include "FileUtil.h"
#include "D3DBase.h" #include "D3DBase.h"
#include "Fifo.h"
#include "Statistics.h" #include "Statistics.h"
#include "Profiler.h" #include "Profiler.h"
#include "VertexManager.h" #include "VertexManager.h"
@ -226,7 +226,7 @@ void Flush()
if (LocalVBuffer == s_pCurBufferPointer) return; if (LocalVBuffer == s_pCurBufferPointer) return;
if(Flushed) return; if(Flushed) return;
Flushed=true; Flushed=true;
VideoFifo_CheckEFBAccess();
DVSTARTPROFILE(); DVSTARTPROFILE();
u32 usedtextures = 0; u32 usedtextures = 0;

View File

@ -65,7 +65,6 @@ static bool s_PluginInitialized = false;
volatile u32 s_swapRequested = FALSE; volatile u32 s_swapRequested = FALSE;
static u32 s_efbAccessRequested = FALSE; static u32 s_efbAccessRequested = FALSE;
static volatile u32 s_FifoShuttingDown = FALSE; static volatile u32 s_FifoShuttingDown = FALSE;
static bool ForceSwap = true;
static volatile struct static volatile struct
{ {
@ -275,7 +274,6 @@ void Video_Prepare()
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_FifoShuttingDown = FALSE; s_FifoShuttingDown = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
ForceSwap = true;
Renderer::Init(); Renderer::Init();
TextureCache::Init(); TextureCache::Init();
BPInit(); BPInit();
@ -342,16 +340,16 @@ void Video_SetRendering(bool bEnabled) {
Fifo_SetRendering(bEnabled); Fifo_SetRendering(bEnabled);
} }
// Run from the graphics thread // Run from the graphics thread (from Fifo.cpp)
void VideoFifo_CheckSwapRequest() void VideoFifo_CheckSwapRequest()
{ {
if (Common::AtomicLoadAcquire(s_swapRequested)) if(g_ActiveConfig.bUseXFB)
{ {
if (ForceSwap || g_ActiveConfig.bUseXFB) if (Common::AtomicLoadAcquire(s_swapRequested))
{ {
Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight); Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight);
Common::AtomicStoreRelease(s_swapRequested, FALSE);
} }
Common::AtomicStoreRelease(s_swapRequested, FALSE);
} }
} }
@ -360,34 +358,29 @@ inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
return !((aLower >= bUpper) || (bLower >= aUpper)); return !((aLower >= bUpper) || (bLower >= aUpper));
} }
// Run from the graphics thread // Run from the graphics thread (from Fifo.cpp)
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
{ {
if (Common::AtomicLoadAcquire(s_swapRequested) && g_ActiveConfig.bUseXFB) if (g_ActiveConfig.bUseXFB)
{ {
u32 aLower = xfbAddr; if(Common::AtomicLoadAcquire(s_swapRequested))
u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight; {
u32 bLower = s_beginFieldArgs.xfbAddr; u32 aLower = xfbAddr;
u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight; u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
u32 bLower = s_beginFieldArgs.xfbAddr;
u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight;
if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
} }
}
ForceSwap = false;
} }
// Run from the CPU thread (from VideoInterface.cpp) // Run from the CPU thread (from VideoInterface.cpp)
void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
{ {
if (s_PluginInitialized && g_ActiveConfig.bUseXFB) if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
{ {
s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth;
s_beginFieldArgs.fbHeight = fbHeight;
Common::AtomicStoreRelease(s_swapRequested, TRUE);
if (g_VideoInitialize.bOnThread) if (g_VideoInitialize.bOnThread)
{ {
while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown) while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown)
@ -395,7 +388,13 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
Common::YieldCPU(); Common::YieldCPU();
} }
else else
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth;
s_beginFieldArgs.fbHeight = fbHeight;
Common::AtomicStoreRelease(s_swapRequested, TRUE);
} }
} }

View File

@ -557,8 +557,6 @@ void Renderer::ResetAPIState()
{ {
// Gets us to a reasonably sane state where it's possible to do things like // Gets us to a reasonably sane state where it's possible to do things like
// image copies with textured quads, etc. // image copies with textured quads, etc.
glDisable(GL_VERTEX_PROGRAM_ARB);// needed by nvidia cards to avoid texture problems
glDisable(GL_FRAGMENT_PROGRAM_ARB);// needed by nvidia cards to avoid texture problems
VertexShaderCache::DisableShader(); VertexShaderCache::DisableShader();
PixelShaderCache::DisableShader(); PixelShaderCache::DisableShader();
glDisable(GL_SCISSOR_TEST); glDisable(GL_SCISSOR_TEST);
@ -586,10 +584,8 @@ void Renderer::RestoreAPIState()
SetColorMask(); SetColorMask();
SetBlendMode(true); SetBlendMode(true);
glEnable(GL_VERTEX_PROGRAM_ARB);// needed by nvidia cards o avoid texture problems VertexShaderCache::SetCurrentShader(1);
glEnable(GL_FRAGMENT_PROGRAM_ARB);// needed by nvidia cards o avoid texture problems PixelShaderCache::SetCurrentShader(1);
VertexShaderCache::SetCurrentShader(0);
PixelShaderCache::SetCurrentShader(0);
} }
void Renderer::SetColorMask() void Renderer::SetColorMask()

View File

@ -202,6 +202,7 @@ void Flush()
if (LocalVBuffer == s_pCurBufferPointer) return; if (LocalVBuffer == s_pCurBufferPointer) return;
if(Flushed) return; if(Flushed) return;
Flushed=true; Flushed=true;
VideoFifo_CheckEFBAccess();
#if defined(_DEBUG) || defined(DEBUGFAST) #if defined(_DEBUG) || defined(DEBUGFAST)
PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGens, PRIM_LOG("frame%d:\n texgen=%d, numchan=%d, dualtex=%d, ztex=%d, cole=%d, alpe=%d, ze=%d", g_ActiveConfig.iSaveTargetId, xfregs.numTexGens,
xfregs.nNumChans, (int)xfregs.bEnableDualTexTransform, bpmem.ztex2.op, xfregs.nNumChans, (int)xfregs.bEnableDualTexTransform, bpmem.ztex2.op,

View File

@ -106,7 +106,6 @@ static bool s_PluginInitialized = false;
volatile u32 s_swapRequested = FALSE; volatile u32 s_swapRequested = FALSE;
static u32 s_efbAccessRequested = FALSE; static u32 s_efbAccessRequested = FALSE;
static volatile u32 s_FifoShuttingDown = FALSE; static volatile u32 s_FifoShuttingDown = FALSE;
static bool ForceSwap = true;
bool IsD3D() bool IsD3D()
{ {
@ -301,8 +300,7 @@ void Video_Prepare(void)
void Shutdown(void) void Shutdown(void)
{ {
s_PluginInitialized = false; s_PluginInitialized = false;
ForceSwap = true;
s_efbAccessRequested = FALSE; s_efbAccessRequested = FALSE;
s_swapRequested = FALSE; s_swapRequested = FALSE;
@ -368,14 +366,13 @@ static volatile struct
// Run from the graphics thread (from Fifo.cpp) // Run from the graphics thread (from Fifo.cpp)
void VideoFifo_CheckSwapRequest() void VideoFifo_CheckSwapRequest()
{ {
if (Common::AtomicLoadAcquire(s_swapRequested)) if(g_ActiveConfig.bUseXFB)
{ {
if (ForceSwap || g_ActiveConfig.bUseXFB) if (Common::AtomicLoadAcquire(s_swapRequested))
{ {
Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight); Renderer::Swap(s_beginFieldArgs.xfbAddr, s_beginFieldArgs.field, s_beginFieldArgs.fbWidth, s_beginFieldArgs.fbHeight);
Common::AtomicStoreRelease(s_swapRequested, FALSE);
} }
Common::AtomicStoreRelease(s_swapRequested, FALSE);
} }
} }
@ -387,31 +384,26 @@ inline bool addrRangesOverlap(u32 aLower, u32 aUpper, u32 bLower, u32 bUpper)
// Run from the graphics thread (from Fifo.cpp) // Run from the graphics thread (from Fifo.cpp)
void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight) void VideoFifo_CheckSwapRequestAt(u32 xfbAddr, u32 fbWidth, u32 fbHeight)
{ {
if (Common::AtomicLoadAcquire(s_swapRequested) && g_ActiveConfig.bUseXFB) if (g_ActiveConfig.bUseXFB)
{ {
u32 aLower = xfbAddr; if(Common::AtomicLoadAcquire(s_swapRequested))
u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight; {
u32 bLower = s_beginFieldArgs.xfbAddr; u32 aLower = xfbAddr;
u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight; u32 aUpper = xfbAddr + 2 * fbWidth * fbHeight;
u32 bLower = s_beginFieldArgs.xfbAddr;
u32 bUpper = s_beginFieldArgs.xfbAddr + 2 * s_beginFieldArgs.fbWidth * s_beginFieldArgs.fbHeight;
if (addrRangesOverlap(aLower, aUpper, bLower, bUpper)) if (addrRangesOverlap(aLower, aUpper, bLower, bUpper))
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
} }
}
ForceSwap = false;
} }
// Run from the CPU thread (from VideoInterface.cpp) // Run from the CPU thread (from VideoInterface.cpp)
void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight) void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
{ {
if (s_PluginInitialized && g_ActiveConfig.bUseXFB) if (s_PluginInitialized && g_ActiveConfig.bUseXFB)
{ {
s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth;
s_beginFieldArgs.fbHeight = fbHeight;
Common::AtomicStoreRelease(s_swapRequested, TRUE);
if (g_VideoInitialize.bOnThread) if (g_VideoInitialize.bOnThread)
{ {
while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown) while (Common::AtomicLoadAcquire(s_swapRequested) && !s_FifoShuttingDown)
@ -420,6 +412,12 @@ void Video_BeginField(u32 xfbAddr, FieldType field, u32 fbWidth, u32 fbHeight)
} }
else else
VideoFifo_CheckSwapRequest(); VideoFifo_CheckSwapRequest();
s_beginFieldArgs.xfbAddr = xfbAddr;
s_beginFieldArgs.field = field;
s_beginFieldArgs.fbWidth = fbWidth;
s_beginFieldArgs.fbHeight = fbHeight;
Common::AtomicStoreRelease(s_swapRequested, TRUE);
} }
} }