VideoCommon: Fix bounding box on AMD/OpenGL/Windows
Co-authored-by: Techjar <tecknojar@gmail.com>
This commit is contained in:
parent
c404452d3e
commit
c58837964f
|
@ -126,6 +126,8 @@ constexpr BugInfo m_known_bugs[] = {
|
|||
-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},
|
||||
{API_OPENGL, OS_WINDOWS, VENDOR_ATI, DRIVER_ATI, Family::UNKNOWN, BUG_BROKEN_SSBO_FIELD_ATOMICS,
|
||||
-1.0, -1.0, true},
|
||||
};
|
||||
|
||||
static std::map<Bug, BugInfo> m_bugs;
|
||||
|
|
|
@ -298,6 +298,14 @@ enum Bug
|
|||
// Started version: -1
|
||||
// Ended version: -1
|
||||
BUG_BROKEN_VECTOR_BITWISE_AND,
|
||||
|
||||
// BUG: Atomic writes to different fields or array elements of an SSBO have no effect, only
|
||||
// writing to the first field/element works. This causes bounding box emulation to give garbage
|
||||
// values under OpenGL.
|
||||
// Affected devices: AMD (Windows)
|
||||
// Started version: -1
|
||||
// Ended version: -1
|
||||
BUG_BROKEN_SSBO_FIELD_ATOMICS,
|
||||
};
|
||||
|
||||
// Initializes our internal vendor, device family, and driver version
|
||||
|
|
|
@ -451,20 +451,37 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType api_type,
|
|||
|
||||
if (bounding_box)
|
||||
{
|
||||
if (api_type == APIType::D3D)
|
||||
{
|
||||
out.Write("globallycoherent RWBuffer<int> bbox_data : register(u2);\n"
|
||||
"#define atomicMin InterlockedMin\n"
|
||||
"#define atomicMax InterlockedMax");
|
||||
}
|
||||
else
|
||||
{
|
||||
out.Write("SSBO_BINDING(0) buffer BBox {{\n");
|
||||
|
||||
if (DriverDetails::HasBug(DriverDetails::BUG_BROKEN_SSBO_FIELD_ATOMICS))
|
||||
{
|
||||
// AMD drivers on Windows seemingly ignore atomic writes to fields or array elements of an
|
||||
// SSBO other than the first one, but using an int4 seems to work fine
|
||||
out.Write(" int4 bbox_data;\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// The Metal shader compiler fails to compile the atomic instructions when operating on
|
||||
// individual components of a vector
|
||||
out.Write(" int bbox_data[4];\n");
|
||||
}
|
||||
|
||||
out.Write("}};");
|
||||
}
|
||||
|
||||
out.Write(R"(
|
||||
#ifdef API_D3D
|
||||
globallycoherent RWBuffer<int> bbox_data : register(u2);
|
||||
#define atomicMin InterlockedMin
|
||||
#define atomicMax InterlockedMax
|
||||
#define bbox_left bbox_data[0]
|
||||
#define bbox_right bbox_data[1]
|
||||
#define bbox_top bbox_data[2]
|
||||
#define bbox_bottom bbox_data[3]
|
||||
#else
|
||||
SSBO_BINDING(0) buffer BBox {{
|
||||
int bbox_left, bbox_right, bbox_top, bbox_bottom;
|
||||
}};
|
||||
#endif
|
||||
|
||||
void UpdateBoundingBoxBuffer(int2 min_pos, int2 max_pos) {{
|
||||
if (bbox_left > min_pos.x)
|
||||
|
|
Loading…
Reference in New Issue