Refactor: Compatible compute and graphics VerifyIO
[platform/upstream/VK-GL-CTS.git] / external / vulkancts / modules / vulkan / spirv_assembly / vktSpvAsmInstructionTests.cpp
index f97e249..77b677b 100644 (file)
@@ -49,6 +49,7 @@
 #include "deMath.h"
 #include "tcuStringTemplate.hpp"
 
+#include "vktSpvAsmCrossStageInterfaceTests.hpp"
 #include "vktSpvAsm8bitStorageTests.hpp"
 #include "vktSpvAsm16bitStorageTests.hpp"
 #include "vktSpvAsmUboMatrixPaddingTests.hpp"
@@ -59,6 +60,8 @@
 #include "vktSpvAsmComputeShaderTestUtil.hpp"
 #include "vktSpvAsmGraphicsShaderTestUtil.hpp"
 #include "vktSpvAsmVariablePointersTests.hpp"
+#include "vktSpvAsmVariableInitTests.hpp"
+#include "vktSpvAsmPointerParameterTests.hpp"
 #include "vktSpvAsmSpirvVersionTests.hpp"
 #include "vktTestCaseUtil.hpp"
 #include "vktSpvAsmLoopDepLenTests.hpp"
@@ -366,7 +369,7 @@ tcu::TestCaseGroup* createOpNopGroup (tcu::TestContext& testCtx)
        return group.release();
 }
 
