1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 Arm Limited.
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 *//*!
20 * \file
21 * \brief Functional integer dot product tests
22 *//*--------------------------------------------------------------------*/
23
24
25 #include "tcuTestLog.hpp"
26 #include "tcuVectorUtil.hpp"
27
28 #include "deRandom.hpp"
29
30 #include "vktSpvAsmComputeShaderCase.hpp"
31 #include "vktSpvAsmComputeShaderTestUtil.hpp"
32 #include "vktSpvAsmIntegerDotProductTests.hpp"
33
34 #include <limits>
35 #include <string>
36
37 // VK_KHR_shader_integer_dot_product tests
38
39 // Note: these tests make use of the following extensions that are not
40 // required by the VK_KHR_shader_integer_dot_product extension itself:
41 // * VK_KHR_8bit_storage (VkPhysicalDevice8BitStorageFeatures) for shaderInt8
42 // * VK_KHR_16bit_storage (VkPhysicalDevice16BitStorageFeatures) for shaderInt16
43
44 namespace vkt
45 {
46 namespace SpirVAssembly
47 {
48
49 using namespace vk;
50 using std::string;
51
52 namespace
53 {
54 using std::vector;
55 using tcu::IVec3;
56 using tcu::TestLog;
57
58 template<typename T>
fillRandomScalars(de::Random & rnd,T minValue,T maxValue,void * dst,int numValues,int offset=0)59 static void fillRandomScalars(de::Random& rnd, T minValue, T maxValue, void* dst, int numValues, int offset = 0)
60 {
61 T* const typedPtr = (T*)dst;
62 for (int ndx = 0; ndx < numValues; ndx++)
63 typedPtr[offset + ndx] = de::randomScalar<T>(rnd, minValue, maxValue);
64 }
65
getEqualValue(T v1,T v2)66 template <typename T> T getEqualValue(T v1, T v2)
67 {
68 DE_ASSERT(v1 == v2);
69 (void)v2;
70 return v1;
71 }
72
73 template <class T>
withinLimits(deInt64 val)74 bool withinLimits(deInt64 val)
75 {
76 return static_cast<deInt64>(std::numeric_limits<T>::min()) <= val
77 && val <= static_cast<deInt64>(std::numeric_limits<T>::max());
78 }
79
80 template <class T, class LHSOperandT, class RHSOperandT>
dotProduct(vector<LHSOperandT> lhs,vector<RHSOperandT> rhs)81 static T dotProduct(vector<LHSOperandT> lhs, vector<RHSOperandT> rhs)
82 {
83 uint64_t res = 0u;
84 size_t size = getEqualValue(lhs.size(), rhs.size());
85
86 for (size_t i = 0; i < size; ++i)
87 res += static_cast<uint64_t>(lhs[i]) * static_cast<uint64_t>(rhs[i]);
88
89 int64_t signedRes;
90 deMemcpy(&signedRes, &res, sizeof(res));
91 return static_cast<T>(signedRes);
92 }
93
94 template <class AddendT, class LHSOperandT, class RHSOperandT>
compareDotProductAccSat(const std::vector<Resource> & inputs,const vector<AllocationSp> & outputAllocs,const std::vector<Resource> &,TestLog &)95 bool compareDotProductAccSat(const std::vector<Resource> &inputs, const vector<AllocationSp>& outputAllocs,
96 const std::vector<Resource>&, TestLog&)
97 {
98 if (inputs.size() != 3 || outputAllocs.size() != 1)
99 return false;
100
101 vector<deUint8> lhsBytes;
102 vector<deUint8> rhsBytes;
103 vector<deUint8> addendBytes;
104
105 inputs[0].getBytes(lhsBytes);
106 inputs[1].getBytes(rhsBytes);
107 inputs[2].getBytes(addendBytes);
108
109 const AddendT* const output = static_cast<AddendT* const>(outputAllocs[0]->getHostPtr());
110 const AddendT* const addends = reinterpret_cast<AddendT* const>(&addendBytes.front());
111 const LHSOperandT* const lhsInts = reinterpret_cast<LHSOperandT* const>(&lhsBytes.front());
112 const RHSOperandT* const rhsInts = reinterpret_cast<RHSOperandT* const>(&rhsBytes.front());
113
114 for (size_t idx = 0; idx < inputs[2].getByteSize() / sizeof(AddendT); ++idx)
115 {
116 size_t vecLen = (inputs[0].getByteSize() / sizeof(LHSOperandT)) / (inputs[2].getByteSize() / sizeof(AddendT));
117
118 std::vector<LHSOperandT> inputVec1Pos;
119 std::vector<RHSOperandT> inputVec2Pos;
120 inputVec1Pos.reserve(vecLen);
121 inputVec2Pos.reserve(vecLen);
122
123 std::vector<LHSOperandT> inputVec1Neg;
124 std::vector<RHSOperandT> inputVec2Neg;
125 inputVec1Neg.reserve(vecLen);
126 inputVec2Neg.reserve(vecLen);
127
128 for (unsigned int vecElem = 0; vecElem < vecLen; ++vecElem)
129 {
130 LHSOperandT elem1 = lhsInts[idx * vecLen + vecElem];
131 RHSOperandT elem2 = rhsInts[idx * vecLen + vecElem];
132
133 // Note: ordering of components does not matter, provided
134 // that it is consistent between lhs and rhs.
135 if ((elem1 < 0) == (elem2 < 0))
136 {
137 inputVec1Pos.push_back(elem1);
138 inputVec2Pos.push_back(elem2);
139 inputVec1Neg.push_back(0);
140 inputVec2Neg.push_back(0);
141 }
142 else
143 {
144 inputVec1Pos.push_back(0);
145 inputVec2Pos.push_back(0);
146 inputVec1Neg.push_back(elem1);
147 inputVec2Neg.push_back(elem2);
148 }
149 }
150
151 deInt64 PosProduct = dotProduct<deInt64>(inputVec1Pos, inputVec2Pos);
152 deInt64 NegProduct = dotProduct<deInt64>(inputVec1Neg, inputVec2Neg);
153 bool outputOverflow = (!withinLimits<AddendT>(PosProduct) || !withinLimits<AddendT>(NegProduct));
154
155 if (!outputOverflow)
156 {
157 AddendT expectedOutput = static_cast<AddendT>(PosProduct + NegProduct);
158 const auto& addend = addends[idx];
159
160 if (addend < 0)
161 {
162 if (expectedOutput < std::numeric_limits<AddendT>::min() - addend)
163 expectedOutput = std::numeric_limits<AddendT>::min();
164 else
165 expectedOutput = static_cast<AddendT>(expectedOutput + addend);
166 }
167 else
168 {
169 if (expectedOutput > std::numeric_limits<AddendT>::max() - addend)
170 expectedOutput = std::numeric_limits<AddendT>::max();
171 else
172 expectedOutput = static_cast<AddendT>(expectedOutput + addend);
173 }
174
175 if (output[idx] != expectedOutput)
176 {
177 return false;
178 }
179 }
180 }
181
182 return true;
183 }
184
185 struct DotProductPackingInfo
186 {
187 bool packed;
188 bool signedLHS;
189 bool signedRHS;
190 };
191
192 struct DotProductVectorInfo
193 {
194 size_t vecElementSize;
195 unsigned int vecLen;
196 };
197
addDotProductExtensionAndFeatures(ComputeShaderSpec & spec,const struct DotProductPackingInfo & packingInfo,size_t elementSize,size_t outSize)198 void addDotProductExtensionAndFeatures(ComputeShaderSpec &spec,
199 const struct DotProductPackingInfo &packingInfo,
200 size_t elementSize, size_t outSize)
201 {
202 spec.extensions.push_back("VK_KHR_shader_integer_dot_product");
203 spec.requestedVulkanFeatures.extIntegerDotProduct.shaderIntegerDotProduct = VK_TRUE;
204
205 DE_ASSERT(!packingInfo.packed || elementSize == 8);
206 if ((!packingInfo.packed && elementSize == 8) || outSize == 8)
207 {
208 spec.requestedVulkanFeatures.extFloat16Int8.shaderInt8 = true;
209 spec.requestedVulkanFeatures.ext8BitStorage.storageBuffer8BitAccess = true;
210 spec.extensions.push_back("VK_KHR_8bit_storage");
211 }
212
213 if (elementSize == 16 || outSize == 16)
214 {
215 spec.requestedVulkanFeatures.coreFeatures.shaderInt16 = true;
216 spec.requestedVulkanFeatures.ext16BitStorage.storageBuffer16BitAccess = true;
217 spec.extensions.push_back("VK_KHR_16bit_storage");
218 }
219 }
220
221 const struct DotProductPackingInfo dotProductPacking[] = {
222 { false, false, false },
223 { false, false, true },
224 { false, true, false },
225 { false, true, true },
226 { true, true, true },
227 { true, true, false },
228 { true, false, true },
229 { true, false, false },
230 };
231
232 const struct DotProductVectorInfo dotProductVector8[] = {
233 { 8, 2 },
234 { 8, 3 },
235 { 8, 4 },
236 };
237
238 const struct DotProductVectorInfo dotProductVector16[] = {
239 { 16, 2 },
240 { 16, 3 },
241 { 16, 4 },
242 };
243
244 const struct DotProductVectorInfo dotProductVector32[] = {
245 { 32, 2 },
246 { 32, 3 },
247 { 32, 4 },
248 };
249
getAlignedVecLen(const DotProductVectorInfo & vectorInfo)250 unsigned int getAlignedVecLen(const DotProductVectorInfo& vectorInfo)
251 {
252 return (vectorInfo.vecLen == 3 ? 4 : vectorInfo.vecLen);
253 }
254
generateIntegerDotProductTypeDeclsAndStrideDecors(std::ostringstream & typeDeclsStream,std::ostringstream & strideDecorsStream,const struct DotProductPackingInfo & packingInfo,const struct DotProductVectorInfo & vectorInfo,size_t outSize,bool signedLHSAndResult,bool signedRHS)255 void generateIntegerDotProductTypeDeclsAndStrideDecors(std::ostringstream &typeDeclsStream, std::ostringstream &strideDecorsStream,
256 const struct DotProductPackingInfo &packingInfo,
257 const struct DotProductVectorInfo &vectorInfo, size_t outSize,
258 bool signedLHSAndResult, bool signedRHS)
259 {
260 size_t signedScalarArraysMask = 0;
261 size_t unsignedScalarArraysMask = 0;
262 bool signedIntVectorNeeded = false;
263 bool unsignedIntVectorNeeded = false;
264
265 if (signedLHSAndResult)
266 signedScalarArraysMask |= static_cast<int>(outSize);
267 else
268 unsignedScalarArraysMask |= static_cast<int>(outSize);
269
270 if (packingInfo.packed)
271 {
272 if (packingInfo.signedLHS || packingInfo.signedRHS)
273 signedScalarArraysMask |= vectorInfo.vecElementSize * vectorInfo.vecLen;
274 if (!packingInfo.signedLHS || !packingInfo.signedRHS)
275 unsignedScalarArraysMask |= vectorInfo.vecElementSize * vectorInfo.vecLen;
276 }
277 else
278 {
279 if (signedLHSAndResult)
280 {
281 signedIntVectorNeeded = true;
282 signedScalarArraysMask |= vectorInfo.vecElementSize;
283 }
284 if (!signedRHS)
285 {
286 unsignedIntVectorNeeded = true;
287 unsignedScalarArraysMask |= vectorInfo.vecElementSize;
288 }
289 }
290
291 size_t signedScalarTypesMask = signedScalarArraysMask;
292 size_t unsignedScalarTypesMask = unsignedScalarArraysMask;
293
294 for (unsigned int size = 8; size <= 64; size *= 2)
295 {
296 if (size != 32)
297 {
298 string sizeStr(de::toString(size));
299 if ((signedScalarTypesMask & size))
300 typeDeclsStream << "%i" << sizeStr << " = OpTypeInt " << sizeStr << " 1\n";
301 if ((unsignedScalarTypesMask & size))
302 typeDeclsStream << "%u" << sizeStr << " = OpTypeInt " << sizeStr << " 0\n";
303 }
304 }
305
306 for (unsigned int size = 8; size <= 64; size *= 2)
307 {
308 string sizeStr = de::toString(size);
309 if ((signedScalarArraysMask & size))
310 {
311 if (size != 32)
312 typeDeclsStream << "%i" << sizeStr << "ptr = OpTypePointer Uniform %i" << sizeStr << "\n"
313 "%i" << sizeStr << "arr = OpTypeRuntimeArray %i" << sizeStr << "\n";
314 strideDecorsStream << "OpDecorate %i" << sizeStr << "arr ArrayStride " << de::toString(size / 8) << "\n";
315 }
316 if ((unsignedScalarArraysMask & size))
317 {
318 typeDeclsStream << "%u" << sizeStr << "ptr = OpTypePointer Uniform %u" << sizeStr << "\n"
319 "%u" << sizeStr << "arr = OpTypeRuntimeArray %u" << sizeStr << "\n";
320 strideDecorsStream << "OpDecorate %u" << sizeStr << "arr ArrayStride " << de::toString(size / 8) << "\n";
321 }
322 }
323
324 if (signedIntVectorNeeded)
325 {
326 string vecType = "%i" + de::toString(vectorInfo.vecElementSize) + "vec" + de::toString(vectorInfo.vecLen);
327 typeDeclsStream << vecType << " = OpTypeVector %i" << vectorInfo.vecElementSize << " " << vectorInfo.vecLen << "\n"
328 << vecType << "ptr = OpTypePointer Uniform " << vecType << "\n"
329 << vecType << "arr = OpTypeRuntimeArray " << vecType << "\n";
330 strideDecorsStream << "OpDecorate " << vecType << "arr ArrayStride "
331 << (vectorInfo.vecLen == 3 ? 4 : vectorInfo.vecLen) * (vectorInfo.vecElementSize / 8) << "\n";
332 }
333
334
335 if (unsignedIntVectorNeeded)
336 {
337 string vecType = "%u" + de::toString(vectorInfo.vecElementSize) + "vec" + de::toString(vectorInfo.vecLen);
338 bool changeTypeName = false;
339 if (vectorInfo.vecElementSize == 32 && vectorInfo.vecLen == 3)
340 changeTypeName = true;
341 else
342 typeDeclsStream << vecType << " = OpTypeVector %u" << vectorInfo.vecElementSize << " " << vectorInfo.vecLen << "\n";
343
344 typeDeclsStream << vecType << "ptr = OpTypePointer Uniform " << (changeTypeName ? "%uvec3" : vecType) << "\n"
345 << vecType << "arr = OpTypeRuntimeArray " << (changeTypeName ? "%uvec3" : vecType) << "\n";
346 strideDecorsStream << "OpDecorate " << vecType << "arr ArrayStride "
347 << (vectorInfo.vecLen == 3 ? 4 : vectorInfo.vecLen) * (vectorInfo.vecElementSize / 8) << "\n";
348 }
349 }
350
generateIntegerDotProductCode(const struct DotProductPackingInfo & packingInfo,const struct DotProductVectorInfo & vectorInfo,size_t outSize,bool signedLHSAndResult,bool signedRHS,bool acc)351 string generateIntegerDotProductCode(const struct DotProductPackingInfo &packingInfo, const struct DotProductVectorInfo &vectorInfo,
352 size_t outSize, bool signedLHSAndResult, bool signedRHS, bool acc)
353 {
354 DE_ASSERT(signedLHSAndResult || !signedRHS);
355
356 const string insnSignedness(signedLHSAndResult ? (signedRHS ? "S" : "SU") : "U");
357 const string insnName(string("Op") + insnSignedness + "Dot" + (acc ? "AccSat" : "") + "KHR");
358
359 const string outputCapability(outSize != 32 ?
360 "OpCapability Int" + de::toString(outSize) + "\n" : "");
361 const string elementCapability(!packingInfo.packed && outSize != vectorInfo.vecElementSize && vectorInfo.vecElementSize != 32 ?
362 "OpCapability Int" + de::toString(vectorInfo.vecElementSize) + "\n" : "");
363
364 const string dotProductInputCapabilityName(
365 packingInfo.packed ? "DotProductInput4x8BitPackedKHR" : (vectorInfo.vecElementSize > 8) ? "DotProductInputAllKHR" : "DotProductInput4x8BitKHR");
366
367 const string capabilities(outputCapability +
368 elementCapability +
369 "OpCapability " + dotProductInputCapabilityName + "\n"
370 "OpCapability DotProductKHR\n");
371 const string extensions("OpExtension \"SPV_KHR_integer_dot_product\"\n");
372
373 const string outType((signedLHSAndResult ? "i" : "u") + de::toString(outSize));
374
375 std::ostringstream typeDeclsStream;
376 std::ostringstream strideDecorsStream;
377 generateIntegerDotProductTypeDeclsAndStrideDecors(typeDeclsStream, strideDecorsStream,
378 packingInfo, vectorInfo, outSize, signedLHSAndResult, signedRHS);
379 string typeDecls(typeDeclsStream.str());
380 string strideDecors(strideDecorsStream.str());
381
382 const string lhsVecType(packingInfo.packed
383 ? string(packingInfo.signedLHS ? "i" : "u") + de::toString(vectorInfo.vecElementSize * vectorInfo.vecLen)
384 : (signedLHSAndResult ? "i" : "u") + ((!signedLHSAndResult && vectorInfo.vecElementSize == 32 && vectorInfo.vecLen == 3) ? "" : de::toString(vectorInfo.vecElementSize)) + "vec" + de::toString(vectorInfo.vecLen));
385 const string rhsVecType(packingInfo.packed
386 ? string(packingInfo.signedRHS ? "i" : "u") + de::toString(vectorInfo.vecElementSize * vectorInfo.vecLen)
387 : (signedRHS ? "i" : "u") + ((!signedRHS && vectorInfo.vecElementSize == 32 && vectorInfo.vecLen == 3) ? "" : de::toString(vectorInfo.vecElementSize)) + "vec" + de::toString(vectorInfo.vecLen));
388 const string lhsVecTypeBase(packingInfo.packed
389 ? string(packingInfo.signedLHS ? "i" : "u") + de::toString(vectorInfo.vecElementSize * vectorInfo.vecLen)
390 : (signedLHSAndResult ? "i" : "u") + de::toString(vectorInfo.vecElementSize) + "vec" + de::toString(vectorInfo.vecLen));
391 const string rhsVecTypeBase(packingInfo.packed
392 ? string(packingInfo.signedRHS ? "i" : "u") + de::toString(vectorInfo.vecElementSize * vectorInfo.vecLen)
393 : (signedRHS ? "i" : "u") + de::toString(vectorInfo.vecElementSize) + "vec" + de::toString(vectorInfo.vecLen));
394
395 const string optFormatParam(packingInfo.packed ? " PackedVectorFormat4x8BitKHR" : "");
396
397 bool bufferSignednessMatches = (packingInfo.packed
398 ? (packingInfo.signedLHS == packingInfo.signedRHS)
399 : (signedLHSAndResult == signedRHS));
400
401 return string(getComputeAsmShaderPreamble(capabilities, extensions)) +
402
403 "OpName %main \"main\"\n"
404 "OpName %id \"gl_GlobalInvocationID\"\n"
405
406 "OpDecorate %id BuiltIn GlobalInvocationId\n"
407 + (bufferSignednessMatches
408 ? "OpDecorate %bufin BufferBlock\n"
409 : "OpDecorate %buflhs BufferBlock\n"
410 "OpDecorate %bufrhs BufferBlock\n") +
411 "OpDecorate %bufout BufferBlock\n"
412 "OpDecorate %indatalhs DescriptorSet 0\n"
413 "OpDecorate %indatalhs Binding 0\n"
414 "OpDecorate %indatarhs DescriptorSet 0\n"
415 "OpDecorate %indatarhs Binding 1\n"
416 + (acc
417 ? "OpDecorate %indataacc DescriptorSet 0\n"
418 "OpDecorate %indataacc Binding 2\n"
419 : "") +
420 "OpDecorate %outdata DescriptorSet 0\n"
421 "OpDecorate %outdata Binding " + (acc ? "3" : "2") + "\n"
422 + strideDecors
423
424 + (bufferSignednessMatches
425 ? "OpMemberDecorate %bufin 0 Offset 0\n"
426 : "OpMemberDecorate %buflhs 0 Offset 0\n"
427 "OpMemberDecorate %bufrhs 0 Offset 0\n") +
428 "OpMemberDecorate %bufout 0 Offset 0\n"
429
430 + getComputeAsmCommonTypes()
431 + typeDecls
432
433 + (bufferSignednessMatches
434 ? "%bufin = OpTypeStruct %" + lhsVecTypeBase + "arr\n"
435 "%bufinptr = OpTypePointer Uniform %bufin\n"
436 : "%buflhs = OpTypeStruct %" + lhsVecTypeBase + "arr\n"
437 "%buflhsptr = OpTypePointer Uniform %buflhs\n"
438 "%bufrhs = OpTypeStruct %" + rhsVecTypeBase + "arr\n"
439 "%bufrhsptr = OpTypePointer Uniform %bufrhs\n") +
440 "%bufout = OpTypeStruct %" + outType + "arr\n"
441 "%bufoutptr = OpTypePointer Uniform %bufout\n"
442 "%indatalhs = OpVariable " + (bufferSignednessMatches ? "%bufinptr" : "%buflhsptr") + " Uniform\n"
443 "%indatarhs = OpVariable " + (bufferSignednessMatches ? "%bufinptr" : "%bufrhsptr") + " Uniform\n"
444 + (acc ? "%indataacc = OpVariable %bufoutptr Uniform\n" : "") +
445 "%outdata = OpVariable %bufoutptr Uniform\n"
446
447 "%id = OpVariable %uvec3ptr Input\n"
448 "%zero = OpConstant %i32 0\n"
449
450 "%main = OpFunction %void None %voidf\n"
451 "%label = OpLabel\n"
452 "%idval = OpLoad %uvec3 %id\n"
453 "%x = OpCompositeExtract %u32 %idval 0\n"
454 "%inloclhs = OpAccessChain %" + lhsVecTypeBase + "ptr %indatalhs %zero %x\n"
455 "%invallhs = OpLoad %" + lhsVecType + " %inloclhs\n"
456 "%inlocrhs = OpAccessChain %" + rhsVecTypeBase + "ptr %indatarhs %zero %x\n"
457 "%invalrhs = OpLoad %" + rhsVecType + " %inlocrhs\n"
458 + (acc
459 ? "%inlocacc = OpAccessChain %" + outType + "ptr %indataacc %zero %x\n"
460 "%invalacc = OpLoad %" + outType + " %inlocacc\n"
461 : ""
462 ) +
463 "%res = " + insnName + " %" + outType + " %invallhs %invalrhs" + (acc ? " %invalacc" : "") + optFormatParam + "\n"
464 "%outloc = OpAccessChain %" + outType + "ptr %outdata %zero %x\n"
465 " OpStore %outloc %res\n"
466 " OpReturn\n"
467 " OpFunctionEnd\n";
468 }
469
470 struct DotProductInputInfo
471 {
472 string name;
473 unsigned int vecLen;
474 size_t vecElemSize;
475 };
476
477 template <class OutputT, class LHSOperandT, class RHSOperandT>
fillDotProductOutputs(int numElements,vector<LHSOperandT> & inputInts1,vector<RHSOperandT> & inputInts2,vector<OutputT> & outputInts,const struct DotProductInputInfo & inputInfo)478 void fillDotProductOutputs(int numElements, vector<LHSOperandT> &inputInts1, vector<RHSOperandT> &inputInts2,
479 vector<OutputT> &outputInts, const struct DotProductInputInfo &inputInfo)
480 {
481 unsigned int alignedVecLen = inputInfo.vecLen == 3 ? 4 : inputInfo.vecLen;
482 for (int ndx = 0; ndx < numElements; ++ndx)
483 {
484 std::vector<LHSOperandT> inputVec1;
485 std::vector<RHSOperandT> inputVec2;
486 inputVec1.reserve(alignedVecLen);
487 inputVec2.reserve(alignedVecLen);
488
489 for (unsigned int vecElem = 0; vecElem < alignedVecLen; ++vecElem)
490 {
491 // Note: ordering of components does not matter, provided
492 // that it is consistent between lhs and rhs.
493 inputVec1.push_back(inputInts1[ndx * alignedVecLen + vecElem]);
494 inputVec2.push_back(inputInts2[ndx * alignedVecLen + vecElem]);
495 }
496
497 outputInts[ndx] = dotProduct<OutputT>(inputVec1, inputVec2);
498 }
499 }
500
getDotProductTestName(const struct DotProductInputInfo & inputInfo,const struct DotProductPackingInfo & packingInfo,size_t outSize)501 string getDotProductTestName(const struct DotProductInputInfo &inputInfo,
502 const struct DotProductPackingInfo &packingInfo, size_t outSize)
503 {
504 return inputInfo.name
505 + (packingInfo.packed ? string("_packed_") : "_")
506 + (packingInfo.signedLHS ? "s" : "u") + (packingInfo.signedRHS ? "s" : "u") +
507 "_v" + de::toString(inputInfo.vecLen) + "i" + de::toString(inputInfo.vecElemSize) +
508 "_out" + de::toString(outSize);
509 }
510
511 template <class InBufferT, class OutBufferT, class OutputT, class OperandT>
addOpSDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,int numElements,vector<OperandT> & inputInts1,vector<OperandT> & inputInts2,const struct DotProductInputInfo & inputInfo,const struct DotProductPackingInfo & packingInfo,const struct DotProductVectorInfo & vectorInfo)512 void addOpSDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group,
513 int numElements, vector<OperandT> &inputInts1, vector<OperandT> &inputInts2,
514 const struct DotProductInputInfo &inputInfo, const struct DotProductPackingInfo &packingInfo,
515 const struct DotProductVectorInfo &vectorInfo)
516 {
517 ComputeShaderSpec spec;
518 size_t outSize = sizeof(OutputT) * 8;
519 vector<OutputT> outputInts (numElements, 0);
520
521 fillDotProductOutputs(numElements, inputInts1, inputInts2, outputInts, inputInfo);
522
523 spec.assembly = generateIntegerDotProductCode(packingInfo, vectorInfo, outSize, true, true, false);
524 addDotProductExtensionAndFeatures(spec, packingInfo, vectorInfo.vecElementSize, outSize);
525
526 spec.inputs.push_back (BufferSp(new InBufferT(inputInts1)));
527 spec.inputs.push_back (BufferSp(new InBufferT(inputInts2)));
528 spec.outputs.push_back (BufferSp(new OutBufferT(outputInts)));
529 spec.numWorkGroups = IVec3(numElements, 1, 1);
530 spec.failResult = QP_TEST_RESULT_FAIL;
531 spec.failMessage = "Output doesn't match with expected";
532
533 string qualTestName(getDotProductTestName(inputInfo, packingInfo, outSize));
534
535 group->addChild(new SpvAsmComputeShaderCase(testCtx, qualTestName.data(), spec));
536 }
537
538 template <class InBufferT, class T>
addOpSDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,const struct DotProductPackingInfo dotProductPackingInfo[],unsigned dotProductPackingInfoSize,const struct DotProductVectorInfo dotProductVectorInfo[],unsigned dotProductVectorInfoSize,T vecMin,T vecMax)539 void addOpSDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name,
540 const struct DotProductPackingInfo dotProductPackingInfo[], unsigned dotProductPackingInfoSize,
541 const struct DotProductVectorInfo dotProductVectorInfo[], unsigned dotProductVectorInfoSize,
542 T vecMin, T vecMax)
543 {
544 const int numElements = 200;
545 // Note: this test does not currently cover 64-bit integer results
546 for (unsigned int j = 0; j < dotProductVectorInfoSize; j++)
547 {
548 const struct DotProductVectorInfo &vectorInfo = dotProductVectorInfo[j];
549 unsigned int alignedVecLen = getAlignedVecLen(vectorInfo);
550 struct DotProductInputInfo inputInfo = { name, vectorInfo.vecLen, vectorInfo.vecElementSize };
551 vector<T> inputInts1 (numElements * alignedVecLen, 0);
552 vector<T> inputInts2 (numElements * alignedVecLen, 0);
553
554 fillRandomScalars(rnd, vecMin, vecMax, &inputInts1[0], numElements * alignedVecLen);
555 fillRandomScalars(rnd, vecMin, vecMax, &inputInts2[0], numElements * alignedVecLen);
556
557 if (vectorInfo.vecLen == 3)
558 for (unsigned int ndx = 0; ndx < numElements; ++ndx)
559 inputInts1[ndx*4+3] = inputInts2[ndx*4+3] = 0;
560
561 for (unsigned int i = 0; i < dotProductPackingInfoSize; i++)
562 {
563 const struct DotProductPackingInfo &packingInfo = dotProductPackingInfo[i];
564 if (packingInfo.packed && (vectorInfo.vecElementSize != 8 || vectorInfo.vecLen != 4))
565 continue;
566
567 if (vectorInfo.vecElementSize <= 32)
568 addOpSDotKHRComputeTests<InBufferT, Int32Buffer, deInt32>(testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
569 if (vectorInfo.vecElementSize <= 16)
570 addOpSDotKHRComputeTests<InBufferT, Int16Buffer, deInt16>(testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
571 if (vectorInfo.vecElementSize <= 8)
572 addOpSDotKHRComputeTests<InBufferT, Int8Buffer, deInt8> (testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
573 }
574 }
575 }
576
577 template <class T>
add32bitOpSDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax)578 void add32bitOpSDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax)
579 {
580 addOpSDotKHRComputeTests<Int32Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
581 dotProductVector32, DE_LENGTH_OF_ARRAY(dotProductVector32), vecMin, vecMax);
582 }
583
584 template <class T>
add16bitOpSDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax)585 void add16bitOpSDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax)
586 {
587 addOpSDotKHRComputeTests<Int16Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
588 dotProductVector16, DE_LENGTH_OF_ARRAY(dotProductVector16), vecMin, vecMax);
589 }
590
591 template <class T>
add8bitOpSDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax)592 void add8bitOpSDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax)
593 {
594 addOpSDotKHRComputeTests<Int8Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
595 dotProductVector8, DE_LENGTH_OF_ARRAY(dotProductVector8), vecMin, vecMax);
596 }
597
598 template <class InBufferT, class OutBufferT, class OutputT, class OperandT>
addOpUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,int numElements,vector<OperandT> & inputInts1,vector<OperandT> & inputInts2,const struct DotProductInputInfo & inputInfo,const struct DotProductPackingInfo & packingInfo,const struct DotProductVectorInfo & vectorInfo)599 void addOpUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group,
600 int numElements, vector<OperandT> &inputInts1, vector<OperandT> &inputInts2,
601 const struct DotProductInputInfo &inputInfo, const struct DotProductPackingInfo &packingInfo,
602 const struct DotProductVectorInfo &vectorInfo)
603 {
604 ComputeShaderSpec spec;
605 size_t outSize = sizeof(OutputT) * 8;
606 vector<OutputT> outputInts (numElements, 0);
607
608 fillDotProductOutputs(numElements, inputInts1, inputInts2, outputInts, inputInfo);
609
610 spec.assembly = generateIntegerDotProductCode(packingInfo, vectorInfo, outSize, false, false, false);
611
612 addDotProductExtensionAndFeatures(spec, packingInfo, vectorInfo.vecElementSize, outSize);
613
614 spec.inputs.push_back (BufferSp(new InBufferT(inputInts1)));
615 spec.inputs.push_back (BufferSp(new InBufferT(inputInts2)));
616 spec.outputs.push_back (BufferSp(new OutBufferT(outputInts)));
617 spec.numWorkGroups = IVec3(numElements, 1, 1);
618 spec.failResult = QP_TEST_RESULT_FAIL;
619 spec.failMessage = "Output doesn't match with expected";
620
621 string qualTestName(getDotProductTestName(inputInfo, packingInfo, outSize));
622
623 group->addChild(new SpvAsmComputeShaderCase(testCtx, qualTestName.data(), spec));
624 }
625
626 template <class InBufferT, class T>
addOpUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,const struct DotProductPackingInfo dotProductPackingInfo[],unsigned dotProductPackingInfoSize,const struct DotProductVectorInfo dotProductVectorInfo[],unsigned dotProductVectorInfoSize,T vecMin,T vecMax)627 void addOpUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name,
628 const struct DotProductPackingInfo dotProductPackingInfo[], unsigned dotProductPackingInfoSize,
629 const struct DotProductVectorInfo dotProductVectorInfo[], unsigned dotProductVectorInfoSize,
630 T vecMin, T vecMax)
631 {
632 const int numElements = 200;
633
634 for (unsigned int j = 0; j < dotProductVectorInfoSize; j++)
635 {
636 const struct DotProductVectorInfo &vectorInfo = dotProductVectorInfo[j];
637 unsigned int alignedVecLen = getAlignedVecLen(vectorInfo);
638 struct DotProductInputInfo inputInfo = { name, vectorInfo.vecLen, vectorInfo.vecElementSize };
639 vector<T> inputInts1 (numElements * alignedVecLen, 0);
640 vector<T> inputInts2 (numElements * alignedVecLen, 0);
641
642 fillRandomScalars(rnd, vecMin, vecMax, &inputInts1[0], numElements * alignedVecLen);
643 fillRandomScalars(rnd, vecMin, vecMax, &inputInts2[0], numElements * alignedVecLen);
644
645 if (vectorInfo.vecLen == 3)
646 for (unsigned int ndx = 0; ndx < numElements; ++ndx)
647 inputInts1[ndx*4+3] = inputInts2[ndx*4+3] = 0;
648
649 for (unsigned int i = 0; i < dotProductPackingInfoSize; i++)
650 {
651 const struct DotProductPackingInfo &packingInfo = dotProductPackingInfo[i];
652 if (packingInfo.packed && (vectorInfo.vecElementSize != 8 || vectorInfo.vecLen != 4))
653 continue;
654
655 if (vectorInfo.vecElementSize <= 32)
656 addOpUDotKHRComputeTests<InBufferT, Uint32Buffer, deUint32>(testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
657 if (vectorInfo.vecElementSize <= 16)
658 addOpUDotKHRComputeTests<InBufferT, Uint16Buffer, deUint16>(testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
659 if (vectorInfo.vecElementSize <= 8)
660 addOpUDotKHRComputeTests<InBufferT, Uint8Buffer, deUint8> (testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
661 }
662 }
663 }
664
665 template <class T>
add32bitOpUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax)666 void add32bitOpUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax)
667 {
668 addOpUDotKHRComputeTests<Uint32Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
669 dotProductVector32, DE_LENGTH_OF_ARRAY(dotProductVector32), vecMin, vecMax);
670 }
671
672 template <class T>
add16bitOpUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax)673 void add16bitOpUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax)
674 {
675 addOpUDotKHRComputeTests<Uint16Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
676 dotProductVector16, DE_LENGTH_OF_ARRAY(dotProductVector16), vecMin, vecMax);
677 }
678
679 template <class T>
add8bitOpUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax)680 void add8bitOpUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax)
681 {
682 addOpUDotKHRComputeTests<Uint8Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
683 dotProductVector8, DE_LENGTH_OF_ARRAY(dotProductVector8), vecMin, vecMax);
684 }
685
686 template <class LHSBufferT, class RHSBufferT, class OutBufferT, class OutputT, class LHSOperandT, class RHSOperandT>
addOpSUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,int numElements,vector<LHSOperandT> & inputInts1,vector<RHSOperandT> & inputInts2,const struct DotProductInputInfo & inputInfo,const struct DotProductPackingInfo & packingInfo,const struct DotProductVectorInfo & vectorInfo)687 void addOpSUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group,
688 int numElements, vector<LHSOperandT> &inputInts1, vector<RHSOperandT> &inputInts2,
689 const struct DotProductInputInfo &inputInfo, const struct DotProductPackingInfo &packingInfo,
690 const struct DotProductVectorInfo &vectorInfo)
691 {
692 ComputeShaderSpec spec;
693 size_t outSize = sizeof(OutputT) * 8;
694 vector<OutputT> outputInts (numElements, 0);
695
696 fillDotProductOutputs(numElements, inputInts1, inputInts2, outputInts, inputInfo);
697
698 spec.assembly = generateIntegerDotProductCode(packingInfo, vectorInfo, outSize, true, false, false);
699 addDotProductExtensionAndFeatures(spec, packingInfo, vectorInfo.vecElementSize, outSize);
700
701 spec.inputs.push_back (BufferSp(new LHSBufferT(inputInts1)));
702 spec.inputs.push_back (BufferSp(new RHSBufferT(inputInts2)));
703 spec.outputs.push_back (BufferSp(new OutBufferT(outputInts)));
704 spec.numWorkGroups = IVec3(numElements, 1, 1);
705 spec.failResult = QP_TEST_RESULT_FAIL;
706 spec.failMessage = "Output doesn't match with expected";
707
708 string qualTestName(getDotProductTestName(inputInfo, packingInfo, outSize));
709
710 group->addChild(new SpvAsmComputeShaderCase(testCtx, qualTestName.data(), spec));
711 }
712
713 template <class LHSBufferT, class RHSBufferT, class LHSOperandT, class RHSOperandT>
addOpSUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,const struct DotProductPackingInfo dotProductPackingInfo[],unsigned dotProductPackingInfoSize,const struct DotProductVectorInfo dotProductVectorInfo[],unsigned dotProductVectorInfoSize,LHSOperandT lhsVecMin,LHSOperandT lhsVecMax,RHSOperandT rhsVecMin,RHSOperandT rhsVecMax)714 void addOpSUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name,
715 const struct DotProductPackingInfo dotProductPackingInfo[], unsigned dotProductPackingInfoSize,
716 const struct DotProductVectorInfo dotProductVectorInfo[], unsigned dotProductVectorInfoSize,
717 LHSOperandT lhsVecMin, LHSOperandT lhsVecMax, RHSOperandT rhsVecMin, RHSOperandT rhsVecMax)
718 {
719 const int numElements = 200;
720 // Note: this test does not currently cover 64-bit integer results
721 for (unsigned int j = 0; j < dotProductVectorInfoSize; j++)
722 {
723 const struct DotProductVectorInfo &vectorInfo = dotProductVectorInfo[j];
724 unsigned int alignedVecLen = getAlignedVecLen(vectorInfo);
725 struct DotProductInputInfo inputInfo = { name, vectorInfo.vecLen, vectorInfo.vecElementSize };
726 vector<LHSOperandT> inputInts1 (numElements * alignedVecLen, 0);
727 vector<RHSOperandT> inputInts2 (numElements * alignedVecLen, 0);
728
729 fillRandomScalars(rnd, lhsVecMin, lhsVecMax, &inputInts1[0], numElements * alignedVecLen);
730 fillRandomScalars(rnd, rhsVecMin, rhsVecMax, &inputInts2[0], numElements * alignedVecLen);
731
732 if (vectorInfo.vecLen == 3)
733 for (unsigned int ndx = 0; ndx < numElements; ++ndx)
734 inputInts1[ndx*4+3] = inputInts2[ndx*4+3] = 0;
735
736
737 for (unsigned int i = 0; i < dotProductPackingInfoSize; i++)
738 {
739 const struct DotProductPackingInfo &packingInfo = dotProductPackingInfo[i];
740 if (packingInfo.packed && (vectorInfo.vecElementSize != 8 || vectorInfo.vecLen != 4))
741 continue;
742
743 if (vectorInfo.vecElementSize <= 32)
744 addOpSUDotKHRComputeTests<LHSBufferT, RHSBufferT, Int32Buffer, deInt32>(testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
745 if (vectorInfo.vecElementSize <= 16)
746 addOpSUDotKHRComputeTests<LHSBufferT, RHSBufferT, Int16Buffer, deInt16>(testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
747 if (vectorInfo.vecElementSize <= 8)
748 addOpSUDotKHRComputeTests<LHSBufferT, RHSBufferT, Int8Buffer, deInt8> (testCtx, group, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo);
749 }
750 }
751 }
752
753 template <class LHSOperandT, class RHSOperandT>
add32bitOpSUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,LHSOperandT lhsVecMin,LHSOperandT lhsVecMax,RHSOperandT rhsVecMin,RHSOperandT rhsVecMax)754 void add32bitOpSUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, LHSOperandT lhsVecMin, LHSOperandT lhsVecMax, RHSOperandT rhsVecMin, RHSOperandT rhsVecMax)
755 {
756 addOpSUDotKHRComputeTests<Int32Buffer, Uint32Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
757 dotProductVector32, DE_LENGTH_OF_ARRAY(dotProductVector32), lhsVecMin, lhsVecMax, rhsVecMin, rhsVecMax);
758 }
759
760 template <class LHSOperandT, class RHSOperandT>
add16bitOpSUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,LHSOperandT lhsVecMin,LHSOperandT lhsVecMax,RHSOperandT rhsVecMin,RHSOperandT rhsVecMax)761 void add16bitOpSUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, LHSOperandT lhsVecMin, LHSOperandT lhsVecMax, RHSOperandT rhsVecMin, RHSOperandT rhsVecMax)
762 {
763 addOpSUDotKHRComputeTests<Int16Buffer, Uint16Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
764 dotProductVector16, DE_LENGTH_OF_ARRAY(dotProductVector16), lhsVecMin, lhsVecMax, rhsVecMin, rhsVecMax);
765 }
766
767 template <class LHSOperandT, class RHSOperandT>
add8bitOpSUDotKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,LHSOperandT lhsVecMin,LHSOperandT lhsVecMax,RHSOperandT rhsVecMin,RHSOperandT rhsVecMax)768 void add8bitOpSUDotKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, LHSOperandT lhsVecMin, LHSOperandT lhsVecMax, RHSOperandT rhsVecMin, RHSOperandT rhsVecMax)
769 {
770 addOpSUDotKHRComputeTests<Int8Buffer, Uint8Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
771 dotProductVector8, DE_LENGTH_OF_ARRAY(dotProductVector8), lhsVecMin, lhsVecMax, rhsVecMin, rhsVecMax);
772 }
773
774 template <class InBufferT, class AddendBufferT, class AddendT, class OperandT>
addOpSDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,int numElements,vector<OperandT> & inputInts1,vector<OperandT> & inputInts2,const struct DotProductInputInfo & inputInfo,const struct DotProductPackingInfo & packingInfo,const struct DotProductVectorInfo & vectorInfo,bool useMaxAddend)775 void addOpSDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd,
776 int numElements, vector<OperandT> &inputInts1, vector<OperandT> &inputInts2,
777 const struct DotProductInputInfo &inputInfo, const struct DotProductPackingInfo &packingInfo,
778 const struct DotProductVectorInfo &vectorInfo, bool useMaxAddend)
779 {
780 ComputeShaderSpec spec;
781 size_t addendSize = sizeof(AddendT) * 8;
782 vector<AddendT> inputInts3 (numElements, 0);
783 vector<AddendT> outputInts (numElements, 0);
784
785 if (useMaxAddend)
786 fillRandomScalars(rnd, (AddendT)(std::numeric_limits<AddendT>::max()-20), (AddendT)(std::numeric_limits<AddendT>::max()),
787 &inputInts3[0], numElements);
788 else
789 fillRandomScalars(rnd, (AddendT)(std::numeric_limits<AddendT>::min()), (AddendT)(std::numeric_limits<AddendT>::min()+20),
790 &inputInts3[0], numElements);
791
792 spec.assembly = generateIntegerDotProductCode(packingInfo, vectorInfo, addendSize, true, true, true);
793
794 addDotProductExtensionAndFeatures(spec, packingInfo, vectorInfo.vecElementSize, addendSize);
795 spec.inputs.push_back (BufferSp(new InBufferT(inputInts1)));
796 spec.inputs.push_back (BufferSp(new InBufferT(inputInts2)));
797 spec.inputs.push_back (BufferSp(new AddendBufferT(inputInts3)));
798 spec.outputs.push_back (BufferSp(new AddendBufferT(outputInts)));
799 spec.numWorkGroups = IVec3(numElements, 1, 1);
800 spec.verifyIO = &compareDotProductAccSat<AddendT, OperandT, OperandT>;
801 spec.failResult = QP_TEST_RESULT_FAIL;
802 spec.failMessage = "Output doesn't match with expected";
803
804 string qualTestName(getDotProductTestName(inputInfo, packingInfo, addendSize));
805
806 group->addChild(new SpvAsmComputeShaderCase(testCtx, qualTestName.data(), spec));
807 }
808
809 template <class InBufferT, class T>
addOpSDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,const struct DotProductPackingInfo dotProductPackingInfo[],unsigned dotProductPackingInfoSize,const struct DotProductVectorInfo dotProductVectorInfo[],unsigned dotProductVectorInfoSize,T vecMin,T vecMax,bool useMaxAddend)810 void addOpSDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name,
811 const struct DotProductPackingInfo dotProductPackingInfo[], unsigned dotProductPackingInfoSize,
812 const struct DotProductVectorInfo dotProductVectorInfo[], unsigned dotProductVectorInfoSize,
813 T vecMin, T vecMax, bool useMaxAddend)
814 {
815 const int numElements = 200;
816 // Note: this test does not currently cover 64-bit integer results
817 for (unsigned int j = 0 ; j < dotProductVectorInfoSize; j++)
818 {
819 const struct DotProductVectorInfo &vectorInfo = dotProductVectorInfo[j];
820 unsigned int alignedVecLen = getAlignedVecLen(vectorInfo);
821 struct DotProductInputInfo inputInfo = { name, vectorInfo.vecLen, vectorInfo.vecElementSize };
822 vector<T> inputInts1 (numElements * alignedVecLen, 0);
823 vector<T> inputInts2 (numElements * alignedVecLen, 0);
824
825 fillRandomScalars(rnd, vecMin, vecMax, &inputInts1[0], numElements * alignedVecLen);
826 fillRandomScalars(rnd, vecMin, vecMax, &inputInts2[0], numElements * alignedVecLen);
827
828 if (vectorInfo.vecLen == 3)
829 for (unsigned int ndx = 0; ndx < numElements; ++ndx)
830 inputInts1[ndx*4+3] = inputInts2[ndx*4+3] = 0;
831
832
833 for (unsigned int i = 0; i < dotProductPackingInfoSize; i++)
834 {
835 const struct DotProductPackingInfo &packingInfo = dotProductPackingInfo[i];
836 if (packingInfo.packed && (vectorInfo.vecElementSize != 8 || vectorInfo.vecLen != 4))
837 continue;
838
839 if (vectorInfo.vecElementSize <= 32)
840 addOpSDotAccSatKHRComputeTests<InBufferT, Int32Buffer, deInt32>(testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
841 if (vectorInfo.vecElementSize <= 16)
842 addOpSDotAccSatKHRComputeTests<InBufferT, Int16Buffer, deInt16>(testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
843 if (vectorInfo.vecElementSize <= 8)
844 addOpSDotAccSatKHRComputeTests<InBufferT, Int8Buffer, deInt8> (testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
845 }
846 }
847 }
848
849 template <class T>
add32bitOpSDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax,bool useMaxAddend=true)850 void add32bitOpSDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax, bool useMaxAddend = true)
851 {
852 addOpSDotAccSatKHRComputeTests<Int32Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
853 dotProductVector32, DE_LENGTH_OF_ARRAY(dotProductVector32), vecMin, vecMax, useMaxAddend);
854 }
855
856 template <class T>
add16bitOpSDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax,bool useMaxAddend=true)857 void add16bitOpSDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax, bool useMaxAddend = true)
858 {
859 addOpSDotAccSatKHRComputeTests<Int16Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
860 dotProductVector16, DE_LENGTH_OF_ARRAY(dotProductVector16), vecMin, vecMax, useMaxAddend);
861 }
862
863 template <class T>
add8bitOpSDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax,bool useMaxAddend=true)864 void add8bitOpSDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax, bool useMaxAddend = true)
865 {
866 addOpSDotAccSatKHRComputeTests<Int8Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
867 dotProductVector8, DE_LENGTH_OF_ARRAY(dotProductVector8), vecMin, vecMax, useMaxAddend);
868 }
869
870 template <class InBufferT, class AddendBufferT, class AddendT, class OperandT>
addOpUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,int numElements,vector<OperandT> & inputInts1,vector<OperandT> & inputInts2,const struct DotProductInputInfo & inputInfo,const struct DotProductPackingInfo & packingInfo,const struct DotProductVectorInfo & vectorInfo,bool useMaxAddend)871 void addOpUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd,
872 int numElements, vector<OperandT> &inputInts1, vector<OperandT> &inputInts2,
873 const struct DotProductInputInfo &inputInfo, const struct DotProductPackingInfo &packingInfo,
874 const struct DotProductVectorInfo &vectorInfo, bool useMaxAddend)
875 {
876 ComputeShaderSpec spec;
877 size_t addendSize = sizeof(AddendT) * 8;
878 vector<AddendT> inputInts3 (numElements, 0);
879 vector<AddendT> outputInts (numElements, 0);
880
881 if (useMaxAddend)
882 fillRandomScalars(rnd, (AddendT)(std::numeric_limits<AddendT>::max()-20), (AddendT)(std::numeric_limits<AddendT>::max()),
883 &inputInts3[0], numElements);
884 else
885 fillRandomScalars(rnd, (AddendT)(std::numeric_limits<AddendT>::min()), (AddendT)(std::numeric_limits<AddendT>::min()+20),
886 &inputInts3[0], numElements);
887
888 spec.assembly = generateIntegerDotProductCode(packingInfo, vectorInfo, addendSize, false, false, true);
889
890 addDotProductExtensionAndFeatures(spec, packingInfo, vectorInfo.vecElementSize, addendSize);
891 spec.inputs.push_back (BufferSp(new InBufferT(inputInts1)));
892 spec.inputs.push_back (BufferSp(new InBufferT(inputInts2)));
893 spec.inputs.push_back (BufferSp(new AddendBufferT(inputInts3)));
894 spec.outputs.push_back (BufferSp(new AddendBufferT(outputInts)));
895 spec.numWorkGroups = IVec3(numElements, 1, 1);
896 spec.verifyIO = &compareDotProductAccSat<AddendT, OperandT, OperandT>;
897 spec.failResult = QP_TEST_RESULT_FAIL;
898 spec.failMessage = "Output doesn't match with expected";
899
900 string qualTestName(getDotProductTestName(inputInfo, packingInfo, addendSize));
901
902 group->addChild(new SpvAsmComputeShaderCase(testCtx, qualTestName.data(), spec));
903 }
904
905 template <class InBufferT, class T>
addOpUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,const struct DotProductPackingInfo dotProductPackingInfo[],unsigned dotProductPackingInfoSize,const struct DotProductVectorInfo dotProductVectorInfo[],unsigned dotProductVectorInfoSize,T vecMin,T vecMax,bool useMaxAddend)906 void addOpUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name,
907 const struct DotProductPackingInfo dotProductPackingInfo[], unsigned dotProductPackingInfoSize,
908 const struct DotProductVectorInfo dotProductVectorInfo[], unsigned dotProductVectorInfoSize,
909 T vecMin, T vecMax, bool useMaxAddend)
910 {
911 const int numElements = 200;
912 // Note: this test does not currently cover 64-bit integer results
913
914 for (unsigned int j = 0 ; j < dotProductVectorInfoSize; j++)
915 {
916 const struct DotProductVectorInfo &vectorInfo = dotProductVectorInfo[j];
917 unsigned int alignedVecLen = getAlignedVecLen(vectorInfo);
918 struct DotProductInputInfo inputInfo = { name, vectorInfo.vecLen, vectorInfo.vecElementSize };
919 vector<T> inputInts1 (numElements * alignedVecLen, 0);
920 vector<T> inputInts2 (numElements * alignedVecLen, 0);
921
922 fillRandomScalars(rnd, vecMin, vecMax, &inputInts1[0], numElements * alignedVecLen);
923 fillRandomScalars(rnd, vecMin, vecMax, &inputInts2[0], numElements * alignedVecLen);
924
925 if (vectorInfo.vecLen == 3)
926 for (unsigned int ndx = 0; ndx < numElements; ++ndx)
927 inputInts1[ndx*4+3] = inputInts2[ndx*4+3] = 0;
928
929 for (unsigned int i = 0; i < dotProductPackingInfoSize; i++)
930 {
931 const struct DotProductPackingInfo &packingInfo = dotProductPackingInfo[i];
932 if (packingInfo.packed && (vectorInfo.vecElementSize != 8 || vectorInfo.vecLen != 4))
933 continue;
934
935 if (vectorInfo.vecElementSize <= 32)
936 addOpUDotAccSatKHRComputeTests<InBufferT, Uint32Buffer, deUint32>(testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
937 if (vectorInfo.vecElementSize <= 16)
938 addOpUDotAccSatKHRComputeTests<InBufferT, Uint16Buffer, deUint16>(testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
939 if (vectorInfo.vecElementSize <= 8)
940 addOpUDotAccSatKHRComputeTests<InBufferT, Uint8Buffer, deUint8> (testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
941 }
942 }
943 }
944
945 template <class T>
add32bitOpUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax,bool useMaxAddend=true)946 void add32bitOpUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax, bool useMaxAddend = true)
947 {
948 addOpUDotAccSatKHRComputeTests<Uint32Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
949 dotProductVector32, DE_LENGTH_OF_ARRAY(dotProductVector32), vecMin, vecMax, useMaxAddend);
950 }
951
952 template <class T>
add16bitOpUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax,bool useMaxAddend=true)953 void add16bitOpUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax, bool useMaxAddend = true)
954 {
955 addOpUDotAccSatKHRComputeTests<Uint16Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
956 dotProductVector16, DE_LENGTH_OF_ARRAY(dotProductVector16), vecMin, vecMax, useMaxAddend);
957 }
958
959 template <class T>
add8bitOpUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,T vecMin,T vecMax,bool useMaxAddend=true)960 void add8bitOpUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, T vecMin, T vecMax, bool useMaxAddend = true)
961 {
962 addOpUDotAccSatKHRComputeTests<Uint8Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
963 dotProductVector8, DE_LENGTH_OF_ARRAY(dotProductVector8), vecMin, vecMax, useMaxAddend);
964 }
965
966 template <class LHSBufferT, class RHSBufferT, class AddendBufferT, class AddendT, class LHSOperandT, class RHSOperandT>
addOpSUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,int numElements,vector<LHSOperandT> & inputInts1,vector<RHSOperandT> & inputInts2,const struct DotProductInputInfo & inputInfo,const struct DotProductPackingInfo & packingInfo,const struct DotProductVectorInfo & vectorInfo,bool useMaxAddend)967 void addOpSUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd,
968 int numElements, vector<LHSOperandT> &inputInts1, vector<RHSOperandT> &inputInts2,
969 const struct DotProductInputInfo &inputInfo, const struct DotProductPackingInfo &packingInfo,
970 const struct DotProductVectorInfo &vectorInfo, bool useMaxAddend)
971 {
972 ComputeShaderSpec spec;
973 size_t addendSize = sizeof(AddendT) * 8;
974 vector<AddendT> inputInts3 (numElements, 0);
975 vector<AddendT> outputInts (numElements, 0);
976
977 // Populate the accumulation buffer with large values to attempt to guarantee saturation
978 if (useMaxAddend)
979 fillRandomScalars(rnd, (AddendT)(std::numeric_limits<AddendT>::max()-20), (AddendT)(std::numeric_limits<AddendT>::max()),
980 &inputInts3[0], numElements);
981 else
982 fillRandomScalars(rnd, (AddendT)(std::numeric_limits<AddendT>::min()), (AddendT)(std::numeric_limits<AddendT>::min()+20),
983 &inputInts3[0], numElements);
984
985 spec.assembly = generateIntegerDotProductCode(packingInfo, vectorInfo, addendSize, true, false, true);
986 addDotProductExtensionAndFeatures(spec, packingInfo, vectorInfo.vecElementSize, addendSize);
987 spec.inputs.push_back (BufferSp(new LHSBufferT(inputInts1)));
988 spec.inputs.push_back (BufferSp(new RHSBufferT(inputInts2)));
989 spec.inputs.push_back (BufferSp(new AddendBufferT(inputInts3)));
990 spec.outputs.push_back (BufferSp(new AddendBufferT(outputInts)));
991 spec.numWorkGroups = IVec3(numElements, 1, 1);
992 spec.verifyIO = &compareDotProductAccSat<AddendT, LHSOperandT, RHSOperandT>;
993 spec.failResult = QP_TEST_RESULT_FAIL;
994 spec.failMessage = "Output doesn't match with expected";
995
996 string qualTestName(getDotProductTestName(inputInfo, packingInfo, addendSize));
997
998 group->addChild(new SpvAsmComputeShaderCase(testCtx, qualTestName.data(), spec));
999 }
1000
1001 template <class LHSBufferT, class RHSBufferT, class LHSOperandT, class RHSOperandT>
addOpSUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,const struct DotProductPackingInfo dotProductPackingInfo[],unsigned dotProductPackingInfoSize,const struct DotProductVectorInfo dotProductVectorInfo[],unsigned dotProductVectorInfoSize,LHSOperandT lhsVecMin,LHSOperandT lhsVecMax,RHSOperandT rhsVecMin,RHSOperandT rhsVecMax,bool useMaxAddend)1002 void addOpSUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name,
1003 const struct DotProductPackingInfo dotProductPackingInfo[], unsigned dotProductPackingInfoSize,
1004 const struct DotProductVectorInfo dotProductVectorInfo[], unsigned dotProductVectorInfoSize,
1005 LHSOperandT lhsVecMin, LHSOperandT lhsVecMax, RHSOperandT rhsVecMin, RHSOperandT rhsVecMax, bool useMaxAddend)
1006 {
1007 const int numElements = 200;
1008 // Note: this test does not currently cover 64-bit integer results
1009
1010 for (unsigned int j = 0; j < dotProductVectorInfoSize; j++)
1011 {
1012 const struct DotProductVectorInfo &vectorInfo = dotProductVectorInfo[j];
1013 unsigned int alignedVecLen = getAlignedVecLen(vectorInfo);
1014 struct DotProductInputInfo inputInfo = { name, vectorInfo.vecLen, vectorInfo.vecElementSize };
1015 vector<LHSOperandT> inputInts1 (numElements * alignedVecLen, 0);
1016 vector<RHSOperandT> inputInts2 (numElements * alignedVecLen, 0);
1017
1018 fillRandomScalars(rnd, lhsVecMin, lhsVecMax, &inputInts1[0], numElements * alignedVecLen);
1019 fillRandomScalars(rnd, rhsVecMin, rhsVecMax, &inputInts2[0], numElements * alignedVecLen);
1020
1021 if (vectorInfo.vecLen == 3)
1022 for (unsigned int ndx = 0; ndx < numElements; ++ndx)
1023 inputInts1[ndx*4+3] = inputInts2[ndx*4+3] = 0;
1024
1025 for (unsigned int i = 0; i < dotProductPackingInfoSize; i++)
1026 {
1027 const struct DotProductPackingInfo &packingInfo = dotProductPackingInfo[i];
1028 if (packingInfo.packed && (vectorInfo.vecElementSize != 8 || vectorInfo.vecLen != 4))
1029 continue;
1030
1031 if (vectorInfo.vecElementSize <= 32)
1032 addOpSUDotAccSatKHRComputeTests<LHSBufferT, RHSBufferT, Int32Buffer, deInt32>(testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
1033 if (vectorInfo.vecElementSize <= 16)
1034 addOpSUDotAccSatKHRComputeTests<LHSBufferT, RHSBufferT, Int16Buffer, deInt16>(testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
1035 if (vectorInfo.vecElementSize <= 8)
1036 addOpSUDotAccSatKHRComputeTests<LHSBufferT, RHSBufferT, Int8Buffer, deInt8> (testCtx, group, rnd, numElements, inputInts1, inputInts2, inputInfo, packingInfo, vectorInfo, useMaxAddend);
1037 }
1038 }
1039 }
1040
1041 template <class LHSOperandT, class RHSOperandT>
add32bitOpSUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,LHSOperandT lhsVecMin,LHSOperandT lhsVecMax,RHSOperandT rhsVecMin,RHSOperandT rhsVecMax,bool useMaxAddend=true)1042 void add32bitOpSUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, LHSOperandT lhsVecMin, LHSOperandT lhsVecMax, RHSOperandT rhsVecMin, RHSOperandT rhsVecMax, bool useMaxAddend = true)
1043 {
1044 addOpSUDotAccSatKHRComputeTests<Int32Buffer, Uint32Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
1045 dotProductVector32, DE_LENGTH_OF_ARRAY(dotProductVector32), lhsVecMin, lhsVecMax, rhsVecMin, rhsVecMax, useMaxAddend);
1046 }
1047
1048 template <class LHSOperandT, class RHSOperandT>
add16bitOpSUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,LHSOperandT lhsVecMin,LHSOperandT lhsVecMax,RHSOperandT rhsVecMin,RHSOperandT rhsVecMax,bool useMaxAddend=true)1049 void add16bitOpSUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, LHSOperandT lhsVecMin, LHSOperandT lhsVecMax, RHSOperandT rhsVecMin, RHSOperandT rhsVecMax, bool useMaxAddend = true)
1050 {
1051 addOpSUDotAccSatKHRComputeTests<Int16Buffer, Uint16Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
1052 dotProductVector16, DE_LENGTH_OF_ARRAY(dotProductVector16), lhsVecMin, lhsVecMax, rhsVecMin, rhsVecMax, useMaxAddend);
1053 }
1054
1055 template <class LHSOperandT, class RHSOperandT>
add8bitOpSUDotAccSatKHRComputeTests(tcu::TestContext & testCtx,tcu::TestCaseGroup * group,de::Random & rnd,string name,LHSOperandT lhsVecMin,LHSOperandT lhsVecMax,RHSOperandT rhsVecMin,RHSOperandT rhsVecMax,bool useMaxAddend=true)1056 void add8bitOpSUDotAccSatKHRComputeTests(tcu::TestContext& testCtx, tcu::TestCaseGroup *group, de::Random &rnd, string name, LHSOperandT lhsVecMin, LHSOperandT lhsVecMax, RHSOperandT rhsVecMin, RHSOperandT rhsVecMax, bool useMaxAddend = true)
1057 {
1058 addOpSUDotAccSatKHRComputeTests<Int8Buffer, Uint8Buffer>(testCtx, group, rnd, name, dotProductPacking, DE_LENGTH_OF_ARRAY(dotProductPacking),
1059 dotProductVector8, DE_LENGTH_OF_ARRAY(dotProductVector8), lhsVecMin, lhsVecMax, rhsVecMin, rhsVecMax, useMaxAddend);
1060 }
1061
1062 } // anon namespace
1063
createOpSDotKHRComputeGroup(tcu::TestContext & testCtx)1064 tcu::TestCaseGroup* createOpSDotKHRComputeGroup(tcu::TestContext& testCtx)
1065 {
1066 // Test the OpSDotKHR instruction
1067 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opsdotkhr"));
1068 de::Random rnd (deStringHash(group->getName()));
1069
1070 add8bitOpSDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt8>::min(), std::numeric_limits<deInt8>::max());
1071 add8bitOpSDotKHRComputeTests(testCtx, group.get(), rnd, string("small"), (deInt8)-20, (deInt8)20);
1072 add16bitOpSDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt16>::min(), std::numeric_limits<deInt16>::max());
1073 add32bitOpSDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt32>::min(), std::numeric_limits<deInt32>::max());
1074
1075 return group.release();
1076 }
1077
createOpUDotKHRComputeGroup(tcu::TestContext & testCtx)1078 tcu::TestCaseGroup* createOpUDotKHRComputeGroup(tcu::TestContext& testCtx)
1079 {
1080 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opudotkhr", "Test the OpUDotKHR instruction"));
1081 de::Random rnd (deStringHash(group->getName()));
1082
1083 add8bitOpUDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deUint8>::min(), std::numeric_limits<deUint8>::max());
1084 add8bitOpUDotKHRComputeTests(testCtx, group.get(), rnd, string("small"), (deUint8)0, (deUint8)20);
1085 add16bitOpUDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deUint16>::min(), std::numeric_limits<deUint16>::max());
1086 add32bitOpUDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deUint32>::min(), std::numeric_limits<deUint32>::max());
1087
1088 return group.release();
1089 }
1090
createOpSUDotKHRComputeGroup(tcu::TestContext & testCtx)1091 tcu::TestCaseGroup* createOpSUDotKHRComputeGroup(tcu::TestContext& testCtx)
1092 {
1093 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opsudotkhr", "Test the OpSUDotKHR instruction"));
1094 de::Random rnd (deStringHash(group->getName()));
1095
1096 add8bitOpSUDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt8>::min(), std::numeric_limits<deInt8>::max(), std::numeric_limits<deUint8>::min(), std::numeric_limits<deUint8>::max());
1097 add8bitOpSUDotKHRComputeTests(testCtx, group.get(), rnd, string("small"), (deInt8)-20, (deInt8)20, (deUint8)0, (deUint8)20);
1098 add16bitOpSUDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt16>::min(), std::numeric_limits<deInt16>::max(), std::numeric_limits<deUint16>::min(), std::numeric_limits<deUint16>::max());
1099 add32bitOpSUDotKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt32>::min(), std::numeric_limits<deInt32>::max(), std::numeric_limits<deUint32>::min(), std::numeric_limits<deUint32>::max());
1100
1101 return group.release();
1102 }
1103
createOpSDotAccSatKHRComputeGroup(tcu::TestContext & testCtx)1104 tcu::TestCaseGroup* createOpSDotAccSatKHRComputeGroup(tcu::TestContext& testCtx)
1105 {
1106 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opsdotaccsatkhr", "Test the OpSDotAccSatKHR instruction"));
1107 de::Random rnd (deStringHash(group->getName()));
1108
1109 add8bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt8>::min(), std::numeric_limits<deInt8>::max());
1110 add8bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deInt8)(12), (deInt8)(20));
1111 add8bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits-neg"), (deInt8)(-20), (deInt8)(-12), false);
1112 add8bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("small"), (deInt8)-4, (deInt8)4);
1113 add8bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("small-neg"), (deInt8)-4, (deInt8)4, false);
1114 add16bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt16>::min(), std::numeric_limits<deInt16>::max());
1115 add16bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deInt16)(-20), (deInt16)(20));
1116 add16bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits-neg"), (deInt16)(-20), (deInt16)(20), false);
1117 add32bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt32>::min(), std::numeric_limits<deInt32>::max());
1118 add32bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deInt32)(std::numeric_limits<deInt8>::min()), (deInt32)(std::numeric_limits<deInt8>::max()));
1119 add32bitOpSDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits-neg"), (deInt32)(std::numeric_limits<deInt8>::min()), (deInt32)(std::numeric_limits<deInt8>::max()), false);
1120
1121 return group.release();
1122 }
1123
createOpUDotAccSatKHRComputeGroup(tcu::TestContext & testCtx)1124 tcu::TestCaseGroup* createOpUDotAccSatKHRComputeGroup(tcu::TestContext& testCtx)
1125 {
1126 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opudotaccsatkhr", "Test the OpUDotAccSatKHR instruction"));
1127 de::Random rnd (deStringHash(group->getName()));
1128
1129 add8bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deUint8>::min(), std::numeric_limits<deUint8>::max());
1130 add8bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deUint8)(12), (deUint8)(20));
1131 add8bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("small"), (deUint8)1, (deUint8)8);
1132 add8bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("small-nosat"), (deUint8)1, (deUint8)8, false);
1133 add16bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deUint16>::min(), std::numeric_limits<deUint16>::max());
1134 add16bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deUint16)(12), (deUint16)(20));
1135 add16bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("nosat"), (deUint16)(12), (deUint16)(20), false);
1136 add32bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deUint32>::min(), std::numeric_limits<deUint32>::max());
1137 add32bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deUint32)(std::numeric_limits<deUint8>::max()-40), (deUint32)(std::numeric_limits<deUint8>::max()-20));
1138 add32bitOpUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("nosat"), (deUint32)(std::numeric_limits<deUint8>::max()-40), (deUint32)(std::numeric_limits<deUint8>::max()-20), false);
1139
1140 return group.release();
1141 }
1142
createOpSUDotAccSatKHRComputeGroup(tcu::TestContext & testCtx)1143 tcu::TestCaseGroup* createOpSUDotAccSatKHRComputeGroup(tcu::TestContext& testCtx)
1144 {
1145 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "opsudotaccsatkhr", "Test the OpSUDotAccSatKHR instruction"));
1146 de::Random rnd (deStringHash(group->getName()));
1147
1148 add8bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt8>::min(), std::numeric_limits<deInt8>::max(), std::numeric_limits<deUint8>::min(), std::numeric_limits<deUint8>::max());
1149 add8bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deInt8)(12), (deInt8)(20), (deUint8)(12), (deUint8)(20));
1150 add8bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits-neg"), (deInt8)(-20), (deInt8)(-12), (deUint8)(12), (deUint8)(20), false);
1151 add8bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("small"), (deInt8)-4, (deInt8)4, (deUint8)1, (deUint8)8);
1152 add8bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("small-neg"), (deInt8)-4, (deInt8)4, (deUint8)1, (deUint8)8, false);
1153 add16bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt16>::min(), std::numeric_limits<deInt16>::max(), std::numeric_limits<deUint16>::min(), std::numeric_limits<deUint16>::max());
1154 add16bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deInt16)(-20), (deInt16)(20), (deUint16)(12), (deUint16)(20));
1155 add16bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits-neg"), (deInt16)(-20), (deInt16)(20), (deUint16)(12), (deUint16)(20), false);
1156 add32bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("all"), std::numeric_limits<deInt32>::min(), std::numeric_limits<deInt32>::max(), std::numeric_limits<deUint32>::min(), std::numeric_limits<deUint32>::max());
1157 add32bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits"), (deInt32)(std::numeric_limits<deInt8>::min()), (deInt32)(std::numeric_limits<deInt8>::max()), (deUint32)(std::numeric_limits<deUint8>::min()), (deUint32)(std::numeric_limits<deUint8>::max()));
1158 add32bitOpSUDotAccSatKHRComputeTests(testCtx, group.get(), rnd, string("limits-neg"), (deInt32)(std::numeric_limits<deInt8>::min()), (deInt32)(std::numeric_limits<deInt8>::max()), (deUint32)(std::numeric_limits<deUint8>::max()), (deUint32)(std::numeric_limits<deUint8>::max()), false);
1159
1160 return group.release();
1161 }
1162
1163 } // SpirVAssembly
1164 } // vkt
1165