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

View File

@ -39,22 +39,7 @@
// --------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------
// State translation lookup tables // 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] = { static const GLenum glCmpFuncs[8] = {
GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL, GL_GREATER, GL_NOTEQUAL, GL_GEQUAL, GL_ALWAYS 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(); VertexManager::Flush();
((u32*)&bpmem)[addr] = newval; ((u32*)&bpmem)[addr] = newval;
PRIM_LOG("constalpha: alp=%d, en=%d\n", bpmem.dstalpha.alpha, bpmem.dstalpha.enable); PRIM_LOG("constalpha: alp=%d, en=%d\n", bpmem.dstalpha.alpha, bpmem.dstalpha.enable);
PixelShaderManager::SetDestAlpha(bpmem.dstalpha); Renderer::SetBlendMode(false);
} }
break; break;
@ -192,13 +177,6 @@ void BPWritten(int addr, int changes, int newval)
bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate, bpmem.blendmode.blendenable, bpmem.blendmode.logicopenable, bpmem.blendmode.colorupdate, bpmem.blendmode.alphaupdate,
bpmem.blendmode.dstfactor, bpmem.blendmode.srcfactor, bpmem.blendmode.subtract, bpmem.blendmode.logicmode); 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 (changes & 2) {
if (Renderer::CanBlendLogicOp()) { if (Renderer::CanBlendLogicOp()) {
if (bpmem.blendmode.logicopenable) { if (bpmem.blendmode.logicopenable) {
@ -251,22 +229,14 @@ void BPWritten(int addr, int changes, int newval)
// } // }
//} //}
} }
if (changes & 4) { /*if (changes & 4) {
// pointless // pointless
//if (bpmem.blendmode.dither) glEnable(GL_DITHER); //if (bpmem.blendmode.dither) glEnable(GL_DITHER);
//else glDisable(GL_DITHER); //else glDisable(GL_DITHER);
} }
if (changes & 0xFE0) { */
if (!bpmem.blendmode.subtract) if (changes & 0xFE1)
glBlendFunc(glSrcFactors[bpmem.blendmode.srcfactor], glDestFactors[bpmem.blendmode.dstfactor]); Renderer::SetBlendMode(false);
}
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 & 0x18) if (changes & 0x18)
Renderer::SetColorMask(); Renderer::SetColorMask();

View File

@ -102,11 +102,30 @@ static bool s_bHaveStencilBuffer = false;
static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal; static Renderer::RenderMode s_RenderMode = Renderer::RM_Normal;
bool g_bBlendLogicOp = false; bool g_bBlendLogicOp = false;
bool g_bBlendSeparate = false;
int frameCount; int frameCount;
void HandleCgError(CGcontext ctx, CGerror err, void *appdata); 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() bool Renderer::Init()
{ {
@ -126,6 +145,8 @@ bool Renderer::Init()
if (strstr(ptoken, "GL_EXT_blend_logic_op") != NULL) if (strstr(ptoken, "GL_EXT_blend_logic_op") != NULL)
g_bBlendLogicOp = true; 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) 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 //Checks if it ONLY has the ATI_draw_buffers extension, some have both
s_bATIDrawBuffers = true; s_bATIDrawBuffers = true;
@ -556,12 +577,12 @@ void Renderer::RestoreGLState()
if (bpmem.genMode.cullmode > 0) glEnable(GL_CULL_FACE); if (bpmem.genMode.cullmode > 0) glEnable(GL_CULL_FACE);
if (bpmem.zmode.testenable) glEnable(GL_DEPTH_TEST); if (bpmem.zmode.testenable) glEnable(GL_DEPTH_TEST);
if (bpmem.blendmode.blendenable) glEnable(GL_BLEND);
if (bpmem.zmode.updateenable) glDepthMask(GL_TRUE); if (bpmem.zmode.updateenable) glDepthMask(GL_TRUE);
glEnable(GL_VERTEX_PROGRAM_ARB); glEnable(GL_VERTEX_PROGRAM_ARB);
glEnable(GL_FRAGMENT_PROGRAM_ARB); glEnable(GL_FRAGMENT_PROGRAM_ARB);
SetColorMask(); SetColorMask();
SetBlendMode(true);
} }
void Renderer::SetColorMask() void Renderer::SetColorMask()
@ -574,6 +595,68 @@ void Renderer::SetColorMask()
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_FALSE); 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() // Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
// case 0x52 > SetScissorRect() // case 0x52 > SetScissorRect()
// --------------- // ---------------

View File

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