-bool compareFUnord (const std::vector<BufferSp>& inputs, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog& log)
+bool compareFUnord (const std::vector<Resource>& inputs, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog& log)
 {
        if (outputAllocs.size() != 1)
                return false;
@@ -375,14 +378,14 @@ bool compareFUnord (const std::vector<BufferSp>& inputs, const vector<Allocation
        vector<deUint8> input2Bytes;
        vector<deUint8> expectedBytes;
 
-       inputs[0]->getBytes(input1Bytes);
-       inputs[1]->getBytes(input2Bytes);
-       expectedOutputs[0]->getBytes(expectedBytes);
+       inputs[0].getBytes(input1Bytes);
+       inputs[1].getBytes(input2Bytes);
+       expectedOutputs[0].getBytes(expectedBytes);
 
-       const deInt32* const    expectedOutputAsInt             = reinterpret_cast<const deInt32* const>(&expectedBytes.front());
-       const deInt32* const    outputAsInt                             = static_cast<const deInt32* const>(outputAllocs[0]->getHostPtr());
-       const float* const              input1AsFloat                   = reinterpret_cast<const float* const>(&input1Bytes.front());
-       const float* const              input2AsFloat                   = reinterpret_cast<const float* const>(&input2Bytes.front());
+       const deInt32* const    expectedOutputAsInt             = reinterpret_cast<const deInt32*>(&expectedBytes.front());
+       const deInt32* const    outputAsInt                             = static_cast<const deInt32*>(outputAllocs[0]->getHostPtr());
+       const float* const              input1AsFloat                   = reinterpret_cast<const float*>(&input1Bytes.front());
+       const float* const              input2AsFloat                   = reinterpret_cast<const float*>(&input2Bytes.front());
        bool returnValue                                                                = true;
 
        for (size_t idx = 0; idx < expectedBytes.size() / sizeof(deInt32); ++idx)
@@ -412,8 +415,8 @@ struct OpFUnordCase
 
 #define ADD_OPFUNORD_CASE(NAME, OPCODE, OPERATOR) \
 do { \
-    struct compare_##NAME { static VkBool32 compare(float x, float y) { return (x OPERATOR y) ? VK_TRUE : VK_FALSE; } }; \
-    cases.push_back(OpFUnordCase(#NAME, OPCODE, compare_##NAME::compare)); \
+       struct compare_##NAME { static VkBool32 compare(float x, float y) { return (x OPERATOR y) ? VK_TRUE : VK_FALSE; } }; \
+       cases.push_back(OpFUnordCase(#NAME, OPCODE, compare_##NAME::compare)); \
 } while (deGetFalse())
 
 tcu::TestCaseGroup* createOpFUnordGroup (tcu::TestContext& testCtx)
@@ -529,22 +532,26 @@ struct OpAtomicCase
 {
        const char*             name;
        const char*             assembly;
+       const char*             retValAssembly;
        OpAtomicType    opAtomic;
        deInt32                 numOutputElements;
 
-                                       OpAtomicCase                    (const char* _name, const char* _assembly, OpAtomicType _opAtomic, deInt32 _numOutputElements)
+                                       OpAtomicCase(const char* _name, const char* _assembly, const char* _retValAssembly, OpAtomicType _opAtomic, deInt32 _numOutputElements)
                                                : name                          (_name)
                                                , assembly                      (_assembly)
+                                               , retValAssembly        (_retValAssembly)
                                                , opAtomic                      (_opAtomic)
                                                , numOutputElements     (_numOutputElements) {}
 };
 
-tcu::TestCaseGroup* createOpAtomicGroup (tcu::TestContext& testCtx, bool useStorageBuffer)
+tcu::TestCaseGroup* createOpAtomicGroup (tcu::TestContext& testCtx, bool useStorageBuffer, int numElements = 65535, bool verifyReturnValues = false)
 {
-       de::MovePtr<tcu::TestCaseGroup> group                           (new tcu::TestCaseGroup(testCtx,
-                                                                                                                                                               useStorageBuffer ? "opatomic_storage_buffer" : "opatomic",
-                                                                                                                                                               "Test the OpAtomic* opcodes"));
-       const int                                               numElements                     = 65535;
+       std::string                                             groupName                       ("opatomic");
+       if (useStorageBuffer)
+               groupName += "_storage_buffer";
+       if (verifyReturnValues)
+               groupName += "_return_values";
+       de::MovePtr<tcu::TestCaseGroup> group                           (new tcu::TestCaseGroup(testCtx, groupName.c_str(), "Test the OpAtomic* opcodes"));
        vector<OpAtomicCase>                    cases;
 
        const StringTemplate                    shaderTemplate  (
@@ -573,6 +580,8 @@ tcu::TestCaseGroup* createOpAtomicGroup (tcu::TestContext& testCtx, bool useStor
                "OpMemberDecorate %sumbuf 0 Coherent\n"
                "OpMemberDecorate %sumbuf 0 Offset 0\n"
 
+               "${RETVAL_BUF_DECORATE}"
+
                + getComputeAsmCommonTypes("${BLOCK_POINTER_TYPE}") +
 
                "%buf       = OpTypeStruct %i32arr\n"
@@ -583,6 +592,8 @@ tcu::TestCaseGroup* createOpAtomicGroup (tcu::TestContext& testCtx, bool useStor
                "%sumbufptr = OpTypePointer ${BLOCK_POINTER_TYPE} %sumbuf\n"
                "%sum       = OpVariable %sumbufptr ${BLOCK_POINTER_TYPE}\n"
 
+               "${RETVAL_BUF_DECL}"
+
                "%id        = OpVariable %uvec3ptr Input\n"
                "%minusone  = OpConstant %i32 -1\n"
                "%zero      = OpConstant %i32 0\n"
@@ -599,28 +610,39 @@ tcu::TestCaseGroup* createOpAtomicGroup (tcu::TestContext& testCtx, bool useStor
 
                "%outloc    = OpAccessChain %i32ptr %sum %zero ${INDEX}\n"
                "${INSTRUCTION}"
+               "${RETVAL_ASSEMBLY}"
 
                "             OpReturn\n"
                "             OpFunctionEnd\n");
 
-       #define ADD_OPATOMIC_CASE(NAME, ASSEMBLY, OPATOMIC, NUM_OUTPUT_ELEMENTS) \
+       #define ADD_OPATOMIC_CASE(NAME, ASSEMBLY, RETVAL_ASSEMBLY, OPATOMIC, NUM_OUTPUT_ELEMENTS) \
        do { \
-               DE_STATIC_ASSERT((NUM_OUTPUT_ELEMENTS) == 1 || (NUM_OUTPUT_ELEMENTS) == numElements); \
-               cases.push_back(OpAtomicCase(#NAME, ASSEMBLY, OPATOMIC, NUM_OUTPUT_ELEMENTS)); \
+               DE_ASSERT((NUM_OUTPUT_ELEMENTS) == 1 || (NUM_OUTPUT_ELEMENTS) == numElements); \
+               cases.push_back(OpAtomicCase(#NAME, ASSEMBLY, RETVAL_ASSEMBLY, OPATOMIC, NUM_OUTPUT_ELEMENTS)); \
        } while (deGetFalse())
-       #define ADD_OPATOMIC_CASE_1(NAME, ASSEMBLY, OPATOMIC) ADD_OPATOMIC_CASE(NAME, ASSEMBLY, OPATOMIC, 1)
-       #define ADD_OPATOMIC_CASE_N(NAME, ASSEMBLY, OPATOMIC) ADD_OPATOMIC_CASE(NAME, ASSEMBLY, OPATOMIC, numElements)
-
-       ADD_OPATOMIC_CASE_1(iadd,       "%unused    = OpAtomicIAdd %i32 %outloc %one %zero %inval\n", OPATOMIC_IADD );
-       ADD_OPATOMIC_CASE_1(isub,       "%unused    = OpAtomicISub %i32 %outloc %one %zero %inval\n", OPATOMIC_ISUB );
-       ADD_OPATOMIC_CASE_1(iinc,       "%unused    = OpAtomicIIncrement %i32 %outloc %one %zero\n",  OPATOMIC_IINC );
-       ADD_OPATOMIC_CASE_1(idec,       "%unused    = OpAtomicIDecrement %i32 %outloc %one %zero\n",  OPATOMIC_IDEC );
-       ADD_OPATOMIC_CASE_N(load,       "%inval2    = OpAtomicLoad %i32 %inloc %zero %zero\n"
-                                                               "             OpStore %outloc %inval2\n",  OPATOMIC_LOAD );
-       ADD_OPATOMIC_CASE_N(store,      "             OpAtomicStore %outloc %zero %zero %inval\n",  OPATOMIC_STORE );
+       #define ADD_OPATOMIC_CASE_1(NAME, ASSEMBLY, RETVAL_ASSEMBLY, OPATOMIC) ADD_OPATOMIC_CASE(NAME, ASSEMBLY, RETVAL_ASSEMBLY, OPATOMIC, 1)
+       #define ADD_OPATOMIC_CASE_N(NAME, ASSEMBLY, RETVAL_ASSEMBLY, OPATOMIC) ADD_OPATOMIC_CASE(NAME, ASSEMBLY, RETVAL_ASSEMBLY, OPATOMIC, numElements)
+
+       ADD_OPATOMIC_CASE_1(iadd,       "%retv      = OpAtomicIAdd %i32 %outloc %one %zero %inval\n",
+                                                               "             OpStore %retloc %retv\n", OPATOMIC_IADD );
+       ADD_OPATOMIC_CASE_1(isub,       "%retv      = OpAtomicISub %i32 %outloc %one %zero %inval\n",
+                                                               "             OpStore %retloc %retv\n", OPATOMIC_ISUB );
+       ADD_OPATOMIC_CASE_1(iinc,       "%retv      = OpAtomicIIncrement %i32 %outloc %one %zero\n",
+                                                               "             OpStore %retloc %retv\n", OPATOMIC_IINC );
+       ADD_OPATOMIC_CASE_1(idec,       "%retv      = OpAtomicIDecrement %i32 %outloc %one %zero\n",
+                                                               "             OpStore %retloc %retv\n", OPATOMIC_IDEC );
+       if (!verifyReturnValues)
+       {
+               ADD_OPATOMIC_CASE_N(load,       "%inval2    = OpAtomicLoad %i32 %inloc %one %zero\n"
+                                                                       "             OpStore %outloc %inval2\n", "", OPATOMIC_LOAD );
+               ADD_OPATOMIC_CASE_N(store,      "             OpAtomicStore %outloc %one %zero %inval\n", "", OPATOMIC_STORE );
+       }
+
        ADD_OPATOMIC_CASE_N(compex, "%even      = OpSMod %i32 %inval %two\n"
                                                                "             OpStore %outloc %even\n"
-                                                               "%unused    = OpAtomicCompareExchange %i32 %outloc %one %zero %zero %minusone %zero\n",  OPATOMIC_COMPEX );
+                                                               "%retv      = OpAtomicCompareExchange %i32 %outloc %one %zero %zero %minusone %zero\n",
+                                                               "                         OpStore %retloc %retv\n", OPATOMIC_COMPEX );
+
 
        #undef ADD_OPATOMIC_CASE
        #undef ADD_OPATOMIC_CASE_1
@@ -637,6 +659,36 @@ tcu::TestCaseGroup* createOpAtomicGroup (tcu::TestContext& testCtx, bool useStor
                specializations["INSTRUCTION"]                  = cases[caseNdx].assembly;
                specializations["BLOCK_DECORATION"]             = useStorageBuffer ? "Block" : "BufferBlock";
                specializations["BLOCK_POINTER_TYPE"]   = useStorageBuffer ? "StorageBuffer" : "Uniform";
+
+               if (verifyReturnValues)
+               {
+                       const StringTemplate blockDecoration    (
+                               "\n"
+                               "OpDecorate %retbuf ${BLOCK_DECORATION}\n"
+                               "OpDecorate %ret DescriptorSet 0\n"
+                               "OpDecorate %ret Binding 2\n"
+                               "OpMemberDecorate %retbuf 0 Offset 0\n\n");
+
+                       const StringTemplate blockDeclaration   (
+                               "\n"
+                               "%retbuf    = OpTypeStruct %i32arr\n"
+                               "%retbufptr = OpTypePointer ${BLOCK_POINTER_TYPE} %retbuf\n"
+                               "%ret       = OpVariable %retbufptr ${BLOCK_POINTER_TYPE}\n\n");
+
+                       specializations["RETVAL_ASSEMBLY"] =
+                               "%retloc    = OpAccessChain %i32ptr %ret %zero %x\n"
+                               + std::string(cases[caseNdx].retValAssembly);
+
+                       specializations["RETVAL_BUF_DECORATE"]  = blockDecoration.specialize(specializations);
+                       specializations["RETVAL_BUF_DECL"]              = blockDeclaration.specialize(specializations);
+               }
+               else
+               {
+                       specializations["RETVAL_ASSEMBLY"]              = "";
+                       specializations["RETVAL_BUF_DECORATE"]  = "";
+                       specializations["RETVAL_BUF_DECL"]              = "";
+               }
+
                spec.assembly                                                   = shaderTemplate.specialize(specializations);
 
                if (useStorageBuffer)
@@ -644,7 +696,33 @@ tcu::TestCaseGroup* createOpAtomicGroup (tcu::TestContext& testCtx, bool useStor
 
                spec.inputs.push_back(BufferSp(new OpAtomicBuffer(numElements, cases[caseNdx].numOutputElements, cases[caseNdx].opAtomic, BUFFERTYPE_INPUT)));
                spec.outputs.push_back(BufferSp(new OpAtomicBuffer(numElements, cases[caseNdx].numOutputElements, cases[caseNdx].opAtomic, BUFFERTYPE_EXPECTED)));
+               if (verifyReturnValues)
+                       spec.outputs.push_back(BufferSp(new OpAtomicBuffer(numElements, cases[caseNdx].numOutputElements, cases[caseNdx].opAtomic, BUFFERTYPE_ATOMIC_RET)));
                spec.numWorkGroups = IVec3(numElements, 1, 1);
+
+               if (verifyReturnValues)
+               {
+                       switch (cases[caseNdx].opAtomic)
+                       {
+                               case OPATOMIC_IADD:
+                                       spec.verifyIO = OpAtomicBuffer::compareWithRetvals<OPATOMIC_IADD>;
+                                       break;
+                               case OPATOMIC_ISUB:
+                                       spec.verifyIO = OpAtomicBuffer::compareWithRetvals<OPATOMIC_ISUB>;
+                                       break;
+                               case OPATOMIC_IINC:
+                                       spec.verifyIO = OpAtomicBuffer::compareWithRetvals<OPATOMIC_IINC>;
+                                       break;
+                               case OPATOMIC_IDEC:
+                                       spec.verifyIO = OpAtomicBuffer::compareWithRetvals<OPATOMIC_IDEC>;
+                                       break;
+                               case OPATOMIC_COMPEX:
+                                       spec.verifyIO = OpAtomicBuffer::compareWithRetvals<OPATOMIC_COMPEX>;
+                                       break;
+                               default:
+                                       DE_FATAL("Unsupported OpAtomic type for return value verification");
+                       }
+               }
                group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
        }
 
@@ -880,13 +958,13 @@ tcu::TestCaseGroup* createOpNoLineGroup (tcu::TestContext& testCtx)
 
 // Compare instruction for the contraction compute case.
 // Returns true if the output is what is expected from the test case.
-bool compareNoContractCase(const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog&)
+bool compareNoContractCase(const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog&)
 {
        if (outputAllocs.size() != 1)
                return false;
 
        // Only size is needed because we are not comparing the exact values.
-       size_t byteSize = expectedOutputs[0]->getByteSize();
+       size_t byteSize = expectedOutputs[0].getByteSize();
 
        const float*    outputAsFloat   = static_cast<const float*>(outputAllocs[0]->getHostPtr());
 
@@ -990,13 +1068,13 @@ tcu::TestCaseGroup* createNoContractionGroup (tcu::TestContext& testCtx)
        return group.release();
 }
 
-bool compareFRem(const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog&)
+bool compareFRem(const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog&)
 {
        if (outputAllocs.size() != 1)
                return false;
 
        vector<deUint8> expectedBytes;
-       expectedOutputs[0]->getBytes(expectedBytes);
+       expectedOutputs[0].getBytes(expectedBytes);
 
        const float*    expectedOutputAsFloat   = reinterpret_cast<const float*>(&expectedBytes.front());
        const float*    outputAsFloat                   = static_cast<const float*>(outputAllocs[0]->getHostPtr());
@@ -1091,12 +1169,12 @@ tcu::TestCaseGroup* createOpFRemGroup (tcu::TestContext& testCtx)
        return group.release();
 }
 
-bool compareNMin (const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog&)
+bool compareNMin (const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog&)
 {
        if (outputAllocs.size() != 1)
                return false;
 
-       const BufferSp&                 expectedOutput                  (expectedOutputs[0]);
+       const BufferSp&                 expectedOutput                  (expectedOutputs[0].getBuffer());
        std::vector<deUint8>    data;
        expectedOutput->getBytes(data);
 
@@ -1215,12 +1293,12 @@ tcu::TestCaseGroup* createOpNMinGroup (tcu::TestContext& testCtx)
        return group.release();
 }
 
-bool compareNMax (const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog&)
+bool compareNMax (const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog&)
 {
        if (outputAllocs.size() != 1)
                return false;
 
-       const BufferSp&                 expectedOutput                  = expectedOutputs[0];
+       const BufferSp&                 expectedOutput                  = expectedOutputs[0].getBuffer();
        std::vector<deUint8>    data;
        expectedOutput->getBytes(data);
 
@@ -1338,12 +1416,12 @@ tcu::TestCaseGroup* createOpNMaxGroup (tcu::TestContext& testCtx)
        return group.release();
 }
 
-bool compareNClamp (const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog&)
+bool compareNClamp (const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog&)
 {
        if (outputAllocs.size() != 1)
                return false;
 
-       const BufferSp&                 expectedOutput                  = expectedOutputs[0];
+       const BufferSp&                 expectedOutput                  = expectedOutputs[0].getBuffer();
        std::vector<deUint8>    data;
        expectedOutput->getBytes(data);
 
@@ -2656,6 +2734,7 @@ tcu::TestCaseGroup* createSpecConstantGroup (tcu::TestContext& testCtx)
        cases.push_back(SpecConstantTwoIntCase("sgreaterthanequal",             " %i32 0",              " %i32 0",              "%bool",        "SGreaterThanEqual    %sc_0 %sc_1",                     -1000,  50,             selectFalseUsingSc,     outputInts2));
        cases.push_back(SpecConstantTwoIntCase("ugreaterthanequal",             " %i32 0",              " %i32 0",              "%bool",        "UGreaterThanEqual    %sc_0 %sc_1",                     10,             10,             selectTrueUsingSc,      outputInts2));
        cases.push_back(SpecConstantTwoIntCase("iequal",                                " %i32 0",              " %i32 0",              "%bool",        "IEqual               %sc_0 %sc_1",                     42,             24,             selectFalseUsingSc,     outputInts2));
+       cases.push_back(SpecConstantTwoIntCase("inotequal",                             " %i32 0",              " %i32 0",              "%bool",        "INotEqual            %sc_0 %sc_1",                     42,             24,             selectTrueUsingSc,      outputInts2));
        cases.push_back(SpecConstantTwoIntCase("logicaland",                    "True %bool",   "True %bool",   "%bool",        "LogicalAnd           %sc_0 %sc_1",                     0,              1,              selectFalseUsingSc,     outputInts2));
        cases.push_back(SpecConstantTwoIntCase("logicalor",                             "False %bool",  "False %bool",  "%bool",        "LogicalOr            %sc_0 %sc_1",                     1,              0,              selectTrueUsingSc,      outputInts2));
        cases.push_back(SpecConstantTwoIntCase("logicalequal",                  "True %bool",   "True %bool",   "%bool",        "LogicalEqual         %sc_0 %sc_1",                     0,              1,              selectFalseUsingSc,     outputInts2));
@@ -2702,8 +2781,8 @@ tcu::TestCaseGroup* createSpecConstantGroup (tcu::TestContext& testCtx)
                spec.inputs.push_back(BufferSp(new Int32Buffer(inputInts)));
                spec.outputs.push_back(BufferSp(new Int32Buffer(cases[caseNdx].expectedOutput)));
                spec.numWorkGroups = IVec3(numElements, 1, 1);
-               spec.specConstants.push_back(cases[caseNdx].scActualValue0);
-               spec.specConstants.push_back(cases[caseNdx].scActualValue1);
+               spec.specConstants.append(cases[caseNdx].scActualValue0);
+               spec.specConstants.append(cases[caseNdx].scActualValue1);
 
                group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].caseName, cases[caseNdx].caseName, spec, features));
        }
@@ -2766,9 +2845,9 @@ tcu::TestCaseGroup* createSpecConstantGroup (tcu::TestContext& testCtx)
        spec.inputs.push_back(BufferSp(new Int32Buffer(inputInts)));
        spec.outputs.push_back(BufferSp(new Int32Buffer(outputInts3)));
        spec.numWorkGroups = IVec3(numElements, 1, 1);
-       spec.specConstants.push_back(123);
-       spec.specConstants.push_back(56);
-       spec.specConstants.push_back(-77);
+       spec.specConstants.append<deInt32>(123);
+       spec.specConstants.append<deInt32>(56);
+       spec.specConstants.append<deInt32>(-77);
 
        group->addChild(new SpvAsmComputeShaderCase(testCtx, "vector_related", "VectorShuffle, CompositeExtract, & CompositeInsert", spec));
 
@@ -3772,12 +3851,12 @@ tcu::TestCaseGroup* createBlockOrderGroup (tcu::TestContext& testCtx)
                "            OpSwitch %mod %default 0 %case0 1 %case1 2 %case2\n"
 
                // Merge block for switch-statement: placed before the case
-                // bodies.  But it must follow OpSwitch which dominates it.
+               // bodies.  But it must follow OpSwitch which dominates it.
                "%switch_merge = OpLabel\n"
                "                OpBranch %if_merge\n"
 
                // Case 1 for switch-statement: placed before case 0.
-                // It must follow the OpSwitch that dominates it.
+               // It must follow the OpSwitch that dominates it.
                "%case1    = OpLabel\n"
                "%x_1      = OpLoad %u32 %xvar\n"
                "%inloc_1  = OpAccessChain %f32ptr %indata %zero %x_1\n"
@@ -4302,13 +4381,13 @@ float constructNormalizedFloat (deInt32 exponent, deUint32 significand)
 
 // Compare instruction for the OpQuantizeF16 compute exact case.
 // Returns true if the output is what is expected from the test case.
-bool compareOpQuantizeF16ComputeExactCase (const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog&)
+bool compareOpQuantizeF16ComputeExactCase (const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog&)
 {
        if (outputAllocs.size() != 1)
                return false;
 
        // Only size is needed because we cannot compare Nans.
-       size_t byteSize = expectedOutputs[0]->getByteSize();
+       size_t byteSize = expectedOutputs[0].getByteSize();
 
        const float*    outputAsFloat   = static_cast<const float*>(outputAllocs[0]->getHostPtr());
 
@@ -4343,15 +4422,15 @@ bool compareOpQuantizeF16ComputeExactCase (const std::vector<BufferSp>&, const v
 }
 
 // Checks that every output from a test-case is a float NaN.
-bool compareNan (const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog&)
+bool compareNan (const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog&)
 {
        if (outputAllocs.size() != 1)
                return false;
 
        // Only size is needed because we cannot compare Nans.
-       size_t byteSize = expectedOutputs[0]->getByteSize();
+       size_t byteSize = expectedOutputs[0].getByteSize();
 
-       const float* const      output_as_float = static_cast<const float* const>(outputAllocs[0]->getHostPtr());
+       const float* const      output_as_float = static_cast<const float*>(outputAllocs[0]->getHostPtr());
 
        for (size_t idx = 0; idx < byteSize / sizeof(float); ++idx)
        {
@@ -4642,10 +4721,10 @@ tcu::TestCaseGroup* createSpecConstantOpQuantizeToF16Group (tcu::TestContext& te
                spec.assembly           = shader;
                spec.numWorkGroups      = IVec3(numCases, 1, 1);
 
-               spec.specConstants.push_back(bitwiseCast<deUint32>(std::numeric_limits<float>::infinity()));
-               spec.specConstants.push_back(bitwiseCast<deUint32>(-std::numeric_limits<float>::infinity()));
-               spec.specConstants.push_back(bitwiseCast<deUint32>(std::ldexp(1.0f, 16)));
-               spec.specConstants.push_back(bitwiseCast<deUint32>(std::ldexp(-1.0f, 32)));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(std::numeric_limits<float>::infinity()));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(-std::numeric_limits<float>::infinity()));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(std::ldexp(1.0f, 16)));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(std::ldexp(-1.0f, 32)));
 
                outputs.push_back(std::numeric_limits<float>::infinity());
                outputs.push_back(-std::numeric_limits<float>::infinity());
@@ -4673,7 +4752,7 @@ tcu::TestCaseGroup* createSpecConstantOpQuantizeToF16Group (tcu::TestContext& te
                outputs.push_back(-std::numeric_limits<float>::quiet_NaN());
 
                for (deUint8 idx = 0; idx < numCases; ++idx)
-                       spec.specConstants.push_back(bitwiseCast<deUint32>(outputs[idx]));
+                       spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(outputs[idx]));
 
                spec.inputs.push_back(BufferSp(new Float32Buffer(inputs)));
                spec.outputs.push_back(BufferSp(new Float32Buffer(outputs)));
@@ -4691,12 +4770,12 @@ tcu::TestCaseGroup* createSpecConstantOpQuantizeToF16Group (tcu::TestContext& te
                spec.assembly           = shader;
                spec.numWorkGroups      = IVec3(numCases, 1, 1);
 
-               spec.specConstants.push_back(bitwiseCast<deUint32>(0.f));
-               spec.specConstants.push_back(bitwiseCast<deUint32>(-0.f));
-               spec.specConstants.push_back(bitwiseCast<deUint32>(std::ldexp(1.0f, -16)));
-               spec.specConstants.push_back(bitwiseCast<deUint32>(std::ldexp(-1.0f, -32)));
-               spec.specConstants.push_back(bitwiseCast<deUint32>(std::ldexp(1.0f, -127)));
-               spec.specConstants.push_back(bitwiseCast<deUint32>(-std::ldexp(1.0f, -128)));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(0.f));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(-0.f));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(std::ldexp(1.0f, -16)));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(std::ldexp(-1.0f, -32)));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(std::ldexp(1.0f, -127)));
+               spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(-std::ldexp(1.0f, -128)));
 
                outputs.push_back(0.f);
                outputs.push_back(-0.f);
@@ -4724,7 +4803,7 @@ tcu::TestCaseGroup* createSpecConstantOpQuantizeToF16Group (tcu::TestContext& te
                for (deUint8 idx = 0; idx < 6; ++idx)
                {
                        const float f = static_cast<float>(idx * 10 - 30) / 4.f;
-                       spec.specConstants.push_back(bitwiseCast<deUint32>(f));
+                       spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(f));
                        outputs.push_back(f);
                }
 
@@ -4751,7 +4830,7 @@ tcu::TestCaseGroup* createSpecConstantOpQuantizeToF16Group (tcu::TestContext& te
                outputs.push_back(constructNormalizedFloat(1, 0xFFE000));
 
                for (deUint8 idx = 0; idx < numCases; ++idx)
-                       spec.specConstants.push_back(bitwiseCast<deUint32>(outputs[idx]));
+                       spec.specConstants.append<deInt32>(bitwiseCast<deUint32>(outputs[idx]));
 
                spec.inputs.push_back(BufferSp(new Float32Buffer(inputs)));
                spec.outputs.push_back(BufferSp(new Float32Buffer(outputs)));
@@ -5051,6 +5130,117 @@ tcu::TestCaseGroup* createSelectionControlGroup (tcu::TestContext& testCtx)
        return group.release();
 }
 
+tcu::TestCaseGroup* createOpNameGroup(tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> group                   (new tcu::TestCaseGroup(testCtx, "opname", "Tests OpName cases"));
+       de::MovePtr<tcu::TestCaseGroup> entryMainGroup  (new tcu::TestCaseGroup(testCtx, "entry_main", "OpName tests with entry main"));
+       de::MovePtr<tcu::TestCaseGroup> entryNotGroup   (new tcu::TestCaseGroup(testCtx, "entry_rdc", "OpName tests with entry rdc"));
+       vector<CaseParameter>                   cases;
+       vector<string>                                  testFunc;
+       de::Random                                              rnd                             (deStringHash(group->getName()));
+       const int                                               numElements             = 100;
+       vector<float>                                   inputFloats             (numElements, 0);
+       vector<float>                                   outputFloats    (numElements, 0);
+
+       fillRandomScalars(rnd, -100.0f, 100.0f, &inputFloats[0], numElements);
+
+       for(size_t ndx = 0; ndx < numElements; ++ndx)
+               outputFloats[ndx] = -inputFloats[ndx];
+
+       const StringTemplate shaderTemplate (
+               "OpCapability Shader\n"
+               "OpMemoryModel Logical GLSL450\n"
+               "OpEntryPoint GLCompute %main \"${ENTRY}\" %id\n"
+               "OpExecutionMode %main LocalSize 1 1 1\n"
+
+               "OpName %${FUNC_ID} \"${NAME}\"\n"
+
+               "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+               + string(getComputeAsmInputOutputBufferTraits())
+
+               + string(getComputeAsmCommonTypes())
+
+               + string(getComputeAsmInputOutputBuffer()) +
+
+               "%id        = OpVariable %uvec3ptr Input\n"
+               "%zero      = OpConstant %i32 0\n"
+
+               "%func      = OpFunction %void None %voidf\n"
+               "%5         = OpLabel\n"
+               "             OpReturn\n"
+               "             OpFunctionEnd\n"
+
+               "%main      = OpFunction %void None %voidf\n"
+               "%entry     = OpLabel\n"
+               "%7         = OpFunctionCall %void %func\n"
+
+               "%idval     = OpLoad %uvec3 %id\n"
+               "%x         = OpCompositeExtract %u32 %idval 0\n"
+
+               "%inloc     = OpAccessChain %f32ptr %indata %zero %x\n"
+               "%inval     = OpLoad %f32 %inloc\n"
+               "%neg       = OpFNegate %f32 %inval\n"
+               "%outloc    = OpAccessChain %f32ptr %outdata %zero %x\n"
+               "             OpStore %outloc %neg\n"
+
+
+               "             OpReturn\n"
+               "             OpFunctionEnd\n");
+
+       cases.push_back(CaseParameter("_is_main", "main"));
+       cases.push_back(CaseParameter("_is_not_main", "not_main"));
+
+       testFunc.push_back("main");
+       testFunc.push_back("func");
+
+       for(size_t fNdx = 0; fNdx < testFunc.size(); ++fNdx)
+       {
+               for(size_t ndx = 0; ndx < cases.size(); ++ndx)
+               {
+                       map<string, string>     specializations;
+                       ComputeShaderSpec       spec;
+
+                       specializations["ENTRY"] = "main";
+                       specializations["FUNC_ID"] = testFunc[fNdx];
+                       specializations["NAME"] = cases[ndx].param;
+                       spec.assembly = shaderTemplate.specialize(specializations);
+                       spec.numWorkGroups = IVec3(numElements, 1, 1);
+                       spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+                       spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+
+                       entryMainGroup->addChild(new SpvAsmComputeShaderCase(testCtx, (testFunc[fNdx] + cases[ndx].name).c_str(), cases[ndx].name, spec));
+               }
+       }
+
+       cases.push_back(CaseParameter("_is_entry", "rdc"));
+
+       for(size_t fNdx = 0; fNdx < testFunc.size(); ++fNdx)
+       {
+               for(size_t ndx = 0; ndx < cases.size(); ++ndx)
+               {
+                       map<string, string>     specializations;
+                       ComputeShaderSpec       spec;
+
+                       specializations["ENTRY"] = "rdc";
+                       specializations["FUNC_ID"] = testFunc[fNdx];
+                       specializations["NAME"] = cases[ndx].param;
+                       spec.assembly = shaderTemplate.specialize(specializations);
+                       spec.numWorkGroups = IVec3(numElements, 1, 1);
+                       spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+                       spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+                       spec.entryPoint = "rdc";
+
+                       entryNotGroup->addChild(new SpvAsmComputeShaderCase(testCtx, (testFunc[fNdx] + cases[ndx].name).c_str(), cases[ndx].name, spec));
+               }
+       }
+
+       group->addChild(entryMainGroup.release());
+       group->addChild(entryNotGroup.release());
+
+       return group.release();
+}
+
 // Assembly code used for testing function control is based on GLSL source code:
 //
 // #version 430
@@ -5382,7 +5572,7 @@ tcu::TestCaseGroup* createOpNoLineTests(tcu::TestContext& testCtx)
                "OpNoLine\n"
                "OpLine %name 1 1\n"
                "OpLine %name 1 1\n"
-               "%second_function = OpFunction %v4f32 None %v4f32_function\n"
+               "%second_function = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "OpNoLine\n"
                "OpLine %name 1 1\n"
                "OpNoLine\n"
@@ -5403,7 +5593,7 @@ tcu::TestCaseGroup* createOpNoLineTests(tcu::TestContext& testCtx)
                "OpNoLine\n"
                "OpNoLine\n"
                "OpLine %name 1 1\n"
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "OpNoLine\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "OpNoLine\n"
@@ -5439,7 +5629,7 @@ tcu::TestCaseGroup* createOpModuleProcessedTests(tcu::TestContext& testCtx)
                "OpModuleProcessed \"Date: 2017/09/21\"\n";
 
        fragments["pre_main"]   =
-               "%second_function = OpFunction %v4f32 None %v4f32_function\n"
+               "%second_function = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%second_param1 = OpFunctionParameter %v4f32\n"
                "%label_secondfunction = OpLabel\n"
                "OpReturnValue %second_param1\n"
@@ -5447,7 +5637,7 @@ tcu::TestCaseGroup* createOpModuleProcessedTests(tcu::TestContext& testCtx)
 
        fragments["testfun"]            =
                // A %test_code function that returns its argument unchanged.
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%val1 = OpFunctionCall %v4f32 %second_function %param1\n"
@@ -5485,7 +5675,7 @@ tcu::TestCaseGroup* createOpLineTests(tcu::TestContext& testCtx)
                "OpLine %other_name 4294967295 0\n"
                "OpLine %other_name 32 40\n"
                "OpLine %file_name 0 0\n"
-               "%second_function = OpFunction %v4f32 None %v4f32_function\n"
+               "%second_function = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "OpLine %file_name 1 0\n"
                "%second_param1 = OpFunctionParameter %v4f32\n"
                "OpLine %file_name 1 3\n"
@@ -5500,7 +5690,7 @@ tcu::TestCaseGroup* createOpLineTests(tcu::TestContext& testCtx)
        fragments["testfun"]            =
                // A %test_code function that returns its argument unchanged.
                "OpLine %file_name 1 0\n"
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "OpLine %file_name 16 330\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "OpLine %file_name 14 442\n"
@@ -5529,7 +5719,7 @@ tcu::TestCaseGroup* createOpConstantNullTests(tcu::TestContext& testCtx)
 
 
        const char                                              functionStart[] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%lbl    = OpLabel\n";
 
@@ -5646,7 +5836,7 @@ tcu::TestCaseGroup* createOpConstantCompositeTests(tcu::TestContext& testCtx)
 
 
        const char                                              functionStart[]  =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%lbl    = OpLabel\n";
 
@@ -5696,10 +5886,10 @@ tcu::TestCaseGroup* createOpConstantCompositeTests(tcu::TestContext& testCtx)
                        "matrix",
 
                        "%mat4x4_f32          = OpTypeMatrix %v4f32 4\n"
-                   "%v4f32_1_0_0_0       = OpConstantComposite %v4f32 %c_f32_1 %c_f32_0 %c_f32_0 %c_f32_0\n"
-                   "%v4f32_0_1_0_0       = OpConstantComposite %v4f32 %c_f32_0 %c_f32_1 %c_f32_0 %c_f32_0\n"
-                   "%v4f32_0_0_1_0       = OpConstantComposite %v4f32 %c_f32_0 %c_f32_0 %c_f32_1 %c_f32_0\n"
-                   "%v4f32_0_5_0_5_0_5_1 = OpConstantComposite %v4f32 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5 %c_f32_1\n"
+                       "%v4f32_1_0_0_0       = OpConstantComposite %v4f32 %c_f32_1 %c_f32_0 %c_f32_0 %c_f32_0\n"
+                       "%v4f32_0_1_0_0       = OpConstantComposite %v4f32 %c_f32_0 %c_f32_1 %c_f32_0 %c_f32_0\n"
+                       "%v4f32_0_0_1_0       = OpConstantComposite %v4f32 %c_f32_0 %c_f32_0 %c_f32_1 %c_f32_0\n"
+                       "%v4f32_0_5_0_5_0_5_1 = OpConstantComposite %v4f32 %c_f32_0_5 %c_f32_0_5 %c_f32_0_5 %c_f32_1\n"
                        "%cval                = OpConstantComposite %mat4x4_f32 %v4f32_1_0_0_0 %v4f32_0_1_0_0 %v4f32_0_0_1_0 %v4f32_0_5_0_5_0_5_1\n",
 
                        "%transformed_param   = OpMatrixTimesVector %v4f32 %cval %param1\n"
@@ -5797,7 +5987,7 @@ tcu::TestCaseGroup* createSelectionBlockOrderTests(tcu::TestContext& testCtx)
        //   return result;
        // }
        const char                                              function[]                      =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1    = OpFunctionParameter %v4f32\n"
                "%lbl       = OpLabel\n"
                "%iptr      = OpVariable %fp_i32 Function\n"
@@ -5889,7 +6079,7 @@ tcu::TestCaseGroup* createSwitchBlockOrderTests(tcu::TestContext& testCtx)
        //   return result;
        // }
        const char                                              function[]                      =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1    = OpFunctionParameter %v4f32\n"
                "%lbl       = OpLabel\n"
                "%iptr      = OpVariable %fp_i32 Function\n"
@@ -6002,7 +6192,7 @@ tcu::TestCaseGroup* createDecorationGroupTests(tcu::TestContext& testCtx)
                "%c_struct2 = OpConstantComposite %struct2 %c_a3f32_2\n";
 
        const char                                              function[]                      =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param     = OpFunctionParameter %v4f32\n"
                "%entry     = OpLabel\n"
                "%result    = OpVariable %fp_v4f32 Function\n"
@@ -6136,11 +6326,11 @@ tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
                "%sc_op     = OpSpecConstantOp ${SC_RESULT_TYPE} ${SC_OP}\n";
 
        const char      function1[]                             =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param     = OpFunctionParameter %v4f32\n"
                "%label     = OpLabel\n"
-               "${TYPE_CONVERT:opt}"
                "%result    = OpVariable %fp_v4f32 Function\n"
+               "${TYPE_CONVERT:opt}"
                "             OpStore %result %param\n"
                "%gen       = ${GEN_RESULT}\n"
                "%index     = OpIAdd %i32 %gen %c_i32_1\n"
@@ -6203,6 +6393,7 @@ tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
        cases.push_back(SpecConstantTwoIntGraphicsCase("sgreaterthanequal",             " %i32 0",              " %i32 0",              "%bool",        "SGreaterThanEqual    %sc_0 %sc_1",                             -1000,  50,             selectFalseUsingSc,     outputColors2));
        cases.push_back(SpecConstantTwoIntGraphicsCase("ugreaterthanequal",             " %i32 0",              " %i32 0",              "%bool",        "UGreaterThanEqual    %sc_0 %sc_1",                             10,             10,             selectTrueUsingSc,      outputColors2));
        cases.push_back(SpecConstantTwoIntGraphicsCase("iequal",                                " %i32 0",              " %i32 0",              "%bool",        "IEqual               %sc_0 %sc_1",                             42,             24,             selectFalseUsingSc,     outputColors2));
+       cases.push_back(SpecConstantTwoIntGraphicsCase("inotequal",                             " %i32 0",              " %i32 0",              "%bool",        "INotEqual            %sc_0 %sc_1",                             42,             24,             selectTrueUsingSc,      outputColors2));
        cases.push_back(SpecConstantTwoIntGraphicsCase("logicaland",                    "True %bool",   "True %bool",   "%bool",        "LogicalAnd           %sc_0 %sc_1",                             0,              1,              selectFalseUsingSc,     outputColors2));
        cases.push_back(SpecConstantTwoIntGraphicsCase("logicalor",                             "False %bool",  "False %bool",  "%bool",        "LogicalOr            %sc_0 %sc_1",                             1,              0,              selectTrueUsingSc,      outputColors2));
        cases.push_back(SpecConstantTwoIntGraphicsCase("logicalequal",                  "True %bool",   "True %bool",   "%bool",        "LogicalEqual         %sc_0 %sc_1",                             0,              1,              selectFalseUsingSc,     outputColors2));
@@ -6220,7 +6411,7 @@ tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
        {
                map<string, string>                     specializations;
                map<string, string>                     fragments;
-               vector<deInt32>                         specConstants;
+               SpecConstants                           specConstants;
                vector<string>                          features;
                PushConstants                           noPushConstants;
                GraphicsResources                       noResources;
@@ -6255,8 +6446,8 @@ tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
                fragments["pre_main"]                           = tcu::StringTemplate(typesAndConstants1).specialize(specializations);
                fragments["testfun"]                            = tcu::StringTemplate(function1).specialize(specializations);
 
-               specConstants.push_back(cases[caseNdx].scActualValue0);
-               specConstants.push_back(cases[caseNdx].scActualValue1);
+               specConstants.append(cases[caseNdx].scActualValue0);
+               specConstants.append(cases[caseNdx].scActualValue1);
 
                createTestsForAllStages(
                        cases[caseNdx].caseName, inputColors, cases[caseNdx].expectedColors, fragments, specConstants,
@@ -6290,7 +6481,7 @@ tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
                "%sc_final    = OpSpecConstantOp %i32   IMul             %sc_sub      %sc_ext_2\n";                                                             // (sc_2 - sc_0) * sc_1
 
        const char      function2[]                             =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param     = OpFunctionParameter %v4f32\n"
                "%label     = OpLabel\n"
                "%result    = OpVariable %fp_v4f32 Function\n"
@@ -6304,15 +6495,15 @@ tcu::TestCaseGroup* createSpecConstantTests (tcu::TestContext& testCtx)
                "             OpFunctionEnd\n";
 
        map<string, string>     fragments;
-       vector<deInt32>         specConstants;
+       SpecConstants           specConstants;
 
        fragments["decoration"] = decorations2;
        fragments["pre_main"]   = typesAndConstants2;
        fragments["testfun"]    = function2;
 
-       specConstants.push_back(56789);
-       specConstants.push_back(-2);
-       specConstants.push_back(56788);
+       specConstants.append<deInt32>(56789);
+       specConstants.append<deInt32>(-2);
+       specConstants.append<deInt32>(56788);
 
        createTestsForAllStages("vector_related", inputColors, outputColors2, fragments, specConstants, group.get());
 
@@ -6352,7 +6543,7 @@ tcu::TestCaseGroup* createOpPhiTests(tcu::TestContext& testCtx)
        //   return result;
        // }
        const char      function1[]                             =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1    = OpFunctionParameter %v4f32\n"
                "%lbl       = OpLabel\n"
                "%iptr      = OpVariable %fp_i32 Function\n"
@@ -6416,7 +6607,7 @@ tcu::TestCaseGroup* createOpPhiTests(tcu::TestContext& testCtx)
 
        // Add .4 to the second element of the given parameter.
        const char      function2[]                             =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param     = OpFunctionParameter %v4f32\n"
                "%entry     = OpLabel\n"
                "%result    = OpVariable %fp_v4f32 Function\n"
@@ -6458,7 +6649,7 @@ tcu::TestCaseGroup* createOpPhiTests(tcu::TestContext& testCtx)
 
        // Swap the second and the third element of the given parameter.
        const char      function3[]                             =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param     = OpFunctionParameter %v4f32\n"
                "%entry     = OpLabel\n"
                "%result    = OpVariable %fp_v4f32 Function\n"
@@ -6515,7 +6706,7 @@ tcu::TestCaseGroup* createNoContractionTests(tcu::TestContext& testCtx)
                "%c_f32_n1pn24   = OpConstant %f32 -0x1p-24\n";
 
        const char                                              function[]       =
-               "%test_code      = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code      = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param          = OpFunctionParameter %v4f32\n"
                "%label          = OpLabel\n"
                "%var1           = OpVariable %fp_f32 Function %c_f32_1pl2_23\n"
@@ -6582,7 +6773,7 @@ tcu::TestCaseGroup* createMemoryAccessTests(tcu::TestContext& testCtx)
                "%fp_stype          = OpTypePointer Function %stype\n";
 
        const char                                              function[]       =
-               "%test_code         = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code         = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1            = OpFunctionParameter %v4f32\n"
                "%lbl               = OpLabel\n"
                "%v1                = OpVariable %fp_v4f32 Function\n"
@@ -6675,7 +6866,7 @@ tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
        {
                fragments["undef_type"] = tests[testNdx].type;
                fragments["testfun"] = StringTemplate(
-                       "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+                       "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                        "%param1 = OpFunctionParameter %v4f32\n"
                        "%label_testfun = OpLabel\n"
                        "%undef = OpUndef ${undef_type}\n"
@@ -6687,7 +6878,7 @@ tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
        fragments.clear();
 
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%undef = OpUndef %f32\n"
@@ -6703,7 +6894,7 @@ tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
        createTestsForAllStages("float32", defaultColors, defaultColors, fragments, opUndefTests.get());
 
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%undef = OpUndef %i32\n"
@@ -6716,7 +6907,7 @@ tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
        createTestsForAllStages("sint32", defaultColors, defaultColors, fragments, opUndefTests.get());
 
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%undef = OpUndef %u32\n"
@@ -6729,7 +6920,7 @@ tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
        createTestsForAllStages("uint32", defaultColors, defaultColors, fragments, opUndefTests.get());
 
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%undef = OpUndef %v4f32\n"
@@ -6743,9 +6934,9 @@ tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
                "%is_nan_2 = OpIsNan %bool %zero_2\n"
                "%is_nan_3 = OpIsNan %bool %zero_3\n"
                "%actually_zero_0 = OpSelect %f32 %is_nan_0 %c_f32_0 %zero_0\n"
-               "%actually_zero_1 = OpSelect %f32 %is_nan_0 %c_f32_0 %zero_1\n"
-               "%actually_zero_2 = OpSelect %f32 %is_nan_0 %c_f32_0 %zero_2\n"
-               "%actually_zero_3 = OpSelect %f32 %is_nan_0 %c_f32_0 %zero_3\n"
+               "%actually_zero_1 = OpSelect %f32 %is_nan_1 %c_f32_0 %zero_1\n"
+               "%actually_zero_2 = OpSelect %f32 %is_nan_2 %c_f32_0 %zero_2\n"
+               "%actually_zero_3 = OpSelect %f32 %is_nan_3 %c_f32_0 %zero_3\n"
                "%param1_0 = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
                "%param1_1 = OpVectorExtractDynamic %f32 %param1 %c_i32_1\n"
                "%param1_2 = OpVectorExtractDynamic %f32 %param1 %c_i32_2\n"
@@ -6766,7 +6957,7 @@ tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
        fragments["pre_main"] =
                "%m2x2f32 = OpTypeMatrix %v2f32 2\n";
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%undef = OpUndef %m2x2f32\n"
@@ -6780,9 +6971,9 @@ tcu::TestCaseGroup* createOpUndefTests(tcu::TestContext& testCtx)
                "%is_nan_2 = OpIsNan %bool %zero_2\n"
                "%is_nan_3 = OpIsNan %bool %zero_3\n"
                "%actually_zero_0 = OpSelect %f32 %is_nan_0 %c_f32_0 %zero_0\n"
-               "%actually_zero_1 = OpSelect %f32 %is_nan_0 %c_f32_0 %zero_1\n"
-               "%actually_zero_2 = OpSelect %f32 %is_nan_0 %c_f32_0 %zero_2\n"
-               "%actually_zero_3 = OpSelect %f32 %is_nan_0 %c_f32_0 %zero_3\n"
+               "%actually_zero_1 = OpSelect %f32 %is_nan_1 %c_f32_0 %zero_1\n"
+               "%actually_zero_2 = OpSelect %f32 %is_nan_2 %c_f32_0 %zero_2\n"
+               "%actually_zero_3 = OpSelect %f32 %is_nan_3 %c_f32_0 %zero_3\n"
                "%param1_0 = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
                "%param1_1 = OpVectorExtractDynamic %f32 %param1 %c_i32_1\n"
                "%param1_2 = OpVectorExtractDynamic %f32 %param1 %c_i32_2\n"
@@ -6926,7 +7117,7 @@ void createOpQuantizeSingleOptionTests(tcu::TestCaseGroup* testCtx)
                "%test_constant = OpConstant %f32 ";  // The value will be test.constant.
 
        StringTemplate  function                        (
-               "%test_code     = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code     = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1        = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%a             = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
@@ -6945,7 +7136,7 @@ void createOpQuantizeSingleOptionTests(tcu::TestCaseGroup* testCtx)
                        "%c             = OpSpecConstantOp %f32 QuantizeToF16 %test_constant\n";
 
        StringTemplate  specConstantFunction(
-               "%test_code     = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code     = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1        = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "${condition}\n"
@@ -6969,7 +7160,7 @@ void createOpQuantizeSingleOptionTests(tcu::TestCaseGroup* testCtx)
        {
                map<string, string>                                                             codeSpecialization;
                map<string, string>                                                             fragments;
-               vector<deInt32>                                                                 passConstants;
+               SpecConstants                                                                   passConstants;
                deInt32                                                                                 specConstant;
 
                codeSpecialization["condition"]                                 = tests[idx].condition;
@@ -6978,7 +7169,7 @@ void createOpQuantizeSingleOptionTests(tcu::TestCaseGroup* testCtx)
                fragments["pre_main"]                                                   = specConstants;
 
                memcpy(&specConstant, &tests[idx].valueAsFloat, sizeof(float));
-               passConstants.push_back(specConstant);
+               passConstants.append(specConstant);
 
                createTestsForAllStages(string("spec_const_") + tests[idx].name, inputColors, expectedColors, fragments, passConstants, testCtx);
        }
@@ -7053,7 +7244,7 @@ void createOpQuantizeTwoPossibilityTests(tcu::TestCaseGroup* testCtx)
        const char* specDecorations = "OpDecorate %input_const  SpecId 0\n";
 
        const char* function  =
-               "%test_code     = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code     = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1        = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%a             = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
@@ -7084,7 +7275,7 @@ void createOpQuantizeTwoPossibilityTests(tcu::TestCaseGroup* testCtx)
        for(size_t idx = 0; idx < (sizeof(tests)/sizeof(tests[0])); ++idx) {
                map<string, string>                                                                     fragments;
                map<string, string>                                                                     constantSpecialization;
-               vector<deInt32>                                                                         passConstants;
+               SpecConstants                                                                           passConstants;
                deInt32                                                                                         specConstant;
 
                constantSpecialization["output1"]                                       = tests[idx].possibleOutput1;
@@ -7094,7 +7285,7 @@ void createOpQuantizeTwoPossibilityTests(tcu::TestCaseGroup* testCtx)
                fragments["pre_main"]                                                           = specConstants.specialize(constantSpecialization);
 
                memcpy(&specConstant, &tests[idx].inputAsFloat, sizeof(float));
-               passConstants.push_back(specConstant);
+               passConstants.append(specConstant);
 
                createTestsForAllStages(string("spec_const_") + tests[idx].name, inputColors, expectedColors, fragments, passConstants, testCtx);
        }
@@ -7200,7 +7391,7 @@ tcu::TestCaseGroup* createLoopTests(tcu::TestContext& testCtx)
        // itself. In SPIR-V terms, the "loop construct" contains no blocks at all
        // -- the "continue construct" forms the entire loop.
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
 
                "%entry = OpLabel\n"
@@ -7229,7 +7420,7 @@ tcu::TestCaseGroup* createLoopTests(tcu::TestContext& testCtx)
 
        // Body comprised of multiple basic blocks.
        const StringTemplate multiBlock(
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
 
                "%entry = OpLabel\n"
@@ -7285,7 +7476,7 @@ tcu::TestCaseGroup* createLoopTests(tcu::TestContext& testCtx)
 
        // A loop with continue statement.
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
 
                "%entry = OpLabel\n"
@@ -7325,7 +7516,7 @@ tcu::TestCaseGroup* createLoopTests(tcu::TestContext& testCtx)
 
        // A loop with break.
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
 
                "%entry = OpLabel\n"
@@ -7370,7 +7561,7 @@ tcu::TestCaseGroup* createLoopTests(tcu::TestContext& testCtx)
 
        // A loop with return.
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
 
                "%entry = OpLabel\n"
@@ -7433,7 +7624,7 @@ tcu::TestCaseGroup* createLoopTests(tcu::TestContext& testCtx)
                "%false = OpConstantFalse %bool\n";
 
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
 
                "%entry = OpLabel\n"
@@ -7491,12 +7682,12 @@ tcu::TestCaseGroup* createBarrierTests(tcu::TestContext& testCtx)
        // A barrier inside a function body.
        fragments["pre_main"] =
                "%Workgroup = OpConstant %i32 2\n"
-               "%SequentiallyConsistent = OpConstant %i32 0x10\n";
+               "%WorkgroupAcquireRelease = OpConstant %i32 0x108\n";
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
-               "OpControlBarrier %Workgroup %Workgroup %SequentiallyConsistent\n"
+               "OpControlBarrier %Workgroup %Workgroup %WorkgroupAcquireRelease\n"
                "OpReturnValue %param1\n"
                "OpFunctionEnd\n";
        addTessCtrlTest(testGroup.get(), "in_function", fragments);
@@ -7504,10 +7695,10 @@ tcu::TestCaseGroup* createBarrierTests(tcu::TestContext& testCtx)
        // Common setup code for the following tests.
        fragments["pre_main"] =
                "%Workgroup = OpConstant %i32 2\n"
-               "%SequentiallyConsistent = OpConstant %i32 0x10\n"
+               "%WorkgroupAcquireRelease = OpConstant %i32 0x108\n"
                "%c_f32_5 = OpConstant %f32 5.\n";
        const string setupPercentZero =  // Begins %test_code function with code that sets %zero to 0u but cannot be optimized away.
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%entry = OpLabel\n"
                ";param1 components are between 0 and 1, so dot product is 4 or less\n"
@@ -7523,18 +7714,18 @@ tcu::TestCaseGroup* createBarrierTests(tcu::TestContext& testCtx)
 
                "%case1 = OpLabel\n"
                ";This barrier should never be executed, but its presence makes test failure more likely when there's a bug.\n"
-               "OpControlBarrier %Workgroup %Workgroup %SequentiallyConsistent\n"
+               "OpControlBarrier %Workgroup %Workgroup %WorkgroupAcquireRelease\n"
                "%wrong_branch_alert1 = OpVectorInsertDynamic %v4f32 %param1 %c_f32_0_5 %c_i32_0\n"
                "OpBranch %switch_exit\n"
 
                "%switch_default = OpLabel\n"
                "%wrong_branch_alert2 = OpVectorInsertDynamic %v4f32 %param1 %c_f32_0_5 %c_i32_0\n"
                ";This barrier should never be executed, but its presence makes test failure more likely when there's a bug.\n"
-               "OpControlBarrier %Workgroup %Workgroup %SequentiallyConsistent\n"
+               "OpControlBarrier %Workgroup %Workgroup %WorkgroupAcquireRelease\n"
                "OpBranch %switch_exit\n"
 
                "%case0 = OpLabel\n"
-               "OpControlBarrier %Workgroup %Workgroup %SequentiallyConsistent\n"
+               "OpControlBarrier %Workgroup %Workgroup %WorkgroupAcquireRelease\n"
                "OpBranch %switch_exit\n"
 
                "%switch_exit = OpLabel\n"
@@ -7552,12 +7743,12 @@ tcu::TestCaseGroup* createBarrierTests(tcu::TestContext& testCtx)
 
                "%else = OpLabel\n"
                ";This barrier should never be executed, but its presence makes test failure more likely when there's a bug.\n"
-               "OpControlBarrier %Workgroup %Workgroup %SequentiallyConsistent\n"
+               "OpControlBarrier %Workgroup %Workgroup %WorkgroupAcquireRelease\n"
                "%wrong_branch_alert = OpVectorInsertDynamic %v4f32 %param1 %c_f32_0_5 %c_i32_0\n"
                "OpBranch %exit\n"
 
                "%then = OpLabel\n"
-               "OpControlBarrier %Workgroup %Workgroup %SequentiallyConsistent\n"
+               "OpControlBarrier %Workgroup %Workgroup %WorkgroupAcquireRelease\n"
                "OpBranch %exit\n"
 
                "%exit = OpLabel\n"
@@ -7585,7 +7776,7 @@ tcu::TestCaseGroup* createBarrierTests(tcu::TestContext& testCtx)
 
                "%exit = OpLabel\n"
                "%val = OpPhi %f32 %val0 %else %val1 %then\n"
-               "OpControlBarrier %Workgroup %Workgroup %SequentiallyConsistent\n"
+               "OpControlBarrier %Workgroup %Workgroup %WorkgroupAcquireRelease\n"
                "%ret = OpVectorInsertDynamic %v4f32 %param1 %val %zero\n"
                "OpReturnValue %ret\n"
                "OpFunctionEnd\n";
@@ -7594,10 +7785,10 @@ tcu::TestCaseGroup* createBarrierTests(tcu::TestContext& testCtx)
        // A barrier inside a loop.
        fragments["pre_main"] =
                "%Workgroup = OpConstant %i32 2\n"
-               "%SequentiallyConsistent = OpConstant %i32 0x10\n"
+               "%WorkgroupAcquireRelease = OpConstant %i32 0x108\n"
                "%c_f32_10 = OpConstant %f32 10.\n";
        fragments["testfun"] =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%entry = OpLabel\n"
                "%val0 = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
@@ -7607,7 +7798,7 @@ tcu::TestCaseGroup* createBarrierTests(tcu::TestContext& testCtx)
                "%loop = OpLabel\n"
                "%count = OpPhi %i32 %c_i32_4 %entry %count__ %loop\n"
                "%val1 = OpPhi %f32 %val0 %entry %val %loop\n"
-               "OpControlBarrier %Workgroup %Workgroup %SequentiallyConsistent\n"
+               "OpControlBarrier %Workgroup %Workgroup %WorkgroupAcquireRelease\n"
                "%fcount = OpConvertSToF %f32 %count\n"
                "%val = OpFAdd %f32 %val1 %fcount\n"
                "%count__ = OpISub %i32 %count %c_i32_1\n"
@@ -7646,7 +7837,7 @@ tcu::TestCaseGroup* createFRemTests(tcu::TestContext& testCtx)
        // vec4 result = (param1 * 8.0) - 4.0;
        // return (frem(result.x,3) + 0.75, frem(result.y, -3) + 0.75, 0, 1)
        fragments["testfun"]                             =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%v_times_8 = OpVectorTimesScalar %v4f32 %param1 %c_f32_8\n"
@@ -7692,7 +7883,7 @@ tcu::TestCaseGroup* createOpSRemGraphicsTests(tcu::TestContext& testCtx, qpTestR
        // ivec4 result = ivec4(srem(ints.x, ints.y), srem(ints.y, ints.z), srem(ints.z, ints.x), 255);
        // return float(result + 128) / 255.0;
        fragments["testfun"]                             =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%div255 = OpFMul %v4f32 %param1 %c_v4f32_255\n"
@@ -7775,7 +7966,7 @@ tcu::TestCaseGroup* createOpSModGraphicsTests(tcu::TestContext& testCtx, qpTestR
        // ivec4 result = ivec4(smod(ints.x, ints.y), smod(ints.y, ints.z), smod(ints.z, ints.x), 255);
        // return float(result + 128) / 255.0;
        fragments["testfun"]                             =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "%div255 = OpFMul %v4f32 %param1 %c_v4f32_255\n"
@@ -7838,79 +8029,172 @@ tcu::TestCaseGroup* createOpSModGraphicsTests(tcu::TestContext& testCtx, qpTestR
        return testGroup.release();
 }
 
+enum ConversionDataType
+{
+       DATA_TYPE_SIGNED_16,
+       DATA_TYPE_SIGNED_32,
+       DATA_TYPE_SIGNED_64,
+       DATA_TYPE_UNSIGNED_16,
+       DATA_TYPE_UNSIGNED_32,
+       DATA_TYPE_UNSIGNED_64,
+       DATA_TYPE_FLOAT_32,
+       DATA_TYPE_FLOAT_64,
+       DATA_TYPE_VEC2_SIGNED_16,
+       DATA_TYPE_VEC2_SIGNED_32
+};
 
-enum IntegerType
+const string getBitWidthStr (ConversionDataType type)
 {
-       INTEGER_TYPE_SIGNED_16,
-       INTEGER_TYPE_SIGNED_32,
-       INTEGER_TYPE_SIGNED_64,
+       switch (type)
+       {
+               case DATA_TYPE_SIGNED_16:
+               case DATA_TYPE_UNSIGNED_16:
+                       return "16";
 
-       INTEGER_TYPE_UNSIGNED_16,
-       INTEGER_TYPE_UNSIGNED_32,
-       INTEGER_TYPE_UNSIGNED_64,
-};
+               case DATA_TYPE_SIGNED_32:
+               case DATA_TYPE_UNSIGNED_32:
+               case DATA_TYPE_FLOAT_32:
+               case DATA_TYPE_VEC2_SIGNED_16:
+                       return "32";
+
+               case DATA_TYPE_SIGNED_64:
+               case DATA_TYPE_UNSIGNED_64:
+               case DATA_TYPE_FLOAT_64:
+               case DATA_TYPE_VEC2_SIGNED_32:
+                       return "64";
 
-const string getBitWidthStr (IntegerType type)
+               default:
+                       DE_ASSERT(false);
+       }
+       return "";
+}
+
+const string getByteWidthStr (ConversionDataType type)
 {
        switch (type)
        {
-               case INTEGER_TYPE_SIGNED_16:
-               case INTEGER_TYPE_UNSIGNED_16:  return "16";
+               case DATA_TYPE_SIGNED_16:
+               case DATA_TYPE_UNSIGNED_16:
+                       return "2";
 
-               case INTEGER_TYPE_SIGNED_32:
-               case INTEGER_TYPE_UNSIGNED_32:  return "32";
+               case DATA_TYPE_SIGNED_32:
+               case DATA_TYPE_UNSIGNED_32:
+               case DATA_TYPE_FLOAT_32:
+               case DATA_TYPE_VEC2_SIGNED_16:
+                       return "4";
 
-               case INTEGER_TYPE_SIGNED_64:
-               case INTEGER_TYPE_UNSIGNED_64:  return "64";
+               case DATA_TYPE_SIGNED_64:
+               case DATA_TYPE_UNSIGNED_64:
+               case DATA_TYPE_FLOAT_64:
+               case DATA_TYPE_VEC2_SIGNED_32:
+                       return "8";
 
-               default:                                                DE_ASSERT(false);
-                                                                               return "";
+               default:
+                       DE_ASSERT(false);
        }
+       return "";
 }
 
-const string getByteWidthStr (IntegerType type)
+bool isSigned (ConversionDataType type)
 {
        switch (type)
        {
-               case INTEGER_TYPE_SIGNED_16:
-               case INTEGER_TYPE_UNSIGNED_16:  return "2";
+               case DATA_TYPE_SIGNED_16:
+               case DATA_TYPE_SIGNED_32:
+               case DATA_TYPE_SIGNED_64:
+               case DATA_TYPE_FLOAT_32:
+               case DATA_TYPE_FLOAT_64:
+               case DATA_TYPE_VEC2_SIGNED_16:
+               case DATA_TYPE_VEC2_SIGNED_32:
+                       return true;
+
+               case DATA_TYPE_UNSIGNED_16:
+               case DATA_TYPE_UNSIGNED_32:
+               case DATA_TYPE_UNSIGNED_64:
+                       return false;
 
-               case INTEGER_TYPE_SIGNED_32:
-               case INTEGER_TYPE_UNSIGNED_32:  return "4";
+               default:
+                       DE_ASSERT(false);
+       }
+       return false;
+}
 
-               case INTEGER_TYPE_SIGNED_64:
-               case INTEGER_TYPE_UNSIGNED_64:  return "8";
+bool isInt (ConversionDataType type)
+{
+       switch (type)
+       {
+               case DATA_TYPE_SIGNED_16:
+               case DATA_TYPE_SIGNED_32:
+               case DATA_TYPE_SIGNED_64:
+               case DATA_TYPE_UNSIGNED_16:
+               case DATA_TYPE_UNSIGNED_32:
+               case DATA_TYPE_UNSIGNED_64:
+                       return true;
+
+               case DATA_TYPE_FLOAT_32:
+               case DATA_TYPE_FLOAT_64:
+               case DATA_TYPE_VEC2_SIGNED_16:
+               case DATA_TYPE_VEC2_SIGNED_32:
+                       return false;
 
-               default:                                                DE_ASSERT(false);
-                                                                               return "";
+               default:
+                       DE_ASSERT(false);
        }
+       return false;
 }
 
-bool isSigned (IntegerType type)
+bool isFloat (ConversionDataType type)
 {
-       return (type <= INTEGER_TYPE_SIGNED_64);
+       switch (type)
+       {
+               case DATA_TYPE_SIGNED_16:
+               case DATA_TYPE_SIGNED_32:
+               case DATA_TYPE_SIGNED_64:
+               case DATA_TYPE_UNSIGNED_16:
+               case DATA_TYPE_UNSIGNED_32:
+               case DATA_TYPE_UNSIGNED_64:
+               case DATA_TYPE_VEC2_SIGNED_16:
+               case DATA_TYPE_VEC2_SIGNED_32:
+                       return false;
+
+               case DATA_TYPE_FLOAT_32:
+               case DATA_TYPE_FLOAT_64:
+                       return true;
+
+               default:
+                       DE_ASSERT(false);
+       }
+       return false;
 }
 
-const string getTypeName (IntegerType type)
+const string getTypeName (ConversionDataType type)
 {
        string prefix = isSigned(type) ? "" : "u";
-       return prefix + "int" + getBitWidthStr(type);
+
+       if              (isInt(type))                                           return prefix + "int"   + getBitWidthStr(type);
+       else if (isFloat(type))                                         return prefix + "float" + getBitWidthStr(type);
+       else if (type == DATA_TYPE_VEC2_SIGNED_16)      return "i16vec2";
+       else if (type == DATA_TYPE_VEC2_SIGNED_32)      return "i32vec2";
+       else                                                                            DE_ASSERT(false);
+
+       return "";
 }
 
-const string getTestName (IntegerType from, IntegerType to)
+const string getTestName (ConversionDataType from, ConversionDataType to)
 {
        return getTypeName(from) + "_to_" + getTypeName(to);
 }
 
-const string getAsmTypeDeclaration (IntegerType type)
+const string getAsmTypeName (ConversionDataType type)
 {
-       string sign = isSigned(type) ? " 1" : " 0";
-       return "OpTypeInt " + getBitWidthStr(type) + sign;
-}
+       string prefix;
+
+       if              (isInt(type))                                           prefix = isSigned(type) ? "i" : "u";
+       else if (isFloat(type))                                         prefix = "f";
+       else if (type == DATA_TYPE_VEC2_SIGNED_16)      return "i16vec2";
+       else if (type == DATA_TYPE_VEC2_SIGNED_32)      return "v2i32";
+       else                                                                            DE_ASSERT(false);
 
-const string getAsmTypeName (IntegerType type)
-{
-       const string prefix = isSigned(type) ? "%i" : "%u";
        return prefix + getBitWidthStr(type);
 }
 
@@ -7920,92 +8204,138 @@ BufferSp getSpecializedBuffer (deInt64 number)
        return BufferSp(new Buffer<T>(vector<T>(1, (T)number)));
 }
 
-BufferSp getBuffer (IntegerType type, deInt64 number)
+BufferSp getBuffer (ConversionDataType type, deInt64 number)
 {
        switch (type)
        {
-               case INTEGER_TYPE_SIGNED_16:    return getSpecializedBuffer<deInt16>(number);
-               case INTEGER_TYPE_SIGNED_32:    return getSpecializedBuffer<deInt32>(number);
-               case INTEGER_TYPE_SIGNED_64:    return getSpecializedBuffer<deInt64>(number);
-
-               case INTEGER_TYPE_UNSIGNED_16:  return getSpecializedBuffer<deUint16>(number);
-               case INTEGER_TYPE_UNSIGNED_32:  return getSpecializedBuffer<deUint32>(number);
-               case INTEGER_TYPE_UNSIGNED_64:  return getSpecializedBuffer<deUint64>(number);
+               case DATA_TYPE_SIGNED_16:               return getSpecializedBuffer<deInt16>(number);
+               case DATA_TYPE_SIGNED_32:               return getSpecializedBuffer<deInt32>(number);
+               case DATA_TYPE_SIGNED_64:               return getSpecializedBuffer<deInt64>(number);
+               case DATA_TYPE_UNSIGNED_16:             return getSpecializedBuffer<deUint16>(number);
+               case DATA_TYPE_UNSIGNED_32:             return getSpecializedBuffer<deUint32>(number);
+               case DATA_TYPE_UNSIGNED_64:             return getSpecializedBuffer<deUint64>(number);
+               case DATA_TYPE_FLOAT_32:                return getSpecializedBuffer<deUint32>(number);
+               case DATA_TYPE_FLOAT_64:                return getSpecializedBuffer<deUint64>(number);
+               case DATA_TYPE_VEC2_SIGNED_16:  return getSpecializedBuffer<deUint32>(number);
+               case DATA_TYPE_VEC2_SIGNED_32:  return getSpecializedBuffer<deUint64>(number);
 
                default:                                                DE_ASSERT(false);
                                                                                return BufferSp(new Buffer<deInt32>(vector<deInt32>(1, 0)));
        }
 }
 
-bool usesInt16 (IntegerType from, IntegerType to)
+bool usesInt16 (ConversionDataType from, ConversionDataType to)
 {
-       return (from == INTEGER_TYPE_SIGNED_16 || from == INTEGER_TYPE_UNSIGNED_16
-                       || to == INTEGER_TYPE_SIGNED_16 || to == INTEGER_TYPE_UNSIGNED_16);
+       return (from == DATA_TYPE_SIGNED_16 || from == DATA_TYPE_UNSIGNED_16
+                       || to == DATA_TYPE_SIGNED_16 || to == DATA_TYPE_UNSIGNED_16
+                       || from == DATA_TYPE_VEC2_SIGNED_16 || to == DATA_TYPE_VEC2_SIGNED_16);
 }
 
-bool usesInt64 (IntegerType from, IntegerType to)
+bool usesInt32 (ConversionDataType from, ConversionDataType to)
 {
-       return (from == INTEGER_TYPE_SIGNED_64 || from == INTEGER_TYPE_UNSIGNED_64
-                       || to == INTEGER_TYPE_SIGNED_64 || to == INTEGER_TYPE_UNSIGNED_64);
+       return (from == DATA_TYPE_SIGNED_32 || from == DATA_TYPE_UNSIGNED_32
+               || to == DATA_TYPE_SIGNED_32 || to == DATA_TYPE_UNSIGNED_32
+               || from == DATA_TYPE_VEC2_SIGNED_32 || to == DATA_TYPE_VEC2_SIGNED_32);
 }
 
-ComputeTestFeatures getConversionUsedFeatures (IntegerType from, IntegerType to)
+bool usesInt64 (ConversionDataType from, ConversionDataType to)
 {
-       if (usesInt16(from, to))
-       {
-               if (usesInt64(from, to))
-               {
-                       return COMPUTE_TEST_USES_INT16_INT64;
-               }
-               else
-               {
-                       return COMPUTE_TEST_USES_INT16;
-               }
-       }
-       else
+       return (from == DATA_TYPE_SIGNED_64 || from == DATA_TYPE_UNSIGNED_64
+                       || to == DATA_TYPE_SIGNED_64 || to == DATA_TYPE_UNSIGNED_64);
+}
+
+bool usesFloat64 (ConversionDataType from, ConversionDataType to)
+{
+       return (from == DATA_TYPE_FLOAT_64 || to == DATA_TYPE_FLOAT_64);
+}
+
+
+ComputeTestFeatures getConversionUsedFeatures (ConversionDataType from, ConversionDataType to)
+{
+       if (usesInt16(from, to) && usesInt64(from, to))                 return COMPUTE_TEST_USES_INT16_INT64;
+       else if (usesInt16(from, to) && usesInt32(from, to))    return COMPUTE_TEST_USES_NONE;
+       else if (usesInt16(from, to))                                                   return COMPUTE_TEST_USES_INT16;                 // This is not set for int16<-->int32 only conversions
+       else if (usesInt64(from, to))                                                   return COMPUTE_TEST_USES_INT64;
+       else if (usesFloat64(from, to))                                                 return COMPUTE_TEST_USES_FLOAT64;
+       else                                                                                                    return COMPUTE_TEST_USES_NONE;
+}
+
+vector<string> getFeatureStringVector (ComputeTestFeatures computeTestFeatures)
+{
+       vector<string> features;
+       if (computeTestFeatures == COMPUTE_TEST_USES_INT16_INT64)
        {
-               return COMPUTE_TEST_USES_INT64;
+               features.push_back("shaderInt16");
+               features.push_back("shaderInt64");
        }
+       else if (computeTestFeatures == COMPUTE_TEST_USES_INT16)                features.push_back("shaderInt16");
+       else if (computeTestFeatures == COMPUTE_TEST_USES_INT64)                features.push_back("shaderInt64");
+       else if (computeTestFeatures == COMPUTE_TEST_USES_FLOAT64)              features.push_back("shaderFloat64");
+       else if (computeTestFeatures == COMPUTE_TEST_USES_NONE)                 {}
+       else                                                                                                                    DE_ASSERT(false);
+
+       return features;
 }
 
 struct ConvertCase
 {
-       ConvertCase (IntegerType from, IntegerType to, deInt64 number)
+       ConvertCase (ConversionDataType from, ConversionDataType to, deInt64 number, bool separateOutput = false, deInt64 outputNumber = 0)
        : m_fromType            (from)
        , m_toType                      (to)
        , m_features            (getConversionUsedFeatures(from, to))
        , m_name                        (getTestName(from, to))
        , m_inputBuffer         (getBuffer(from, number))
-       , m_outputBuffer        (getBuffer(to, number))
        {
                m_asmTypes["inputType"]         = getAsmTypeName(from);
                m_asmTypes["outputType"]        = getAsmTypeName(to);
 
+               if (separateOutput)
+                       m_outputBuffer = getBuffer(to, outputNumber);
+               else
+                       m_outputBuffer = getBuffer(to, number);
+
                if (m_features == COMPUTE_TEST_USES_INT16)
                {
-                       m_asmTypes["int_capabilities"]    = "OpCapability Int16\n"
-                                                                                               "OpCapability StorageUniformBufferBlock16\n";
-                       m_asmTypes["int_additional_decl"] = "%i16        = OpTypeInt 16 1\n"
-                                                                                               "%u16        = OpTypeInt 16 0\n";
-                       m_asmTypes["int_extensions"]      = "OpExtension \"SPV_KHR_16bit_storage\"\n";
+                       m_asmTypes["datatype_capabilities"]       =             "OpCapability Int16\n"
+                                                                                                               "OpCapability StorageUniformBufferBlock16\n"
+                                                                                                               "OpCapability StorageUniform16\n";
+                       m_asmTypes["datatype_additional_decl"] =        "%i16        = OpTypeInt 16 1\n"
+                                                                                                               "%u16        = OpTypeInt 16 0\n"
+                                                                                                               "%i16vec2    = OpTypeVector %i16 2\n";
+                       m_asmTypes["datatype_extensions"]         =             "OpExtension \"SPV_KHR_16bit_storage\"\n";
                }
                else if (m_features == COMPUTE_TEST_USES_INT64)
                {
-                       m_asmTypes["int_capabilities"]    = "OpCapability Int64\n";
-                       m_asmTypes["int_additional_decl"] = "%i64        = OpTypeInt 64 1\n"
-                                                                                               "%u64        = OpTypeInt 64 0\n";
-                       m_asmTypes["int_extensions"]      = "";
+                       m_asmTypes["datatype_capabilities"]       =             "OpCapability Int64\n";
+                       m_asmTypes["datatype_additional_decl"] =        "%i64        = OpTypeInt 64 1\n"
+                                                                                                               "%u64        = OpTypeInt 64 0\n";
+                       m_asmTypes["datatype_extensions"]         =             "";
                }
                else if (m_features == COMPUTE_TEST_USES_INT16_INT64)
                {
-                       m_asmTypes["int_capabilities"]    = "OpCapability Int16\n"
-                                                                                               "OpCapability StorageUniformBufferBlock16\n"
-                                                                                               "OpCapability Int64\n";
-                       m_asmTypes["int_additional_decl"] = "%i16        = OpTypeInt 16 1\n"
-                                                                                               "%u16        = OpTypeInt 16 0\n"
-                                                                                               "%i64        = OpTypeInt 64 1\n"
-                                                                                               "%u64        = OpTypeInt 64 0\n";
-                       m_asmTypes["int_extensions"]      = "OpExtension \"SPV_KHR_16bit_storage\"\n";
+                       m_asmTypes["datatype_capabilities"]       =             "OpCapability Int16\n"
+                                                                                                               "OpCapability StorageUniformBufferBlock16\n"
+                                                                                                               "OpCapability StorageUniform16\n"
+                                                                                                               "OpCapability Int64\n";
+                       m_asmTypes["datatype_additional_decl"] =        "%i16        = OpTypeInt 16 1\n"
+                                                                                                               "%u16        = OpTypeInt 16 0\n"
+                                                                                                               "%i64        = OpTypeInt 64 1\n"
+                                                                                                               "%u64        = OpTypeInt 64 0\n";
+                       m_asmTypes["datatype_extensions"]         =             "OpExtension \"SPV_KHR_16bit_storage\"\n";
+               }
+               else if (m_features == COMPUTE_TEST_USES_FLOAT64)
+               {
+                       m_asmTypes["datatype_capabilities"]             =       "OpCapability Float64\n";
+                       m_asmTypes["datatype_additional_decl"]  =       "%f64        = OpTypeFloat 64\n";
+               }
+               else if (usesInt16(from, to) && usesInt32(from, to))
+               {
+                       m_asmTypes["datatype_capabilities"]       =             "OpCapability StorageUniformBufferBlock16\n"
+                                                                                                               "OpCapability StorageUniform16\n";
+                       m_asmTypes["datatype_additional_decl"] =        "%i16        = OpTypeInt 16 1\n"
+                                                                                                               "%u16        = OpTypeInt 16 0\n"
+                                                                                                               "%i16vec2    = OpTypeVector %i16 2\n";
+                       m_asmTypes["datatype_extensions"]         =             "OpExtension \"SPV_KHR_16bit_storage\"\n";
                }
                else
                {
@@ -8013,8 +8343,8 @@ struct ConvertCase
                }
        }
 
-       IntegerType                             m_fromType;
-       IntegerType                             m_toType;
+       ConversionDataType              m_fromType;
+       ConversionDataType              m_toType;
        ComputeTestFeatures             m_features;
        string                                  m_name;
        map<string, string>             m_asmTypes;
@@ -8026,29 +8356,24 @@ const string getConvertCaseShaderStr (const string& instruction, const ConvertCa
 {
        map<string, string> params = convertCase.m_asmTypes;
 
-       params["instruction"] = instruction;
-
-       params["inDecorator"] = getByteWidthStr(convertCase.m_fromType);
-       params["outDecorator"] = getByteWidthStr(convertCase.m_toType);
+       params["instruction"]   = instruction;
+       params["inDecorator"]   = getByteWidthStr(convertCase.m_fromType);
+       params["outDecorator"]  = getByteWidthStr(convertCase.m_toType);
 
        const StringTemplate shader (
                "OpCapability Shader\n"
-               "${int_capabilities}"
-               "${int_extensions}"
+               "${datatype_capabilities}"
+               "${datatype_extensions:opt}"
                "OpMemoryModel Logical GLSL450\n"
-               "OpEntryPoint GLCompute %main \"main\" %id\n"
+               "OpEntryPoint GLCompute %main \"main\"\n"
                "OpExecutionMode %main LocalSize 1 1 1\n"
                "OpSource GLSL 430\n"
                "OpName %main           \"main\"\n"
-               "OpName %id             \"gl_GlobalInvocationID\"\n"
                // Decorators
-               "OpDecorate %id BuiltIn GlobalInvocationId\n"
                "OpDecorate %indata DescriptorSet 0\n"
                "OpDecorate %indata Binding 0\n"
                "OpDecorate %outdata DescriptorSet 0\n"
                "OpDecorate %outdata Binding 1\n"
-               "OpDecorate %in_arr ArrayStride ${inDecorator}\n"
-               "OpDecorate %out_arr ArrayStride ${outDecorator}\n"
                "OpDecorate %in_buf BufferBlock\n"
                "OpDecorate %out_buf BufferBlock\n"
                "OpMemberDecorate %in_buf 0 Offset 0\n"
@@ -8058,33 +8383,28 @@ const string getConvertCaseShaderStr (const string& instruction, const ConvertCa
                "%voidf      = OpTypeFunction %void\n"
                "%u32        = OpTypeInt 32 0\n"
                "%i32        = OpTypeInt 32 1\n"
-               "${int_additional_decl}"
+               "%f32        = OpTypeFloat 32\n"
+               "%v2i32      = OpTypeVector %i32 2\n"
+               "${datatype_additional_decl}"
                "%uvec3      = OpTypeVector %u32 3\n"
-               "%uvec3ptr   = OpTypePointer Input %uvec3\n"
                // Derived types
-               "%in_ptr     = OpTypePointer Uniform ${inputType}\n"
-               "%out_ptr    = OpTypePointer Uniform ${outputType}\n"
-               "%in_arr     = OpTypeRuntimeArray ${inputType}\n"
-               "%out_arr    = OpTypeRuntimeArray ${outputType}\n"
-               "%in_buf     = OpTypeStruct %in_arr\n"
-               "%out_buf    = OpTypeStruct %out_arr\n"
+               "%in_ptr     = OpTypePointer Uniform %${inputType}\n"
+               "%out_ptr    = OpTypePointer Uniform %${outputType}\n"
+               "%in_buf     = OpTypeStruct %${inputType}\n"
+               "%out_buf    = OpTypeStruct %${outputType}\n"
                "%in_bufptr  = OpTypePointer Uniform %in_buf\n"
                "%out_bufptr = OpTypePointer Uniform %out_buf\n"
                "%indata     = OpVariable %in_bufptr Uniform\n"
                "%outdata    = OpVariable %out_bufptr Uniform\n"
-               "%inputptr   = OpTypePointer Input ${inputType}\n"
-               "%id         = OpVariable %uvec3ptr Input\n"
                // Constants
                "%zero       = OpConstant %i32 0\n"
                // Main function
                "%main       = OpFunction %void None %voidf\n"
                "%label      = OpLabel\n"
-               "%idval      = OpLoad %uvec3 %id\n"
-               "%x          = OpCompositeExtract %u32 %idval 0\n"
-               "%inloc      = OpAccessChain %in_ptr %indata %zero %x\n"
-               "%outloc     = OpAccessChain %out_ptr %outdata %zero %x\n"
-               "%inval      = OpLoad ${inputType} %inloc\n"
-               "%conv       = ${instruction} ${outputType} %inval\n"
+               "%inloc      = OpAccessChain %in_ptr %indata %zero\n"
+               "%outloc     = OpAccessChain %out_ptr %outdata %zero\n"
+               "%inval      = OpLoad %${inputType} %inloc\n"
+               "%conv       = ${instruction} %${outputType} %inval\n"
                "              OpStore %outloc %conv\n"
                "              OpReturn\n"
                "              OpFunctionEnd\n"
@@ -8093,83 +8413,178 @@ const string getConvertCaseShaderStr (const string& instruction, const ConvertCa
        return shader.specialize(params);
 }
 
-void createSConvertCases (vector<ConvertCase>& testCases)
+void createConvertCases (vector<ConvertCase>& testCases, const string& instruction)
 {
-       // Convert int to int
-       testCases.push_back(ConvertCase(INTEGER_TYPE_SIGNED_16, INTEGER_TYPE_SIGNED_32,         14669));
-       testCases.push_back(ConvertCase(INTEGER_TYPE_SIGNED_16, INTEGER_TYPE_SIGNED_64,         3341));
+       if (instruction == "OpUConvert")
+       {
+               // Convert unsigned int to unsigned int
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_16,          DATA_TYPE_UNSIGNED_32,          60653));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_16,          DATA_TYPE_UNSIGNED_64,          17991));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_32,          DATA_TYPE_UNSIGNED_64,          904256275));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_32,          DATA_TYPE_UNSIGNED_16,          6275));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_64,          DATA_TYPE_UNSIGNED_32,          701256243));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_64,          DATA_TYPE_UNSIGNED_16,          4741));
+       }
+       else if (instruction == "OpSConvert")
+       {
+               // Sign extension int->int
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_16,            DATA_TYPE_SIGNED_32,            14669));
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_16,            DATA_TYPE_SIGNED_64,            -3341));
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_32,            DATA_TYPE_SIGNED_64,            973610259));
+
+               // Truncate for int->int
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_32,            DATA_TYPE_SIGNED_16,            12382));
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_64,            DATA_TYPE_SIGNED_32,            -972812359));
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_64,            DATA_TYPE_SIGNED_16,            -1067742499291926803ll,                         true,   -4371));
+
+               // Sign extension for int->uint
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_16,            DATA_TYPE_UNSIGNED_32,          14669));
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_16,            DATA_TYPE_UNSIGNED_64,          -3341,                                                          true,   18446744073709548275ull));
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_32,            DATA_TYPE_UNSIGNED_64,          973610259));
+
+               // Truncate for int->uint
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_32,            DATA_TYPE_UNSIGNED_16,          12382));
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_64,            DATA_TYPE_UNSIGNED_32,          -972812359,                                                     true,   3322154937u));
+               testCases.push_back(ConvertCase(DATA_TYPE_SIGNED_64,            DATA_TYPE_UNSIGNED_16,          -1067742499291926803ll,                         true,   61165));
+
+               // Sign extension for uint->int
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_16,          DATA_TYPE_SIGNED_32,            14669));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_16,          DATA_TYPE_SIGNED_64,            62195,                                                          true,   -3341));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_32,          DATA_TYPE_SIGNED_64,            973610259));
+
+               // Truncate for uint->int
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_32,          DATA_TYPE_SIGNED_16,            12382));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_64,          DATA_TYPE_SIGNED_32,            18446744072736739257ull,                        true,   -972812359));
+               testCases.push_back(ConvertCase(DATA_TYPE_UNSIGNED_64,          DATA_TYPE_SIGNED_16,            17379001574417624813ull,                        true,   -4371));
+
+               // Convert i16vec2 to i32vec2 and vice versa
+               // Unsigned values are used here to represent negative signed values and to allow defined shifting behaviour.
+               // The actual signed value -32123 is used here as uint16 value 33413 and uint32 value 4294935173
+               testCases.push_back(ConvertCase(DATA_TYPE_VEC2_SIGNED_16,       DATA_TYPE_VEC2_SIGNED_32,       (33413u << 16)                  | 27593,        true,   (4294935173ull << 32)   | 27593));
+               testCases.push_back(ConvertCase(DATA_TYPE_VEC2_SIGNED_32,       DATA_TYPE_VEC2_SIGNED_16,       (4294935173ull << 32)   | 27593,        true,   (33413u << 16)                  | 27593));
+       }
+       else if (instruction == "OpFConvert")
+       {
+               // All hexadecimal values below represent 1024.0 as 32/64-bit IEEE 754 float
+               testCases.push_back(ConvertCase(DATA_TYPE_FLOAT_32,                     DATA_TYPE_FLOAT_64,                     0x449a4000,                                                     true,   0x4093480000000000));
+               testCases.push_back(ConvertCase(DATA_TYPE_FLOAT_64,                     DATA_TYPE_FLOAT_32,                     0x4093480000000000,                                     true,   0x449a4000));
+       }
+       else
+               DE_FATAL("Unknown instruction");
+}
+
+const map<string, string> getConvertCaseFragments (string instruction, const ConvertCase& convertCase)
+{
+       map<string, string> params = convertCase.m_asmTypes;
+       map<string, string> fragments;
 
-       testCases.push_back(ConvertCase(INTEGER_TYPE_SIGNED_32, INTEGER_TYPE_SIGNED_64,         973610259));
+       params["instruction"] = instruction;
+       params["inDecorator"] = getByteWidthStr(convertCase.m_fromType);
+
+       const StringTemplate decoration (
+               "      OpDecorate %SSBOi DescriptorSet 0\n"
+               "      OpDecorate %SSBOo DescriptorSet 0\n"
+               "      OpDecorate %SSBOi Binding 0\n"
+               "      OpDecorate %SSBOo Binding 1\n"
+               "      OpDecorate %s_SSBOi Block\n"
+               "      OpDecorate %s_SSBOo Block\n"
+               "OpMemberDecorate %s_SSBOi 0 Offset 0\n"
+               "OpMemberDecorate %s_SSBOo 0 Offset 0\n");
+
+       const StringTemplate pre_main (
+               "${datatype_additional_decl:opt}"
+               "    %ptr_in = OpTypePointer StorageBuffer %${inputType}\n"
+               "   %ptr_out = OpTypePointer StorageBuffer %${outputType}\n"
+               "   %s_SSBOi = OpTypeStruct %${inputType}\n"
+               "   %s_SSBOo = OpTypeStruct %${outputType}\n"
+               " %ptr_SSBOi = OpTypePointer StorageBuffer %s_SSBOi\n"
+               " %ptr_SSBOo = OpTypePointer StorageBuffer %s_SSBOo\n"
+               "     %SSBOi = OpVariable %ptr_SSBOi StorageBuffer\n"
+               "     %SSBOo = OpVariable %ptr_SSBOo StorageBuffer\n");
+
+       const StringTemplate testfun (
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
+               "%param     = OpFunctionParameter %v4f32\n"
+               "%label     = OpLabel\n"
+               "%iLoc      = OpAccessChain %ptr_in %SSBOi %c_u32_0\n"
+               "%oLoc      = OpAccessChain %ptr_out %SSBOo %c_u32_0\n"
+               "%valIn     = OpLoad %${inputType} %iLoc\n"
+               "%valOut    = ${instruction} %${outputType} %valIn\n"
+               "             OpStore %oLoc %valOut\n"
+               "             OpReturnValue %param\n"
+               "             OpFunctionEnd\n");
+
+       params["datatype_extensions"] =
+               params["datatype_extensions"] +
+               "OpExtension \"SPV_KHR_storage_buffer_storage_class\"\n";
 
-       // Convert int to unsigned int
-       testCases.push_back(ConvertCase(INTEGER_TYPE_SIGNED_16, INTEGER_TYPE_UNSIGNED_32,       9288));
-       testCases.push_back(ConvertCase(INTEGER_TYPE_SIGNED_16, INTEGER_TYPE_UNSIGNED_64,       15460));
+       fragments["capability"] = params["datatype_capabilities"];
+       fragments["extension"]  = params["datatype_extensions"];
+       fragments["decoration"] = decoration.specialize(params);
+       fragments["pre_main"]   = pre_main.specialize(params);
+       fragments["testfun"]    = testfun.specialize(params);
 
-       testCases.push_back(ConvertCase(INTEGER_TYPE_SIGNED_32, INTEGER_TYPE_UNSIGNED_64,       346213461));
+       return fragments;
 }
 
