From: Connor Abbott Date: Thu, 18 Oct 2018 12:20:31 +0000 (+0200) Subject: Make VK_KHR_shader_subgroup_vote tests work with sparse dispatch X-Git-Tag: upstream/1.3.5~2324^2~63 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9429e621c48848d224e35f30a1ae45a4a079922c;p=platform%2Fupstream%2FVK-GL-CTS.git Make VK_KHR_shader_subgroup_vote tests work with sparse dispatch The voteallequal tests created a value which was supposed to be different for some threads in the subgroup, and then called voteAllEqual() on it expecting it to return false. However, because the entire expression was reduced modulo 2, if the implementation dispatched threads in a sparse manner so that some subgroup indices were skipped, then all the active threads could have wound up with the same value. In particular, this caused the graphics voteallequal tests to fail in the fragment stage on AMD due to how the hardware dispatches single-pixel point sprites. Fix this by just using gl_SubgroupIndex directly, so that every thread is guaranteed to get a unique value. Some care has to be taken for boolean values -- I've just made them use subgroupElect() instead, as that's the simplest way to get a guaranteed-divergent boolean value. Affected tests: dEQP-VK.subgroups.vote.* Components: Vulkan VK-GL-CTS Issue: 1437 Change-Id: I10ddc438db4cd4925bdbc4f458a082fcab9c9155 --- diff --git a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp index 328d896..c8ced10 100755 --- a/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp +++ b/external/vulkancts/modules/vulkan/subgroups/vktSubgroupsVoteTests.cpp @@ -220,6 +220,8 @@ struct CaseDefinition void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefinition caseDef) { const vk::ShaderBuildOptions buildOptions (programCollection.usedVulkanVersion, vk::SPIRV_VERSION_1_3, 0u); + const bool formatIsBoolean = + VK_FORMAT_R8_USCALED == caseDef.format || VK_FORMAT_R8G8_USCALED == caseDef.format || VK_FORMAT_R8G8B8_USCALED == caseDef.format || VK_FORMAT_R8G8B8A8_USCALED == caseDef.format; if (VK_SHADER_STAGE_FRAGMENT_BIT != caseDef.shaderStage) subgroups::setFragmentShaderFrameBuffer(programCollection); @@ -253,7 +255,7 @@ void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefiniti " result |= 0x4;\n" : (OPTYPE_ALLEQUAL == caseDef.opType) ? " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + - " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(12.0 * float(data[gl_SubgroupInvocationID]) + ((gl_SubgroupInvocationID % 5)%2));\n" + " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + (formatIsBoolean ? "(subgroupElect())\n;" : "(12.0 * float(data[gl_SubgroupInvocationID]) + gl_SubgroupInvocationID);\n") + " result = " + getOpTypeName(caseDef.opType) + "(" + subgroups::getFormatNameForGLSL(caseDef.format) + "(1)) ? 0x1 : 0;\n" " result |= " + getOpTypeName(caseDef.opType) + @@ -389,7 +391,7 @@ void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefiniti " result |= 0x4;\n" : (OPTYPE_ALLEQUAL == caseDef.opType) ? " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + - " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(12.0 * float(data[gl_SubgroupInvocationID]) + ((int(gl_FragCoord.x*gl_SubgroupInvocationID) % 5)%2));\n" + " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + (formatIsBoolean ? "(subgroupElect());\n" : "(12.0 * float(data[gl_SubgroupInvocationID]) + int(gl_FragCoord.x*gl_SubgroupInvocationID));\n") + " result |= " + getOpTypeName(caseDef.opType) + "(" + subgroups::getFormatNameForGLSL(caseDef.format) + "(1)) ? 0x10 : 0;\n" " result |= " + getOpTypeName(caseDef.opType) + @@ -439,6 +441,8 @@ void initFrameBufferPrograms (SourceCollections& programCollection, CaseDefiniti void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef) { + const bool formatIsBoolean = + VK_FORMAT_R8_USCALED == caseDef.format || VK_FORMAT_R8G8_USCALED == caseDef.format || VK_FORMAT_R8G8B8_USCALED == caseDef.format || VK_FORMAT_R8G8B8A8_USCALED == caseDef.format; if (VK_SHADER_STAGE_COMPUTE_BIT == caseDef.shaderStage) { std::ostringstream src; @@ -484,7 +488,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef) else if (OPTYPE_ALLEQUAL == caseDef.opType) { src << " " << subgroups::getFormatNameForGLSL(caseDef.format) <<" valueEqual = " << subgroups::getFormatNameForGLSL(caseDef.format) << "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" - << " " << subgroups::getFormatNameForGLSL(caseDef.format) <<" valueNoEqual = " << subgroups::getFormatNameForGLSL(caseDef.format) << "(12.0 * float(data[gl_SubgroupInvocationID]) + ((offset % 5)%2));\n" + << " " << subgroups::getFormatNameForGLSL(caseDef.format) <<" valueNoEqual = " << subgroups::getFormatNameForGLSL(caseDef.format) << (formatIsBoolean ? "(subgroupElect());\n" : "(12.0 * float(data[gl_SubgroupInvocationID]) + offset);\n") <<" result[offset] = " << getOpTypeName(caseDef.opType) << "(" << subgroups::getFormatNameForGLSL(caseDef.format) << "(1)) ? 0x1 : 0x0;\n" << " result[offset] |= " << getOpTypeName(caseDef.opType) @@ -520,7 +524,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef) " result[offset] |= 0x4;\n" : (OPTYPE_ALLEQUAL == caseDef.opType) ? " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + - " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(12.0 * float(data[gl_SubgroupInvocationID]) + ((gl_SubgroupInvocationID % 5)%2));\n" + " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + (formatIsBoolean ? "(subgroupElect());\n" : "(12.0 * float(data[gl_SubgroupInvocationID]) + gl_SubgroupInvocationID);\n") + " result[offset] = " + getOpTypeName(caseDef.opType) + "(" + subgroups::getFormatNameForGLSL(caseDef.format) + "(1)) ? 0x1 : 0;\n" " result[offset] |= " + getOpTypeName(caseDef.opType) + @@ -662,7 +666,7 @@ void initPrograms(SourceCollections& programCollection, CaseDefinition caseDef) " result |= 0x4;\n" : (OPTYPE_ALLEQUAL == caseDef.opType) ? " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(1.25 * float(data[gl_SubgroupInvocationID]) + 5.0);\n" + - " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + "(12.0 * float(data[gl_SubgroupInvocationID]) + ((int(gl_FragCoord.x*gl_SubgroupInvocationID) % 5)%2));\n" + " " + subgroups::getFormatNameForGLSL(caseDef.format) + " valueNoEqual = " + subgroups::getFormatNameForGLSL(caseDef.format) + (formatIsBoolean ? "(subgroupElect());\n" : "(12.0 * float(data[gl_SubgroupInvocationID]) + int(gl_FragCoord.x*gl_SubgroupInvocationID));\n") + " result = " + getOpTypeName(caseDef.opType) + "(" + subgroups::getFormatNameForGLSL(caseDef.format) + "(1)) ? 0x1 : 0;\n" " result |= " + getOpTypeName(caseDef.opType) +