#include "deMath.h"
#include "tcuStringTemplate.hpp"
+#include "vktSpvAsmCrossStageInterfaceTests.hpp"
#include "vktSpvAsm8bitStorageTests.hpp"
#include "vktSpvAsm16bitStorageTests.hpp"
#include "vktSpvAsmUboMatrixPaddingTests.hpp"
#include "vktSpvAsmComputeShaderTestUtil.hpp"
#include "vktSpvAsmGraphicsShaderTestUtil.hpp"
#include "vktSpvAsmVariablePointersTests.hpp"
+#include "vktSpvAsmVariableInitTests.hpp"
+#include "vktSpvAsmPointerParameterTests.hpp"
#include "vktSpvAsmSpirvVersionTests.hpp"
#include "vktTestCaseUtil.hpp"
#include "vktSpvAsmLoopDepLenTests.hpp"
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;
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)
#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)
{
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 (
"OpMemberDecorate %sumbuf 0 Coherent\n"
"OpMemberDecorate %sumbuf 0 Offset 0\n"
+ "${RETVAL_BUF_DECORATE}"
+
+ getComputeAsmCommonTypes("${BLOCK_POINTER_TYPE}") +
"%buf = OpTypeStruct %i32arr\n"
"%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"
"%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
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)
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));
}
// 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());
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());
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);
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);
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);
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));
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));
}
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));
" 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"
// 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());
}
// 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)
{
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());
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)));
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);
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);
}
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)));
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
"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"
"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"
"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"
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"
"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"
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"
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";
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";
"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"
// 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"
// 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"
"%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"
"%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"
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));
{
map<string, string> specializations;
map<string, string> fragments;
- vector<deInt32> specConstants;
+ SpecConstants specConstants;
vector<string> features;
PushConstants noPushConstants;
GraphicsResources noResources;
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,
"%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"
" 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());
// 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"
// 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"
// 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"
"%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"
"%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"
{
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"
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"
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"
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"
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"
"%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"
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"
"%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"
"%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"
"%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"
{
map<string, string> codeSpecialization;
map<string, string> fragments;
- vector<deInt32> passConstants;
+ SpecConstants passConstants;
deInt32 specConstant;
codeSpecialization["condition"] = tests[idx].condition;
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);
}
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"
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;
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);
}
// 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"
// 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"
// 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"
// 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"
// 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"
"%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"
// 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);
// 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"
"%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"
"%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"
"%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";
// 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"
"%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"
// 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"
// 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"
// 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"
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);
}
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
{
}
}
- IntegerType m_fromType;
- IntegerType m_toType;
+ ConversionDataType m_fromType;
+ ConversionDataType m_toType;
ComputeTestFeatures m_features;
string m_name;
map<string, string> m_asmTypes;
{
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"
"%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"
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();
}
).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());
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());
}
// 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());
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);
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"
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;
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));
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));
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));
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());