-//  Test for the OpSConvert instruction.
-tcu::TestCaseGroup* createSConvertTests (tcu::TestContext& testCtx)
+// Test for OpSConvert, OpUConvert and OpFConvert in compute shaders
+tcu::TestCaseGroup* createConvertComputeTests (tcu::TestContext& testCtx, const string& instruction, const string& name)
 {
-       const string instruction                                ("OpSConvert");
-       de::MovePtr<tcu::TestCaseGroup> group   (new tcu::TestCaseGroup(testCtx, "sconvert", "OpSConvert"));
-       vector<ConvertCase>                             testCases;
-       createSConvertCases(testCases);
+       de::MovePtr<tcu::TestCaseGroup>         group(new tcu::TestCaseGroup(testCtx, name.c_str(), instruction.c_str()));
+       vector<ConvertCase>                                     testCases;
+       createConvertCases(testCases, instruction);
 
        for (vector<ConvertCase>::const_iterator test = testCases.begin(); test != testCases.end(); ++test)
        {
-               ComputeShaderSpec       spec;
-
-               spec.assembly = getConvertCaseShaderStr(instruction, *test);
-               spec.inputs.push_back(test->m_inputBuffer);
-               spec.outputs.push_back(test->m_outputBuffer);
-               spec.numWorkGroups = IVec3(1, 1, 1);
+               ComputeShaderSpec spec;
+               spec.assembly                   = getConvertCaseShaderStr(instruction, *test);
+               spec.numWorkGroups              = IVec3(1, 1, 1);
+               spec.inputs.push_back   (test->m_inputBuffer);
+               spec.outputs.push_back  (test->m_outputBuffer);
 
-               if (test->m_features == COMPUTE_TEST_USES_INT16 || test->m_features == COMPUTE_TEST_USES_INT16_INT64)
-               {
+               if (test->m_features == COMPUTE_TEST_USES_INT16 || test->m_features == COMPUTE_TEST_USES_INT16_INT64 || usesInt16(test->m_fromType, test->m_toType)) {
                        spec.extensions.push_back("VK_KHR_16bit_storage");
                        spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
                }
 
-               group->addChild(new SpvAsmComputeShaderCase(testCtx, test->m_name.c_str(), "Convert integers with OpSConvert.", spec, test->m_features));
+               group->addChild(new SpvAsmComputeShaderCase(testCtx, test->m_name.c_str(), "", spec, test->m_features));
        }
-
        return group.release();
 }
 
-void createUConvertCases (vector<ConvertCase>& testCases)
-{
-       // Convert unsigned int to unsigned int
-       testCases.push_back(ConvertCase(INTEGER_TYPE_UNSIGNED_16,       INTEGER_TYPE_UNSIGNED_32,       60653));
-       testCases.push_back(ConvertCase(INTEGER_TYPE_UNSIGNED_16,       INTEGER_TYPE_UNSIGNED_64,       17991));
-
-       testCases.push_back(ConvertCase(INTEGER_TYPE_UNSIGNED_32,       INTEGER_TYPE_UNSIGNED_64,       904256275));
-}
-
-//  Test for the OpUConvert instruction.
-tcu::TestCaseGroup* createUConvertTests (tcu::TestContext& testCtx)
+// Test for OpSConvert, OpUConvert and OpFConvert in graphics shaders
+tcu::TestCaseGroup* createConvertGraphicsTests (tcu::TestContext& testCtx, const string& instruction, const string& name)
 {
-       const string instruction                                ("OpUConvert");
-       de::MovePtr<tcu::TestCaseGroup> group   (new tcu::TestCaseGroup(testCtx, "uconvert", "OpUConvert"));
-       vector<ConvertCase>                             testCases;
-       createUConvertCases(testCases);
+       de::MovePtr<tcu::TestCaseGroup>         group(new tcu::TestCaseGroup(testCtx, name.c_str(), instruction.c_str()));
+       vector<ConvertCase>                                     testCases;
+       createConvertCases(testCases, instruction);
 
        for (vector<ConvertCase>::const_iterator test = testCases.begin(); test != testCases.end(); ++test)
        {
-               ComputeShaderSpec       spec;
-
-               spec.assembly = getConvertCaseShaderStr(instruction, *test);
-               spec.inputs.push_back(test->m_inputBuffer);
-               spec.outputs.push_back(test->m_outputBuffer);
-               spec.numWorkGroups = IVec3(1, 1, 1);
-
-               if (test->m_features == COMPUTE_TEST_USES_INT16 || test->m_features == COMPUTE_TEST_USES_INT16_INT64)
+               map<string, string>     fragments               = getConvertCaseFragments(instruction, *test);
+               vector<string>          features                = getFeatureStringVector(test->m_features);
+               GraphicsResources       resources;
+               vector<string>          extensions;
+               SpecConstants           noSpecConstants;
+               PushConstants           noPushConstants;
+               VulkanFeatures          vulkanFeatures;
+               GraphicsInterfaces      noInterfaces;
+               tcu::RGBA                       defaultColors[4];
+
+               getDefaultColors                        (defaultColors);
+               resources.inputs.push_back      (Resource(test->m_inputBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
+               resources.outputs.push_back     (Resource(test->m_outputBuffer, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER));
+               extensions.push_back            ("VK_KHR_storage_buffer_storage_class");
+
+               if (test->m_features == COMPUTE_TEST_USES_INT16 || test->m_features == COMPUTE_TEST_USES_INT16_INT64 || usesInt16(test->m_fromType, test->m_toType))
                {
-                       spec.extensions.push_back("VK_KHR_16bit_storage");
-                       spec.requestedVulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
+                       extensions.push_back("VK_KHR_16bit_storage");
+                       vulkanFeatures.ext16BitStorage = EXT16BITSTORAGEFEATURES_UNIFORM_BUFFER_BLOCK;
                }
 
-               group->addChild(new SpvAsmComputeShaderCase(testCtx, test->m_name.c_str(), "Convert integers with OpUConvert.", spec, test->m_features));
+               createTestsForAllStages(
+                       test->m_name, defaultColors, defaultColors, fragments, noSpecConstants,
+                       noPushConstants, resources, noInterfaces, extensions, features, vulkanFeatures, group.get());
        }
        return group.release();
 }
@@ -8789,7 +9204,7 @@ const string specializeDefaultOutputShaderTemplate (const NumberType type, const
        ).specialize(parameters);
 }
 
-bool compareFloats (const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog& log)
+bool compareFloats (const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog& log)
 {
        DE_ASSERT(outputAllocs.size() != 0);
        DE_ASSERT(outputAllocs.size() == expectedOutputs.size());
@@ -8803,7 +9218,7 @@ bool compareFloats (const std::vector<BufferSp>&, const vector<AllocationSp>& ou
                float                   expected;
                float                   actual;
 
-               expectedOutputs[outputNdx]->getBytes(expectedBytes);
+               expectedOutputs[outputNdx].getBytes(expectedBytes);
                memcpy(&expected, &expectedBytes.front(), expectedBytes.size());
                memcpy(&actual, outputAllocs[outputNdx]->getHostPtr(), expectedBytes.size());
 
@@ -8819,7 +9234,7 @@ bool compareFloats (const std::vector<BufferSp>&, const vector<AllocationSp>& ou
 }
 
 // Checks if the driver crash with uninitialized cases
-bool passthruVerify (const std::vector<BufferSp>&, const vector<AllocationSp>& outputAllocs, const std::vector<BufferSp>& expectedOutputs, TestLog&)
+bool passthruVerify (const std::vector<Resource>&, const vector<AllocationSp>& outputAllocs, const std::vector<Resource>& expectedOutputs, TestLog&)
 {
        DE_ASSERT(outputAllocs.size() != 0);
        DE_ASSERT(outputAllocs.size() == expectedOutputs.size());
@@ -8828,7 +9243,7 @@ bool passthruVerify (const std::vector<BufferSp>&, const vector<AllocationSp>& o
        for (size_t outputNdx = 0; outputNdx < outputAllocs.size(); ++outputNdx)
        {
                vector<deUint8> expectedBytes;
-               expectedOutputs[outputNdx]->getBytes(expectedBytes);
+               expectedOutputs[outputNdx].getBytes(expectedBytes);
 
                const size_t    width                   = expectedBytes.size();
                vector<char>    data                    (width);
@@ -8917,7 +9332,7 @@ tcu::TestCaseGroup* createOpNopTests (tcu::TestContext& testCtx)
        getDefaultColors(defaultColors);
 
        opNopFragments["testfun"]               =
-               "%test_code = OpFunction %v4f32 None %v4f32_function\n"
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
                "%param1 = OpFunctionParameter %v4f32\n"
                "%label_testfun = OpLabel\n"
                "OpNop\n"
@@ -8943,6 +9358,33 @@ tcu::TestCaseGroup* createOpNopTests (tcu::TestContext& testCtx)
        return testGroup.release();
 }
 
+tcu::TestCaseGroup* createOpNameTests (tcu::TestContext& testCtx)
+{
+       de::MovePtr<tcu::TestCaseGroup> testGroup (new tcu::TestCaseGroup(testCtx, "opname","Test OpName"));
+       RGBA                                                    defaultColors[4];
+       map<string, string>                             opNameFragments;
+
+       getDefaultColors(defaultColors);
+
+       opNameFragments["debug"]                =
+               "OpName %BP_main \"not_main\"";
+
+       opNameFragments["testfun"]              =
+               "%test_code = OpFunction %v4f32 None %v4f32_v4f32_function\n"
+               "%param1 = OpFunctionParameter %v4f32\n"
+               "%label_func = OpLabel\n"
+               "%a = OpVectorExtractDynamic %f32 %param1 %c_i32_0\n"
+               "%b = OpFAdd %f32 %a %a\n"
+               "%c = OpFSub %f32 %b %a\n"
+               "%ret = OpVectorInsertDynamic %v4f32 %param1 %c %c_i32_0\n"
+               "OpReturnValue %ret\n"
+               "OpFunctionEnd\n";
+
+       createTestsForAllStages("opname", defaultColors, defaultColors, opNameFragments, testGroup.get());
+
+       return testGroup.release();
+}
+
 tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
 {
        const bool testComputePipeline = true;
@@ -8956,7 +9398,8 @@ tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
        computeTests->addChild(createOpNopGroup(testCtx));
        computeTests->addChild(createOpFUnordGroup(testCtx));
        computeTests->addChild(createOpAtomicGroup(testCtx, false));
-       computeTests->addChild(createOpAtomicGroup(testCtx, true)); // Using new StorageBuffer decoration
+       computeTests->addChild(createOpAtomicGroup(testCtx, true));                                     // Using new StorageBuffer decoration
+       computeTests->addChild(createOpAtomicGroup(testCtx, false, 1024, true));        // Return value validation
        computeTests->addChild(createOpLineGroup(testCtx));
        computeTests->addChild(createOpModuleProcessedGroup(testCtx));
        computeTests->addChild(createOpNoLineGroup(testCtx));
@@ -8985,8 +9428,9 @@ tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
        computeTests->addChild(createOpSRemComputeGroup64(testCtx, QP_TEST_RESULT_PASS));
        computeTests->addChild(createOpSModComputeGroup(testCtx, QP_TEST_RESULT_PASS));
        computeTests->addChild(createOpSModComputeGroup64(testCtx, QP_TEST_RESULT_PASS));
-       computeTests->addChild(createSConvertTests(testCtx));
-       computeTests->addChild(createUConvertTests(testCtx));
+       computeTests->addChild(createConvertComputeTests(testCtx, "OpSConvert", "sconvert"));
+       computeTests->addChild(createConvertComputeTests(testCtx, "OpUConvert", "uconvert"));
+       computeTests->addChild(createConvertComputeTests(testCtx, "OpFConvert", "fconvert"));
        computeTests->addChild(createOpCompositeInsertGroup(testCtx));
        computeTests->addChild(createOpInBoundsAccessChainGroup(testCtx));
        computeTests->addChild(createShaderDefaultOutputGroup(testCtx));
@@ -9005,10 +9449,14 @@ tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
        computeTests->addChild(create8BitStorageComputeGroup(testCtx));
        computeTests->addChild(create16BitStorageComputeGroup(testCtx));
        computeTests->addChild(createUboMatrixPaddingComputeGroup(testCtx));
+       computeTests->addChild(createVariableInitComputeGroup(testCtx));
        computeTests->addChild(createConditionalBranchComputeGroup(testCtx));
        computeTests->addChild(createIndexingComputeGroup(testCtx));
        computeTests->addChild(createVariablePointersComputeGroup(testCtx));
        computeTests->addChild(createImageSamplerComputeGroup(testCtx));
+       computeTests->addChild(createOpNameGroup(testCtx));
+       computeTests->addChild(createPointerParameterComputeGroup(testCtx));
+       graphicsTests->addChild(createCrossStageInterfaceTests(testCtx));
        graphicsTests->addChild(createSpivVersionCheckTests(testCtx, !testComputePipeline));
        graphicsTests->addChild(createOpNopTests(testCtx));
        graphicsTests->addChild(createOpSourceTests(testCtx));
@@ -9043,14 +9491,20 @@ tcu::TestCaseGroup* createInstructionTests (tcu::TestContext& testCtx)
 
                graphicsTests->addChild(graphicsAndroidTests.release());
        }
+       graphicsTests->addChild(createOpNameTests(testCtx));
 
        graphicsTests->addChild(create8BitStorageGraphicsGroup(testCtx));
        graphicsTests->addChild(create16BitStorageGraphicsGroup(testCtx));
        graphicsTests->addChild(createUboMatrixPaddingGraphicsGroup(testCtx));
+       graphicsTests->addChild(createVariableInitGraphicsGroup(testCtx));
        graphicsTests->addChild(createConditionalBranchGraphicsGroup(testCtx));
        graphicsTests->addChild(createIndexingGraphicsGroup(testCtx));
        graphicsTests->addChild(createVariablePointersGraphicsGroup(testCtx));
        graphicsTests->addChild(createImageSamplerGraphicsGroup(testCtx));
+       graphicsTests->addChild(createConvertGraphicsTests(testCtx, "OpSConvert", "sconvert"));
+       graphicsTests->addChild(createConvertGraphicsTests(testCtx, "OpUConvert", "uconvert"));
+       graphicsTests->addChild(createConvertGraphicsTests(testCtx, "OpFConvert", "fconvert"));
+       graphicsTests->addChild(createPointerParameterGraphicsGroup(testCtx));
 
        instructionTests->addChild(computeTests.release());
        instructionTests->addChild(graphicsTests.release());