From 6d4867e36a5459b1606809ab9ded18ecbe463fc6 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Tue, 28 Oct 2014 22:03:06 -0500 Subject: [PATCH] Fixes missing objects on Adreno hardware. This particular bug from our friends over at Qualcomm manifests itself due to our alpha testing code having a conditional if statement in it. This is a fairly recent breakage this time around, it was introduced in the v95 driver which comes with Android 5.0 on the Nexus 5. So to break this issue down; In our alpha testing code we have two comparisons that happen and if they are true we will continue rendering, but if they aren't true we do an early discard and return. This is summed up with a fairly simple if statement. if (!(condition_1 condition_2)) { /* discard and return */ } This particular issue isn't actually due to the conditions within the if statement, but the negation of the result. This is the particular issue that causes Qualcomm to fall flat on its face while doing so. I've got two simple test cases that demonstrate this. Non-working: http://hastebin.com/evugohixov.avrasm Working: http://hastebin.com/afimesuwen.avrasm As one can see, the disassembled output between the two shaders is different even though in reality it should have the same visual result. I'm currently writing up a simple test program for Qualcomm to enjoy, since they will be asking for one when I tell them about the bug. It will be tracked in our video driver failure spreadsheet along with the others. --- Source/Core/VideoCommon/PixelShaderGen.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 4ef07dbb10..0f03fc013b 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -943,7 +943,10 @@ static inline void WriteAlphaTest(T& out, pixel_shader_uid_data* uid_data, API_T out.SetConstantsUsed(C_ALPHA, C_ALPHA); - out.Write("\tif(!( "); + // This outputted if statement is not like 'if(!(cond))' for a reason. + // Qualcomm's v95 drivers produce incorrect code using logical not + // Checking against false produces the correct code. + out.Write("\tif(( "); uid_data->alpha_test_comp0 = bpmem.alpha_test.comp0; uid_data->alpha_test_comp1 = bpmem.alpha_test.comp1; @@ -958,7 +961,7 @@ static inline void WriteAlphaTest(T& out, pixel_shader_uid_data* uid_data, API_T // Lookup the second component from the alpha function table compindex = bpmem.alpha_test.comp1; out.Write(tevAlphaFuncsTable[compindex], alphaRef[1]); - out.Write(")) {\n"); + out.Write(") == false) {\n"); out.Write("\t\tocol0 = float4(0.0, 0.0, 0.0, 0.0);\n"); if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)