Add test to stress wide OpPhi instructions
authorJari Komppa <jari.komppa@siru.fi>
Tue, 22 Aug 2017 11:50:17 +0000 (14:50 +0300)
committerAlexander Galazin <Alexander.Galazin@arm.com>
Wed, 6 Sep 2017 16:29:04 +0000 (12:29 -0400)
New test that has a 1024 case wide OpPhi instruction.

The test has been written so that it is easy to change to any desirable
width; based on the SPIR-V specification a width of 16k should be
acceptable (as there can be 16k switch cases). However, that would
generate a rather large (about 50kLOC) shader.

Affects:

dEQP-VK.spirv_assembly.instruction.compute.opphi.wide

Components: Vulkan

VK-GL-CTS issue: 259

Change-Id: Ide349e19ab4811c8c8c13bff0d72ac6cf19349ed

android/cts/master/vk-master.txt
external/vulkancts/modules/vulkan/spirv_assembly/vktSpvAsmInstructionTests.cpp
external/vulkancts/mustpass/1.0.3/vk-default.txt

index a61ab53..7885baf 100644 (file)
@@ -162189,6 +162189,7 @@ dEQP-VK.spirv_assembly.instruction.compute.decoration_group.all
 dEQP-VK.spirv_assembly.instruction.compute.opphi.block
 dEQP-VK.spirv_assembly.instruction.compute.opphi.induction
 dEQP-VK.spirv_assembly.instruction.compute.opphi.swap
+dEQP-VK.spirv_assembly.instruction.compute.opphi.wide
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.none
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.unroll
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.dont_unroll
index 171a3e6..9986732 100644 (file)
@@ -2524,18 +2524,60 @@ tcu::TestCaseGroup* createSpecConstantGroup (tcu::TestContext& testCtx)
        return group.release();
 }
 
+string generateConstantDefinitions (int count)
+{
+       std::stringstream       r;
+       for (int i = 0; i < count; i++)
+               r << "%cf" << (i * 10 + 5) << " = OpConstant %f32 " <<(i * 10 + 5) << ".0\n";
+       return r.str() + string("\n");
+}
+
+string generateSwitchCases (int count)
+{
+       std::stringstream       r;
+       for (int i = 0; i < count; i++)
+               r << " " << i << " %case" << i;
+       return r.str() + string("\n");
+}
+
+string generateSwitchTargets (int count)
+{
+       std::stringstream       r;
+       for (int i = 0; i < count; i++)
+               r << "%case" << i << " = OpLabel\n            OpBranch %phi\n";
+       return r.str() + string("\n");
+}
+
+string generateOpPhiParams (int count)
+{
+       std::stringstream       r;
+       for (int i = 0; i < count; i++)
+               r << " %cf" << (i * 10 + 5) << " %case" << i;
+       return r.str() + string("\n");
+}
+
+string generateIntWidth (int value)
+{
+       std::stringstream       r;
+       r << value;
+       return r.str();
+}
+
 tcu::TestCaseGroup* createOpPhiGroup (tcu::TestContext& testCtx)
 {
        de::MovePtr<tcu::TestCaseGroup> group                   (new tcu::TestCaseGroup(testCtx, "opphi", "Test the OpPhi instruction"));
        ComputeShaderSpec                               spec1;
        ComputeShaderSpec                               spec2;
        ComputeShaderSpec                               spec3;
+       ComputeShaderSpec                               spec4;
        de::Random                                              rnd                             (deStringHash(group->getName()));
        const int                                               numElements             = 100;
        vector<float>                                   inputFloats             (numElements, 0);
        vector<float>                                   outputFloats1   (numElements, 0);
        vector<float>                                   outputFloats2   (numElements, 0);
        vector<float>                                   outputFloats3   (numElements, 0);
+       vector<float>                                   outputFloats4   (numElements, 0);
+       const int                                               test4Width              = 1024;
 
        fillRandomScalars(rnd, -300.f, 300.f, &inputFloats[0], numElements);
 
@@ -2553,6 +2595,9 @@ tcu::TestCaseGroup* createOpPhiGroup (tcu::TestContext& testCtx)
                }
                outputFloats2[ndx] = inputFloats[ndx] + 6.5f * 3;
                outputFloats3[ndx] = 8.5f - inputFloats[ndx];
