#include "deUniquePtr.hpp"
#include "tcuStringTemplate.hpp"
+#include <cmath>
+
#include "vktSpvAsmComputeShaderCase.hpp"
#include "vktSpvAsmComputeShaderTestUtil.hpp"
#include "vktTestCaseUtil.hpp"
using tcu::Vec4;
using de::UniquePtr;
using tcu::StringTemplate;
+using tcu::Vec4;
typedef Unique<VkShaderModule> ModuleHandleUp;
typedef de::SharedPtr<ModuleHandleUp> ModuleHandleSp;
template<typename T> T randomScalar (de::Random& rnd, T minValue, T maxValue);
template<> inline float randomScalar (de::Random& rnd, float minValue, float maxValue) { return rnd.getFloat(minValue, maxValue); }
template<> inline deInt32 randomScalar (de::Random& rnd, deInt32 minValue, deInt32 maxValue) { return rnd.getInt(minValue, maxValue); }
-template<> inline deUint32 randomScalar (de::Random& rnd, deUint32 minValue, deUint32 maxValue) { return minValue + rnd.getUint32() % (maxValue - minValue + 1); }
template<typename T>
static void fillRandomScalars (de::Random& rnd, T minValue, T maxValue, void* dst, int numValues, int offset = 0)
typedPtr[offset + ndx] = randomScalar<T>(rnd, minValue, maxValue);
}
+struct CaseParameter
+{
+ const char* name;
+ string param;
+
+ CaseParameter (const char* case_, const string& param_) : name(case_), param(param_) {}
+};
+
// Assembly code used for testing OpNop, OpConstant{Null|Composite}, Op[No]Line, OpSource[Continued], OpSourceExtension, OpUndef is based on GLSL source code:
//
// #version 430
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "OpNop appearing at different places", spec));
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "OpLine appearing at different places", spec));
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "OpNoLine appearing at different places", spec));
return group.release();
}
+tcu::TestCaseGroup* createNoContractionGroup (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "nocontraction", "Test the NoContraction decoration"));
+ vector<CaseParameter> cases;
+ de::Random rnd (deStringHash(group->getName()));
+ const int numElements = 100;
+ vector<float> inputFloats1 (numElements, 0);
+ vector<float> inputFloats2 (numElements, 0);
+ vector<float> outputFloats (numElements, 0);
+ const StringTemplate shaderTemplate (
+ string(s_ShaderPreamble) +
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ "${DECORATION}\n"
+
+ "OpDecorate %inbuf1 BufferBlock\n"
+ "OpDecorate %indata1 DescriptorSet 0\n"
+ "OpDecorate %indata1 Binding 0\n"
+ "OpDecorate %inbuf2 BufferBlock\n"
+ "OpDecorate %indata2 DescriptorSet 0\n"
+ "OpDecorate %indata2 Binding 1\n"
+ "OpDecorate %outbuf BufferBlock\n"
+ "OpDecorate %outdata DescriptorSet 0\n"
+ "OpDecorate %outdata Binding 2\n"
+ "OpDecorate %f32arr ArrayStride 4\n"
+ "OpMemberDecorate %inbuf1 0 Offset 0\n"
+ "OpMemberDecorate %inbuf2 0 Offset 0\n"
+ "OpMemberDecorate %outbuf 0 Offset 0\n"
+
+ + string(s_CommonTypes) +
+
+ "%inbuf1 = OpTypeStruct %f32arr\n"
+ "%inbufptr1 = OpTypePointer Uniform %inbuf1\n"
+ "%indata1 = OpVariable %inbufptr1 Uniform\n"
+ "%inbuf2 = OpTypeStruct %f32arr\n"
+ "%inbufptr2 = OpTypePointer Uniform %inbuf2\n"
+ "%indata2 = OpVariable %inbufptr2 Uniform\n"
+ "%outbuf = OpTypeStruct %f32arr\n"
+ "%outbufptr = OpTypePointer Uniform %outbuf\n"
+ "%outdata = OpVariable %outbufptr Uniform\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%c_f_m1 = OpConstant %f32 -1.\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc1 = OpAccessChain %f32ptr %indata1 %zero %x\n"
+ "%inval1 = OpLoad %f32 %inloc1\n"
+ "%inloc2 = OpAccessChain %f32ptr %indata2 %zero %x\n"
+ "%inval2 = OpLoad %f32 %inloc2\n"
+ "%mul = OpFMul %f32 %inval1 %inval2\n"
+ "%add = OpFAdd %f32 %mul %c_f_m1\n"
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpStore %outloc %add\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n");
+
+ cases.push_back(CaseParameter("multiplication", "OpDecorate %mul NoContraction"));
+ cases.push_back(CaseParameter("addition", "OpDecorate %add NoContraction"));
+ cases.push_back(CaseParameter("both", "OpDecorate %mul NoContraction\nOpDecorate %add NoContraction"));
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ {
+ inputFloats1[ndx] = 1.f + std::ldexp(1.f, -23); // 1 + 2^-23.
+ inputFloats2[ndx] = 1.f - std::ldexp(1.f, -23); // 1 - 2^-23.
+ // Result for (1 + 2^-23) * (1 - 2^-23) - 1. With NoContraction, the multiplication will be
+ // conducted separately and the result is rounded to 1. So the final result will be 0.f.
+ // If the operation is combined into a precise fused multiply-add, then the result would be
+ // 2^-46 (0xa8800000).
+ outputFloats[ndx] = 0.f;
+ }
+
+ for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
+ {
+ map<string, string> specializations;
+ ComputeShaderSpec spec;
+
+ specializations["DECORATION"] = cases[caseNdx].param;
+ spec.assembly = shaderTemplate.specialize(specializations);
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats1)));
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats2)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
+ }
+ return group.release();
+}
+
+// Copy contents in the input buffer to the output buffer.
+tcu::TestCaseGroup* createOpCopyMemoryGroup (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opcopymemory", "Test the OpCopyMemory instruction"));
+ de::Random rnd (deStringHash(group->getName()));
+ const int numElements = 100;
+
+ // The following case adds vec4(0., 0.5, 1.5, 2.5) to each of the elements in the input buffer and writes output to the output buffer.
+ ComputeShaderSpec spec1;
+ vector<Vec4> inputFloats1 (numElements);
+ vector<Vec4> outputFloats1 (numElements);
+
+ fillRandomScalars(rnd, -200.f, 200.f, &inputFloats1[0], numElements * 4);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ outputFloats1[ndx] = inputFloats1[ndx] + Vec4(0.f, 0.5f, 1.5f, 2.5f);
+
+ spec1.assembly =
+ string(s_ShaderPreamble) +
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) +
+
+ "%vec4 = OpTypeVector %f32 4\n"
+ "%vec4ptr_u = OpTypePointer Uniform %vec4\n"
+ "%vec4ptr_f = OpTypePointer Function %vec4\n"
+ "%vec4arr = OpTypeRuntimeArray %vec4\n"
+ "%inbuf = OpTypeStruct %vec4arr\n"
+ "%inbufptr = OpTypePointer Uniform %inbuf\n"
+ "%indata = OpVariable %inbufptr Uniform\n"
+ "%outbuf = OpTypeStruct %vec4arr\n"
+ "%outbufptr = OpTypePointer Uniform %outbuf\n"
+ "%outdata = OpVariable %outbufptr Uniform\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%c_f_0 = OpConstant %f32 0.\n"
+ "%c_f_0_5 = OpConstant %f32 0.5\n"
+ "%c_f_1_5 = OpConstant %f32 1.5\n"
+ "%c_f_2_5 = OpConstant %f32 2.5\n"
+ "%c_vec4 = OpConstantComposite %vec4 %c_f_0 %c_f_0_5 %c_f_1_5 %c_f_2_5\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%v_vec4 = OpVariable %vec4ptr_f Function\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %vec4ptr_u %indata %zero %x\n"
+ "%outloc = OpAccessChain %vec4ptr_u %outdata %zero %x\n"
+ " OpCopyMemory %v_vec4 %inloc\n"
+ "%v_vec4_val = OpLoad %vec4 %v_vec4\n"
+ "%add = OpFAdd %vec4 %v_vec4_val %c_vec4\n"
+ " OpStore %outloc %add\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+
+ spec1.inputs.push_back(BufferSp(new Vec4Buffer(inputFloats1)));
+ spec1.outputs.push_back(BufferSp(new Vec4Buffer(outputFloats1)));
+ spec1.numWorkGroups = IVec3(numElements, 1, 1);
+ spec1.entryPoint = "main";
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "vector", "OpCopyMemory elements of vector type", spec1));
+
+ // The following case copies a float[100] variable from the input buffer to the output buffer.
+ ComputeShaderSpec spec2;
+ vector<float> inputFloats2 (numElements);
+ vector<float> outputFloats2 (numElements);
+
+ fillRandomScalars(rnd, -200.f, 200.f, &inputFloats2[0], numElements);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ outputFloats2[ndx] = inputFloats2[ndx];
+
+ spec2.assembly =
+ string(s_ShaderPreamble) +
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) +
+
+ "%hundred = OpConstant %u32 100\n"
+ "%f32arr100 = OpTypeArray %f32 %hundred\n"
+ "%f32arr100ptr_f = OpTypePointer Function %f32arr100\n"
+ "%f32arr100ptr_u = OpTypePointer Uniform %f32arr100\n"
+ "%inbuf = OpTypeStruct %f32arr100\n"
+ "%inbufptr = OpTypePointer Uniform %inbuf\n"
+ "%indata = OpVariable %inbufptr Uniform\n"
+ "%outbuf = OpTypeStruct %f32arr100\n"
+ "%outbufptr = OpTypePointer Uniform %outbuf\n"
+ "%outdata = OpVariable %outbufptr Uniform\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%var = OpVariable %f32arr100ptr_f Function\n"
+ "%inarr = OpAccessChain %f32arr100ptr_u %indata %zero\n"
+ "%outarr = OpAccessChain %f32arr100ptr_u %outdata %zero\n"
+ " OpCopyMemory %var %inarr\n"
+ " OpCopyMemory %outarr %var\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+
+ spec2.inputs.push_back(BufferSp(new Float32Buffer(inputFloats2)));
+ spec2.outputs.push_back(BufferSp(new Float32Buffer(outputFloats2)));
+ spec2.numWorkGroups = IVec3(1, 1, 1);
+ spec2.entryPoint = "main";
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "array", "OpCopyMemory elements of array type", spec2));
+
+ // The following case copies a struct{vec4, vec4, vec4, vec4} variable from the input buffer to the output buffer.
+ ComputeShaderSpec spec3;
+ vector<float> inputFloats3 (16);
+ vector<float> outputFloats3 (16);
+
+ fillRandomScalars(rnd, -200.f, 200.f, &inputFloats3[0], 16);
+
+ for (size_t ndx = 0; ndx < 16; ++ndx)
+ outputFloats3[ndx] = -inputFloats3[ndx];
+
+ spec3.assembly =
+ string(s_ShaderPreamble) +
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) +
+
+ "%vec4 = OpTypeVector %f32 4\n"
+ "%inbuf = OpTypeStruct %vec4 %vec4 %vec4 %vec4\n"
+ "%inbufptr = OpTypePointer Uniform %inbuf\n"
+ "%indata = OpVariable %inbufptr Uniform\n"
+ "%outbuf = OpTypeStruct %vec4 %vec4 %vec4 %vec4\n"
+ "%outbufptr = OpTypePointer Uniform %outbuf\n"
+ "%outdata = OpVariable %outbufptr Uniform\n"
+ "%vec4stptr = OpTypePointer Function %inbuf\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%var = OpVariable %vec4stptr Function\n"
+ " OpCopyMemory %var %indata\n"
+ " OpCopyMemory %outdata %var\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+
+ spec3.inputs.push_back(BufferSp(new Float32Buffer(inputFloats3)));
+ spec3.outputs.push_back(BufferSp(new Float32Buffer(outputFloats3)));
+ spec3.numWorkGroups = IVec3(1, 1, 1);
+ spec3.entryPoint = "main";
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "struct", "OpCopyMemory elements of struct type", spec3));
+
+ // The following case negates multiple float variables from the input buffer and stores the results to the output buffer.
+ ComputeShaderSpec spec4;
+ vector<float> inputFloats4 (numElements);
+ vector<float> outputFloats4 (numElements);
+
+ fillRandomScalars(rnd, -200.f, 200.f, &inputFloats4[0], numElements);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ outputFloats4[ndx] = -inputFloats4[ndx];
+
+ spec4.assembly =
+ string(s_ShaderPreamble) +
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) + string(s_InputOutputBuffer) +
+
+ "%f32ptr_f = OpTypePointer Function %f32\n"
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%var = OpVariable %f32ptr_f Function\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpCopyMemory %var %inloc\n"
+ "%val = OpLoad %f32 %var\n"
+ "%neg = OpFNegate %f32 %val\n"
+ " OpStore %outloc %neg\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+
+ spec4.inputs.push_back(BufferSp(new Float32Buffer(inputFloats4)));
+ spec4.outputs.push_back(BufferSp(new Float32Buffer(outputFloats4)));
+ spec4.numWorkGroups = IVec3(numElements, 1, 1);
+ spec4.entryPoint = "main";
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "float", "OpCopyMemory elements of float type", spec4));
+
+ return group.release();
+}
+
+tcu::TestCaseGroup* createOpCopyObjectGroup (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opcopyobject", "Test the OpCopyObject instruction"));
+ ComputeShaderSpec spec;
+ de::Random rnd (deStringHash(group->getName()));
+ const int numElements = 100;
+ vector<float> inputFloats (numElements, 0);
+ vector<float> outputFloats (numElements, 0);
+
+ fillRandomScalars(rnd, -200.f, 200.f, &inputFloats[0], numElements);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ outputFloats[ndx] = inputFloats[ndx] + 7.5f;
+
+ spec.assembly =
+ string(s_ShaderPreamble) +
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) +
+
+ "%fvec3 = OpTypeVector %f32 3\n"
+ "%fmat = OpTypeMatrix %fvec3 3\n"
+ "%three = OpConstant %u32 3\n"
+ "%farr = OpTypeArray %f32 %three\n"
+ "%fst = OpTypeStruct %f32 %f32\n"
+
+ + string(s_InputOutputBuffer) +
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%c_f = OpConstant %f32 1.5\n"
+ "%c_fvec3 = OpConstantComposite %fvec3 %c_f %c_f %c_f\n"
+ "%c_fmat = OpConstantComposite %fmat %c_fvec3 %c_fvec3 %c_fvec3\n"
+ "%c_farr = OpConstantComposite %farr %c_f %c_f %c_f\n"
+ "%c_fst = OpConstantComposite %fst %c_f %c_f\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%c_f_copy = OpCopyObject %f32 %c_f\n"
+ "%c_fvec3_copy = OpCopyObject %fvec3 %c_fvec3\n"
+ "%c_fmat_copy = OpCopyObject %fmat %c_fmat\n"
+ "%c_farr_copy = OpCopyObject %farr %c_farr\n"
+ "%c_fst_copy = OpCopyObject %fst %c_fst\n"
+ "%fvec3_elem = OpCompositeExtract %f32 %c_fvec3_copy 0\n"
+ "%fmat_elem = OpCompositeExtract %f32 %c_fmat_copy 1 2\n"
+ "%farr_elem = OpCompositeExtract %f32 %c_fmat_copy 2\n"
+ "%fst_elem = OpCompositeExtract %f32 %c_fmat_copy 1\n"
+ // Add up. 1.5 * 5 = 7.5.
+ "%add1 = OpFAdd %f32 %c_f_copy %fvec3_elem\n"
+ "%add2 = OpFAdd %f32 %add1 %fmat_elem\n"
+ "%add3 = OpFAdd %f32 %add2 %farr_elem\n"
+ "%add4 = OpFAdd %f32 %add3 %fst_elem\n"
+
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ "%inval = OpLoad %f32 %inloc\n"
+ "%add = OpFAdd %f32 %add4 %inval\n"
+ " OpStore %outloc %add\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "spotcheck", "OpCopyObject on different types", spec));
+
+ return group.release();
+}
+
// Assembly code used for testing OpUnreachable is based on GLSL source code:
//
// #version 430
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "OpUnreachable appearing at different places", spec));
spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats4)));
spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "decoration group cases", spec));
return group.release();
}
-tcu::TestCaseGroup* createOpPhiGroup (tcu::TestContext& testCtx)
+struct SpecConstantTwoIntCase
+{
+ const char* caseName;
+ const char* scDefinition0;
+ const char* scDefinition1;
+ const char* scResultType;
+ const char* scOperation;
+ deInt32 scActualValue0;
+ deInt32 scActualValue1;
+ const char* resultOperation;
+ vector<deInt32> expectedOutput;
+
+ SpecConstantTwoIntCase (const char* name,
+ const char* definition0,
+ const char* definition1,
+ const char* resultType,
+ const char* operation,
+ deInt32 value0,
+ deInt32 value1,
+ const char* resultOp,
+ const vector<deInt32>& output)
+ : caseName (name)
+ , scDefinition0 (definition0)
+ , scDefinition1 (definition1)
+ , scResultType (resultType)
+ , scOperation (operation)
+ , scActualValue0 (value0)
+ , scActualValue1 (value1)
+ , resultOperation (resultOp)
+ , expectedOutput (output) {}
+};
+
+tcu::TestCaseGroup* createSpecConstantGroup (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opspecconstantop", "Test the OpSpecConstantOp instruction"));
+ vector<SpecConstantTwoIntCase> cases;
+ de::Random rnd (deStringHash(group->getName()));
+ const int numElements = 100;
+ vector<deInt32> inputInts (numElements, 0);
+ vector<deInt32> outputInts1 (numElements, 0);
+ vector<deInt32> outputInts2 (numElements, 0);
+ vector<deInt32> outputInts3 (numElements, 0);
+ vector<deInt32> outputInts4 (numElements, 0);
+ vector<deInt32> outputInts5 (numElements, 0);
+ const StringTemplate shaderTemplate (
+ string(s_ShaderPreamble) +
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+ "OpDecorate %sc_0 SpecId 0\n"
+ "OpDecorate %sc_1 SpecId 1\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) +
+
+ "%i32ptr = OpTypePointer Uniform %i32\n"
+ "%i32arr = OpTypeRuntimeArray %i32\n"
+ "%boolptr = OpTypePointer Uniform %bool\n"
+ "%boolarr = OpTypeRuntimeArray %bool\n"
+ "%inbuf = OpTypeStruct %i32arr\n"
+ "%inbufptr = OpTypePointer Uniform %inbuf\n"
+ "%indata = OpVariable %inbufptr Uniform\n"
+ "%outbuf = OpTypeStruct %i32arr\n"
+ "%outbufptr = OpTypePointer Uniform %outbuf\n"
+ "%outdata = OpVariable %outbufptr Uniform\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+
+ "%sc_0 = OpSpecConstant${SC_DEF0}\n"
+ "%sc_1 = OpSpecConstant${SC_DEF1}\n"
+ "%sc_final = OpSpecConstantOp ${SC_RESULT_TYPE} ${SC_OP}\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %i32ptr %indata %zero %x\n"
+ "%inval = OpLoad %i32 %inloc\n"
+ "%final = ${GEN_RESULT}\n"
+ "%outloc = OpAccessChain %i32ptr %outdata %zero %x\n"
+ " OpStore %outloc %final\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n");
+
+ fillRandomScalars(rnd, -65536, 65536, &inputInts[0], numElements);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ {
+ outputInts1[ndx] = inputInts[ndx] + 42;
+ outputInts2[ndx] = inputInts[ndx];
+ outputInts3[ndx] = inputInts[ndx] - 11200;
+ outputInts4[ndx] = inputInts[ndx] + 1;
+ outputInts5[ndx] = inputInts[ndx] - 2;
+ }
+
+ const char addScToInput[] = "OpIAdd %i32 %inval %sc_final";
+ const char selectTrueUsingSc[] = "OpSelect %i32 %sc_final %inval %zero";
+ const char selectFalseUsingSc[] = "OpSelect %i32 %sc_final %zero %inval";
+
+ cases.push_back(SpecConstantTwoIntCase("iadd", " %i32 0", " %i32 0", "%i32", "IAdd %sc_0 %sc_1", 62, -20, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("isub", " %i32 0", " %i32 0", "%i32", "ISub %sc_0 %sc_1", 100, 58, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("imul", " %i32 0", " %i32 0", "%i32", "IMul %sc_0 %sc_1", -2, -21, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("sdiv", " %i32 0", " %i32 0", "%i32", "SDiv %sc_0 %sc_1", -126, -3, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("udiv", " %i32 0", " %i32 0", "%i32", "UDiv %sc_0 %sc_1", 126, 3, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("srem", " %i32 0", " %i32 0", "%i32", "SRem %sc_0 %sc_1", 7, -3, addScToInput, outputInts4));
+ cases.push_back(SpecConstantTwoIntCase("smod", " %i32 0", " %i32 0", "%i32", "SMod %sc_0 %sc_1", 7, -3, addScToInput, outputInts5));
+ cases.push_back(SpecConstantTwoIntCase("umod", " %i32 0", " %i32 0", "%i32", "UMod %sc_0 %sc_1", 342, 50, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("bitwiseand", " %i32 0", " %i32 0", "%i32", "BitwiseAnd %sc_0 %sc_1", 42, 63, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("bitwiseor", " %i32 0", " %i32 0", "%i32", "BitwiseOr %sc_0 %sc_1", 34, 8, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("bitwisexor", " %i32 0", " %i32 0", "%i32", "BitwiseAnd %sc_0 %sc_1", 18, 56, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("shiftrightlogical", " %i32 0", " %i32 0", "%i32", "ShiftRightLogical %sc_0 %sc_1", 168, 2, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("shiftrightarithmetic", " %i32 0", " %i32 0", "%i32", "ShiftRightArithmetic %sc_0 %sc_1", 168, 2, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("shiftleftlogical", " %i32 0", " %i32 0", "%i32", "ShiftLeftLogical %sc_0 %sc_1", 21, 1, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("slessthan", " %i32 0", " %i32 0", "%bool", "SLessThan %sc_0 %sc_1", -20, -10, selectTrueUsingSc, outputInts2));
+ cases.push_back(SpecConstantTwoIntCase("ulessthan", " %i32 0", " %i32 0", "%bool", "ULessThan %sc_0 %sc_1", 10, 20, selectTrueUsingSc, outputInts2));
+ cases.push_back(SpecConstantTwoIntCase("sgreaterthan", " %i32 0", " %i32 0", "%bool", "SGreaterThan %sc_0 %sc_1", -1000, 50, selectFalseUsingSc, outputInts2));
+ cases.push_back(SpecConstantTwoIntCase("ugreaterthan", " %i32 0", " %i32 0", "%bool", "UGreaterThan %sc_0 %sc_1", 10, 5, selectTrueUsingSc, outputInts2));
+ cases.push_back(SpecConstantTwoIntCase("slessthanequal", " %i32 0", " %i32 0", "%bool", "SLessThanEqual %sc_0 %sc_1", -10, -10, selectTrueUsingSc, outputInts2));
+ cases.push_back(SpecConstantTwoIntCase("ulessthanequal", " %i32 0", " %i32 0", "%bool", "ULessThanEqual %sc_0 %sc_1", 50, 100, selectTrueUsingSc, outputInts2));
+ 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("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));
+ cases.push_back(SpecConstantTwoIntCase("logicalnotequal", "False %bool", "False %bool", "%bool", "LogicalNotEqual %sc_0 %sc_1", 1, 0, selectTrueUsingSc, outputInts2));
+ cases.push_back(SpecConstantTwoIntCase("snegate", " %i32 0", " %i32 0", "%i32", "SNegate %sc_0", -42, 0, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("not", " %i32 0", " %i32 0", "%i32", "Not %sc_0", -43, 0, addScToInput, outputInts1));
+ cases.push_back(SpecConstantTwoIntCase("logicalnot", "False %bool", "False %bool", "%bool", "LogicalNot %sc_0", 1, 0, selectFalseUsingSc, outputInts2));
+ cases.push_back(SpecConstantTwoIntCase("select", "False %bool", " %i32 0", "%i32", "Select %sc_0 %sc_1 %zero", 1, 42, addScToInput, outputInts1));
+ // OpSConvert, OpFConvert: these two instructions involve ints/floats of different bitwidths.
+ // \todo[2015-12-1 antiagainst] OpQuantizeToF16
+
+ for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
+ {
+ map<string, string> specializations;
+ ComputeShaderSpec spec;
+
+ specializations["SC_DEF0"] = cases[caseNdx].scDefinition0;
+ specializations["SC_DEF1"] = cases[caseNdx].scDefinition1;
+ specializations["SC_RESULT_TYPE"] = cases[caseNdx].scResultType;
+ specializations["SC_OP"] = cases[caseNdx].scOperation;
+ specializations["GEN_RESULT"] = cases[caseNdx].resultOperation;
+
+ spec.assembly = shaderTemplate.specialize(specializations);
+ 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.entryPoint = "main";
+ spec.specConstants.push_back(cases[caseNdx].scActualValue0);
+ spec.specConstants.push_back(cases[caseNdx].scActualValue1);
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].caseName, cases[caseNdx].caseName, spec));
+ }
+
+ ComputeShaderSpec spec;
+
+ spec.assembly =
+ string(s_ShaderPreamble) +
+
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+ "OpDecorate %sc_0 SpecId 0\n"
+ "OpDecorate %sc_1 SpecId 1\n"
+ "OpDecorate %sc_2 SpecId 2\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) +
+
+ "%ivec3 = OpTypeVector %i32 3\n"
+ "%i32ptr = OpTypePointer Uniform %i32\n"
+ "%i32arr = OpTypeRuntimeArray %i32\n"
+ "%boolptr = OpTypePointer Uniform %bool\n"
+ "%boolarr = OpTypeRuntimeArray %bool\n"
+ "%inbuf = OpTypeStruct %i32arr\n"
+ "%inbufptr = OpTypePointer Uniform %inbuf\n"
+ "%indata = OpVariable %inbufptr Uniform\n"
+ "%outbuf = OpTypeStruct %i32arr\n"
+ "%outbufptr = OpTypePointer Uniform %outbuf\n"
+ "%outdata = OpVariable %outbufptr Uniform\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%ivec3_0 = OpConstantComposite %ivec3 %zero %zero %zero\n"
+
+ "%sc_0 = OpSpecConstant %i32 0\n"
+ "%sc_1 = OpSpecConstant %i32 0\n"
+ "%sc_2 = OpSpecConstant %i32 0\n"
+ "%sc_vec3_0 = OpSpecConstantOp %ivec3 CompositeInsert %sc_0 %ivec3_0 0\n" // (sc_0, 0, 0)
+ "%sc_vec3_1 = OpSpecConstantOp %ivec3 CompositeInsert %sc_1 %ivec3_0 1\n" // (0, sc_1, 0)
+ "%sc_vec3_2 = OpSpecConstantOp %ivec3 CompositeInsert %sc_2 %ivec3_0 2\n" // (0, 0, sc_2)
+ "%sc_vec3_01 = OpSpecConstantOp %ivec3 VectorShuffle %sc_vec3_0 %sc_vec3_1 1 0 4\n" // (0, sc_0, sc_1)
+ "%sc_vec3_012 = OpSpecConstantOp %ivec3 VectorShuffle %sc_vec3_01 %sc_vec3_2 5 1 2\n" // (sc_2, sc_0, sc_1)
+ "%sc_ext_0 = OpSpecConstantOp %i32 CompositeExtract %sc_vec3_012 0\n" // sc_2
+ "%sc_ext_1 = OpSpecConstantOp %i32 CompositeExtract %sc_vec3_012 1\n" // sc_0
+ "%sc_ext_2 = OpSpecConstantOp %i32 CompositeExtract %sc_vec3_012 2\n" // sc_1
+ "%sc_sub = OpSpecConstantOp %i32 ISub %sc_ext_0 %sc_ext_1\n" // (sc_2 - sc_0)
+ "%sc_final = OpSpecConstantOp %i32 IMul %sc_sub %sc_ext_2\n" // (sc_2 - sc_0) * sc_1
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %i32ptr %indata %zero %x\n"
+ "%inval = OpLoad %i32 %inloc\n"
+ "%final = OpIAdd %i32 %inval %sc_final\n"
+ "%outloc = OpAccessChain %i32ptr %outdata %zero %x\n"
+ " OpStore %outloc %final\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+ spec.inputs.push_back(BufferSp(new Int32Buffer(inputInts)));
+ spec.outputs.push_back(BufferSp(new Int32Buffer(outputInts3)));
+ spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
+ spec.specConstants.push_back(123);
+ spec.specConstants.push_back(56);
+ spec.specConstants.push_back(-77);
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "vector_related", "VectorShuffle, CompositeExtract, & CompositeInsert", spec));
+
+ return group.release();
+} tcu::TestCaseGroup* createOpPhiGroup (tcu::TestContext& testCtx)
{
de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opphi", "Test the OpPhi instruction"));
ComputeShaderSpec spec;
spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "OpPhi corner cases", spec));
spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "various out-of-order blocks", spec));
return group.release();
}
-struct CaseParameter
+tcu::TestCaseGroup* createMultipleShaderGroup (tcu::TestContext& testCtx)
{
- const char* name;
- string param;
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "multiple_shaders", "Test multiple shaders in the same module"));
+ ComputeShaderSpec spec1;
+ ComputeShaderSpec spec2;
+ de::Random rnd (deStringHash(group->getName()));
+ const int numElements = 100;
+ vector<float> inputFloats (numElements, 0);
+ vector<float> outputFloats1 (numElements, 0);
+ vector<float> outputFloats2 (numElements, 0);
- CaseParameter (const char* case_, const string& param_) : name(case_), param(param_) {}
-};
+ fillRandomScalars(rnd, -500.f, 500.f, &inputFloats[0], numElements);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ {
+ outputFloats1[ndx] = inputFloats[ndx] + inputFloats[ndx];
+ outputFloats2[ndx] = -inputFloats[ndx];
+ }
+
+ const string assembly =
+ "OpCapability Shader\n"
+ "OpMemoryModel Logical GLSL450\n"
+ "OpEntryPoint GLCompute %comp_main1 \"entrypoint1\" %id\n"
+ "OpEntryPoint GLCompute %comp_main2 \"entrypoint2\" %id\n"
+ // A module cannot have two OpEntryPoint instructions with the same Execution Model and the same Name string.
+ "OpEntryPoint Vertex %vert_main \"entrypoint2\" %vert_builtins %vertexID %instanceID\n"
+ "OpExecutionMode %main LocalSize 1 1 1\n";
+
+ "OpName %comp_main1 \"entrypoint1\"\n"
+ "OpName %comp_main2 \"entrypoint2\"\n"
+ "OpName %vert_main \"entrypoint2\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+ "OpName %vert_builtin_st \"gl_PerVertex\"\n"
+ "OpName %vertexID \"gl_VertexID\"\n"
+ "OpName %instanceID \"gl_InstanceID\"\n"
+ "OpMemberName %vert_builtin_st 0 \"gl_Position\"\n"
+ "OpMemberName %vert_builtin_st 1 \"gl_PointSize\"\n"
+ "OpMemberName %vert_builtin_st 2 \"gl_ClipDistance\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+ "OpDecorate %vertexID BuiltIn VertexId\n"
+ "OpDecorate %instanceID BuiltIn InstanceId\n"
+ "OpDecorate %vert_builtin_st Block\n"
+ "OpMemberDecorate %vert_builtin_st 0 BuiltIn Position\n"
+ "OpMemberDecorate %vert_builtin_st 1 BuiltIn PointSize\n"
+ "OpMemberDecorate %vert_builtin_st 2 BuiltIn ClipDistance\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) + string(s_InputOutputBuffer) +
+
+ "%i32ptr = OpTypePointer Input %i32\n"
+ "%vec4 = OpTypeVector %f32 4\n"
+ "%vec4ptr = OpTypePointer Output %vec4\n"
+ "%f32arr1 = OpTypeArray %f32 %one\n"
+ "%vert_builtin_st = OpTypeStruct %vec4 %f32 %f32arr1\n"
+ "%vert_builtin_st_ptr = OpTypePointer Output %vert_builtin_st\n"
+ "%vert_builtins = OpVariable %vert_builtin_st_ptr Output\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%vertexID = OpVariable %i32ptr Input\n"
+ "%instanceID = OpVariable %i32ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%one = OpConstant %u32 1\n"
+ "%c_f32_1 = OpConstant %f32 1\n"
+ "%c_vec4_1 = OpConstantComposite %vec4 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_1\n"
+
+ // gl_Position = vec4(1.);
+ "%vert_main = OpFunction %void None %voidf\n"
+ "%vert_entry = OpLabel\n"
+ "%position = OpAccessChain %vec4ptr %vert_builtins %zero\n"
+ " OpStore %position %c_vec4_1\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n"
+
+ // Double inputs.
+ "%comp_main1 = OpFunction %void None %voidf\n"
+ "%comp1_entry = OpLabel\n"
+ "%idval1 = OpLoad %uvec3 %id\n"
+ "%x1 = OpCompositeExtract %u32 %idval1 0\n"
+ "%inloc1 = OpAccessChain %f32ptr %indata %zero %x1\n"
+ "%inval1 = OpLoad %f32 %inloc1\n"
+ "%add = OpFAdd %f32 %inval1 %inval1\n"
+ "%outloc1 = OpAccessChain %f32ptr %outdata %zero %x1\n"
+ " OpStore %outloc1 %add\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n"
+
+ // Negate inputs.
+ "%comp_main2 = OpFunction %void None %voidf\n"
+ "%comp2_entry = OpLabel\n"
+ "%idval2 = OpLoad %uvec3 %id\n"
+ "%x2 = OpCompositeExtract %u32 %idval2 0\n"
+ "%inloc2 = OpAccessChain %f32ptr %indata %zero %x2\n"
+ "%inval2 = OpLoad %f32 %inloc2\n"
+ "%neg = OpFNegate %f32 %inval2\n"
+ "%outloc2 = OpAccessChain %f32ptr %outdata %zero %x2\n"
+ " OpStore %outloc2 %neg\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+
+ spec1.assembly = assembly;
+ spec1.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ spec1.outputs.push_back(BufferSp(new Float32Buffer(outputFloats1)));
+ spec1.numWorkGroups = IVec3(numElements, 1, 1);
+ spec1.entryPoint = "entrypoint1";
+
+ spec2.assembly = assembly;
+ spec2.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ spec2.outputs.push_back(BufferSp(new Float32Buffer(outputFloats2)));
+ spec2.numWorkGroups = IVec3(numElements, 1, 1);
+ spec2.entryPoint = "entrypoint2";
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "shader1", "multiple shaders in the same module", spec1));
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "shader2", "multiple shaders in the same module", spec2));
+
+ return group.release();
+}
tcu::TestCaseGroup* createOpSourceGroup (tcu::TestContext& testCtx)
{
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
}
spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
}
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
}
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
}
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, "spotcheck", "Check that values constructed via OpConstantNull & OpConstantComposite can be used", spec));
spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
}
spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
}
spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
+ }
+
+ return group.release();
+}
+
+tcu::TestCaseGroup* createMemoryAccessGroup (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "memory_access", "Tests memory access cases"));
+ vector<CaseParameter> cases;
+ de::Random rnd (deStringHash(group->getName()));
+ const int numElements = 100;
+ vector<float> inputFloats (numElements, 0);
+ vector<float> outputFloats (numElements, 0);
+ const StringTemplate shaderTemplate (
+ string(s_ShaderPreamble) +
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(s_InputOutputBufferTraits) + string(s_CommonTypes) + string(s_InputOutputBuffer) +
+
+ "%f32ptr_f = OpTypePointer Function %f32\n"
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%four = OpConstant %i32 4\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%copy = OpVariable %f32ptr_f Function\n"
+ "%idval = OpLoad %uvec3 %id ${ACCESS}\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpCopyMemory %copy %inloc ${ACCESS}\n"
+ "%val1 = OpLoad %f32 %copy\n"
+ "%val2 = OpLoad %f32 %inloc\n"
+ "%add = OpFAdd %f32 %val1 %val2\n"
+ " OpStore %outloc %add ${ACCESS}\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n");
+
+ cases.push_back(CaseParameter("null", ""));
+ cases.push_back(CaseParameter("none", "None"));
+ cases.push_back(CaseParameter("volatile", "Volatile"));
+ cases.push_back(CaseParameter("aligned", "Aligned 4"));
+ cases.push_back(CaseParameter("nontemporal", "Nontemporal"));
+ cases.push_back(CaseParameter("aligned_nontemporal", "Aligned|Nontemporal 4"));
+ cases.push_back(CaseParameter("aligned_volatile", "Volatile|Aligned 4"));
+
+ fillRandomScalars(rnd, -100.f, 100.f, &inputFloats[0], numElements);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ outputFloats[ndx] = inputFloats[ndx] + inputFloats[ndx];
+
+ for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
+ {
+ map<string, string> specializations;
+ ComputeShaderSpec spec;
+
+ specializations["ACCESS"] = cases[caseNdx].param;
+ spec.assembly = shaderTemplate.specialize(specializations);
+ spec.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
}
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
+ spec.entryPoint = "main";
group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].name, cases[caseNdx].name, spec));
}
instructionTests->addChild(createOpConstantNullGroup(testCtx));
instructionTests->addChild(createOpConstantCompositeGroup(testCtx));
instructionTests->addChild(createOpConstantUsageGroup(testCtx));
+ instructionTests->addChild(createSpecConstantGroup(testCtx));
instructionTests->addChild(createOpSourceGroup(testCtx));
instructionTests->addChild(createOpSourceExtensionGroup(testCtx));
instructionTests->addChild(createDecorationGroupGroup(testCtx));
instructionTests->addChild(createFunctionControlGroup(testCtx));
instructionTests->addChild(createSelectionControlGroup(testCtx));
instructionTests->addChild(createBlockOrderGroup(testCtx));
+ instructionTests->addChild(createMultipleShaderGroup(testCtx));
+ instructionTests->addChild(createMemoryAccessGroup(testCtx));
+ instructionTests->addChild(createOpCopyMemoryGroup(testCtx));
+ instructionTests->addChild(createOpCopyObjectGroup(testCtx));
+ instructionTests->addChild(createNoContractionGroup(testCtx));
instructionTests->addChild(createOpUndefGroup(testCtx));
instructionTests->addChild(createOpUnreachableGroup(testCtx));