Destination alpha works in OGL. Fixed reading XFB address from VI regs and removed a check to fix games which keep the XFB some place other than mem 1.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1921 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
donkopunchstania 2009-01-18 19:03:14 +00:00
parent 1ef5eca30c
commit 4930a6d6cb
4 changed files with 101 additions and 48 deletions

View File

@ -502,7 +502,6 @@ void Update()
{
LastTime += (TicksPerFrame / LineCount);
//
VerticalBeamPos++;
if (VerticalBeamPos > LineCount)
{
@ -517,19 +516,19 @@ void Update()
if (NextXFBRender == 1)
{
NextXFBRender = LinesPerField;
// The & mask is a hack for mario kart
u32 addr = (VideoInterface::m_FrameBufferTop.Hex & 0xFFFFFFF) | 0x80000000;
if (addr >= 0x80000000 &&
addr <= (0x81800000-640*480*2))
xfbPtr = Memory::GetPointer(addr);
u32 addr = (VideoInterface::m_FrameBufferTop.Hex & 0xFFFFFFF);
if (VideoInterface::m_FrameBufferTop.Hex & 0x10000000)
addr = addr << 5;
xfbPtr = Memory::GetPointer(addr);
}
else
{
NextXFBRender = 1;
u32 addr = (VideoInterface::m_FrameBufferBottom.Hex & 0xFFFFFFF) | 0x80000000;
if (addr >= 0x80000000 &&
addr <= (0x81800000-640*480*2))
xfbPtr = Memory::GetPointer(addr);
u32 addr = (VideoInterface::m_FrameBufferBottom.Hex & 0xFFFFFFF);
// check the top buffer address not the bottom
if (VideoInterface::m_FrameBufferTop.Hex & 0x10000000)
addr = addr << 5;
xfbPtr = Memory::GetPointer(addr);
yOffset = -1;
}
Common::PluginVideo* video = CPluginManager::GetInstance().GetVideo();

View File

@ -39,22 +39,7 @@
// ---------------------------------------------------------------------------------------
// State translation lookup tables
// -------------
static const GLenum glSrcFactors[8] =
{
GL_ZERO,
GL_ONE,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA
};
static const GLenum glDestFactors[8] = {
GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA
};
static const GLenum glCmpFuncs[8] = {
GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS
};
@ -162,7 +147,7 @@ void BPWritten(int addr, int changes, int newval)
VertexManager::Flush();
((u32*)&bpmem)[addr] = newval;
PRIM_LOG("constalpha: alp=%d, en=%d\n", bpmem.dstalpha.alpha, bpmem.dstalpha.enable);
PixelShaderManager::SetDestAlpha(bpmem.dstalpha);
Renderer::SetBlendMode(false);
}
break;
@ -191,14 +176,7 @@ void BPWritten(int addr, int changes, int newval)
PRIM_LOG("blendmode: en=%d, open=%d, colupd=%d, alphaupd=%d, dst=%d, src=%d, sub=%d, mode=%d\n",
bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate,
bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode);
if (changes & 1) {
if (bpmem.blendmode.blendenable) {
glEnable(GL_BLEND);
}
else glDisable(GL_BLEND);
}
if (changes & 2) {
if (Renderer::CanBlendLogicOp()) {
if (bpmem.blendmode.logicopenable) {
@ -251,22 +229,14 @@ void BPWritten(int addr, int changes, int newval)
// }
//}
}
if (changes & 4) {
/*if (changes & 4) {
// pointless
//if (bpmem.blendmode.dither) glEnable(GL_DITHER);
//else glDisable(GL_DITHER);
}
if (changes & 0xFE0) {
if (!bpmem.blendmode.subtract)
glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]);
}
if (changes & 0x800) {
glBlendEquation(bpmem.blendmode.subtract ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD);
if (bpmem.blendmode.subtract)
glBlendFunc(GL_ONE, GL_ONE);
else
glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]);
}
*/
if (changes & 0xFE1)
Renderer::SetBlendMode(false);
if (changes & 0x18)
Renderer::SetColorMask();

View File

@ -102,11 +102,30 @@ static bool s_bHaveStencilBuffer = false;
static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal;
bool g_bBlendLogicOp = false;
bool g_bBlendSeparate = false;
int frameCount;
void HandleCgError(CGcontext ctx, CGerror err, void *appdata);
/////////////////////////////
static const GLenum glSrcFactors[8] =
{
GL_ZERO,
GL_ONE,
GL_DST_COLOR,
GL_ONE_MINUS_DST_COLOR,
GL_SRC_ALPHA,
GL_ONE_MINUS_SRC_ALPHA,
GL_DST_ALPHA,
GL_ONE_MINUS_DST_ALPHA
};
static const GLenum glDestFactors[8] = {
GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,
GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA, GL_ONE_MINUS_DST_ALPHA
};
static u32 s_blendMode;
bool Renderer::Init()
{
@ -126,6 +145,8 @@ bool Renderer::Init()
if (strstr(ptoken, "GL_EXT_blend_logic_op") != NULL)
g_bBlendLogicOp = true;
if (strstr(ptoken, "GL_EXT_blend_func_separate") != NULL && strstr(ptoken, "GL_EXT_blend_equation_separate") != NULL)
g_bBlendSeparate = true;
if (strstr(ptoken, "ATI_draw_buffers") != NULL && strstr(ptoken, "ARB_draw_buffers") == NULL)
//Checks if it ONLY has the ATI_draw_buffers extension, some have both
s_bATIDrawBuffers = true;
@ -556,12 +577,12 @@ void Renderer::RestoreGLState()
if (bpmem.genMode.cullmode > 0) glEnable(GL_CULL_FACE);
if (bpmem.zmode.testenable) glEnable(GL_DEPTH_TEST);
if (bpmem.blendmode.blendenable) glEnable(GL_BLEND);
if (bpmem.zmode.updateenable) glDepthMask(GL_TRUE);
glEnable(GL_VERTEX_PROGRAM_ARB);
glEnable(GL_FRAGMENT_PROGRAM_ARB);
SetColorMask();
SetBlendMode(true);
}
void Renderer::SetColorMask()
@ -574,6 +595,68 @@ void Renderer::SetColorMask()
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE);
}
void Renderer::SetBlendMode(bool forceUpdate)
{
// blend mode bit mask
// 0 - blend enable
// 1 - dst alpha enable
// 2 - reverse subtract enable (else add)
// 3-5 - srcRGB function
// 6-8 - dstRGB function
// 9-16 - dstAlpha
u32 newval = bpmem.blendmode.subtract << 2;
if (g_bBlendSeparate) {
newval |= bpmem.dstalpha.enable ? 3 : 0;
newval |= bpmem.dstalpha.alpha << 9;
}
if (bpmem.blendmode.blendenable) {
newval |= 1;
if (bpmem.blendmode.subtract) {
newval |= 0x0048; // src 1 dst 1
} else {
newval |= bpmem.blendmode.srcfactor << 3;
newval |= bpmem.blendmode.dstfactor << 6;
}
} else {
newval |= 0x0008; // src 1 dst 0
}
u32 changes = forceUpdate ? 0xFFFFFFFF : newval ^ s_blendMode;
if (changes & 1) {
newval & 1 ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
}
bool dstAlphaEnable = g_bBlendSeparate && newval & 2;
if (changes & 6) {
// dst alpha enable or subtract enable change
if (dstAlphaEnable)
glBlendEquationSeparate(newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD, GL_FUNC_ADD);
else
glBlendEquation(newval & 4 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_ADD);
}
if (changes & 0x1FA) {
// dst alpha enable or blend RGB change
if (dstAlphaEnable)
glBlendFuncSeparate(glSrcFactors[(newval >> 3) & 7], glDestFactors[(newval >> 6) & 7], GL_CONSTANT_ALPHA, GL_ZERO);
else
glBlendFunc(glSrcFactors[(newval >> 3) & 7], glDestFactors[(newval >> 6) & 7]);
}
if (dstAlphaEnable && changes & 0x1FE00) {
// dst alpha color change
glBlendColor(0, 0, 0, (float)bpmem.dstalpha.alpha / 255.0f);
}
s_blendMode = newval;
}
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
// case 0x52 > SetScissorRect()
// ---------------
@ -1133,4 +1216,4 @@ void UpdateViewport()
}
glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f);
}
}

View File

@ -116,6 +116,7 @@ public:
static GLuint GetZBufferTarget();
static void SetColorMask();
static void SetBlendMode(bool forceUpdate);
static bool SetScissorRect();
static void SetRenderMode(RenderMode mode);