+
+               int index4 = (int)deFloor(deAbs((float)ndx * inputFloats[ndx]));
+               outputFloats4[ndx] = (float)(index4 % test4Width) * 10.0f + 5.0f;
        }
 
        spec1.assembly =
@@ -2705,6 +2750,64 @@ tcu::TestCaseGroup* createOpPhiGroup (tcu::TestContext& testCtx)
 
        group->addChild(new SpvAsmComputeShaderCase(testCtx, "swap", "Swap the values of two variables using OpPhi", spec3));
 
+       spec4.assembly =
+               "OpCapability Shader\n"
+               "%ext = OpExtInstImport \"GLSL.std.450\"\n"
+               "OpMemoryModel Logical GLSL450\n"
+               "OpEntryPoint GLCompute %main \"main\" %id\n"
+               "OpExecutionMode %main LocalSize 1 1 1\n"
+
+               "OpSource GLSL 430\n"
+               "OpName %main \"main\"\n"
+               "OpName %id \"gl_GlobalInvocationID\"\n"
+
+               "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+               + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+               "%id       = OpVariable %uvec3ptr Input\n"
+               "%zero     = OpConstant %i32 0\n"
+               "%cimod    = OpConstant %u32 " + generateIntWidth(test4Width) + "\n"
+
+               + generateConstantDefinitions(test4Width) +
+
+               "%main     = OpFunction %void None %voidf\n"
+               "%entry    = OpLabel\n"
+               "%idval    = OpLoad %uvec3 %id\n"
+               "%x        = OpCompositeExtract %u32 %idval 0\n"
+               "%inloc    = OpAccessChain %f32ptr %indata %zero %x\n"
+               "%inval    = OpLoad %f32 %inloc\n"
+               "%xf       = OpConvertUToF %f32 %x\n"
+               "%xm       = OpFMul %f32 %xf %inval\n"
+               "%xa       = OpExtInst %f32 %ext FAbs %xm\n"
+               "%xi       = OpConvertFToU %u32 %xa\n"
+               "%selector = OpUMod %u32 %xi %cimod\n"
+               "            OpSelectionMerge %phi None\n"
+               "            OpSwitch %selector %default "
+
+               + generateSwitchCases(test4Width) +
+
+               "%default  = OpLabel\n"
+               "            OpUnreachable\n"
+
+               + generateSwitchTargets(test4Width) +
+
+               "%phi      = OpLabel\n"
+               "%result   = OpPhi %f32"
+
+               + generateOpPhiParams(test4Width) +
+
+               "%outloc   = OpAccessChain %f32ptr %outdata %zero %x\n"
+               "            OpStore %outloc %result\n"
+               "            OpReturn\n"
+
+               "            OpFunctionEnd\n";
+       spec4.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+       spec4.outputs.push_back(BufferSp(new Float32Buffer(outputFloats4)));
+       spec4.numWorkGroups = IVec3(numElements, 1, 1);
+
+       group->addChild(new SpvAsmComputeShaderCase(testCtx, "wide", "OpPhi with a lot of parameters", spec4));
+
        return group.release();
 }
 
index c736972..2077260 100644 (file)
@@ -162194,6 +162194,7 @@ dEQP-VK.spirv_assembly.instruction.compute.decoration_group.all
 dEQP-VK.spirv_assembly.instruction.compute.opphi.block
 dEQP-VK.spirv_assembly.instruction.compute.opphi.induction
 dEQP-VK.spirv_assembly.instruction.compute.opphi.swap
+dEQP-VK.spirv_assembly.instruction.compute.opphi.wide
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.none
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.unroll
 dEQP-VK.spirv_assembly.instruction.compute.loop_control.dont_unroll