Skip to content

Commit

Permalink
DriverDetails: Fix broken vector bitwise AND on Mali drivers
Browse files Browse the repository at this point in the history
  • Loading branch information
lynxnb committed Apr 11, 2021
1 parent 5322256 commit fcaea7d
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 6 deletions.
4 changes: 4 additions & 0 deletions Source/Core/VideoCommon/DriverDetails.cpp
Expand Up @@ -122,6 +122,10 @@ constexpr BugInfo m_known_bugs[] = {
-1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_QUALCOMM, DRIVER_QUALCOMM, Family::UNKNOWN,
BUG_SLOW_CACHED_READBACK_MEMORY, -1.0, -1.0, true},
{API_OPENGL, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKEN_VECTOR_BITWISE_AND,
-1.0, -1.0, true},
{API_VULKAN, OS_ALL, VENDOR_ARM, DRIVER_ARM, Family::UNKNOWN, BUG_BROKEN_VECTOR_BITWISE_AND,
-1.0, -1.0, true},
};

static std::map<Bug, BugInfo> m_bugs;
Expand Down
10 changes: 10 additions & 0 deletions Source/Core/VideoCommon/DriverDetails.h
Expand Up @@ -288,6 +288,16 @@ enum Bug
// Mali Vulkan driver, causing high CPU usage in the __pi___inval_cache_range kernel
// function. This flag causes readback buffers to select the coherent type.
BUG_SLOW_CACHED_READBACK_MEMORY,

// BUG: Apparently ARM Mali GLSL compiler managed to break bitwise AND operations between
// two integers vectors, when one of them is non-constant (though the exact cases of when
// this occurs are still unclear to me). The resulting vector from the operation will be
// the constant vector.
// Easy enough to fix, just do the bitwise AND operation on the vector components first and
// then construct the final vector.
// Started version: -1
// Ended version: -1
BUG_BROKEN_VECTOR_BITWISE_AND,
};

// Initializes our internal vendor, device family, and driver version
Expand Down
23 changes: 17 additions & 6 deletions Source/Core/VideoCommon/PixelShaderGen.cpp
Expand Up @@ -1252,12 +1252,23 @@ static void WriteStage(ShaderCode& out, const pixel_shader_uid_data* uid_data, i
if (ac.dest >= TevOutput::Color0)
out.SetConstantsUsed(C_COLORS + u32(ac.dest.Value()), C_COLORS + u32(ac.dest.Value()));

out.Write("\ttevin_a = int4({}, {})&int4(255, 255, 255, 255);\n",
tev_c_input_table[u32(cc.a.Value())], tev_a_input_table[u32(ac.a.Value())]);
out.Write("\ttevin_b = int4({}, {})&int4(255, 255, 255, 255);\n",
tev_c_input_table[u32(cc.b.Value())], tev_a_input_table[u32(ac.b.Value())]);
out.Write("\ttevin_c = int4({}, {})&int4(255, 255, 255, 255);\n",
tev_c_input_table[u32(cc.c.Value())], tev_a_input_table[u32(ac.c.Value())]);
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_VECTOR_BITWISE_AND)) {
out.Write("\ttevin_a = int4({} & 255, {} & 255);\n",
tev_c_input_table[u32(cc.a.Value())], tev_a_input_table[u32(ac.a.Value())]);
out.Write("\ttevin_b = int4({} & 255, {} & 255);\n",
tev_c_input_table[u32(cc.b.Value())], tev_a_input_table[u32(ac.b.Value())]);
out.Write("\ttevin_c = int4({} & 255, {} & 255);\n",
tev_c_input_table[u32(cc.c.Value())], tev_a_input_table[u32(ac.c.Value())]);
}
else
{
out.Write("\ttevin_a = int4({}, {})&int4(255, 255, 255, 255);\n",
tev_c_input_table[u32(cc.a.Value())], tev_a_input_table[u32(ac.a.Value())]);
out.Write("\ttevin_b = int4({}, {})&int4(255, 255, 255, 255);\n",
tev_c_input_table[u32(cc.b.Value())], tev_a_input_table[u32(ac.b.Value())]);
out.Write("\ttevin_c = int4({}, {})&int4(255, 255, 255, 255);\n",
tev_c_input_table[u32(cc.c.Value())], tev_a_input_table[u32(ac.c.Value())]);
}
out.Write("\ttevin_d = int4({}, {});\n", tev_c_input_table[u32(cc.d.Value())],
tev_a_input_table[u32(ac.d.Value())]);

Expand Down

0 comments on commit fcaea7d

Please sign in to comment.