Add a temporary hack option that may help debugging the wipeout glow.

It reduces the glow problem by a lot but is obviously incorrect.
This commit is contained in:
Henrik Rydgård 2013-10-30 22:44:01 +01:00
parent 357b133ff6
commit 07a868910e
7 changed files with 120 additions and 19 deletions

View file

@ -183,6 +183,7 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) {
graphics->Get("DisableStencilTest", &bDisableStencilTest, false);
graphics->Get("AlwaysDepthWrite", &bAlwaysDepthWrite, false);
graphics->Get("LowQualitySplineBezier", &bLowQualitySplineBezier, false);
graphics->Get("WipeFramebufferAlpha", &bWipeFramebufferAlpha, false);
graphics->Get("PostShader", &sPostShaderName, "Off");
IniFile::Section *sound = iniFile.GetOrCreateSection("Sound");

View file

@ -97,6 +97,7 @@ public:
bool bDisableStencilTest;
bool bAlwaysDepthWrite;
bool bLowQualitySplineBezier;
bool bWipeFramebufferAlpha; // this was meant to be CopyStencilToAlpha but not done yet.
std::string sPostShaderName; // Off for off.
// Sound

View file

@ -24,7 +24,6 @@
using namespace Gen;
// GPRs are numbered 0 to 31
// VFPU regs are numbered 32 to 159.
// Then we have some temp regs for VFPU handling from 160 to 175.

View file

@ -76,6 +76,21 @@ static const char basic_vs[] =
" gl_Position = a_position;\n"
"}\n";
static const char color_fs[] =
#ifdef USING_GLES2
"precision mediump float;\n"
#endif
"uniform vec4 u_color;\n"
"void main() {\n"
" gl_FragColor.rgba = u_color;\n"
"}\n";
static const char color_vs[] =
"attribute vec4 a_position;\n"
"void main() {\n"
" gl_Position = a_position;\n"
"}\n";
// Aggressively delete unused FBO:s to save gpu memory.
enum {
FBO_OLD_AGE = 5,
@ -175,6 +190,14 @@ void FramebufferManager::CompileDraw2DProgram() {
glUniform1i(draw2dprogram_->sampler0, 0);
}
plainColorProgram_ = glsl_create_source(color_vs, color_fs, &errorString);
if (!plainColorProgram_) {
ERROR_LOG_REPORT(G3D, "Failed to compile plainColorProgram! This shouldn't happen.\n%s", errorString.c_str());
} else {
glsl_bind(plainColorProgram_);
plainColorLoc_ = glsl_uniform_loc(plainColorProgram_, "u_color");
}
SetNumExtraFBOs(0);
const ShaderInfo *shaderInfo = 0;
if (g_Config.sPostShaderName != "Off") {
@ -397,6 +420,42 @@ void FramebufferManager::DrawPixels(const u8 *framebuf, GEBufferFormat pixelForm
}
}
void FramebufferManager::DrawPlainColor(u32 color) {
// Cannot take advantage of scissor + clear here - this has to be a regular draw so that
// stencil can be used and abused, as that's what we're gonna use this for.
static const float pos[12] = {
-1,-1,-1,
1,-1,-1,
1,1,-1,
-1,1,-1
};
static const GLubyte indices[4] = {0,1,3,2};
GLSLProgram *program = 0;
if (!draw2dprogram_) {
CompileDraw2DProgram();
}
program = plainColorProgram_;
const float col[4] = {
((color & 0xFF)) / 255.0f,
((color & 0xFF00) >> 8) / 255.0f,
((color & 0xFF0000) >> 16) / 255.0f,
((color & 0xFF000000) >> 24) / 255.0f,
};
glsl_bind(program);
glUniform4fv(plainColorLoc_, 1, col);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(program->a_position);
glVertexAttribPointer(program->a_position, 3, GL_FLOAT, GL_FALSE, 12, pos);
glDrawElements(GL_TRIANGLE_STRIP, 4, GL_UNSIGNED_BYTE, indices);
glDisableVertexAttribArray(program->a_position);
glsl_unbind();
}
void FramebufferManager::DrawActiveTexture(GLuint texture, float x, float y, float w, float h, float destW, float destH, bool flip, float uscale, float vscale, GLSLProgram *program) {
if (texture) {
// We know the texture, we can do a DrawTexture shortcut on nvidia.
@ -433,8 +492,7 @@ void FramebufferManager::DrawActiveTexture(GLuint texture, float x, float y, flo
}
const float texCoords[8] = {0,v1, u2,v1, u2,v2, 0,v2};
const GLubyte indices[4] = {0,1,3,2};
static const GLubyte indices[4] = {0,1,3,2};
if (!program) {
if (!draw2dprogram_) {
CompileDraw2DProgram();
@ -550,6 +608,31 @@ void FramebufferManager::SetRenderFrameBuffer() {
currentRenderVfb_->reallyDirtyAfterDisplay = true;
return;
}
if (g_Config.iRenderingMode != 0 && g_Config.bWipeFramebufferAlpha && currentRenderVfb_) {
// Hack is enabled, and there was a previous framebuffer.
// Before we switch, let's do a series of trickery to copy one bit of stencil to
// destination alpha. Or actually, this is just a bunch of hackery attempts on Wipeout.
// Ignore for now.
/*
glstate.depthTest.disable();
glstate.colorMask.set(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
glstate.stencilTest.enable();
glstate.stencilOp.set(GL_KEEP, GL_KEEP, GL_KEEP); // don't modify stencil§
glstate.stencilFunc.set(GL_GEQUAL, 0xFE, 0xFF);
DrawPlainColor(0x00000000);
//glstate.stencilFunc.set(GL_LESS, 0x80, 0xFF);
//DrawPlainColor(0xFF000000);
glstate.stencilTest.disable();
glstate.colorMask.set(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
*/
glstate.depthTest.disable();
glstate.colorMask.set(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
DrawPlainColor(0x00000000);
shaderManager_->DirtyLastShader(); // dirty lastShader_
}
gstate_c.framebufChanged = false;
// Get parameters

View file

@ -38,7 +38,7 @@ enum {
FB_USAGE_TEXTURE = 4,
};
enum {
enum {
FB_NON_BUFFERED_MODE = 0,
FB_BUFFERED_MODE = 1,
#ifndef USING_GLES2
@ -52,7 +52,7 @@ enum {
struct VirtualFramebuffer {
int last_frame_used;
int last_frame_render;
bool memoryUpdated;
bool memoryUpdated;
u32 fb_address;
u32 z_address;
@ -119,6 +119,8 @@ public:
// If texture != 0, will bind it.
void DrawActiveTexture(GLuint texture, float x, float y, float w, float h, float destW, float destH, bool flip = false, float uscale = 1.0f, float vscale = 1.0f, GLSLProgram *program = 0);
void DrawPlainColor(u32 color);
void DestroyAllFBOs();
void DecimateFBOs();
@ -199,7 +201,9 @@ private:
u8 *convBuf;
GLSLProgram *draw2dprogram_;
GLSLProgram *plainColorProgram_;
GLSLProgram *postShaderProgram_;
int plainColorLoc_;
TextureCache *textureCache_;
ShaderManager *shaderManager_;

View file

@ -299,35 +299,37 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
// We should set "ref" to that value instead of 0.
// In case of clear rectangles, we set it again once we know what the color is.
glstate.stencilFunc.set(GL_ALWAYS, 255, 0xFF);
} else
} else {
glstate.stencilTest.disable();
}
} else {
#if !defined(USING_GLES2)
// Logic Ops
if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY) {
glstate.colorLogicOp.enable();
glstate.logicOp.set(logicOps[gstate.getLogicOp()]);
} else
} else {
glstate.colorLogicOp.disable();
#endif
}
#endif
// Set cull
bool cullEnabled = !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES && gstate.isCullEnabled();
if (cullEnabled) {
glstate.cullFace.enable();
glstate.cullFaceMode.set(cullingMode[gstate.getCullMode()]);
} else
} else {
glstate.cullFace.disable();
}
// Depth Test
if (gstate.isDepthTestEnabled()) {
glstate.depthTest.enable();
glstate.depthFunc.set(ztests[gstate.getDepthTestFunction()]);
glstate.depthWrite.set(gstate.isDepthWriteEnabled() || alwaysDepthWrite ? GL_TRUE : GL_FALSE);
} else
} else {
glstate.depthTest.disable();
}
// PSP color/alpha mask is per bit but we can only support per byte.
// But let's do that, at least. And let's try a threshold.
bool rmask = (gstate.pmskc & 0xFF) < 128;
@ -335,7 +337,7 @@ void TransformDrawEngine::ApplyDrawState(int prim) {
bool bmask = ((gstate.pmskc >> 16) & 0xFF) < 128;
bool amask = (gstate.pmska & 0xFF) < 128;
glstate.colorMask.set(rmask, gmask, bmask, amask);
// Stencil Test
if (gstate.isStencilTestEnabled() && enableStencilTest) {
glstate.stencilTest.enable();

View file

@ -731,10 +731,12 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
}
}
// Here's the best opportunity to try to detect rectangles used to clear the screen, and
// Here's the best opportunity to try to detect rectangles used to clear the screen, and
// replace them with real OpenGL clears. This can provide a speedup on certain mobile chips.
// Disabled for now - depth does not come out exactly the same
// Disabled for now - depth does not come out exactly the same.
//
// An alternative option is to simply ditch all the verts except the first and last to create a single
// rectangle out of many. Quite a small optimization though.
if (false && maxIndex > 1 && gstate.isModeClear() && prim == GE_PRIM_RECTANGLES && IsReallyAClear(maxIndex)) {
u32 clearColor;
memcpy(&clearColor, transformed[0].color0, 4);
@ -749,7 +751,16 @@ void TransformDrawEngine::SoftwareTransformAndDraw(
bool colorMask = gstate.isClearModeColorMask();
bool alphaMask = gstate.isClearModeAlphaMask();
glstate.colorMask.set(colorMask, colorMask, colorMask, alphaMask);
glstate.stencilTest.set(false);
if (alphaMask) {
glstate.stencilTest.set(true);
// Clear stencil
// TODO: extract the stencilValue properly, see below
int stencilValue = 0;
glstate.stencilFunc.set(GL_ALWAYS, stencilValue, 255);
} else {
// Don't touch stencil
glstate.stencilTest.set(false);
}
glstate.scissorTest.set(false);
bool depthMask = gstate.isClearModeDepthMask();