Skip to content

Commit

Permalink
Make VK_KHR_shader_subgroup_vote tests work with sparse dispatch
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cwabbott0 authored and alegal-arm committed Oct 25, 2018
1 parent a642cc1 commit 9429e62
Showing 1 changed file with 9 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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) +
Expand Down Expand Up @@ -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) +
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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) +
Expand Down Expand Up @@ -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) +
Expand Down

0 comments on commit 9429e62

Please sign in to comment.