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:
parent
4afe48a0fb
commit
d511b50612
|
@ -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) {
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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]);
|
||||||
|
|
|
@ -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?
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue