1 /*
2  * Copyright (C) 2020-2021 Intel Corporation
3  *
4  * SPDX-License-Identifier: MIT
5  *
6  */
7 
8 #include "shared/source/kernel/kernel_arg_descriptor.h"
9 #include "shared/test/common/test_macros/test.h"
10 
11 #include <gtest/gtest.h>
12 
13 #include <limits>
14 
TEST(Undefined,GivenAnyTypeThenReturnsMaxValue)15 TEST(Undefined, GivenAnyTypeThenReturnsMaxValue) {
16     EXPECT_EQ(std::numeric_limits<uint8_t>::max(), NEO::undefined<uint8_t>);
17     EXPECT_EQ(std::numeric_limits<uint16_t>::max(), NEO::undefined<uint16_t>);
18     EXPECT_EQ(std::numeric_limits<uint32_t>::max(), NEO::undefined<uint32_t>);
19     EXPECT_EQ(std::numeric_limits<uint64_t>::max(), NEO::undefined<uint64_t>);
20 }
21 
TEST(IsUndefinedOffset,GivenAnyTypeThenComparesAgainstUndefined)22 TEST(IsUndefinedOffset, GivenAnyTypeThenComparesAgainstUndefined) {
23     EXPECT_TRUE(NEO::isUndefinedOffset(NEO::undefined<uint8_t>));
24     EXPECT_TRUE(NEO::isUndefinedOffset(NEO::undefined<uint16_t>));
25     EXPECT_TRUE(NEO::isUndefinedOffset(NEO::undefined<uint32_t>));
26     EXPECT_TRUE(NEO::isUndefinedOffset(NEO::undefined<uint64_t>));
27 
28     EXPECT_FALSE(NEO::isUndefinedOffset<uint64_t>(NEO::undefined<uint8_t>));
29     EXPECT_FALSE(NEO::isUndefinedOffset<uint64_t>(NEO::undefined<uint16_t>));
30     EXPECT_FALSE(NEO::isUndefinedOffset<uint64_t>(NEO::undefined<uint32_t>));
31 
32     EXPECT_FALSE(NEO::isUndefinedOffset<uint8_t>(0));
33     EXPECT_FALSE(NEO::isUndefinedOffset<uint8_t>(0));
34     EXPECT_FALSE(NEO::isUndefinedOffset<uint8_t>(0));
35     EXPECT_FALSE(NEO::isUndefinedOffset<uint8_t>(0));
36 }
37 
TEST(IsValidOffset,GivenAnyTypeThenComparesAgainstUndefined)38 TEST(IsValidOffset, GivenAnyTypeThenComparesAgainstUndefined) {
39     EXPECT_FALSE(NEO::isValidOffset(NEO::undefined<uint8_t>));
40     EXPECT_FALSE(NEO::isValidOffset(NEO::undefined<uint16_t>));
41     EXPECT_FALSE(NEO::isValidOffset(NEO::undefined<uint32_t>));
42     EXPECT_FALSE(NEO::isValidOffset(NEO::undefined<uint64_t>));
43 
44     EXPECT_TRUE(NEO::isValidOffset<uint64_t>(NEO::undefined<uint8_t>));
45     EXPECT_TRUE(NEO::isValidOffset<uint64_t>(NEO::undefined<uint16_t>));
46     EXPECT_TRUE(NEO::isValidOffset<uint64_t>(NEO::undefined<uint32_t>));
47 
48     EXPECT_TRUE(NEO::isValidOffset<uint8_t>(0));
49     EXPECT_TRUE(NEO::isValidOffset<uint8_t>(0));
50     EXPECT_TRUE(NEO::isValidOffset<uint8_t>(0));
51     EXPECT_TRUE(NEO::isValidOffset<uint8_t>(0));
52 }
53 
TEST(ArgDescPointer,WhenDefaultInitializedThenOffsetsAreUndefined)54 TEST(ArgDescPointer, WhenDefaultInitializedThenOffsetsAreUndefined) {
55     NEO::ArgDescPointer argPtr;
56     EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.bindful));
57     EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.stateless));
58     EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.bindless));
59     EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.bufferOffset));
60     EXPECT_TRUE(NEO::isUndefinedOffset(argPtr.slmOffset));
61 
62     EXPECT_EQ(0U, argPtr.requiredSlmAlignment);
63     EXPECT_EQ(0U, argPtr.pointerSize);
64     EXPECT_TRUE(argPtr.accessedUsingStatelessAddressingMode);
65 }
66 
TEST(ArgDescPointerIsPureStateful,WhenQueriedThenReturnsTrueIfPointerIsNotAccessedInStatelessManner)67 TEST(ArgDescPointerIsPureStateful, WhenQueriedThenReturnsTrueIfPointerIsNotAccessedInStatelessManner) {
68     NEO::ArgDescPointer argPtr;
69     argPtr.accessedUsingStatelessAddressingMode = true;
70     EXPECT_FALSE(argPtr.isPureStateful());
71 
72     argPtr.accessedUsingStatelessAddressingMode = false;
73     EXPECT_TRUE(argPtr.isPureStateful());
74 }
75 
TEST(ArgDescImage,WhenDefaultInitializedThenOffsetsAreUndefined)76 TEST(ArgDescImage, WhenDefaultInitializedThenOffsetsAreUndefined) {
77     NEO::ArgDescImage argImage;
78     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.bindful));
79     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.bindless));
80     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.imgWidth));
81     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.imgHeight));
82     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.imgDepth));
83     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.channelDataType));
84     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.channelOrder));
85     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.arraySize));
86     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.numSamples));
87     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.numMipLevels));
88     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.flatBaseOffset));
89     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.flatWidth));
90     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.flatHeight));
91     EXPECT_TRUE(NEO::isUndefinedOffset(argImage.metadataPayload.flatPitch));
92 }
93 
TEST(ArgDescSampler,WhenDefaultInitializedThenOffsetsAreUndefined)94 TEST(ArgDescSampler, WhenDefaultInitializedThenOffsetsAreUndefined) {
95     NEO::ArgDescSampler argSampler;
96     EXPECT_EQ(0U, argSampler.samplerType);
97     EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.bindful));
98     EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.bindless));
99     EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.metadataPayload.samplerSnapWa));
100     EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.metadataPayload.samplerAddressingMode));
101     EXPECT_TRUE(NEO::isUndefinedOffset(argSampler.metadataPayload.samplerNormalizedCoords));
102 }
103 
TEST(ArgDescValue,WhenDefaultInitializedThenOffsetsAreUndefined)104 TEST(ArgDescValue, WhenDefaultInitializedThenOffsetsAreUndefined) {
105     NEO::ArgDescValue argValue;
106     EXPECT_TRUE(argValue.elements.empty());
107 
108     NEO::ArgDescValue::Element argValueElement;
109     EXPECT_TRUE(NEO::isUndefinedOffset(argValueElement.offset));
110     EXPECT_EQ(0U, argValueElement.size);
111     EXPECT_EQ(0U, argValueElement.sourceOffset);
112 }
113 
TEST(ArgDescriptor,WhenDefaultInitializedThenTypeIsUnknown)114 TEST(ArgDescriptor, WhenDefaultInitializedThenTypeIsUnknown) {
115     NEO::ArgDescriptor arg;
116     EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, arg.type);
117 }
118 
TEST(ArgDescriptorExtendedTypeInfo,WhenDefaultInitializedThenFlagsAreCleared)119 TEST(ArgDescriptorExtendedTypeInfo, WhenDefaultInitializedThenFlagsAreCleared) {
120     NEO::ArgDescriptor::ExtendedTypeInfo argExtendedTypeInfo;
121     EXPECT_EQ(0U, argExtendedTypeInfo.packed);
122 
123     NEO::ArgDescriptor arg;
124     EXPECT_EQ(0U, arg.getExtendedTypeInfo().packed);
125     EXPECT_EQ(&arg.getExtendedTypeInfo(), &const_cast<const NEO::ArgDescriptor &>(arg).getExtendedTypeInfo());
126 }
127 
TEST(ArgDescriptorGetTraits,WhenDefaultInitializedThenTraitsAreCleared)128 TEST(ArgDescriptorGetTraits, WhenDefaultInitializedThenTraitsAreCleared) {
129     NEO::ArgTypeTraits expected;
130     NEO::ArgDescriptor arg;
131     NEO::ArgTypeTraits &got = arg.getTraits();
132     EXPECT_EQ(expected.accessQualifier, got.accessQualifier);
133     EXPECT_EQ(expected.addressQualifier, got.addressQualifier);
134     EXPECT_EQ(expected.argByValSize, got.argByValSize);
135     EXPECT_EQ(expected.typeQualifiers.packed, got.typeQualifiers.packed);
136     EXPECT_EQ(&arg.getTraits(), &const_cast<const NEO::ArgDescriptor &>(arg).getTraits());
137 }
138 
TEST(ArgDescriptorIsReadOnly,GivenImageArgWhenAccessQualifierIsReadOnlyThenReturnsTrue)139 TEST(ArgDescriptorIsReadOnly, GivenImageArgWhenAccessQualifierIsReadOnlyThenReturnsTrue) {
140     NEO::ArgDescriptor arg;
141     arg.as<NEO::ArgDescImage>(true);
142     arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessReadOnly;
143     EXPECT_TRUE(arg.isReadOnly());
144 
145     arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessNone;
146     EXPECT_FALSE(arg.isReadOnly());
147     arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessReadWrite;
148     EXPECT_FALSE(arg.isReadOnly());
149     arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessWriteOnly;
150     EXPECT_FALSE(arg.isReadOnly());
151     arg.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessUnknown;
152     EXPECT_FALSE(arg.isReadOnly());
153 }
154 
TEST(ArgDescriptorIsReadOnly,GivenPointerArgWhenConstQualifiedThenReturnsTrue)155 TEST(ArgDescriptorIsReadOnly, GivenPointerArgWhenConstQualifiedThenReturnsTrue) {
156     NEO::ArgDescriptor arg;
157     arg.as<NEO::ArgDescPointer>(true);
158     arg.getTraits().typeQualifiers.constQual = true;
159     EXPECT_TRUE(arg.isReadOnly());
160 
161     arg.getTraits().typeQualifiers.constQual = false;
162     EXPECT_FALSE(arg.isReadOnly());
163 }
164 
TEST(ArgDescriptorIsReadOnly,GivenPointerArgWhenConstantAddressSpaceThenReturnsTrue)165 TEST(ArgDescriptorIsReadOnly, GivenPointerArgWhenConstantAddressSpaceThenReturnsTrue) {
166     NEO::ArgDescriptor arg;
167     arg.as<NEO::ArgDescPointer>(true);
168     arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrConstant;
169     EXPECT_TRUE(arg.isReadOnly());
170 
171     arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrGlobal;
172     EXPECT_FALSE(arg.isReadOnly());
173 
174     arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrLocal;
175     EXPECT_FALSE(arg.isReadOnly());
176 
177     arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrPrivate;
178     EXPECT_FALSE(arg.isReadOnly());
179 
180     arg.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrUnknown;
181     EXPECT_FALSE(arg.isReadOnly());
182 }
183 
TEST(ArgDescriptorIsReadOnly,GivenSamplerArgThenReturnsTrue)184 TEST(ArgDescriptorIsReadOnly, GivenSamplerArgThenReturnsTrue) {
185     NEO::ArgDescriptor arg;
186     arg.as<NEO::ArgDescSampler>(true);
187     EXPECT_TRUE(arg.isReadOnly());
188 }
189 
TEST(ArgDescriptorIsReadOnly,GivenValueArgThenReturnsTrue)190 TEST(ArgDescriptorIsReadOnly, GivenValueArgThenReturnsTrue) {
191     NEO::ArgDescriptor arg;
192     arg.as<NEO::ArgDescValue>(true);
193     EXPECT_TRUE(arg.isReadOnly());
194 }
195 
TEST(ArgDescriptorIs,WhenQueriedThenComparesAgainstStoredArgType)196 TEST(ArgDescriptorIs, WhenQueriedThenComparesAgainstStoredArgType) {
197     NEO::ArgDescriptor args[] = {{NEO::ArgDescriptor::ArgTPointer},
198                                  {NEO::ArgDescriptor::ArgTImage},
199                                  {NEO::ArgDescriptor::ArgTSampler},
200                                  {NEO::ArgDescriptor::ArgTValue}};
201     for (const auto &arg : args) {
202         EXPECT_EQ(arg.type == NEO::ArgDescriptor::ArgTPointer, arg.is<NEO::ArgDescriptor::ArgTPointer>());
203         EXPECT_EQ(arg.type == NEO::ArgDescriptor::ArgTImage, arg.is<NEO::ArgDescriptor::ArgTImage>());
204         EXPECT_EQ(arg.type == NEO::ArgDescriptor::ArgTSampler, arg.is<NEO::ArgDescriptor::ArgTSampler>());
205         EXPECT_EQ(arg.type == NEO::ArgDescriptor::ArgTValue, arg.is<NEO::ArgDescriptor::ArgTValue>());
206     }
207 }
208 
TEST(ArgDescriptorAs,GivenUninitializedArgWhenInitializationRequestedThenInitializesTheArg)209 TEST(ArgDescriptorAs, GivenUninitializedArgWhenInitializationRequestedThenInitializesTheArg) {
210     NEO::ArgDescriptor argPointer;
211     NEO::ArgDescriptor argImage;
212     NEO::ArgDescriptor argSampler;
213     NEO::ArgDescriptor argValue;
214 
215     argPointer.as<NEO::ArgDescPointer>(true);
216     argImage.as<NEO::ArgDescImage>(true);
217     argSampler.as<NEO::ArgDescSampler>(true);
218     argValue.as<NEO::ArgDescValue>(true);
219     EXPECT_EQ(NEO::ArgDescriptor::ArgTPointer, argPointer.type);
220     EXPECT_EQ(NEO::ArgDescriptor::ArgTImage, argImage.type);
221     EXPECT_EQ(NEO::ArgDescriptor::ArgTSampler, argSampler.type);
222     EXPECT_EQ(NEO::ArgDescriptor::ArgTValue, argValue.type);
223 }
224 
TEST(ArgDescriptorAs,GivenUninitializedArgWhenInitializationNotRequestedThenAborts)225 TEST(ArgDescriptorAs, GivenUninitializedArgWhenInitializationNotRequestedThenAborts) {
226     NEO::ArgDescriptor argPointer;
227     NEO::ArgDescriptor argImage;
228     NEO::ArgDescriptor argSampler;
229     NEO::ArgDescriptor argValue;
230 
231     EXPECT_THROW(argPointer.as<NEO::ArgDescPointer>(false), std::exception);
232     EXPECT_THROW(argImage.as<NEO::ArgDescImage>(false), std::exception);
233     EXPECT_THROW(argSampler.as<NEO::ArgDescSampler>(false), std::exception);
234     EXPECT_THROW(argValue.as<NEO::ArgDescValue>(false), std::exception);
235     EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, argPointer.type);
236     EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, argImage.type);
237     EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, argSampler.type);
238     EXPECT_EQ(NEO::ArgDescriptor::ArgTUnknown, argValue.type);
239 }
240 
TEST(ArgDescriptorAs,GivenMismatchedArgTypeThenAborts)241 TEST(ArgDescriptorAs, GivenMismatchedArgTypeThenAborts) {
242     NEO::ArgDescriptor argPointer;
243     NEO::ArgDescriptor argImage;
244     NEO::ArgDescriptor argSampler;
245     NEO::ArgDescriptor argValue;
246 
247     argPointer.as<NEO::ArgDescPointer>(true);
248     argImage.as<NEO::ArgDescImage>(true);
249     argSampler.as<NEO::ArgDescSampler>(true);
250     argValue.as<NEO::ArgDescValue>(true);
251 
252     EXPECT_NO_THROW(argPointer.as<NEO::ArgDescPointer>());
253     EXPECT_NO_THROW(argImage.as<NEO::ArgDescImage>());
254     EXPECT_NO_THROW(argSampler.as<NEO::ArgDescSampler>());
255     EXPECT_NO_THROW(argValue.as<NEO::ArgDescValue>());
256 
257     EXPECT_THROW(argPointer.as<NEO::ArgDescImage>(), std::exception);
258     EXPECT_THROW(argPointer.as<NEO::ArgDescSampler>(), std::exception);
259     EXPECT_THROW(argPointer.as<NEO::ArgDescValue>(), std::exception);
260 
261     EXPECT_THROW(argImage.as<NEO::ArgDescPointer>(), std::exception);
262     EXPECT_THROW(argImage.as<NEO::ArgDescSampler>(), std::exception);
263     EXPECT_THROW(argImage.as<NEO::ArgDescValue>(), std::exception);
264 
265     EXPECT_THROW(argSampler.as<NEO::ArgDescPointer>(), std::exception);
266     EXPECT_THROW(argSampler.as<NEO::ArgDescImage>(), std::exception);
267     EXPECT_THROW(argSampler.as<NEO::ArgDescValue>(), std::exception);
268 
269     EXPECT_THROW(argValue.as<NEO::ArgDescPointer>(), std::exception);
270     EXPECT_THROW(argValue.as<NEO::ArgDescImage>(), std::exception);
271     EXPECT_THROW(argValue.as<NEO::ArgDescSampler>(), std::exception);
272 
273     EXPECT_NO_THROW(const_cast<NEO::ArgDescriptor &>(argPointer).as<NEO::ArgDescPointer>());
274     EXPECT_NO_THROW(const_cast<NEO::ArgDescriptor &>(argImage).as<NEO::ArgDescImage>());
275     EXPECT_NO_THROW(const_cast<NEO::ArgDescriptor &>(argSampler).as<NEO::ArgDescSampler>());
276     EXPECT_NO_THROW(const_cast<NEO::ArgDescriptor &>(argValue).as<NEO::ArgDescValue>());
277 
278     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argPointer).as<NEO::ArgDescImage>(), std::exception);
279     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argPointer).as<NEO::ArgDescSampler>(), std::exception);
280     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argPointer).as<NEO::ArgDescValue>(), std::exception);
281 
282     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argImage).as<NEO::ArgDescPointer>(), std::exception);
283     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argImage).as<NEO::ArgDescSampler>(), std::exception);
284     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argImage).as<NEO::ArgDescValue>(), std::exception);
285 
286     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argSampler).as<NEO::ArgDescPointer>(), std::exception);
287     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argSampler).as<NEO::ArgDescImage>(), std::exception);
288     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argSampler).as<NEO::ArgDescValue>(), std::exception);
289 
290     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argValue).as<NEO::ArgDescPointer>(), std::exception);
291     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argValue).as<NEO::ArgDescImage>(), std::exception);
292     EXPECT_THROW(const_cast<NEO::ArgDescriptor &>(argValue).as<NEO::ArgDescSampler>(), std::exception);
293 }
294 
TEST(ArgDescriptorCopyAssign,WhenCopyAssignedThenCopiesExtendedTypeInfo)295 TEST(ArgDescriptorCopyAssign, WhenCopyAssignedThenCopiesExtendedTypeInfo) {
296     NEO::ArgDescriptor arg0;
297     arg0.getExtendedTypeInfo().isAccelerator = true;
298     arg0.getExtendedTypeInfo().hasDeviceSideEnqueueExtendedDescriptor = true;
299 
300     NEO::ArgDescriptor arg1{arg0};
301     NEO::ArgDescriptor arg2;
302     arg2 = arg1;
303     EXPECT_EQ(arg0.getExtendedTypeInfo().packed, arg2.getExtendedTypeInfo().packed);
304 }
305 
TEST(ArgDescriptorCopyAssign,WhenCopyAssignedThenCopiesTraits)306 TEST(ArgDescriptorCopyAssign, WhenCopyAssignedThenCopiesTraits) {
307     NEO::ArgDescriptor arg0;
308     arg0.getTraits().accessQualifier = NEO::KernelArgMetadata::AccessWriteOnly;
309     arg0.getTraits().addressQualifier = NEO::KernelArgMetadata::AddrLocal;
310     arg0.getTraits().argByValSize = 3;
311     arg0.getTraits().typeQualifiers.restrictQual = true;
312 
313     NEO::ArgDescriptor arg2;
314     arg2 = arg0;
315     EXPECT_EQ(arg0.getTraits().accessQualifier, arg2.getTraits().accessQualifier);
316     EXPECT_EQ(arg0.getTraits().addressQualifier, arg2.getTraits().addressQualifier);
317     EXPECT_EQ(arg0.getTraits().argByValSize, arg2.getTraits().argByValSize);
318     EXPECT_EQ(arg0.getTraits().typeQualifiers.packed, arg2.getTraits().typeQualifiers.packed);
319 }
320 
TEST(ArgDescriptorCopyAssign,GivenPointerArgWhenCopyAssignedThenCopiesDataBasedOnArgType)321 TEST(ArgDescriptorCopyAssign, GivenPointerArgWhenCopyAssignedThenCopiesDataBasedOnArgType) {
322     NEO::ArgDescriptor arg0;
323     auto &argPointer = arg0.as<NEO::ArgDescPointer>(true);
324     argPointer.bindful = 2;
325     argPointer.stateless = 3;
326     argPointer.bindless = 5;
327     argPointer.bufferOffset = 7;
328     argPointer.slmOffset = 11;
329     argPointer.requiredSlmAlignment = 13;
330     argPointer.pointerSize = 17;
331     argPointer.accessedUsingStatelessAddressingMode = false;
332 
333     NEO::ArgDescriptor arg2;
334     arg2 = arg0;
335     EXPECT_EQ(argPointer.bindful, arg2.as<NEO::ArgDescPointer>().bindful);
336     EXPECT_EQ(argPointer.stateless, arg2.as<NEO::ArgDescPointer>().stateless);
337     EXPECT_EQ(argPointer.bindless, arg2.as<NEO::ArgDescPointer>().bindless);
338     EXPECT_EQ(argPointer.bufferOffset, arg2.as<NEO::ArgDescPointer>().bufferOffset);
339     EXPECT_EQ(argPointer.slmOffset, arg2.as<NEO::ArgDescPointer>().slmOffset);
340     EXPECT_EQ(argPointer.requiredSlmAlignment, arg2.as<NEO::ArgDescPointer>().requiredSlmAlignment);
341     EXPECT_EQ(argPointer.pointerSize, arg2.as<NEO::ArgDescPointer>().pointerSize);
342     EXPECT_EQ(argPointer.accessedUsingStatelessAddressingMode, arg2.as<NEO::ArgDescPointer>().accessedUsingStatelessAddressingMode);
343 }
344 
TEST(ArgDescriptorCopyAssign,GivenImageArgWhenCopyAssignedThenCopiesDataBasedOnArgType)345 TEST(ArgDescriptorCopyAssign, GivenImageArgWhenCopyAssignedThenCopiesDataBasedOnArgType) {
346     NEO::ArgDescriptor arg0;
347     auto &argImage = arg0.as<NEO::ArgDescImage>(true);
348     argImage.bindful = 2;
349     argImage.bindless = 3;
350 
351     argImage.metadataPayload.imgWidth = 5;
352     argImage.metadataPayload.imgHeight = 7;
353     argImage.metadataPayload.imgDepth = 11;
354     argImage.metadataPayload.channelDataType = 13;
355     argImage.metadataPayload.channelOrder = 17;
356 
357     argImage.metadataPayload.arraySize = 19;
358     argImage.metadataPayload.numSamples = 23;
359     argImage.metadataPayload.numMipLevels = 29;
360 
361     argImage.metadataPayload.flatBaseOffset = 31;
362     argImage.metadataPayload.flatWidth = 37;
363     argImage.metadataPayload.flatHeight = 41;
364     argImage.metadataPayload.flatPitch = 43;
365 
366     NEO::ArgDescriptor arg2;
367     arg2 = arg0;
368     EXPECT_EQ(argImage.metadataPayload.imgWidth, arg2.as<NEO::ArgDescImage>().metadataPayload.imgWidth);
369     EXPECT_EQ(argImage.metadataPayload.imgHeight, arg2.as<NEO::ArgDescImage>().metadataPayload.imgHeight);
370     EXPECT_EQ(argImage.metadataPayload.imgDepth, arg2.as<NEO::ArgDescImage>().metadataPayload.imgDepth);
371     EXPECT_EQ(argImage.metadataPayload.channelDataType, arg2.as<NEO::ArgDescImage>().metadataPayload.channelDataType);
372     EXPECT_EQ(argImage.metadataPayload.channelOrder, arg2.as<NEO::ArgDescImage>().metadataPayload.channelOrder);
373     EXPECT_EQ(argImage.metadataPayload.arraySize, arg2.as<NEO::ArgDescImage>().metadataPayload.arraySize);
374     EXPECT_EQ(argImage.metadataPayload.numSamples, arg2.as<NEO::ArgDescImage>().metadataPayload.numSamples);
375     EXPECT_EQ(argImage.metadataPayload.numMipLevels, arg2.as<NEO::ArgDescImage>().metadataPayload.numMipLevels);
376     EXPECT_EQ(argImage.metadataPayload.flatBaseOffset, arg2.as<NEO::ArgDescImage>().metadataPayload.flatBaseOffset);
377     EXPECT_EQ(argImage.metadataPayload.flatWidth, arg2.as<NEO::ArgDescImage>().metadataPayload.flatWidth);
378     EXPECT_EQ(argImage.metadataPayload.flatHeight, arg2.as<NEO::ArgDescImage>().metadataPayload.flatHeight);
379     EXPECT_EQ(argImage.metadataPayload.flatPitch, arg2.as<NEO::ArgDescImage>().metadataPayload.flatPitch);
380 }
381 
TEST(ArgDescriptorCopyAssign,GivenSamplerArgWhenCopyAssignedThenCopiesDataBasedOnArgType)382 TEST(ArgDescriptorCopyAssign, GivenSamplerArgWhenCopyAssignedThenCopiesDataBasedOnArgType) {
383     NEO::ArgDescriptor arg0;
384     auto &argSampler = arg0.as<NEO::ArgDescSampler>(true);
385     argSampler.samplerType = 2;
386     argSampler.bindful = 3;
387     argSampler.bindless = 5;
388     argSampler.metadataPayload.samplerSnapWa = 7;
389     argSampler.metadataPayload.samplerAddressingMode = 11;
390     argSampler.metadataPayload.samplerNormalizedCoords = 13;
391 
392     NEO::ArgDescriptor arg2;
393     arg2 = arg0;
394     EXPECT_EQ(argSampler.samplerType, arg2.as<NEO::ArgDescSampler>().samplerType);
395     EXPECT_EQ(argSampler.bindful, arg2.as<NEO::ArgDescSampler>().bindful);
396     EXPECT_EQ(argSampler.bindless, arg2.as<NEO::ArgDescSampler>().bindless);
397     EXPECT_EQ(argSampler.metadataPayload.samplerSnapWa, arg2.as<NEO::ArgDescSampler>().metadataPayload.samplerSnapWa);
398     EXPECT_EQ(argSampler.metadataPayload.samplerAddressingMode, arg2.as<NEO::ArgDescSampler>().metadataPayload.samplerAddressingMode);
399     EXPECT_EQ(argSampler.metadataPayload.samplerNormalizedCoords, arg2.as<NEO::ArgDescSampler>().metadataPayload.samplerNormalizedCoords);
400 }
401 
TEST(ArgDescriptorCopyAssign,GivenValueArgWhenCopyAssignedThenCopiesDataBasedOnArgType)402 TEST(ArgDescriptorCopyAssign, GivenValueArgWhenCopyAssignedThenCopiesDataBasedOnArgType) {
403     NEO::ArgDescValue::Element element0;
404     element0.offset = 2;
405     element0.size = 3;
406     element0.sourceOffset = 5;
407 
408     NEO::ArgDescValue::Element element1;
409     element1.offset = 7;
410     element1.size = 11;
411     element1.sourceOffset = 13;
412 
413     NEO::ArgDescriptor arg0;
414     auto &argValue = arg0.as<NEO::ArgDescValue>(true);
415     argValue.elements.push_back(element0);
416     argValue.elements.push_back(element1);
417 
418     NEO::ArgDescriptor arg2;
419     arg2 = arg0;
420     ASSERT_EQ(argValue.elements.size(), arg2.as<NEO::ArgDescValue>().elements.size());
421     for (size_t i = 0; i < argValue.elements.size(); ++i) {
422         EXPECT_EQ(argValue.elements[i].offset, arg2.as<NEO::ArgDescValue>().elements[i].offset) << i;
423         EXPECT_EQ(argValue.elements[i].offset, arg2.as<NEO::ArgDescValue>().elements[i].offset) << i;
424         EXPECT_EQ(argValue.elements[i].offset, arg2.as<NEO::ArgDescValue>().elements[i].offset) << i;
425     }
426 }
427 
TEST(SetOffsetsVec,GivenArrayOfCrossThreadDataThenCopiesProperAmountOfElements)428 TEST(SetOffsetsVec, GivenArrayOfCrossThreadDataThenCopiesProperAmountOfElements) {
429     NEO::CrossThreadDataOffset src[3] = {2, 3, 5};
430     NEO::CrossThreadDataOffset dst[3] = {7, 11, 13};
431     NEO::setOffsetsVec(dst, src);
432     EXPECT_EQ(dst[0], src[0]);
433     EXPECT_EQ(dst[1], src[1]);
434     EXPECT_EQ(dst[2], src[2]);
435 }
436 
TEST(PatchNonPointer,GivenUndefinedOffsetThenReturnsFalse)437 TEST(PatchNonPointer, GivenUndefinedOffsetThenReturnsFalse) {
438     uint8_t buffer[64];
439     uint32_t value = 7;
440     EXPECT_FALSE(NEO::patchNonPointer(buffer, NEO::undefined<NEO::CrossThreadDataOffset>, value));
441 }
442 
TEST(PatchNonPointer,GivenOutOfBoundsOffsetThenAbort)443 TEST(PatchNonPointer, GivenOutOfBoundsOffsetThenAbort) {
444     uint8_t buffer[64];
445     uint32_t value = 7;
446     EXPECT_THROW(NEO::patchNonPointer(buffer, sizeof(buffer), value), std::exception);
447     EXPECT_THROW(NEO::patchNonPointer(buffer, sizeof(buffer) - sizeof(value) + 1, value), std::exception);
448 }
449 
TEST(PatchNonPointer,GivenValidOffsetThenPatchProperly)450 TEST(PatchNonPointer, GivenValidOffsetThenPatchProperly) {
451     alignas(8) uint8_t buffer[64];
452     memset(buffer, 3, sizeof(buffer));
453     uint32_t value32 = 7;
454     uint64_t value64 = 13;
455     EXPECT_TRUE(NEO::patchNonPointer(buffer, 0, value32));
456     EXPECT_TRUE(NEO::patchNonPointer(buffer, 8, value64));
457     EXPECT_TRUE(NEO::patchNonPointer(buffer, sizeof(buffer) - sizeof(value64), value64));
458 
459     alignas(8) uint8_t expected[64];
460     memset(expected, 3, sizeof(expected));
461     *reinterpret_cast<uint32_t *>(expected) = value32;
462     *reinterpret_cast<uint64_t *>(expected + 8) = value64;
463     *reinterpret_cast<uint64_t *>(expected + sizeof(expected) - sizeof(value64)) = value64;
464     EXPECT_EQ(0, memcmp(expected, buffer, sizeof(buffer)));
465 }
466 
TEST(PatchVecNonPointer,GivenArrayOfOffsetsThenReturnsNumberOfValuesProperlyPatched)467 TEST(PatchVecNonPointer, GivenArrayOfOffsetsThenReturnsNumberOfValuesProperlyPatched) {
468     alignas(8) uint8_t buffer[64];
469     memset(buffer, 3, sizeof(buffer));
470     NEO::CrossThreadDataOffset offsets[] = {0, 4, sizeof(buffer) - sizeof(uint32_t), NEO::undefined<NEO::CrossThreadDataOffset>};
471     uint32_t values[] = {7, 11, 13, 17};
472     auto numPatched = NEO::patchVecNonPointer(buffer, offsets, values);
473     EXPECT_EQ(3U, numPatched);
474     alignas(8) uint8_t expected[64];
475     memset(expected, 3, sizeof(expected));
476     *reinterpret_cast<uint32_t *>(expected) = 7;
477     *reinterpret_cast<uint32_t *>(expected + 4) = 11;
478     *reinterpret_cast<uint32_t *>(expected + sizeof(expected) - sizeof(uint32_t)) = 13;
479     EXPECT_EQ(0, memcmp(expected, buffer, sizeof(buffer)));
480 }
481 
TEST(PatchPointer,GivenUnhandledPointerSizeThenAborts)482 TEST(PatchPointer, GivenUnhandledPointerSizeThenAborts) {
483     alignas(8) uint8_t buffer[64];
484     memset(buffer, 3, sizeof(buffer));
485     NEO::ArgDescPointer ptrArg;
486     uintptr_t ptrValue = reinterpret_cast<uintptr_t>(&ptrArg);
487     ptrArg.pointerSize = 5;
488     ptrArg.stateless = 0U;
489     EXPECT_THROW(patchPointer(buffer, ptrArg, ptrValue), std::exception);
490 }
491 
TEST(PatchPointer,GivenUnhandledPointerSizeWhenStatelessOffsetIsUndefinedThenIgnoresPointerSize)492 TEST(PatchPointer, GivenUnhandledPointerSizeWhenStatelessOffsetIsUndefinedThenIgnoresPointerSize) {
493     alignas(8) uint8_t buffer[64];
494     memset(buffer, 3, sizeof(buffer));
495     NEO::ArgDescPointer ptrArg;
496     uintptr_t ptrValue = reinterpret_cast<uintptr_t>(&ptrArg);
497     ptrArg.pointerSize = 5;
498     ptrArg.stateless = NEO::undefined<NEO::CrossThreadDataOffset>;
499     EXPECT_NO_THROW(patchPointer(buffer, ptrArg, ptrValue));
500 }
501 
TEST(PatchPointer,Given32bitPointerSizeThenPatchesOnly32bits)502 TEST(PatchPointer, Given32bitPointerSizeThenPatchesOnly32bits) {
503     alignas(8) uint8_t buffer[64];
504     memset(buffer, 3, sizeof(buffer));
505     NEO::ArgDescPointer ptrArg;
506     uintptr_t ptrValue = reinterpret_cast<uintptr_t>(&ptrArg);
507     ptrArg.stateless = 0U;
508     ptrArg.pointerSize = 4;
509     EXPECT_TRUE(patchPointer(buffer, ptrArg, ptrValue));
510     alignas(8) uint8_t expected[64];
511     memset(expected, 3, sizeof(expected));
512     *reinterpret_cast<uint32_t *>(expected) = static_cast<uint32_t>(ptrValue);
513 }
514 
TEST(PatchPointer,Given64bitPointerSizeThenPatchesAll64bits)515 TEST(PatchPointer, Given64bitPointerSizeThenPatchesAll64bits) {
516     alignas(8) uint8_t buffer[64];
517     memset(buffer, 3, sizeof(buffer));
518     NEO::ArgDescPointer ptrArg;
519     uintptr_t ptrValue = reinterpret_cast<uintptr_t>(&ptrArg);
520     ptrArg.stateless = 0U;
521     ptrArg.pointerSize = 8;
522     EXPECT_TRUE(patchPointer(buffer, ptrArg, ptrValue));
523     alignas(8) uint8_t expected[64];
524     memset(expected, 3, sizeof(expected));
525     *reinterpret_cast<uint64_t *>(expected) = static_cast<uint64_t>(ptrValue);
526 }