Skip to content
Permalink
Browse files

Merge pull request #11277 from unknownbrackets/fragtest

Oops, fix an edge case for avoiding discard
  • Loading branch information...
hrydgard committed Jul 30, 2018
2 parents a776dce + 7885a88 commit 31646d6c8d065547bd7b86679c30a909e1a08414
Showing with 28 additions and 52 deletions.
  1. +26 −51 GPU/Common/GPUStateUtils.cpp
  2. +1 −0 GPU/GLES/TextureCacheGLES.cpp
  3. +1 −1 headless/WindowsHeadlessHost.cpp
@@ -40,20 +40,28 @@ bool CanUseHardwareTransform(int prim) {
return !gstate.isModeThrough() && prim != GE_PRIM_RECTANGLES;
}

// Dest factors where it's safe to eliminate the alpha test under certain conditions
static const bool safeDestFactors[16] = {
true, // GE_DSTBLEND_SRCCOLOR,
true, // GE_DSTBLEND_INVSRCCOLOR,
false, // GE_DSTBLEND_SRCALPHA,
true, // GE_DSTBLEND_INVSRCALPHA,
true, // GE_DSTBLEND_DSTALPHA,
true, // GE_DSTBLEND_INVDSTALPHA,
false, // GE_DSTBLEND_DOUBLESRCALPHA,
false, // GE_DSTBLEND_DOUBLEINVSRCALPHA,
true, // GE_DSTBLEND_DOUBLEDSTALPHA,
true, // GE_DSTBLEND_DOUBLEINVDSTALPHA,
true, //GE_DSTBLEND_FIXB,
};
bool NeedsTestDiscard() {
// We assume this is called only when enabled and not trivially true (may also be for color testing.)
if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF)
return true;
if (gstate.isDepthTestEnabled() && gstate.isDepthWriteEnabled())
return true;
if (!gstate.isAlphaBlendEnabled())
return true;
if (gstate.getBlendFuncA() != GE_SRCBLEND_SRCALPHA && gstate.getBlendFuncA() != GE_DSTBLEND_DOUBLESRCALPHA)
return true;
// GE_DSTBLEND_DOUBLEINVSRCALPHA is actually inverse double src alpha, and doubling zero is still zero.
if (gstate.getBlendFuncB() != GE_DSTBLEND_INVSRCALPHA && gstate.getBlendFuncB() != GE_DSTBLEND_DOUBLEINVSRCALPHA) {
if (gstate.getBlendFuncB() != GE_DSTBLEND_FIXB || gstate.getFixB() != 0xFFFFFF)
return true;
}
if (gstate.getBlendEq() != GE_BLENDMODE_MUL_AND_ADD && gstate.getBlendEq() != GE_BLENDMODE_MUL_AND_SUBTRACT_REVERSE)
return true;
if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY)
return true;

return false;
}

bool IsAlphaTestTriviallyTrue() {
switch (gstate.getAlphaTestFunction()) {
@@ -80,25 +88,10 @@ bool IsAlphaTestTriviallyTrue() {

case GE_COMP_GREATER:
{
#if 0
// Easy way to check the values in the debugger without ruining && early-out
bool doTextureAlpha = gstate.isTextureAlphaUsed();
bool stencilTest = gstate.isStencilTestEnabled();
bool depthTest = gstate.isDepthTestEnabled();
GEComparison depthTestFunc = gstate.getDepthTestFunction();
int alphaRef = gstate.getAlphaTestRef();
int blendA = gstate.getBlendFuncA();
bool blendEnabled = gstate.isAlphaBlendEnabled();
int blendB = gstate.getBlendFuncA();
#endif
return (gstate_c.vertexFullAlpha && (gstate_c.textureFullAlpha || !gstate.isTextureAlphaUsed())) || (
(!gstate.isStencilTestEnabled() &&
!gstate.isDepthTestEnabled() &&
(!gstate.isLogicOpEnabled() || gstate.getLogicOp() == GE_LOGIC_COPY) &&
gstate.getAlphaTestRef() == 0 &&
gstate.isAlphaBlendEnabled() &&
gstate.getBlendFuncA() == GE_SRCBLEND_SRCALPHA &&
safeDestFactors[(int)gstate.getBlendFuncB()]));
// If the texture and vertex only use 1.0 alpha, then the ref value doesn't matter.
if (gstate_c.vertexFullAlpha && (gstate_c.textureFullAlpha || !gstate.isTextureAlphaUsed()))
return true;
return gstate.getAlphaTestRef() == 0 && !NeedsTestDiscard();
}

case GE_COMP_LEQUAL:
@@ -113,24 +106,6 @@ bool IsAlphaTestTriviallyTrue() {
}
}

bool NeedsTestDiscard() {
// We assume this is called only when enabled and not trivially true (may also be for color testing.)
if (gstate.isStencilTestEnabled() && (gstate.pmska & 0xFF) != 0xFF)
return true;
if (gstate.isDepthTestEnabled() && gstate.isDepthWriteEnabled())
return true;
if (!gstate.isAlphaBlendEnabled())
return true;
if (gstate.isLogicOpEnabled() && gstate.getLogicOp() != GE_LOGIC_COPY)
return true;
if (gstate.getBlendFuncA() != GE_SRCBLEND_SRCALPHA && gstate.getBlendFuncA() != GE_DSTBLEND_DOUBLESRCALPHA)
return true;
if (!safeDestFactors[(int)gstate.getBlendFuncB()])
return true;

return false;
}

bool IsAlphaTestAgainstZero() {
return gstate.getAlphaTestRef() == 0 && gstate.getAlphaTestMask() == 0xFF;
}
@@ -862,6 +862,7 @@ bool TextureCacheGLES::GetCurrentTextureDebug(GPUDebugBuffer &buffer, int level)
GLRenderManager *renderManager = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER);

// Not a framebuffer, so let's assume these are right.
// TODO: But they may definitely not be, if the texture was scaled.
int w = gstate.getTextureWidth(level);
int h = gstate.getTextureHeight(level);

@@ -163,7 +163,7 @@ bool WindowsHeadlessHost::InitGraphics(std::string *error_message, GraphicsConte

void WindowsHeadlessHost::ShutdownGraphics() {
gfx_->StopThread();
while (threadState_ != RenderThreadState::STOPPED)
while (threadState_ != RenderThreadState::STOPPED && threadState_ != RenderThreadState::IDLE)
sleep_ms(1);

gfx_->Shutdown();

0 comments on commit 31646d6

Please sign in to comment.
You can’t perform that action at this time.