From 0c0d66809d9c029c0468982725ab63be48500081 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 29 Aug 2018 03:00:08 -0700 Subject: [PATCH] PixelShaderGen: Split bbox into seperate variables The Metal shader compiler fails to compile the atomic instructions when operating on individual components of a vector. Spltting it into four variables shouldn't make any difference for other platforms, as they are accessed independently. --- Source/Core/VideoCommon/PixelShaderGen.cpp | 24 ++++++++++++------ Source/Core/VideoCommon/UberShaderPixel.cpp | 28 +++++++++++++-------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 5271d31671..936dd8e937 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -448,7 +448,7 @@ void WritePixelShaderCommonHeader(ShaderCode& out, APIType ApiType, u32 num_texg if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { out.Write("SSBO_BINDING(0) buffer BBox {\n" - "\tint4 bbox_data;\n" + "\tint bbox_left, bbox_right, bbox_top, bbox_bottom;\n" "};\n"); } else @@ -853,13 +853,21 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const ShaderHostConfig& host if (uid_data->bounding_box) { - const char* atomic_op = - (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) ? "atomic" : "Interlocked"; - out.Write("\tif(bbox_data[0] > int(rawpos.x)) %sMin(bbox_data[0], int(rawpos.x));\n" - "\tif(bbox_data[1] < int(rawpos.x)) %sMax(bbox_data[1], int(rawpos.x));\n" - "\tif(bbox_data[2] > int(rawpos.y)) %sMin(bbox_data[2], int(rawpos.y));\n" - "\tif(bbox_data[3] < int(rawpos.y)) %sMax(bbox_data[3], int(rawpos.y));\n", - atomic_op, atomic_op, atomic_op, atomic_op); + if (ApiType == APIType::D3D) + { + out.Write( + "\tif(bbox_data[0] > int(rawpos.x)) InterlockedMin(bbox_data[0], int(rawpos.x));\n" + "\tif(bbox_data[1] < int(rawpos.x)) InterlockedMax(bbox_data[1], int(rawpos.x));\n" + "\tif(bbox_data[2] > int(rawpos.y)) InterlockedMin(bbox_data[2], int(rawpos.y));\n" + "\tif(bbox_data[3] < int(rawpos.y)) InterlockedMax(bbox_data[3], int(rawpos.y));\n"); + } + else + { + out.Write("\tif(bbox_left > int(rawpos.x)) atomicMin(bbox_left, int(rawpos.x));\n" + "\tif(bbox_right < int(rawpos.x)) atomicMax(bbox_right, int(rawpos.x));\n" + "\tif(bbox_top > int(rawpos.y)) atomicMin(bbox_top, int(rawpos.y));\n" + "\tif(bbox_bottom < int(rawpos.y)) atomicMax(bbox_bottom, int(rawpos.y));\n"); + } } out.Write("}\n"); diff --git a/Source/Core/VideoCommon/UberShaderPixel.cpp b/Source/Core/VideoCommon/UberShaderPixel.cpp index 6c5f6f84fe..4d66fac968 100644 --- a/Source/Core/VideoCommon/UberShaderPixel.cpp +++ b/Source/Core/VideoCommon/UberShaderPixel.cpp @@ -1239,17 +1239,23 @@ ShaderCode GenPixelShader(APIType ApiType, const ShaderHostConfig& host_config, if (bounding_box) { - const char* atomic_op = - (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) ? "atomic" : "Interlocked"; out.Write(" if (bpmem_bounding_box) {\n"); - out.Write(" if(bbox_data[0] > int(rawpos.x)) %sMin(bbox_data[0], int(rawpos.x));\n", - atomic_op); - out.Write(" if(bbox_data[1] < int(rawpos.x)) %sMax(bbox_data[1], int(rawpos.x));\n", - atomic_op); - out.Write(" if(bbox_data[2] > int(rawpos.y)) %sMin(bbox_data[2], int(rawpos.y));\n", - atomic_op); - out.Write(" if(bbox_data[3] < int(rawpos.y)) %sMax(bbox_data[3], int(rawpos.y));\n", - atomic_op); + if (ApiType == APIType::D3D) + { + out.Write( + " if(bbox_data[0] > int(rawpos.x)) InterlockedMin(bbox_data[0], int(rawpos.x));\n" + " if(bbox_data[1] < int(rawpos.x)) InterlockedMax(bbox_data[1], int(rawpos.x));\n" + " if(bbox_data[2] > int(rawpos.y)) InterlockedMin(bbox_data[2], int(rawpos.y));\n" + " if(bbox_data[3] < int(rawpos.y)) InterlockedMax(bbox_data[3], int(rawpos.y));\n"); + } + else + { + out.Write("\tif(bbox_left > int(rawpos.x)) atomicMin(bbox_left, int(rawpos.x));\n" + "\tif(bbox_right < int(rawpos.x)) atomicMax(bbox_right, int(rawpos.x));\n" + "\tif(bbox_top > int(rawpos.y)) atomicMin(bbox_top, int(rawpos.y));\n" + "\tif(bbox_bottom < int(rawpos.y)) atomicMax(bbox_bottom, int(rawpos.y));\n"); + } + out.Write(" }\n"); } @@ -1414,4 +1420,4 @@ void EnumeratePixelShaderUids(const std::function& } } } -} +} // namespace UberShader