#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"
const NameCodePair tests[] =
{
{"bool", "", "%bool"},
- {"vec2uint32", "%type = OpTypeVector %u32 2", "%type"},
+ {"vec2uint32", "", "%v2u32"},
{"image", "%type = OpTypeImage %f32 2D 0 0 0 1 Unknown", "%type"},
{"sampler", "%type = OpTypeSampler", "%type"},
{"sampledimage", "%img = OpTypeImage %f32 2D 0 0 0 1 Unknown\n" "%type = OpTypeSampledImage %img", "%type"},
"%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.
return "OpTypeInt " + getBitWidthStr(type) + sign;
}
+const string getAsmTypeName (IntegerType type)
+{
+ const string prefix = isSigned(type) ? "%i" : "%u";
+ return prefix + getBitWidthStr(type);
+}
+
template<typename T>
BufferSp getSpecializedBuffer (deInt64 number)
{
, m_inputBuffer (getBuffer(from, number))
, m_outputBuffer (getBuffer(to, number))
{
- m_asmTypes["inputType"] = getAsmTypeDeclaration(from);
- m_asmTypes["outputType"] = getAsmTypeDeclaration(to);
+ m_asmTypes["inputType"] = getAsmTypeName(from);
+ m_asmTypes["outputType"] = getAsmTypeName(to);
if (m_features == COMPUTE_TEST_USES_INT16)
{
- m_asmTypes["int_capabilities"] = "OpCapability Int16\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_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_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"
"%voidf = OpTypeFunction %void\n"
"%u32 = OpTypeInt 32 0\n"
"%i32 = OpTypeInt 32 1\n"
+ "${int_additional_decl}"
"%uvec3 = OpTypeVector %u32 3\n"
"%uvec3ptr = OpTypePointer Input %uvec3\n"
- // Custom types
- "%in_type = ${inputType}\n"
- "%out_type = ${outputType}\n"
// Derived types
- "%in_ptr = OpTypePointer Uniform %in_type\n"
- "%out_ptr = OpTypePointer Uniform %out_type\n"
- "%in_arr = OpTypeRuntimeArray %in_type\n"
- "%out_arr = OpTypeRuntimeArray %out_type\n"
+ "%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_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 %in_type\n"
+ "%inputptr = OpTypePointer Input ${inputType}\n"
"%id = OpVariable %uvec3ptr Input\n"
// Constants
"%zero = OpConstant %i32 0\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 %in_type %inloc\n"
- "%conv = ${instruction} %out_type %inval\n"
+ "%inval = OpLoad ${inputType} %inloc\n"
+ "%conv = ${instruction} ${outputType} %inval\n"
" OpStore %outloc %conv\n"
" OpReturn\n"
" OpFunctionEnd\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();
// Vec2 to Vec4
for (int width = 2; width <= 4; ++width)
{
- string randomConst = numberToString(getInt(rnd));
- string widthStr = numberToString(width);
- int index = rnd.getInt(0, width-1);
-
- params["type"] = "vec";
- params["name"] = params["type"] + "_" + widthStr;
- params["compositeType"] = "%composite = OpTypeVector %custom " + widthStr +"\n";
- params["filler"] = string("%filler = OpConstant %custom ") + getRandomConstantString(type, rnd) + "\n";
- params["compositeConstruct"] = "%instance = OpCompositeConstruct %composite" + repeatString(" %filler", width) + "\n";
- params["indexes"] = numberToString(index);
+ const string randomConst = numberToString(getInt(rnd));
+ const string widthStr = numberToString(width);
+ const string composite_type = "${customType}vec" + widthStr;
+ const int index = rnd.getInt(0, width-1);
+
+ params["type"] = "vec";
+ params["name"] = params["type"] + "_" + widthStr;
+ params["compositeDecl"] = composite_type + " = OpTypeVector ${customType} " + widthStr +"\n";
+ params["compositeType"] = composite_type;
+ params["filler"] = string("%filler = OpConstant ${customType} ") + getRandomConstantString(type, rnd) + "\n";
+ params["compositeConstruct"] = "%instance = OpCompositeConstruct " + composite_type + repeatString(" %filler", width) + "\n";
+ params["indexes"] = numberToString(index);
testCases.push_back(params);
}
}
string widthStr = numberToString(width);
int index = rnd.getInt(0, width-1);
- params["type"] = "array";
- params["name"] = params["type"] + "_" + widthStr;
- params["compositeType"] = string("%arraywidth = OpConstant %u32 " + widthStr + "\n")
- + "%composite = OpTypeArray %custom %arraywidth\n";
-
- params["filler"] = string("%filler = OpConstant %custom ") + getRandomConstantString(type, rnd) + "\n";
+ params["type"] = "array";
+ params["name"] = params["type"] + "_" + widthStr;
+ params["compositeDecl"] = string("%arraywidth = OpConstant %u32 " + widthStr + "\n")
+ + "%composite = OpTypeArray ${customType} %arraywidth\n";
+ params["compositeType"] = "%composite";
+ params["filler"] = string("%filler = OpConstant ${customType} ") + getRandomConstantString(type, rnd) + "\n";
params["compositeConstruct"] = "%instance = OpCompositeConstruct %composite" + repeatString(" %filler", width) + "\n";
- params["indexes"] = numberToString(index);
+ params["indexes"] = numberToString(index);
testCases.push_back(params);
}
}
string randomConst = numberToString(getInt(rnd));
int index = rnd.getInt(0, width-1);
- params["type"] = "struct";
- params["name"] = params["type"] + "_" + numberToString(width);
- params["compositeType"] = "%composite = OpTypeStruct" + repeatString(" %custom", width) + "\n";
- params["filler"] = string("%filler = OpConstant %custom ") + getRandomConstantString(type, rnd) + "\n";
+ params["type"] = "struct";
+ params["name"] = params["type"] + "_" + numberToString(width);
+ params["compositeDecl"] = "%composite = OpTypeStruct" + repeatString(" ${customType}", width) + "\n";
+ params["compositeType"] = "%composite";
+ params["filler"] = string("%filler = OpConstant ${customType} ") + getRandomConstantString(type, rnd) + "\n";
params["compositeConstruct"] = "%instance = OpCompositeConstruct %composite" + repeatString(" %filler", width) + "\n";
- params["indexes"] = numberToString(index);
+ params["indexes"] = numberToString(index);
testCases.push_back(params);
}
}
int index_1 = rnd.getInt(0, width-1);
string columnStr = numberToString(column);
- params["type"] = "matrix";
- params["name"] = params["type"] + "_" + widthStr + "x" + columnStr;
- params["compositeType"] = string("%vectype = OpTypeVector %custom " + widthStr + "\n")
+ params["type"] = "matrix";
+ params["name"] = params["type"] + "_" + widthStr + "x" + columnStr;
+ params["compositeDecl"] = string("%vectype = OpTypeVector ${customType} " + widthStr + "\n")
+ "%composite = OpTypeMatrix %vectype " + columnStr + "\n";
+ params["compositeType"] = "%composite";
- params["filler"] = string("%filler = OpConstant %custom ") + getRandomConstantString(type, rnd) + "\n"
+ params["filler"] = string("%filler = OpConstant ${customType} ") + getRandomConstantString(type, rnd) + "\n"
+ "%fillerVec = OpConstantComposite %vectype" + repeatString(" %filler", width) + "\n";
params["compositeConstruct"] = "%instance = OpCompositeConstruct %composite" + repeatString(" %fillerVec", column) + "\n";
- params["indexes"] = numberToString(index_0) + " " + numberToString(index_1);
+ params["indexes"] = numberToString(index_0) + " " + numberToString(index_1);
testCases.push_back(params);
}
}
}
}
+const string getAssemblyTypeName (const NumberType type)
+{
+ switch (type)
+ {
+ case NUMBERTYPE_INT32: return "%i32";
+ case NUMBERTYPE_UINT32: return "%u32";
+ case NUMBERTYPE_FLOAT32: return "%f32";
+ default: DE_ASSERT(false); return "";
+ }
+}
+
const string specializeCompositeInsertShaderTemplate (const NumberType type, const map<string, string>& params)
{
map<string, string> parameters(params);
- parameters["typeDeclaration"] = getAssemblyTypeDeclaration(type);
-
+ const string customType = getAssemblyTypeName(type);
+ map<string, string> substCustomType;
+ substCustomType["customType"] = customType;
+ parameters["compositeDecl"] = StringTemplate(parameters.at("compositeDecl")).specialize(substCustomType);
+ parameters["compositeType"] = StringTemplate(parameters.at("compositeType")).specialize(substCustomType);
+ parameters["compositeConstruct"] = StringTemplate(parameters.at("compositeConstruct")).specialize(substCustomType);
+ parameters["filler"] = StringTemplate(parameters.at("filler")).specialize(substCustomType);
+ parameters["customType"] = customType;
parameters["compositeDecorator"] = (parameters["type"] == "array") ? "OpDecorate %composite ArrayStride 4\n" : "";
- return StringTemplate (
+ if (parameters.at("compositeType") != "%u32vec3")
+ {
+ parameters["u32vec3Decl"] = "%u32vec3 = OpTypeVector %u32 3\n";
+ }
+
+ return StringTemplate(
"OpCapability Shader\n"
"OpCapability Matrix\n"
"OpMemoryModel Logical GLSL450\n"
"%voidf = OpTypeFunction %void\n"
"%u32 = OpTypeInt 32 0\n"
"%i32 = OpTypeInt 32 1\n"
- "%uvec3 = OpTypeVector %u32 3\n"
- "%uvec3ptr = OpTypePointer Input %uvec3\n"
+ "%f32 = OpTypeFloat 32\n"
- // Custom type
- "%custom = ${typeDeclaration}\n"
- "${compositeType}"
+ // Composite declaration
+ "${compositeDecl}"
// Constants
"${filler}"
+ "${u32vec3Decl:opt}"
+ "%uvec3ptr = OpTypePointer Input %u32vec3\n"
+
// Inherited from custom
- "%customptr = OpTypePointer Uniform %custom\n"
- "%customarr = OpTypeRuntimeArray %custom\n"
+ "%customptr = OpTypePointer Uniform ${customType}\n"
+ "%customarr = OpTypeRuntimeArray ${customType}\n"
"%buf = OpTypeStruct %customarr\n"
"%bufptr = OpTypePointer Uniform %buf\n"
"%main = OpFunction %void None %voidf\n"
"%label = OpLabel\n"
- "%idval = OpLoad %uvec3 %id\n"
+ "%idval = OpLoad %u32vec3 %id\n"
"%x = OpCompositeExtract %u32 %idval 0\n"
"%inloc = OpAccessChain %customptr %indata %zero %x\n"
"%outloc = OpAccessChain %customptr %outdata %zero %x\n"
// Read the input value
- "%inval = OpLoad %custom %inloc\n"
+ "%inval = OpLoad ${customType} %inloc\n"
// Create the composite and fill it
"${compositeConstruct}"
// Insert the input value to a place
- "%instance2 = OpCompositeInsert %composite %inval %instance ${indexes}\n"
+ "%instance2 = OpCompositeInsert ${compositeType} %inval %instance ${indexes}\n"
// Read back the value from the position
- "%out_val = OpCompositeExtract %custom %instance2 ${indexes}\n"
+ "%out_val = OpCompositeExtract ${customType} %instance2 ${indexes}\n"
// Store it in the output position
" OpStore %outloc %out_val\n"
" OpReturn\n"
vector<string> indexes = de::splitString(fullIndex, ' ');
map<string, string> parameters (params);
- parameters["typeDeclaration"] = getAssemblyTypeDeclaration(type);
- parameters["structType"] = repeatString(" %composite", structInfo.components);
+ parameters["structType"] = repeatString(" ${compositeType}", structInfo.components);
parameters["structConstruct"] = repeatString(" %instance", structInfo.components);
- parameters["insertIndexes"] = fullIndex;
+ parameters["insertIndexes"] = fullIndex;
// In matrix cases the last two index is the CompositeExtract indexes
const deUint32 extractIndexes = (parameters["type"] == "matrix") ? 2 : 1;
parameters["compositeDecorator"] = (parameters["type"] == "array") ? "OpDecorate %composite ArrayStride 4\n" : "";
- return StringTemplate (
+ const string customType = getAssemblyTypeName(type);
+ map<string, string> substCustomType;
+ substCustomType["customType"] = customType;
+ parameters["compositeDecl"] = StringTemplate(parameters.at("compositeDecl")).specialize(substCustomType);
+ parameters["compositeType"] = StringTemplate(parameters.at("compositeType")).specialize(substCustomType);
+ parameters["compositeConstruct"] = StringTemplate(parameters.at("compositeConstruct")).specialize(substCustomType);
+ parameters["filler"] = StringTemplate(parameters.at("filler")).specialize(substCustomType);
+ parameters["customType"] = customType;
+
+ const string compositeType = parameters.at("compositeType");
+ map<string, string> substCompositeType;
+ substCompositeType["compositeType"] = compositeType;
+ parameters["structType"] = StringTemplate(parameters.at("structType")).specialize(substCompositeType);
+ if (compositeType != "%u32vec3")
+ {
+ parameters["u32vec3Decl"] = "%u32vec3 = OpTypeVector %u32 3\n";
+ }
+
+ return StringTemplate(
"OpCapability Shader\n"
"OpCapability Matrix\n"
"OpMemoryModel Logical GLSL450\n"
// General types
"%void = OpTypeVoid\n"
"%voidf = OpTypeFunction %void\n"
+ "%i32 = OpTypeInt 32 1\n"
"%u32 = OpTypeInt 32 0\n"
- "%uvec3 = OpTypeVector %u32 3\n"
- "%uvec3ptr = OpTypePointer Input %uvec3\n"
- // Custom type
- "%custom = ${typeDeclaration}\n"
+ "%f32 = OpTypeFloat 32\n"
// Custom types
- "${compositeType}"
+ "${compositeDecl}"
+ // %u32vec3 if not already declared in ${compositeDecl}
+ "${u32vec3Decl:opt}"
+ "%uvec3ptr = OpTypePointer Input %u32vec3\n"
// Inherited from composite
- "%composite_p = OpTypePointer Function %composite\n"
+ "%composite_p = OpTypePointer Function ${compositeType}\n"
"%struct_t = OpTypeStruct${structType}\n"
"%struct_p = OpTypePointer Function %struct_t\n"
// Constants
"${filler}"
"${accessChainConstDeclaration}"
// Inherited from custom
- "%customptr = OpTypePointer Uniform %custom\n"
- "%customarr = OpTypeRuntimeArray %custom\n"
+ "%customptr = OpTypePointer Uniform ${customType}\n"
+ "%customarr = OpTypeRuntimeArray ${customType}\n"
"%buf = OpTypeStruct %customarr\n"
"%bufptr = OpTypePointer Uniform %buf\n"
"%indata = OpVariable %bufptr Uniform\n"
"%main = OpFunction %void None %voidf\n"
"%label = OpLabel\n"
"%struct_v = OpVariable %struct_p Function\n"
- "%idval = OpLoad %uvec3 %id\n"
+ "%idval = OpLoad %u32vec3 %id\n"
"%x = OpCompositeExtract %u32 %idval 0\n"
// Create the input/output type
"%inloc = OpInBoundsAccessChain %customptr %indata %zero %x\n"
"%outloc = OpInBoundsAccessChain %customptr %outdata %zero %x\n"
// Read the input value
- "%inval = OpLoad %custom %inloc\n"
+ "%inval = OpLoad ${customType} %inloc\n"
// Create the composite and fill it
"${compositeConstruct}"
// Create the struct and fill it with the composite
" OpStore %struct_v %comp_obj\n"
// Get deepest possible composite pointer
"%inner_ptr = OpInBoundsAccessChain %composite_p %struct_v${accessChainIndexes}\n"
- "%read_obj = OpLoad %composite %inner_ptr\n"
+ "%read_obj = OpLoad ${compositeType} %inner_ptr\n"
// Read back the stored value
- "%read_val = OpCompositeExtract %custom %read_obj${extractIndexes}\n"
+ "%read_val = OpCompositeExtract ${customType} %read_obj${extractIndexes}\n"
" OpStore %outloc %read_val\n"
" OpReturn\n"
- " OpFunctionEnd\n").specialize(parameters);
+ " OpFunctionEnd\n"
+ ).specialize(parameters);
}
tcu::TestCaseGroup* createOpInBoundsAccessChainGroup (tcu::TestContext& testCtx)
{
map<string, string> parameters(params);
- parameters["typeDeclaration"] = getAssemblyTypeDeclaration(type);
+ parameters["customType"] = getAssemblyTypeName(type);
// Declare the const value, and use it in the initializer
if (params.find("constValue") != params.end())
{
- parameters["constDeclaration"] = "%const = OpConstant %in_type " + params.at("constValue") + "\n";
- parameters["variableInitializer"] = "%const";
+ parameters["variableInitializer"] = " %const";
}
// Uninitialized case
else
{
- parameters["constDeclaration"] = "";
- parameters["variableInitializer"] = "";
+ parameters["commentDecl"] = ";";
}
return StringTemplate(
"%voidf = OpTypeFunction %void\n"
"%u32 = OpTypeInt 32 0\n"
"%i32 = OpTypeInt 32 1\n"
+ "%f32 = OpTypeFloat 32\n"
"%uvec3 = OpTypeVector %u32 3\n"
"%uvec3ptr = OpTypePointer Input %uvec3\n"
- // Custom types
- "%in_type = ${typeDeclaration}\n"
- // "%const = OpConstant %in_type ${constValue}\n"
- "${constDeclaration}\n"
+ "${commentDecl:opt}%const = OpConstant ${customType} ${constValue:opt}\n"
// Derived types
- "%in_ptr = OpTypePointer Uniform %in_type\n"
- "%in_arr = OpTypeRuntimeArray %in_type\n"
+ "%in_ptr = OpTypePointer Uniform ${customType}\n"
+ "%in_arr = OpTypeRuntimeArray ${customType}\n"
"%in_buf = OpTypeStruct %in_arr\n"
"%in_bufptr = OpTypePointer Uniform %in_buf\n"
"%indata = OpVariable %in_bufptr Uniform\n"
"%outdata = OpVariable %in_bufptr Uniform\n"
"%id = OpVariable %uvec3ptr Input\n"
- "%var_ptr = OpTypePointer Function %in_type\n"
+ "%var_ptr = OpTypePointer Function ${customType}\n"
// Constants
"%zero = OpConstant %i32 0\n"
// Main function
"%main = OpFunction %void None %voidf\n"
"%label = OpLabel\n"
- "%out_var = OpVariable %var_ptr Function ${variableInitializer}\n"
+ "%out_var = OpVariable %var_ptr Function${variableInitializer:opt}\n"
"%idval = OpLoad %uvec3 %id\n"
"%x = OpCompositeExtract %u32 %idval 0\n"
"%inloc = OpAccessChain %in_ptr %indata %zero %x\n"
"%outloc = OpAccessChain %in_ptr %outdata %zero %x\n"
- "%outval = OpLoad %in_type %out_var\n"
+ "%outval = OpLoad ${customType} %out_var\n"
" OpStore %outloc %outval\n"
" OpReturn\n"
" OpFunctionEnd\n"
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());