#include "vktSpvAsmUboMatrixPaddingTests.hpp"
#include "vktSpvAsmConditionalBranchTests.hpp"
#include "vktSpvAsmIndexingTests.hpp"
+#include "vktSpvAsmImageSamplerTests.hpp"
#include "vktSpvAsmComputeShaderCase.hpp"
#include "vktSpvAsmComputeShaderTestUtil.hpp"
#include "vktSpvAsmGraphicsShaderTestUtil.hpp"
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:
+// Assembly code used for testing LocalSize, OpNop, OpConstant{Null|Composite}, Op[No]Line, OpSource[Continued], OpSourceExtension, OpUndef is based on GLSL source code:
//
// #version 430
//
// output_data.elements[x] = -input_data.elements[x];
// }
-
-static string getAsmForOpNopTest(bool useLiteralLocalSize, bool useSpecConstantWorkgroupSize) {
+static string getAsmForLocalSizeTest(bool useLiteralLocalSize, bool useSpecConstantWorkgroupSize, IVec3 workGroupSize, deUint32 ndx)
+{
std::ostringstream out;
out << getComputeAsmShaderPreambleWithoutLocalSize();
- if (useLiteralLocalSize) {
- out << "OpExecutionMode %main LocalSize 1 1 1\n";
+
+ if (useLiteralLocalSize)
+ {
+ out << "OpExecutionMode %main LocalSize "
+ << workGroupSize.x() << " " << workGroupSize.y() << " " << workGroupSize.z() << "\n";
}
out << "OpSource GLSL 430\n"
"OpName %id \"gl_GlobalInvocationID\"\n"
"OpDecorate %id BuiltIn GlobalInvocationId\n";
- if (useSpecConstantWorkgroupSize) {
+ if (useSpecConstantWorkgroupSize)
+ {
out << "OpDecorate %spec_0 SpecId 100\n"
- "OpDecorate %spec_0 SpecId 100\n"
- "OpDecorate %spec_1 SpecId 101\n"
- "OpDecorate %spec_2 SpecId 102\n"
- "OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n";
+ << "OpDecorate %spec_1 SpecId 101\n"
+ << "OpDecorate %spec_2 SpecId 102\n"
+ << "OpDecorate %gl_WorkGroupSize BuiltIn WorkgroupSize\n";
}
out << getComputeAsmInputOutputBufferTraits()
<< getComputeAsmCommonTypes()
<< getComputeAsmInputOutputBuffer()
<< "%id = OpVariable %uvec3ptr Input\n"
- << "%zero = OpConstant %i32 0\n";
+ << "%zero = OpConstant %i32 0 \n";
- if (useSpecConstantWorkgroupSize) {
- out << "%spec_0 = OpSpecConstant %u32 1\n"
- "%spec_1 = OpSpecConstant %u32 1\n"
- "%spec_2 = OpSpecConstant %u32 1\n"
- "%gl_WorkGroupSize = OpSpecConstantComposite %uvec3 %spec_0 %spec_1 %spec_2\n";
+ if (useSpecConstantWorkgroupSize)
+ {
+ out << "%spec_0 = OpSpecConstant %u32 "<< workGroupSize.x() << "\n"
+ << "%spec_1 = OpSpecConstant %u32 "<< workGroupSize.y() << "\n"
+ << "%spec_2 = OpSpecConstant %u32 "<< workGroupSize.z() << "\n"
+ << "%gl_WorkGroupSize = OpSpecConstantComposite %uvec3 %spec_0 %spec_1 %spec_2\n";
}
out << "%main = OpFunction %void None %voidf\n"
- "%label = OpLabel\n"
- "%idval = OpLoad %uvec3 %id\n"
- "%x = OpCompositeExtract %u32 %idval 0\n"
+ << "%label = OpLabel\n"
+ << "%idval = OpLoad %uvec3 %id\n"
+ << "%ndx = OpCompositeExtract %u32 %idval " << ndx << "\n"
+
+ "%inloc = OpAccessChain %f32ptr %indata %zero %ndx\n"
+ "%inval = OpLoad %f32 %inloc\n"
+ "%neg = OpFNegate %f32 %inval\n"
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %ndx\n"
+ " OpStore %outloc %neg\n"
+ " OpReturn\n"
+ " OpFunctionEnd\n";
+ return out.str();
+}
- " OpNop\n" // Inside a function body
+tcu::TestCaseGroup* createLocalSizeGroup (tcu::TestContext& testCtx)
+{
+ de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "localsize", ""));
+ ComputeShaderSpec spec;
+ de::Random rnd (deStringHash(group->getName()));
+ const deUint32 numElements = 64u;
+ vector<float> positiveFloats (numElements, 0);
+ vector<float> negativeFloats (numElements, 0);
- "%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";
- return out.str();
+ fillRandomScalars(rnd, 1.f, 100.f, &positiveFloats[0], numElements);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ negativeFloats[ndx] = -positiveFloats[ndx];
+
+ spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
+ spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
+
+ spec.numWorkGroups = IVec3(numElements, 1, 1);
+
+ spec.assembly = getAsmForLocalSizeTest(true, false, IVec3(1, 1, 1), 0u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_localsize", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(true, true, IVec3(1, 1, 1), 0u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_and_specid_localsize", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(false, true, IVec3(1, 1, 1), 0u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "specid_localsize", "", spec));
+
+ spec.numWorkGroups = IVec3(1, 1, 1);
+
+ spec.assembly = getAsmForLocalSizeTest(true, false, IVec3(numElements, 1, 1), 0u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_localsize_x", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(true, true, IVec3(numElements, 1, 1), 0u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_and_specid_localsize_x", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(false, true, IVec3(numElements, 1, 1), 0u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "specid_localsize_x", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(true, false, IVec3(1, numElements, 1), 1u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_localsize_y", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(true, true, IVec3(1, numElements, 1), 1u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_and_specid_localsize_y", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(false, true, IVec3(1, numElements, 1), 1u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "specid_localsize_y", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(true, false, IVec3(1, 1, numElements), 2u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_localsize_z", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(true, true, IVec3(1, 1, numElements), 2u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_and_specid_localsize_z", "", spec));
+
+ spec.assembly = getAsmForLocalSizeTest(false, true, IVec3(1, 1, numElements), 2u);
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "specid_localsize_z", "", spec));
+
+ return group.release();
}
tcu::TestCaseGroup* createOpNopGroup (tcu::TestContext& testCtx)
for (size_t ndx = 0; ndx < numElements; ++ndx)
negativeFloats[ndx] = -positiveFloats[ndx];
+ spec.assembly =
+ string(getComputeAsmShaderPreamble()) +
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes())
+
+ + string(getComputeAsmInputOutputBuffer()) +
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%label = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+
+ " OpNop\n" // Inside a function body
+
+ "%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";
spec.inputs.push_back(BufferSp(new Float32Buffer(positiveFloats)));
spec.outputs.push_back(BufferSp(new Float32Buffer(negativeFloats)));
spec.numWorkGroups = IVec3(numElements, 1, 1);
- spec.assembly = getAsmForOpNopTest(true, false);
- group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_localsize", "OpNop appearing at different places", spec));
-
- spec.assembly = getAsmForOpNopTest(true, true);
- group->addChild(new SpvAsmComputeShaderCase(testCtx, "literal_and_specid_localsize", "OpNop appearing at different places", spec));
-
- spec.assembly = getAsmForOpNopTest(false, true);
- group->addChild(new SpvAsmComputeShaderCase(testCtx, "specid_localsize", "OpNop appearing at different places", spec));
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "all", "OpNop appearing at different places", spec));
return group.release();
}
vector<deInt32> outputInts3 (numElements, 0);
vector<deInt32> outputInts4 (numElements, 0);
const StringTemplate shaderTemplate (
- string(getComputeAsmShaderPreamble()) +
+ "${CAPABILITIES:opt}"
+ + string(getComputeAsmShaderPreamble()) +
"OpName %main \"main\"\n"
"OpName %id \"gl_GlobalInvocationID\"\n"
+ string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) +
+ "${OPTYPE_DEFINITIONS:opt}"
"%buf = OpTypeStruct %i32arr\n"
"%bufptr = OpTypePointer Uniform %buf\n"
"%indata = OpVariable %bufptr Uniform\n"
"%main = OpFunction %void None %voidf\n"
"%label = OpLabel\n"
+ "${TYPE_CONVERT:opt}"
"%idval = OpLoad %uvec3 %id\n"
"%x = OpCompositeExtract %u32 %idval 0\n"
"%inloc = OpAccessChain %i32ptr %indata %zero %x\n"
}
const char addScToInput[] = "OpIAdd %i32 %inval %sc_final";
+ const char addSc32ToInput[] = "OpIAdd %i32 %inval %sc_final32";
const char selectTrueUsingSc[] = "OpSelect %i32 %sc_final %inval %zero";
const char selectFalseUsingSc[] = "OpSelect %i32 %sc_final %zero %inval";
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.
+ cases.push_back(SpecConstantTwoIntCase("sconvert", " %i32 0", " %i32 0", "%i16", "SConvert %sc_0", -11200, 0, addSc32ToInput, outputInts3));
+ // -969998336 stored as 32-bit two's complement is the binary representation of -11200 as IEEE-754 Float
+ cases.push_back(SpecConstantTwoIntCase("fconvert", " %f32 0", " %f32 0", "%f64", "FConvert %sc_0", -969998336, 0, addSc32ToInput, outputInts3));
for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
{
map<string, string> specializations;
ComputeShaderSpec spec;
+ ComputeTestFeatures features = COMPUTE_TEST_USES_NONE;
specializations["SC_DEF0"] = cases[caseNdx].scDefinition0;
specializations["SC_DEF1"] = cases[caseNdx].scDefinition1;
specializations["SC_OP"] = cases[caseNdx].scOperation;
specializations["GEN_RESULT"] = cases[caseNdx].resultOperation;
+ // Special SPIR-V code for SConvert-case
+ if (strcmp(cases[caseNdx].caseName, "sconvert") == 0)
+ {
+ features = COMPUTE_TEST_USES_INT16;
+ specializations["CAPABILITIES"] = "OpCapability Int16\n"; // Adds 16-bit integer capability
+ specializations["OPTYPE_DEFINITIONS"] = "%i16 = OpTypeInt 16 1\n"; // Adds 16-bit integer type
+ specializations["TYPE_CONVERT"] = "%sc_final32 = OpSConvert %i32 %sc_final\n"; // Converts 16-bit integer to 32-bit integer
+ }
+
+ // Special SPIR-V code for FConvert-case
+ if (strcmp(cases[caseNdx].caseName, "fconvert") == 0)
+ {
+ features = COMPUTE_TEST_USES_FLOAT64;
+ specializations["CAPABILITIES"] = "OpCapability Float64\n"; // Adds 64-bit float capability
+ specializations["OPTYPE_DEFINITIONS"] = "%f64 = OpTypeFloat 64\n"; // Adds 64-bit float type
+ specializations["TYPE_CONVERT"] = "%sc_final32 = OpConvertFToS %i32 %sc_final\n"; // Converts 64-bit float to 32-bit integer
+ }
+
spec.assembly = shaderTemplate.specialize(specializations);
spec.inputs.push_back(BufferSp(new Int32Buffer(inputInts)));
spec.outputs.push_back(BufferSp(new Int32Buffer(cases[caseNdx].expectedOutput)));
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));
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, cases[caseNdx].caseName, cases[caseNdx].caseName, spec, features));
}
ComputeShaderSpec spec;
return group.release();
}
+void createOpPhiVartypeTests (de::MovePtr<tcu::TestCaseGroup>& group, tcu::TestContext& testCtx)
+{
+ ComputeShaderSpec specInt;
+ ComputeShaderSpec specFloat;
+ ComputeShaderSpec specVec3;
+ ComputeShaderSpec specMat4;
+ ComputeShaderSpec specArray;
+ ComputeShaderSpec specStruct;
+ de::Random rnd (deStringHash(group->getName()));
+ const int numElements = 100;
+ vector<float> inputFloats (numElements, 0);
+ vector<float> outputFloats (numElements, 0);
+
+ fillRandomScalars(rnd, -300.f, 300.f, &inputFloats[0], numElements);
+
+ // CPU might not use the same rounding mode as the GPU. Use whole numbers to avoid rounding differences.
+ floorAll(inputFloats);
+
+ for (size_t ndx = 0; ndx < numElements; ++ndx)
+ {
+ // Just check if the value is positive or not
+ outputFloats[ndx] = (inputFloats[ndx] > 0) ? 1.0f : -1.0f;
+ }
+
+ // All of the tests are of the form:
+ //
+ // testtype r
+ //
+ // if (inputdata > 0)
+ // r = 1
+ // else
+ // r = -1
+ //
+ // return (float)r
+
+ specFloat.assembly =
+ string(getComputeAsmShaderPreamble()) +
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%float_0 = OpConstant %f32 0.0\n"
+ "%float_1 = OpConstant %f32 1.0\n"
+ "%float_n1 = OpConstant %f32 -1.0\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%entry = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%inval = OpLoad %f32 %inloc\n"
+
+ "%comp = OpFOrdGreaterThan %bool %inval %float_0\n"
+ " OpSelectionMerge %cm None\n"
+ " OpBranchConditional %comp %tb %fb\n"
+ "%tb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%fb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%cm = OpLabel\n"
+ "%res = OpPhi %f32 %float_1 %tb %float_n1 %fb\n"
+
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpStore %outloc %res\n"
+ " OpReturn\n"
+
+ " OpFunctionEnd\n";
+ specFloat.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ specFloat.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ specFloat.numWorkGroups = IVec3(numElements, 1, 1);
+
+ specMat4.assembly =
+ string(getComputeAsmShaderPreamble()) +
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%v4f32 = OpTypeVector %f32 4\n"
+ "%mat4v4f32 = OpTypeMatrix %v4f32 4\n"
+ "%zero = OpConstant %i32 0\n"
+ "%float_0 = OpConstant %f32 0.0\n"
+ "%float_1 = OpConstant %f32 1.0\n"
+ "%float_n1 = OpConstant %f32 -1.0\n"
+ "%m11 = OpConstantComposite %v4f32 %float_1 %float_0 %float_0 %float_0\n"
+ "%m12 = OpConstantComposite %v4f32 %float_0 %float_1 %float_0 %float_0\n"
+ "%m13 = OpConstantComposite %v4f32 %float_0 %float_0 %float_1 %float_0\n"
+ "%m14 = OpConstantComposite %v4f32 %float_0 %float_0 %float_0 %float_1\n"
+ "%m1 = OpConstantComposite %mat4v4f32 %m11 %m12 %m13 %m14\n"
+ "%m21 = OpConstantComposite %v4f32 %float_n1 %float_0 %float_0 %float_0\n"
+ "%m22 = OpConstantComposite %v4f32 %float_0 %float_n1 %float_0 %float_0\n"
+ "%m23 = OpConstantComposite %v4f32 %float_0 %float_0 %float_n1 %float_0\n"
+ "%m24 = OpConstantComposite %v4f32 %float_0 %float_0 %float_0 %float_n1\n"
+ "%m2 = OpConstantComposite %mat4v4f32 %m21 %m22 %m23 %m24\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%entry = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%inval = OpLoad %f32 %inloc\n"
+
+ "%comp = OpFOrdGreaterThan %bool %inval %float_0\n"
+ " OpSelectionMerge %cm None\n"
+ " OpBranchConditional %comp %tb %fb\n"
+ "%tb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%fb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%cm = OpLabel\n"
+ "%mres = OpPhi %mat4v4f32 %m1 %tb %m2 %fb\n"
+ "%res = OpCompositeExtract %f32 %mres 2 2\n"
+
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpStore %outloc %res\n"
+ " OpReturn\n"
+
+ " OpFunctionEnd\n";
+ specMat4.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ specMat4.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ specMat4.numWorkGroups = IVec3(numElements, 1, 1);
+
+ specVec3.assembly =
+ string(getComputeAsmShaderPreamble()) +
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%float_0 = OpConstant %f32 0.0\n"
+ "%float_1 = OpConstant %f32 1.0\n"
+ "%float_n1 = OpConstant %f32 -1.0\n"
+ "%v1 = OpConstantComposite %fvec3 %float_1 %float_1 %float_1\n"
+ "%v2 = OpConstantComposite %fvec3 %float_n1 %float_n1 %float_n1\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%entry = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%inval = OpLoad %f32 %inloc\n"
+
+ "%comp = OpFOrdGreaterThan %bool %inval %float_0\n"
+ " OpSelectionMerge %cm None\n"
+ " OpBranchConditional %comp %tb %fb\n"
+ "%tb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%fb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%cm = OpLabel\n"
+ "%vres = OpPhi %fvec3 %v1 %tb %v2 %fb\n"
+ "%res = OpCompositeExtract %f32 %vres 2\n"
+
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpStore %outloc %res\n"
+ " OpReturn\n"
+
+ " OpFunctionEnd\n";
+ specVec3.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ specVec3.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ specVec3.numWorkGroups = IVec3(numElements, 1, 1);
+
+ specInt.assembly =
+ string(getComputeAsmShaderPreamble()) +
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%float_0 = OpConstant %f32 0.0\n"
+ "%i1 = OpConstant %i32 1\n"
+ "%i2 = OpConstant %i32 -1\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%entry = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%inval = OpLoad %f32 %inloc\n"
+
+ "%comp = OpFOrdGreaterThan %bool %inval %float_0\n"
+ " OpSelectionMerge %cm None\n"
+ " OpBranchConditional %comp %tb %fb\n"
+ "%tb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%fb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%cm = OpLabel\n"
+ "%ires = OpPhi %i32 %i1 %tb %i2 %fb\n"
+ "%res = OpConvertSToF %f32 %ires\n"
+
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpStore %outloc %res\n"
+ " OpReturn\n"
+
+ " OpFunctionEnd\n";
+ specInt.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ specInt.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ specInt.numWorkGroups = IVec3(numElements, 1, 1);
+
+ specArray.assembly =
+ string(getComputeAsmShaderPreamble()) +
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%u7 = OpConstant %u32 7\n"
+ "%float_0 = OpConstant %f32 0.0\n"
+ "%float_1 = OpConstant %f32 1.0\n"
+ "%float_n1 = OpConstant %f32 -1.0\n"
+ "%f32a7 = OpTypeArray %f32 %u7\n"
+ "%a1 = OpConstantComposite %f32a7 %float_1 %float_1 %float_1 %float_1 %float_1 %float_1 %float_1\n"
+ "%a2 = OpConstantComposite %f32a7 %float_n1 %float_n1 %float_n1 %float_n1 %float_n1 %float_n1 %float_n1\n"
+ "%main = OpFunction %void None %voidf\n"
+ "%entry = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%inval = OpLoad %f32 %inloc\n"
+
+ "%comp = OpFOrdGreaterThan %bool %inval %float_0\n"
+ " OpSelectionMerge %cm None\n"
+ " OpBranchConditional %comp %tb %fb\n"
+ "%tb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%fb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%cm = OpLabel\n"
+ "%ares = OpPhi %f32a7 %a1 %tb %a2 %fb\n"
+ "%res = OpCompositeExtract %f32 %ares 5\n"
+
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpStore %outloc %res\n"
+ " OpReturn\n"
+
+ " OpFunctionEnd\n";
+ specArray.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ specArray.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ specArray.numWorkGroups = IVec3(numElements, 1, 1);
+
+ specStruct.assembly =
+ string(getComputeAsmShaderPreamble()) +
+
+ "OpSource GLSL 430\n"
+ "OpName %main \"main\"\n"
+ "OpName %id \"gl_GlobalInvocationID\"\n"
+
+ "OpDecorate %id BuiltIn GlobalInvocationId\n"
+
+ + string(getComputeAsmInputOutputBufferTraits()) + string(getComputeAsmCommonTypes()) + string(getComputeAsmInputOutputBuffer()) +
+
+ "%id = OpVariable %uvec3ptr Input\n"
+ "%zero = OpConstant %i32 0\n"
+ "%float_0 = OpConstant %f32 0.0\n"
+ "%float_1 = OpConstant %f32 1.0\n"
+ "%float_n1 = OpConstant %f32 -1.0\n"
+
+ "%v2f32 = OpTypeVector %f32 2\n"
+ "%Data2 = OpTypeStruct %f32 %v2f32\n"
+ "%Data = OpTypeStruct %Data2 %f32\n"
+
+ "%in1a = OpConstantComposite %v2f32 %float_1 %float_1\n"
+ "%in1b = OpConstantComposite %Data2 %float_1 %in1a\n"
+ "%s1 = OpConstantComposite %Data %in1b %float_1\n"
+ "%in2a = OpConstantComposite %v2f32 %float_n1 %float_n1\n"
+ "%in2b = OpConstantComposite %Data2 %float_n1 %in2a\n"
+ "%s2 = OpConstantComposite %Data %in2b %float_n1\n"
+
+ "%main = OpFunction %void None %voidf\n"
+ "%entry = OpLabel\n"
+ "%idval = OpLoad %uvec3 %id\n"
+ "%x = OpCompositeExtract %u32 %idval 0\n"
+ "%inloc = OpAccessChain %f32ptr %indata %zero %x\n"
+ "%inval = OpLoad %f32 %inloc\n"
+
+ "%comp = OpFOrdGreaterThan %bool %inval %float_0\n"
+ " OpSelectionMerge %cm None\n"
+ " OpBranchConditional %comp %tb %fb\n"
+ "%tb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%fb = OpLabel\n"
+ " OpBranch %cm\n"
+ "%cm = OpLabel\n"
+ "%sres = OpPhi %Data %s1 %tb %s2 %fb\n"
+ "%res = OpCompositeExtract %f32 %sres 0 0\n"
+
+ "%outloc = OpAccessChain %f32ptr %outdata %zero %x\n"
+ " OpStore %outloc %res\n"
+ " OpReturn\n"
+
+ " OpFunctionEnd\n";
+ specStruct.inputs.push_back(BufferSp(new Float32Buffer(inputFloats)));
+ specStruct.outputs.push_back(BufferSp(new Float32Buffer(outputFloats)));
+ specStruct.numWorkGroups = IVec3(numElements, 1, 1);
+
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "vartype_int", "OpPhi with int variables", specInt));
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "vartype_float", "OpPhi with float variables", specFloat));
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "vartype_vec3", "OpPhi with vec3 variables", specVec3));
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "vartype_mat4", "OpPhi with mat4 variables", specMat4));
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "vartype_array", "OpPhi with array variables", specArray));
+ group->addChild(new SpvAsmComputeShaderCase(testCtx, "vartype_struct", "OpPhi with struct variables", specStruct));
+}
+
string generateConstantDefinitions (int count)
{
std::ostringstream r;
group->addChild(new SpvAsmComputeShaderCase(testCtx, "nested", "Stress OpPhi with a lot of nesting", spec5));
+ createOpPhiVartypeTests(group, testCtx);
+
return group.release();
}
"OpDecorate %sc_1 SpecId 1\n";
const char typesAndConstants1[] =
+ "${OPTYPE_DEFINITIONS:opt}"
"%sc_0 = OpSpecConstant${SC_DEF0}\n"
"%sc_1 = OpSpecConstant${SC_DEF1}\n"
"%sc_op = OpSpecConstantOp ${SC_RESULT_TYPE} ${SC_OP}\n";
"%test_code = OpFunction %v4f32 None %v4f32_function\n"
"%param = OpFunctionParameter %v4f32\n"
"%label = OpLabel\n"
+ "${TYPE_CONVERT:opt}"
"%result = OpVariable %fp_v4f32 Function\n"
" OpStore %result %param\n"
"%gen = ${GEN_RESULT}\n"
outputColors2[3] = RGBA(0, 0, 255, 255);
const char addZeroToSc[] = "OpIAdd %i32 %c_i32_0 %sc_op";
+ const char addZeroToSc32[] = "OpIAdd %i32 %c_i32_0 %sc_op32";
const char selectTrueUsingSc[] = "OpSelect %i32 %sc_op %c_i32_1 %c_i32_0";
const char selectFalseUsingSc[] = "OpSelect %i32 %sc_op %c_i32_0 %c_i32_1";
cases.push_back(SpecConstantTwoIntGraphicsCase("not", " %i32 0", " %i32 0", "%i32", "Not %sc_0", -2, 0, addZeroToSc, outputColors2));
cases.push_back(SpecConstantTwoIntGraphicsCase("logicalnot", "False %bool", "False %bool", "%bool", "LogicalNot %sc_0", 1, 0, selectFalseUsingSc, outputColors2));
cases.push_back(SpecConstantTwoIntGraphicsCase("select", "False %bool", " %i32 0", "%i32", "Select %sc_0 %sc_1 %c_i32_0", 1, 1, addZeroToSc, outputColors2));
- // OpSConvert, OpFConvert: these two instructions involve ints/floats of different bitwidths.
+ cases.push_back(SpecConstantTwoIntGraphicsCase("sconvert", " %i32 0", " %i32 0", "%i16", "SConvert %sc_0", -1, 0, addZeroToSc32, outputColors0));
+ // -1082130432 stored as 32-bit two's complement is the binary representation of -1 as IEEE-754 Float
+ cases.push_back(SpecConstantTwoIntGraphicsCase("fconvert", " %f32 0", " %f32 0", "%f64", "FConvert %sc_0", -1082130432, 0, addZeroToSc32, outputColors0));
// \todo[2015-12-1 antiagainst] OpQuantizeToF16
for (size_t caseNdx = 0; caseNdx < cases.size(); ++caseNdx)
{
- map<string, string> specializations;
- map<string, string> fragments;
- vector<deInt32> specConstants;
+ map<string, string> specializations;
+ map<string, string> fragments;
+ vector<deInt32> specConstants;
+ vector<string> features;
+ PushConstants noPushConstants;
+ GraphicsResources noResources;
+ GraphicsInterfaces noInterfaces;
+ std::vector<std::string> noExtensions;
+
+ // Special SPIR-V code for SConvert-case
+ if (strcmp(cases[caseNdx].caseName, "sconvert") == 0)
+ {
+ features.push_back("shaderInt16");
+ fragments["capability"] = "OpCapability Int16\n"; // Adds 16-bit integer capability
+ specializations["OPTYPE_DEFINITIONS"] = "%i16 = OpTypeInt 16 1\n"; // Adds 16-bit integer type
+ specializations["TYPE_CONVERT"] = "%sc_op32 = OpSConvert %i32 %sc_op\n"; // Converts 16-bit integer to 32-bit integer
+ }
+
+ // Special SPIR-V code for FConvert-case
+ if (strcmp(cases[caseNdx].caseName, "fconvert") == 0)
+ {
+ features.push_back("shaderFloat64");
+ fragments["capability"] = "OpCapability Float64\n"; // Adds 64-bit float capability
+ specializations["OPTYPE_DEFINITIONS"] = "%f64 = OpTypeFloat 64\n"; // Adds 64-bit float type
+ specializations["TYPE_CONVERT"] = "%sc_op32 = OpConvertFToS %i32 %sc_op\n"; // Converts 64-bit float to 32-bit integer
+ }
specializations["SC_DEF0"] = cases[caseNdx].scDefinition0;
specializations["SC_DEF1"] = cases[caseNdx].scDefinition1;
specConstants.push_back(cases[caseNdx].scActualValue0);
specConstants.push_back(cases[caseNdx].scActualValue1);
- createTestsForAllStages(cases[caseNdx].caseName, inputColors, cases[caseNdx].expectedColors, fragments, specConstants, group.get());
+ createTestsForAllStages(
+ cases[caseNdx].caseName, inputColors, cases[caseNdx].expectedColors, fragments, specConstants,
+ noPushConstants, noResources, noInterfaces, noExtensions, features, VulkanFeatures(), group.get());
}
const char decorations2[] =
"%c_vec4_1 = OpConstantComposite %v4f32 %c_f32_1 %c_f32_1 %c_f32_1 %c_f32_1\n"
"%c_f32_1pl2_23 = OpConstant %f32 0x1.000002p+0\n" // 1 + 2^-23
"%c_f32_1mi2_23 = OpConstant %f32 0x1.fffffcp-1\n" // 1 - 2^-23
- "%c_f32_n1pn24 = OpConstant %f32 -0x1p-24\n"
- ;
+ "%c_f32_n1pn24 = OpConstant %f32 -0x1p-24\n";
const char function[] =
"%test_code = OpFunction %v4f32 None %v4f32_function\n"
"%b = OpFAdd %f32 %a %actually_zero\n"
"%ret = OpVectorInsertDynamic %v4f32 %param1 %b %c_i32_0\n"
"OpReturnValue %ret\n"
- "OpFunctionEnd\n"
- ;
+ "OpFunctionEnd\n";
+
createTestsForAllStages("float32", defaultColors, defaultColors, fragments, opUndefTests.get());
fragments["testfun"] =
"%a = OpVectorExtractDynamic %f32 %param1 %zero\n"
"%ret = OpVectorInsertDynamic %v4f32 %param1 %a %c_i32_0\n"
"OpReturnValue %ret\n"
- "OpFunctionEnd\n"
- ;
+ "OpFunctionEnd\n";
+
createTestsForAllStages("sint32", defaultColors, defaultColors, fragments, opUndefTests.get());
fragments["testfun"] =
"%a = OpVectorExtractDynamic %f32 %param1 %zero\n"
"%ret = OpVectorInsertDynamic %v4f32 %param1 %a %c_i32_0\n"
"OpReturnValue %ret\n"
- "OpFunctionEnd\n"
- ;
+ "OpFunctionEnd\n";
+
createTestsForAllStages("uint32", defaultColors, defaultColors, fragments, opUndefTests.get());
fragments["testfun"] =
"%ret1 = OpVectorInsertDynamic %v4f32 %ret2 %sum_1 %c_i32_1\n"
"%ret = OpVectorInsertDynamic %v4f32 %ret1 %sum_0 %c_i32_0\n"
"OpReturnValue %ret\n"
- "OpFunctionEnd\n"
- ;
+ "OpFunctionEnd\n";
+
createTestsForAllStages("vec4float32", defaultColors, defaultColors, fragments, opUndefTests.get());
fragments["pre_main"] =
"%ret1 = OpVectorInsertDynamic %v4f32 %ret2 %sum_1 %c_i32_1\n"
"%ret = OpVectorInsertDynamic %v4f32 %ret1 %sum_0 %c_i32_0\n"
"OpReturnValue %ret\n"
- "OpFunctionEnd\n"
- ;
+ "OpFunctionEnd\n";
+
createTestsForAllStages("matrix", defaultColors, defaultColors, fragments, opUndefTests.get());
return opUndefTests.release();
"%result = OpVectorInsertDynamic %v4f32 %param1 %val %c_i32_0\n"
"OpReturnValue %result\n"
- "OpFunctionEnd\n"
- ;
+ "OpFunctionEnd\n";
+
createTestsForAllStages("single_block", defaultColors, defaultColors, fragments, testGroup.get());
// Body comprised of multiple basic blocks.
if (m_features == COMPUTE_TEST_USES_INT16)
{
- m_asmTypes["int_capabilities"] = "OpCapability Int16\n";
- m_asmTypes["int_additional_decl"] = "%i16 = OpTypeInt 16 1\n%u16 = OpTypeInt 16 0\n";
+ 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";
}
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_capabilities"] = "OpCapability Int64\n";
+ m_asmTypes["int_additional_decl"] = "%i64 = OpTypeInt 64 1\n"
+ "%u64 = OpTypeInt 64 0\n";
+ m_asmTypes["int_extensions"] = "";
}
else if (m_features == COMPUTE_TEST_USES_INT16_INT64)
{
- m_asmTypes["int_capabilities"] = string("OpCapability Int16\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_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";
}
else
{
const StringTemplate shader (
"OpCapability Shader\n"
"${int_capabilities}"
+ "${int_extensions}"
"OpMemoryModel Logical GLSL450\n"
"OpEntryPoint GLCompute %main \"main\" %id\n"
"OpExecutionMode %main LocalSize 1 1 1\n"
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)
+ {
+ spec.extensions.push_back("VK_KHR_16bit_storage");
+ }
+
group->addChild(new SpvAsmComputeShaderCase(testCtx, test->m_name.c_str(), "Convert integers with OpSConvert.", spec, test->m_features));
}
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)
+ {
+ spec.extensions.push_back("VK_KHR_16bit_storage");
+ }
+
group->addChild(new SpvAsmComputeShaderCase(testCtx, test->m_name.c_str(), "Convert integers with OpUConvert.", spec, test->m_features));
}
return group.release();
de::MovePtr<tcu::TestCaseGroup> computeTests (new tcu::TestCaseGroup(testCtx, "compute", "Compute Instructions with special opcodes/operands"));
de::MovePtr<tcu::TestCaseGroup> graphicsTests (new tcu::TestCaseGroup(testCtx, "graphics", "Graphics Instructions with special opcodes/operands"));
+ computeTests->addChild(createLocalSizeGroup(testCtx));
computeTests->addChild(createOpNopGroup(testCtx));
computeTests->addChild(createOpFUnordGroup(testCtx));
computeTests->addChild(createOpAtomicGroup(testCtx, false));
computeTests->addChild(createConditionalBranchComputeGroup(testCtx));
computeTests->addChild(createIndexingComputeGroup(testCtx));
computeTests->addChild(createVariablePointersComputeGroup(testCtx));
+ computeTests->addChild(createImageSamplerComputeGroup(testCtx));
graphicsTests->addChild(createOpNopTests(testCtx));
graphicsTests->addChild(createOpSourceTests(testCtx));
graphicsTests->addChild(createOpSourceContinuedTests(testCtx));
graphicsTests->addChild(createConditionalBranchGraphicsGroup(testCtx));
graphicsTests->addChild(createIndexingGraphicsGroup(testCtx));
graphicsTests->addChild(createVariablePointersGraphicsGroup(testCtx));
+ graphicsTests->addChild(createImageSamplerGraphicsGroup(testCtx));
instructionTests->addChild(computeTests.release());
instructionTests->addChild(graphicsTests.release());