1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2016 The Khronos Group Inc.
6 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 *
20 *//*!
21 * \file
22 * \brief Vulkan Image Clearing Tests
23 *//*--------------------------------------------------------------------*/
24
25 #include "vktApiImageClearingTests.hpp"
26
27 #include "deRandom.hpp"
28 #include "deMath.h"
29 #include "deSTLUtil.hpp"
30 #include "deStringUtil.hpp"
31 #include "deUniquePtr.hpp"
32 #include "deArrayUtil.hpp"
33 #include "deInt32.h"
34 #include "vkImageUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vktTestCase.hpp"
37 #include "vktTestCaseUtil.hpp"
38 #include "vktTestGroupUtil.hpp"
39 #include "vkQueryUtil.hpp"
40 #include "vkRefUtil.hpp"
41 #include "vkTypeUtil.hpp"
42 #include "vkCmdUtil.hpp"
43 #include "tcuImageCompare.hpp"
44 #include "tcuTexture.hpp"
45 #include "tcuTextureUtil.hpp"
46 #include "tcuVectorType.hpp"
47 #include "tcuTexture.hpp"
48 #include "tcuFloat.hpp"
49 #include "tcuTestLog.hpp"
50 #include "tcuVectorUtil.hpp"
51 #include <sstream>
52 #include <numeric>
53
54 namespace vkt
55 {
56
57 namespace api
58 {
59
60 using namespace vk;
61 using namespace tcu;
62
63 namespace
64 {
65
66 enum AllocationKind
67 {
68 ALLOCATION_KIND_SUBALLOCATED = 0,
69 ALLOCATION_KIND_DEDICATED,
70
71 ALLOCATION_KIND_LAST,
72 };
73
74 union Threshold
75 {
76 Vec4 vec4;
77 IVec4 ivec4;
78 UVec4 uvec4;
79 };
80
is64Format(const tcu::TextureFormat tcuFormat)81 bool is64Format(const tcu::TextureFormat tcuFormat)
82 {
83 const auto bitDepths = getTextureFormatBitDepth(tcuFormat);
84 const bool is64Bit = tcu::boolAny(tcu::equal(bitDepths, tcu::IVec4(64, 64, 64, 64)));
85
86 return is64Bit;
87 }
88
allocateBuffer(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkBuffer & buffer,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)89 de::MovePtr<Allocation> allocateBuffer(const InstanceInterface &vki, const DeviceInterface &vkd,
90 const VkPhysicalDevice &physDevice, const VkDevice device,
91 const VkBuffer &buffer, const MemoryRequirement requirement,
92 Allocator &allocator, AllocationKind allocationKind)
93 {
94 switch (allocationKind)
95 {
96 case ALLOCATION_KIND_SUBALLOCATED:
97 {
98 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
99
100 return allocator.allocate(memoryRequirements, requirement);
101 }
102
103 case ALLOCATION_KIND_DEDICATED:
104 {
105 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
106 }
107
108 default:
109 {
110 TCU_THROW(InternalError, "Invalid allocation kind");
111 }
112 }
113 }
114
allocateImage(const InstanceInterface & vki,const DeviceInterface & vkd,const VkPhysicalDevice & physDevice,const VkDevice device,const VkImage & image,const MemoryRequirement requirement,Allocator & allocator,AllocationKind allocationKind)115 de::MovePtr<Allocation> allocateImage(const InstanceInterface &vki, const DeviceInterface &vkd,
116 const VkPhysicalDevice &physDevice, const VkDevice device, const VkImage &image,
117 const MemoryRequirement requirement, Allocator &allocator,
118 AllocationKind allocationKind)
119 {
120 switch (allocationKind)
121 {
122 case ALLOCATION_KIND_SUBALLOCATED:
123 {
124 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
125
126 return allocator.allocate(memoryRequirements, requirement);
127 }
128
129 case ALLOCATION_KIND_DEDICATED:
130 {
131 return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
132 }
133
134 default:
135 {
136 TCU_THROW(InternalError, "Invalid allocation kind");
137 }
138 }
139 }
140
getMipLevelExtent(VkExtent3D baseExtent,const uint32_t mipLevel)141 VkExtent3D getMipLevelExtent(VkExtent3D baseExtent, const uint32_t mipLevel)
142 {
143 baseExtent.width = std::max(baseExtent.width >> mipLevel, 1u);
144 baseExtent.height = std::max(baseExtent.height >> mipLevel, 1u);
145 baseExtent.depth = std::max(baseExtent.depth >> mipLevel, 1u);
146 return baseExtent;
147 }
148
getNumMipLevels(const VkExtent3D & baseExtent,const uint32_t maxMipLevels)149 uint32_t getNumMipLevels(const VkExtent3D &baseExtent, const uint32_t maxMipLevels)
150 {
151 const uint32_t widestEdge = std::max(std::max(baseExtent.width, baseExtent.height), baseExtent.depth);
152 return std::min(static_cast<uint32_t>(deFloatLog2(static_cast<float>(widestEdge))) + 1u, maxMipLevels);
153 }
154
greatestCommonDivisor(const uint32_t a,const uint32_t b)155 uint32_t greatestCommonDivisor(const uint32_t a, const uint32_t b)
156 {
157 /* Find GCD */
158 uint32_t temp;
159 uint32_t x = a;
160 uint32_t y = b;
161
162 while (x % y != 0)
163 {
164 temp = y;
165 y = x % y;
166 x = temp;
167 }
168 return y;
169 }
170
lowestCommonMultiple(const uint32_t a,const uint32_t b)171 uint32_t lowestCommonMultiple(const uint32_t a, const uint32_t b)
172 {
173 return (a * b) / greatestCommonDivisor(a, b);
174 }
175
getImageMipLevelSizes(const uint32_t pixelSize,const VkExtent3D & baseExtent,const uint32_t numMipLevels,const uint32_t perLevelAlignment=1u)176 std::vector<uint32_t> getImageMipLevelSizes(const uint32_t pixelSize, const VkExtent3D &baseExtent,
177 const uint32_t numMipLevels, const uint32_t perLevelAlignment = 1u)
178 {
179 std::vector<uint32_t> results(numMipLevels);
180
181 for (uint32_t mipLevel = 0; mipLevel < numMipLevels; ++mipLevel)
182 {
183 const VkExtent3D extent = getMipLevelExtent(baseExtent, mipLevel);
184 results[mipLevel] = static_cast<uint32_t>(extent.width * extent.height * extent.depth * pixelSize);
185 results[mipLevel] = ((results[mipLevel] + perLevelAlignment - 1) / perLevelAlignment) * perLevelAlignment;
186 }
187
188 return results;
189 }
190
191 struct LayerRange
192 {
193 uint32_t baseArrayLayer;
194 uint32_t layerCount;
195 };
196
isInClearRange(const UVec4 & clearCoords,const uint32_t x,const uint32_t y,uint32_t arrayLayer=0,tcu::Maybe<LayerRange> imageViewLayerRange=tcu::Maybe<LayerRange> (),tcu::Maybe<LayerRange> attachmentClearLayerRange=tcu::Maybe<LayerRange> ())197 inline bool isInClearRange(const UVec4 &clearCoords, const uint32_t x, const uint32_t y, uint32_t arrayLayer = 0,
198 tcu::Maybe<LayerRange> imageViewLayerRange = tcu::Maybe<LayerRange>(),
199 tcu::Maybe<LayerRange> attachmentClearLayerRange = tcu::Maybe<LayerRange>())
200 {
201 if (attachmentClearLayerRange)
202 {
203 // Only layers in range passed to clear command are cleared
204
205 const uint32_t clearBaseLayer =
206 (imageViewLayerRange ? imageViewLayerRange->baseArrayLayer : 0) + attachmentClearLayerRange->baseArrayLayer;
207 const uint32_t clearLayerCount = (attachmentClearLayerRange->layerCount == VK_REMAINING_ARRAY_LAYERS) ?
208 imageViewLayerRange->layerCount :
209 clearBaseLayer + attachmentClearLayerRange->layerCount;
210
211 if ((arrayLayer < clearBaseLayer) || (arrayLayer >= (clearLayerCount)))
212 {
213 return false;
214 }
215 }
216
217 if (clearCoords == UVec4())
218 {
219 return true;
220 }
221
222 //! Check if a point lies in a cross-like area.
223 return !((x < clearCoords[0] && y < clearCoords[1]) || (x < clearCoords[0] && y >= clearCoords[3]) ||
224 (x >= clearCoords[2] && y < clearCoords[1]) || (x >= clearCoords[2] && y >= clearCoords[3]));
225 }
226
isInInitialClearRange(uint32_t mipLevel,uint32_t arrayLayer,LayerRange imageViewLayerRange)227 inline bool isInInitialClearRange(uint32_t mipLevel, uint32_t arrayLayer, LayerRange imageViewLayerRange)
228 {
229 if (mipLevel > 0)
230 {
231 // intial clear is done using FB bound to level 0 only
232 return false;
233 }
234
235 // Only layers in range bound to framebuffer are cleared to initial color
236 if ((arrayLayer < imageViewLayerRange.baseArrayLayer) ||
237 (arrayLayer >= (imageViewLayerRange.baseArrayLayer + imageViewLayerRange.layerCount)))
238 {
239 return false;
240 }
241
242 return true;
243 }
244
245 // This method is copied from the vktRenderPassTests.cpp. It should be moved to a common place.
calcFloatDiff(float a,float b)246 int calcFloatDiff(float a, float b)
247 {
248 const int asign = Float32(a).sign();
249 const int bsign = Float32(b).sign();
250
251 const uint32_t avalue = (Float32(a).bits() & ((0x1u << 31u) - 1u));
252 const uint32_t bvalue = (Float32(b).bits() & ((0x1u << 31u) - 1u));
253
254 if (asign != bsign)
255 return avalue + bvalue + 1u;
256 else if (avalue < bvalue)
257 return bvalue - avalue;
258 else
259 return avalue - bvalue;
260 }
261
262 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter.
comparePixelToDepthClearValue(const ConstPixelBufferAccess & access,int x,int y,int z,float ref,std::string & stringResult)263 bool comparePixelToDepthClearValue(const ConstPixelBufferAccess &access, int x, int y, int z, float ref,
264 std::string &stringResult)
265 {
266 const TextureFormat format = getEffectiveDepthStencilTextureFormat(access.getFormat(), Sampler::MODE_DEPTH);
267 const TextureChannelClass channelClass = getTextureChannelClass(format.type);
268
269 switch (channelClass)
270 {
271 case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
272 case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
273 {
274 const int bitDepth = getTextureFormatBitDepth(format).x();
275 const float depth = access.getPixDepth(x, y, z);
276 const float threshold = 2.0f / (float)((1 << bitDepth) - 1);
277 const bool result = deFloatAbs(depth - ref) <= threshold;
278
279 if (!result)
280 {
281 std::stringstream s;
282 s << "Ref:" << ref << " Threshold:" << threshold << " Depth:" << depth;
283 stringResult = s.str();
284 }
285
286 return result;
287 }
288
289 case TEXTURECHANNELCLASS_FLOATING_POINT:
290 {
291 const float depth = access.getPixDepth(x, y, z);
292 const int mantissaBits = getTextureFormatMantissaBitDepth(format).x();
293 const int threshold = (10 * 1) << (23 - mantissaBits);
294
295 DE_ASSERT(mantissaBits <= 23);
296
297 const bool result = calcFloatDiff(depth, ref) <= threshold;
298
299 if (!result)
300 {
301 float floatThreshold = Float32((uint32_t)threshold).asFloat();
302 std::stringstream s;
303
304 s << "Ref:" << ref << " Threshold:" << floatThreshold << " Depth:" << depth;
305 stringResult = s.str();
306 }
307
308 return result;
309 }
310
311 default:
312 DE_FATAL("Invalid channel class");
313 return false;
314 }
315 }
316
317 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter.
comparePixelToStencilClearValue(const ConstPixelBufferAccess & access,int x,int y,int z,uint32_t ref,std::string & stringResult)318 bool comparePixelToStencilClearValue(const ConstPixelBufferAccess &access, int x, int y, int z, uint32_t ref,
319 std::string &stringResult)
320 {
321 const uint32_t stencil = access.getPixStencil(x, y, z);
322 const bool result = stencil == ref;
323
324 if (!result)
325 {
326 std::stringstream s;
327 s << "Ref:" << ref << " Threshold:0"
328 << " Stencil:" << stencil;
329 stringResult = s.str();
330 }
331
332 return result;
333 }
334
335 // This method is copied from the vktRenderPassTests.cpp and extended with the stringResult parameter.
comparePixelToColorClearValue(const ConstPixelBufferAccess & access,int x,int y,int z,const VkClearColorValue & ref,std::string & stringResult,const Threshold & threshold,const BVec4 & channelMask,const TextureChannelClass & channelClass)336 bool comparePixelToColorClearValue(const ConstPixelBufferAccess &access, int x, int y, int z,
337 const VkClearColorValue &ref, std::string &stringResult, const Threshold &threshold,
338 const BVec4 &channelMask, const TextureChannelClass &channelClass)
339 {
340 const bool is64Bit = is64Format(access.getFormat());
341
342 switch (channelClass)
343 {
344 case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
345 case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
346 {
347 DE_ASSERT(!is64Bit); // There are no 64-bit fixed point formats.
348
349 const Vec4 resColor(access.getPixel(x, y, z));
350 Vec4 refColor(ref.float32[0], ref.float32[1], ref.float32[2], ref.float32[3]);
351
352 if (isSRGB(access.getFormat()))
353 refColor = linearToSRGB(refColor);
354
355 const bool result = !(anyNotEqual(
356 logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold.vec4), channelMask), channelMask));
357
358 if (!result)
359 {
360 std::stringstream s;
361 s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold.vec4
362 << " Color:" << resColor;
363 stringResult = s.str();
364 }
365
366 return result;
367 }
368
369 case TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
370 {
371 uint64_t packed[2]{0ull, 0ull};
372
373 deMemcpy(packed + 0, ref.uint32 + 0, sizeof(uint64_t));
374 deMemcpy(packed + 1, ref.uint32 + 2, sizeof(uint64_t));
375
376 const U64Vec4 resColor(access.getPixelUint64(x, y, z));
377 const U64Vec4 refColor((is64Bit ? packed[0] : static_cast<uint64_t>(ref.uint32[0])),
378 (is64Bit ? packed[1] : static_cast<uint64_t>(ref.uint32[1])),
379 static_cast<uint64_t>(is64Bit ? 0u : ref.uint32[2]),
380 static_cast<uint64_t>(is64Bit ? 0u : ref.uint32[3]));
381 const U64Vec4 threshold64(threshold.uvec4[0], threshold.uvec4[1], threshold.uvec4[2], threshold.uvec4[3]);
382 const bool result = !(
383 anyNotEqual(logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold64), channelMask), channelMask));
384
385 if (!result)
386 {
387 std::stringstream s;
388 s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold64 << " Color:" << resColor;
389 stringResult = s.str();
390 }
391
392 return result;
393 }
394
395 case TEXTURECHANNELCLASS_SIGNED_INTEGER:
396 {
397 int64_t packed[2]{0ll, 0ll};
398
399 deMemcpy(packed + 0, ref.int32 + 0, sizeof(int64_t));
400 deMemcpy(packed + 1, ref.int32 + 2, sizeof(int64_t));
401
402 const I64Vec4 resColor(access.getPixelInt64(x, y, z));
403 const I64Vec4 refColor((is64Bit ? packed[0] : static_cast<int64_t>(ref.int32[0])),
404 (is64Bit ? packed[1] : static_cast<int64_t>(ref.int32[1])),
405 static_cast<int64_t>(is64Bit ? 0 : ref.int32[2]),
406 static_cast<int64_t>(is64Bit ? 0 : ref.int32[3]));
407 const I64Vec4 threshold64(threshold.ivec4[0], threshold.ivec4[1], threshold.ivec4[2], threshold.ivec4[3]);
408 const bool result = !(
409 anyNotEqual(logicalAnd(lessThanEqual(absDiff(resColor, refColor), threshold64), channelMask), channelMask));
410
411 if (!result)
412 {
413 std::stringstream s;
414 s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << threshold64 << " Color:" << resColor;
415 stringResult = s.str();
416 }
417
418 return result;
419 }
420
421 case TEXTURECHANNELCLASS_FLOATING_POINT:
422 {
423 // Not supported so far. The threshold calculation would need to be adjusted, and the framework currently does not
424 // support reading 64-bit floats from pixel buffer accesses (see getPixel below).
425 DE_ASSERT(!is64Bit);
426
427 const Vec4 resColor(access.getPixel(x, y, z));
428 const Vec4 refColor(ref.float32[0], ref.float32[1], ref.float32[2], ref.float32[3]);
429 DE_ASSERT(allEqual(greaterThanEqual(threshold.ivec4, IVec4(0)), BVec4(true)));
430
431 for (int ndx = 0; ndx < 4; ndx++)
432 {
433 const bool result =
434 !(calcFloatDiff(resColor[ndx], refColor[ndx]) > threshold.ivec4[ndx] && channelMask[ndx]);
435
436 if (!result)
437 {
438 float floatThreshold = Float32((uint32_t)(threshold).ivec4[0]).asFloat();
439 Vec4 thresholdVec4(floatThreshold, floatThreshold, floatThreshold, floatThreshold);
440 std::stringstream s;
441 s << "Ref:" << refColor << " Mask:" << channelMask << " Threshold:" << thresholdVec4
442 << " Color:" << resColor;
443 stringResult = s.str();
444
445 return false;
446 }
447 }
448
449 return true;
450 }
451
452 default:
453 DE_FATAL("Invalid channel class");
454 return false;
455 }
456 }
457
extentToString(VkExtent3D extent,VkImageType imageType)458 std::string extentToString(VkExtent3D extent, VkImageType imageType)
459 {
460 // Don't append image dimensions when using the dimensions found in original test cases. This avoids name clashing with the old versions.
461 if (imageType == VK_IMAGE_TYPE_1D && extent.width == 256u)
462 return "";
463 if (imageType == VK_IMAGE_TYPE_2D && extent.width == 256u && extent.height == 256u)
464 return "";
465 if (imageType == VK_IMAGE_TYPE_3D && extent.width == 256u && extent.height == 256u && extent.depth == 16u)
466 return "";
467
468 return (std::string("_") + de::toString(extent.width) + std::string("x") + de::toString(extent.height) +
469 (extent.depth != 1 ? (std::string("x") + de::toString(extent.depth)) : ""));
470 }
471
472 enum SeparateDepthStencilLayoutMode
473 {
474 SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE = 0,
475 SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_DEPTH,
476 SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_STENCIL,
477 };
478
479 struct TestParams
480 {
481 bool useSingleMipLevel; //!< only mip level 0, otherwise up to maxMipLevels
482 VkImageType imageType;
483 VkFormat imageFormat;
484 VkImageTiling imageTiling;
485 VkExtent3D imageExtent;
486 uint32_t imageLayerCount;
487 LayerRange imageViewLayerRange;
488 VkClearValue initValue;
489 VkClearValue clearValue[2]; //!< the second value is used with more than one mip map
490 bool useSeparateExpectedClearValue;
491 VkClearValue expectedClearValue[2];
492 LayerRange clearLayerRange;
493 AllocationKind allocationKind;
494 bool isCube;
495 SeparateDepthStencilLayoutMode separateDepthStencilLayoutMode;
496 bool isColorMultipleSubresourceRangeTest;
497 VkSampleCountFlagBits imageSampleCount;
498 };
499
500 template <typename T>
501 class ImageClearingTestCase : public vkt::TestCase
502 {
503 public:
ImageClearingTestCase(tcu::TestContext & testCtx,const std::string & name,TestParams params)504 ImageClearingTestCase(tcu::TestContext &testCtx, const std::string &name, TestParams params)
505 : vkt::TestCase(testCtx, name)
506 , m_params(params)
507 {
508 }
509
createInstance(Context & context) const510 TestInstance *createInstance(Context &context) const override
511 {
512 return new T(context, m_params);
513 }
514
checkSupport(Context & context) const515 void checkSupport(Context &context) const override
516 {
517 #ifndef CTS_USES_VULKANSC
518 if (m_params.imageFormat == VK_FORMAT_A8_UNORM_KHR ||
519 m_params.imageFormat == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)
520 context.requireDeviceFunctionality("VK_KHR_maintenance5");
521 #endif // CTS_USES_VULKANSC
522
523 if (m_params.allocationKind == ALLOCATION_KIND_DEDICATED)
524 context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");
525
526 if (m_params.separateDepthStencilLayoutMode != SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE)
527 context.requireDeviceFunctionality("VK_KHR_separate_depth_stencil_layouts");
528 }
529
530 private:
531 TestParams m_params;
532 };
533
534 class ImageClearingTestInstance : public vkt::TestInstance
535 {
536 public:
537 ImageClearingTestInstance(Context &context, const TestParams &testParams);
538
539 Move<VkCommandPool> createCommandPool(VkCommandPoolCreateFlags commandPoolCreateFlags) const;
540 Move<VkCommandBuffer> allocatePrimaryCommandBuffer(VkCommandPool commandPool) const;
541 Move<VkImage> createImage(VkImageType imageType, VkFormat format, VkImageTiling tiling, VkExtent3D extent,
542 uint32_t arrayLayerCount, VkImageUsageFlags usage,
543 VkSampleCountFlagBits sampleCount = VK_SAMPLE_COUNT_1_BIT) const;
544 Move<VkImageView> createImageView(VkImage image, VkImageViewType viewType, VkFormat format,
545 VkImageAspectFlags aspectMask, LayerRange layerRange) const;
546 Move<VkRenderPass> createRenderPass(VkFormat format, VkSampleCountFlagBits sampleCount) const;
547 Move<VkFramebuffer> createFrameBuffer(VkImageView imageView, VkRenderPass renderPass, uint32_t imageWidth,
548 uint32_t imageHeight, uint32_t imageLayersCount,
549 VkSampleCountFlagBits sampleCount) const;
550 void beginCommandBuffer(VkCommandBufferUsageFlags usageFlags) const;
551 void endCommandBuffer(void) const;
552 void submitCommandBuffer(void) const;
553 void beginRenderPass(VkSubpassContents content, VkClearValue clearValue) const;
554 void preClearImage(const uint32_t imageMipLevels, VkExtent3D imageExtent, uint32_t imageLayerCount,
555 Unique<VkCommandBuffer> &commandBuffer) const;
556 Move<VkBuffer> createImageClearingBuffer(const DeviceInterface &vkd, const VkDevice device);
557
558 void pipelineImageBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
559 VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout,
560 VkImageLayout newLayout, VkImageAspectFlags aspectMask = 0u) const;
561 void pipelineMultisampleImageBarrier(VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
562 VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask,
563 VkImageLayout oldLayout, VkImageLayout newLayout,
564 VkImageAspectFlags aspectMask = 0u) const;
565
566 de::MovePtr<TextureLevelPyramid> readImage(VkImageAspectFlags aspectMask, uint32_t baseLayer) const;
567 tcu::TestStatus verifyResultImage(const std::string &successMessage, const UVec4 &clearCoords = UVec4()) const;
568
569 protected:
570 enum ViewType
571 {
572 VIEW_TYPE_SINGLE,
573 VIEW_TYPE_ARRAY,
574 VIEW_TYPE_CUBE
575 };
576 VkImageViewType getCorrespondingImageViewType(VkImageType imageType, ViewType viewType) const;
577 VkImageUsageFlags getImageUsageFlags(VkFormat format) const;
578 VkImageAspectFlags getImageAspectFlags(VkFormat format) const;
579 bool getIsAttachmentFormat(VkFormat format, VkImageTiling tiling) const;
580 bool getIs3DFormat(VkFormat format, VkImageType type, VkImageTiling tiling, VkImageUsageFlags usage,
581 VkImageCreateFlags flags) const;
582 bool getIsStencilFormat(VkFormat format) const;
583 bool getIsDepthFormat(VkFormat format) const;
584 VkImageFormatProperties getImageFormatProperties(void) const;
585 VkImageCreateFlags getImageCreateFlags(void) const;
586 ViewType getViewType(uint32_t imageLayerCount) const;
587 de::MovePtr<Allocation> allocateAndBindImageMemory(VkImage image) const;
588 de::MovePtr<Allocation> allocateAndBindBufferMemory(VkBuffer buffer) const;
589 void pipelineImageBarrierGen(VkImage image, VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask,
590 VkAccessFlags srcAccessMask, VkAccessFlags dstAccessMask, VkImageLayout oldLayout,
591 VkImageLayout newLayout, VkImageAspectFlags aspectMask = 0u) const;
592
593 const TestParams &m_params;
594 const VkDevice m_device;
595 const InstanceInterface &m_vki;
596 const DeviceInterface &m_vkd;
597 const VkQueue m_queue;
598 const uint32_t m_queueFamilyIndex;
599 Allocator &m_allocator;
600
601 const bool m_isAttachmentFormat;
602 const VkImageUsageFlags m_imageUsageFlags;
603 const VkImageAspectFlags m_imageAspectFlags;
604 const VkImageFormatProperties m_imageFormatProperties;
605 const uint32_t m_imageMipLevels;
606 const uint32_t m_thresholdMipLevel;
607
608 Unique<VkCommandPool> m_commandPool;
609 Unique<VkCommandBuffer> m_commandBuffer;
610
611 const bool m_is3DFormat;
612 Unique<VkImage> m_image;
613 Move<VkBuffer> m_stagingBuffer;
614 de::MovePtr<Allocation> m_stagingBufferMemory;
615 de::MovePtr<Allocation> m_imageMemory;
616 Unique<VkImageView> m_imageView;
617 Unique<VkImage> m_multisampleImage;
618 de::MovePtr<Allocation> m_multisampleImageMemory;
619 Unique<VkImageView> m_multisampleImageView;
620 Move<VkRenderPass> m_renderPass;
621 Move<VkFramebuffer> m_frameBuffer;
622 };
623
ImageClearingTestInstance(Context & context,const TestParams & params)624 ImageClearingTestInstance::ImageClearingTestInstance(Context &context, const TestParams ¶ms)
625 : TestInstance(context)
626 , m_params(params)
627 , m_device(context.getDevice())
628 , m_vki(context.getInstanceInterface())
629 , m_vkd(context.getDeviceInterface())
630 , m_queue(context.getUniversalQueue())
631 , m_queueFamilyIndex(context.getUniversalQueueFamilyIndex())
632 , m_allocator(context.getDefaultAllocator())
633 , m_isAttachmentFormat(getIsAttachmentFormat(params.imageFormat, params.imageTiling))
634 , m_imageUsageFlags(getImageUsageFlags(params.imageFormat))
635 , m_imageAspectFlags(getImageAspectFlags(params.imageFormat))
636 , m_imageFormatProperties(getImageFormatProperties())
637 , m_imageMipLevels(
638 params.useSingleMipLevel ? 1u : getNumMipLevels(params.imageExtent, m_imageFormatProperties.maxMipLevels))
639 , m_thresholdMipLevel(std::max(m_imageMipLevels / 2u, 1u))
640 , m_commandPool(createCommandPool(VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT))
641 , m_commandBuffer(allocatePrimaryCommandBuffer(*m_commandPool))
642 , m_is3DFormat(getIs3DFormat(params.imageFormat, params.imageType, params.imageTiling,
643 getImageUsageFlags(params.imageFormat), 0u))
644
645 , m_image(createImage(params.imageType, params.imageFormat, params.imageTiling, params.imageExtent,
646 params.imageLayerCount, m_imageUsageFlags, VK_SAMPLE_COUNT_1_BIT))
647
648 , m_stagingBuffer(createImageClearingBuffer(m_vkd, m_device))
649 , m_stagingBufferMemory(allocateAndBindBufferMemory(*m_stagingBuffer))
650
651 , m_imageMemory(allocateAndBindImageMemory(*m_image))
652 , m_imageView(
653 m_isAttachmentFormat ?
654 createImageView(*m_image,
655 getCorrespondingImageViewType(params.imageType, getViewType(params.imageLayerCount)),
656 params.imageFormat, m_imageAspectFlags, params.imageViewLayerRange) :
657 vk::Move<VkImageView>())
658 , m_multisampleImage((params.imageSampleCount > VK_SAMPLE_COUNT_1_BIT) ?
659 createImage(params.imageType, params.imageFormat, params.imageTiling, params.imageExtent,
660 params.imageLayerCount, m_imageUsageFlags, params.imageSampleCount) :
661 vk::Move<VkImage>())
662 , m_multisampleImageMemory((params.imageSampleCount > VK_SAMPLE_COUNT_1_BIT) ?
663 allocateAndBindImageMemory(*m_multisampleImage) :
664 de::MovePtr<Allocation>())
665 , m_multisampleImageView(
666 (m_isAttachmentFormat && (params.imageSampleCount > VK_SAMPLE_COUNT_1_BIT)) ?
667 createImageView(*m_multisampleImage,
668 getCorrespondingImageViewType(params.imageType, getViewType(params.imageLayerCount)),
669 params.imageFormat, m_imageAspectFlags, params.imageViewLayerRange) :
670 vk::Move<VkImageView>())
671
672 {
673 if (!m_is3DFormat)
674 {
675 if (m_isAttachmentFormat)
676 {
677 m_renderPass = createRenderPass(params.imageFormat, params.imageSampleCount);
678
679 m_frameBuffer =
680 createFrameBuffer(*m_imageView, *m_renderPass, params.imageExtent.width, params.imageExtent.height,
681 params.imageViewLayerRange.layerCount, m_params.imageSampleCount);
682 }
683 }
684 }
685
getViewType(uint32_t imageLayerCount) const686 ImageClearingTestInstance::ViewType ImageClearingTestInstance::getViewType(uint32_t imageLayerCount) const
687 {
688 if (imageLayerCount > 1u)
689 return m_params.isCube ? VIEW_TYPE_CUBE : VIEW_TYPE_ARRAY;
690 else
691 return VIEW_TYPE_SINGLE;
692 }
693
getCorrespondingImageViewType(VkImageType imageType,ViewType viewType) const694 VkImageViewType ImageClearingTestInstance::getCorrespondingImageViewType(VkImageType imageType, ViewType viewType) const
695 {
696 switch (imageType)
697 {
698 case VK_IMAGE_TYPE_1D:
699 return (viewType == VIEW_TYPE_ARRAY) ? VK_IMAGE_VIEW_TYPE_1D_ARRAY : VK_IMAGE_VIEW_TYPE_1D;
700 case VK_IMAGE_TYPE_2D:
701 if (viewType == VIEW_TYPE_ARRAY)
702 return VK_IMAGE_VIEW_TYPE_2D_ARRAY;
703 else if (viewType == VIEW_TYPE_CUBE)
704 return VK_IMAGE_VIEW_TYPE_CUBE;
705 else
706 return VK_IMAGE_VIEW_TYPE_2D;
707 case VK_IMAGE_TYPE_3D:
708 if (viewType != VIEW_TYPE_SINGLE)
709 {
710 DE_FATAL("Cannot have 3D image array");
711 }
712 return VK_IMAGE_VIEW_TYPE_3D;
713 default:
714 DE_FATAL("Unknown image type!");
715 }
716
717 return VK_IMAGE_VIEW_TYPE_2D;
718 }
719
getImageUsageFlags(VkFormat format) const720 VkImageUsageFlags ImageClearingTestInstance::getImageUsageFlags(VkFormat format) const
721 {
722 VkImageUsageFlags commonFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
723
724 if (m_isAttachmentFormat)
725 {
726 if (isDepthStencilFormat(format))
727 return commonFlags | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
728
729 return commonFlags | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
730 }
731 return commonFlags;
732 }
733
getImageAspectFlags(VkFormat format) const734 VkImageAspectFlags ImageClearingTestInstance::getImageAspectFlags(VkFormat format) const
735 {
736 VkImageAspectFlags imageAspectFlags = 0;
737
738 if (getIsDepthFormat(format))
739 imageAspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
740
741 if (getIsStencilFormat(format))
742 imageAspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
743
744 if (imageAspectFlags == 0)
745 imageAspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
746
747 return imageAspectFlags;
748 }
749
getIs3DFormat(VkFormat format,VkImageType type,VkImageTiling tiling,VkImageUsageFlags usage,VkImageCreateFlags flags) const750 bool ImageClearingTestInstance::getIs3DFormat(VkFormat format, VkImageType type, VkImageTiling tiling,
751 VkImageUsageFlags usage, VkImageCreateFlags flags) const
752 {
753 const VkImageFormatProperties props = vk::getPhysicalDeviceImageFormatProperties(
754 m_vki, m_context.getPhysicalDevice(), format, type, tiling, usage, flags);
755
756 return props.maxExtent.depth > 1u;
757 }
758
getIsAttachmentFormat(VkFormat format,VkImageTiling tiling) const759 bool ImageClearingTestInstance::getIsAttachmentFormat(VkFormat format, VkImageTiling tiling) const
760 {
761 const VkFormatProperties props =
762 vk::getPhysicalDeviceFormatProperties(m_vki, m_context.getPhysicalDevice(), format);
763 const VkFormatFeatureFlags features =
764 tiling == VK_IMAGE_TILING_OPTIMAL ? props.optimalTilingFeatures : props.linearTilingFeatures;
765
766 return (features &
767 (vk::VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT | vk::VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) != 0;
768 }
769
getIsStencilFormat(VkFormat format) const770 bool ImageClearingTestInstance::getIsStencilFormat(VkFormat format) const
771 {
772 const TextureFormat tcuFormat = mapVkFormat(format);
773
774 if (tcuFormat.order == TextureFormat::S || tcuFormat.order == TextureFormat::DS)
775 return true;
776
777 return false;
778 }
779
getIsDepthFormat(VkFormat format) const780 bool ImageClearingTestInstance::getIsDepthFormat(VkFormat format) const
781 {
782 const TextureFormat tcuFormat = mapVkFormat(format);
783
784 if (tcuFormat.order == TextureFormat::D || tcuFormat.order == TextureFormat::DS)
785 return true;
786
787 return false;
788 }
789
getImageCreateFlags(void) const790 VkImageCreateFlags ImageClearingTestInstance::getImageCreateFlags(void) const
791 {
792 return m_params.isCube ? (VkImageCreateFlags)VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (VkImageCreateFlags)0;
793 }
794
getImageFormatProperties(void) const795 VkImageFormatProperties ImageClearingTestInstance::getImageFormatProperties(void) const
796 {
797 VkImageFormatProperties properties;
798 const VkResult result = m_vki.getPhysicalDeviceImageFormatProperties(
799 m_context.getPhysicalDevice(), m_params.imageFormat, m_params.imageType, m_params.imageTiling,
800 m_imageUsageFlags, getImageCreateFlags(), &properties);
801
802 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
803 TCU_THROW(NotSupportedError, "Format not supported");
804 else
805 return properties;
806 }
807
allocateAndBindImageMemory(VkImage image) const808 de::MovePtr<Allocation> ImageClearingTestInstance::allocateAndBindImageMemory(VkImage image) const
809 {
810 de::MovePtr<Allocation> imageMemory(allocateImage(m_vki, m_vkd, m_context.getPhysicalDevice(), m_device, image,
811 MemoryRequirement::Any, m_allocator, m_params.allocationKind));
812 VK_CHECK(m_vkd.bindImageMemory(m_device, image, imageMemory->getMemory(), imageMemory->getOffset()));
813 return imageMemory;
814 }
815
allocateAndBindBufferMemory(VkBuffer buffer) const816 de::MovePtr<Allocation> ImageClearingTestInstance::allocateAndBindBufferMemory(VkBuffer buffer) const
817 {
818 de::MovePtr<Allocation> stagingBufferMemory =
819 allocateBuffer(m_vki, m_vkd, m_context.getPhysicalDevice(), m_device, buffer, MemoryRequirement::HostVisible,
820 m_allocator, m_params.allocationKind);
821 VK_CHECK(
822 m_vkd.bindBufferMemory(m_device, buffer, stagingBufferMemory->getMemory(), stagingBufferMemory->getOffset()));
823 return stagingBufferMemory;
824 }
825
createCommandPool(VkCommandPoolCreateFlags commandPoolCreateFlags) const826 Move<VkCommandPool> ImageClearingTestInstance::createCommandPool(VkCommandPoolCreateFlags commandPoolCreateFlags) const
827 {
828 return vk::createCommandPool(m_vkd, m_device, commandPoolCreateFlags, m_queueFamilyIndex);
829 }
830
allocatePrimaryCommandBuffer(VkCommandPool commandPool) const831 Move<VkCommandBuffer> ImageClearingTestInstance::allocatePrimaryCommandBuffer(VkCommandPool commandPool) const
832 {
833 return vk::allocateCommandBuffer(m_vkd, m_device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
834 }
835
createImage(VkImageType imageType,VkFormat format,VkImageTiling tiling,VkExtent3D extent,uint32_t arrayLayerCount,VkImageUsageFlags usage,VkSampleCountFlagBits sampleCount) const836 Move<VkImage> ImageClearingTestInstance::createImage(VkImageType imageType, VkFormat format, VkImageTiling tiling,
837 VkExtent3D extent, uint32_t arrayLayerCount,
838 VkImageUsageFlags usage, VkSampleCountFlagBits sampleCount) const
839 {
840 if (arrayLayerCount > m_imageFormatProperties.maxArrayLayers)
841 TCU_THROW(NotSupportedError, "Device does not support enough image array layers");
842
843 if ((sampleCount & m_imageFormatProperties.sampleCounts) == 0)
844 TCU_THROW(NotSupportedError, "Device does not support sample count under test");
845
846 const VkImageCreateInfo imageCreateInfo = {
847 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
848 DE_NULL, // const void* pNext;
849 getImageCreateFlags(), // VkImageCreateFlags flags;
850 imageType, // VkImageType imageType;
851 format, // VkFormat format;
852 extent, // VkExtent3D extent;
853 m_imageMipLevels, // uint32_t mipLevels;
854 arrayLayerCount, // uint32_t arrayLayers;
855 sampleCount, // VkSampleCountFlagBits samples;
856 tiling, // VkImageTiling tiling;
857 usage, // VkImageUsageFlags usage;
858 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
859 1u, // uint32_t queueFamilyIndexCount;
860 &m_queueFamilyIndex, // const uint32_t* pQueueFamilyIndices;
861 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
862 };
863
864 return vk::createImage(m_vkd, m_device, &imageCreateInfo, DE_NULL);
865 }
866
createImageView(VkImage image,VkImageViewType viewType,VkFormat format,VkImageAspectFlags aspectMask,LayerRange layerRange) const867 Move<VkImageView> ImageClearingTestInstance::createImageView(VkImage image, VkImageViewType viewType, VkFormat format,
868 VkImageAspectFlags aspectMask, LayerRange layerRange) const
869 {
870 const VkImageViewCreateInfo imageViewCreateInfo = {
871 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
872 DE_NULL, // const void* pNext;
873 0u, // VkImageViewCreateFlags flags;
874 image, // VkImage image;
875 viewType, // VkImageViewType viewType;
876 format, // VkFormat format;
877 {
878 VK_COMPONENT_SWIZZLE_IDENTITY, // VkComponentSwizzle r;
879 VK_COMPONENT_SWIZZLE_IDENTITY, // VkComponentSwizzle g;
880 VK_COMPONENT_SWIZZLE_IDENTITY, // VkComponentSwizzle b;
881 VK_COMPONENT_SWIZZLE_IDENTITY, // VkComponentSwizzle a;
882 }, // VkComponentMapping components;
883 {
884 aspectMask, // VkImageAspectFlags aspectMask;
885 0u, // uint32_t baseMipLevel;
886 1u, // uint32_t mipLevels;
887 layerRange.baseArrayLayer, // uint32_t baseArrayLayer;
888 layerRange.layerCount, // uint32_t arraySize;
889 }, // VkImageSubresourceRange subresourceRange;
890 };
891
892 return vk::createImageView(m_vkd, m_device, &imageViewCreateInfo, DE_NULL);
893 }
894
createRenderPass(VkFormat format,VkSampleCountFlagBits sampleCount) const895 Move<VkRenderPass> ImageClearingTestInstance::createRenderPass(VkFormat format, VkSampleCountFlagBits sampleCount) const
896 {
897 if (m_params.separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE)
898 {
899 VkImageLayout imageLayout;
900
901 if (isDepthStencilFormat(format))
902 imageLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
903 else
904 imageLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
905
906 const VkAttachmentDescription attachmentDesc = {
907 0u, // VkAttachmentDescriptionFlags flags;
908 format, // VkFormat format;
909 sampleCount, // VkSampleCountFlagBits samples;
910 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
911 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
912 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp;
913 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
914 imageLayout, // VkImageLayout initialLayout;
915 imageLayout, // VkImageLayout finalLayout;
916 };
917
918 const VkAttachmentDescription attachmentResolveDesc = {
919 0u, // VkAttachmentDescriptionFlags flags;
920 format, // VkFormat format;
921 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
922 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
923 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
924 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
925 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
926 imageLayout, // VkImageLayout initialLayout;
927 imageLayout, // VkImageLayout finalLayout;
928 };
929
930 const VkAttachmentDescription attachments[2] = {attachmentDesc, attachmentResolveDesc};
931
932 uint32_t attachmentCount = 1;
933 if (sampleCount > VK_SAMPLE_COUNT_1_BIT)
934 attachmentCount++;
935
936 const VkAttachmentReference attachmentRef = {
937 0u, // uint32_t attachment;
938 imageLayout, // VkImageLayout layout;
939 };
940
941 const VkAttachmentReference attachmentResolveRef = {
942 1u, // uint32_t attachment;
943 imageLayout, // VkImageLayout layout;
944 };
945
946 const VkAttachmentReference *pColorAttachments = DE_NULL;
947 const VkAttachmentReference *pDepthStencilAttachment = DE_NULL;
948 const VkAttachmentReference *pResolveAttachments = DE_NULL;
949 uint32_t colorAttachmentCount = 1;
950
951 if (isDepthStencilFormat(format))
952 {
953 colorAttachmentCount = 0;
954 pDepthStencilAttachment = &attachmentRef;
955 }
956 else
957 {
958 colorAttachmentCount = 1;
959 pColorAttachments = &attachmentRef;
960 if (sampleCount > VK_SAMPLE_COUNT_1_BIT)
961 pResolveAttachments = &attachmentResolveRef;
962 }
963
964 const VkSubpassDescription subpassDesc[1] = {{
965 0u, // VkSubpassDescriptionFlags flags;
966 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
967 0u, // uint32_t inputAttachmentCount;
968 DE_NULL, // const VkAttachmentReference* pInputAttachments;
969 colorAttachmentCount, // uint32_t colorAttachmentCount;
970 pColorAttachments, // const VkAttachmentReference* pColorAttachments;
971 pResolveAttachments, // const VkAttachmentReference* pResolveAttachments;
972 pDepthStencilAttachment, // const VkAttachmentReference* pDepthStencilAttachment;
973 0u, // uint32_t preserveAttachmentCount;
974 DE_NULL, // const VkAttachmentReference* pPreserveAttachments;
975 }};
976
977 const VkRenderPassCreateInfo renderPassCreateInfo = {
978 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
979 DE_NULL, // const void* pNext;
980 0u, // VkRenderPassCreateFlags flags;
981 attachmentCount, // uint32_t attachmentCount;
982 attachments, // const VkAttachmentDescription* pAttachments;
983 1u, // uint32_t subpassCount;
984 subpassDesc, // const VkSubpassDescription* pSubpasses;
985 0u, // uint32_t dependencyCount;
986 DE_NULL, // const VkSubpassDependency* pDependencies;
987 };
988
989 return vk::createRenderPass(m_vkd, m_device, &renderPassCreateInfo, DE_NULL);
990 }
991 else
992 {
993 // Make sure VK_KHR_create_renderpass2 is supported. Due to InstanceFactory1 being used and the render pass being created in
994 // the instance constructor and not every time, this is the best moment to check.
995 m_context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
996
997 VkImageLayout initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
998 VkImageLayout finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
999 VkAttachmentDescriptionStencilLayout stencilLayouts = {
1000 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT,
1001 DE_NULL,
1002 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1003 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1004 };
1005
1006 VkImageLayout imageLayout;
1007 VkAttachmentReferenceStencilLayout stencilLayoutRef = {
1008 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_STENCIL_LAYOUT,
1009 DE_NULL,
1010 VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
1011 };
1012
1013 if (m_params.separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_DEPTH)
1014 {
1015 initialLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
1016 finalLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
1017 stencilLayouts.stencilInitialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1018 stencilLayouts.stencilFinalLayout = VK_IMAGE_LAYOUT_GENERAL;
1019 imageLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
1020 stencilLayoutRef.stencilLayout = VK_IMAGE_LAYOUT_GENERAL;
1021 }
1022 else
1023 {
1024 initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
1025 finalLayout = VK_IMAGE_LAYOUT_GENERAL;
1026 stencilLayouts.stencilInitialLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
1027 stencilLayouts.stencilFinalLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
1028 imageLayout = VK_IMAGE_LAYOUT_GENERAL;
1029 stencilLayoutRef.stencilLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
1030 }
1031
1032 const VkAttachmentDescription2 attachmentDesc = {
1033 VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, // VkStructureType sType;
1034 &stencilLayouts, // const void* pNext;
1035 0u, // VkAttachmentDescriptionFlags flags;
1036 format, // VkFormat format;
1037 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1038 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
1039 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
1040 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp stencilLoadOp;
1041 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp stencilStoreOp;
1042 initialLayout, // VkImageLayout initialLayout;
1043 finalLayout, // VkImageLayout finalLayout;
1044 };
1045
1046 const VkAttachmentReference2 attachmentRef = {
1047 VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, // VkStructureType sType;
1048 &stencilLayoutRef, // const void* pNext;
1049 0u, // uint32_t attachment;
1050 imageLayout, // VkImageLayout layout;
1051 0u, // VkImageAspectFlags aspectMask;
1052 };
1053
1054 const VkSubpassDescription2 subpassDesc = {
1055 VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, // VkStructureType sType;
1056 DE_NULL, // const void* pNext;
1057 0u, // VkSubpassDescriptionFlags flags;
1058 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1059 0u, // uint32_t viewMask;
1060 0u, // uint32_t inputAttachmentCount;
1061 DE_NULL, // const VkAttachmentReference2KHR* pInputAttachments;
1062 0u, // uint32_t colorAttachmentCount;
1063 DE_NULL, // const VkAttachmentReference2KHR* pColorAttachments;
1064 DE_NULL, // const VkAttachmentReference2KHR* pResolveAttachments;
1065 &attachmentRef, // const VkAttachmentReference2KHR* pDepthStencilAttachment;
1066 0u, // uint32_t preserveAttachmentCount;
1067 DE_NULL, // const VkAttachmentReference2KHR* pPreserveAttachments;
1068 };
1069
1070 const VkRenderPassCreateInfo2 renderPassCreateInfo = {
1071 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, // VkStructureType sType;
1072 DE_NULL, // const void* pNext;
1073 0u, // VkRenderPassCreateFlags flags;
1074 1u, // uint32_t attachmentCount;
1075 &attachmentDesc, // const VkAttachmentDescription* pAttachments;
1076 1u, // uint32_t subpassCount;
1077 &subpassDesc, // const VkSubpassDescription* pSubpasses;
1078 0u, // uint32_t dependencyCount;
1079 DE_NULL, // const VkSubpassDependency* pDependencies;
1080 0u, // uint32_t correlatedViewMaskCount;
1081 DE_NULL, // const uint32_t* pCorrelatedViewMasks;
1082 };
1083
1084 return vk::createRenderPass2(m_vkd, m_device, &renderPassCreateInfo, DE_NULL);
1085 }
1086 }
1087
createFrameBuffer(VkImageView imageView,VkRenderPass renderPass,uint32_t imageWidth,uint32_t imageHeight,uint32_t imageLayersCount,VkSampleCountFlagBits sampleCount) const1088 Move<VkFramebuffer> ImageClearingTestInstance::createFrameBuffer(VkImageView imageView, VkRenderPass renderPass,
1089 uint32_t imageWidth, uint32_t imageHeight,
1090 uint32_t imageLayersCount,
1091 VkSampleCountFlagBits sampleCount) const
1092 {
1093 std::vector<VkImageView> attachmentViews;
1094
1095 if (sampleCount > VK_SAMPLE_COUNT_1_BIT)
1096 attachmentViews.push_back(*m_multisampleImageView);
1097
1098 attachmentViews.push_back(imageView);
1099
1100 const VkFramebufferCreateInfo framebufferCreateInfo = {
1101 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1102 DE_NULL, // const void* pNext;
1103 0u, // VkFramebufferCreateFlags flags;
1104 renderPass, // VkRenderPass renderPass;
1105 de::sizeU32(attachmentViews), // uint32_t attachmentCount;
1106 de::dataOrNull(attachmentViews), // const VkImageView* pAttachments;
1107 imageWidth, // uint32_t width;
1108 imageHeight, // uint32_t height;
1109 imageLayersCount, // uint32_t layers;
1110 };
1111
1112 return createFramebuffer(m_vkd, m_device, &framebufferCreateInfo, DE_NULL);
1113 }
1114
beginCommandBuffer(VkCommandBufferUsageFlags usageFlags) const1115 void ImageClearingTestInstance::beginCommandBuffer(VkCommandBufferUsageFlags usageFlags) const
1116 {
1117 vk::beginCommandBuffer(m_vkd, *m_commandBuffer, usageFlags);
1118 }
1119
endCommandBuffer(void) const1120 void ImageClearingTestInstance::endCommandBuffer(void) const
1121 {
1122 vk::endCommandBuffer(m_vkd, *m_commandBuffer);
1123 }
1124
submitCommandBuffer(void) const1125 void ImageClearingTestInstance::submitCommandBuffer(void) const
1126 {
1127 submitCommandsAndWait(m_vkd, m_device, m_queue, m_commandBuffer.get());
1128 m_context.resetCommandPoolForVKSC(m_device, *m_commandPool);
1129 }
1130
pipelineImageBarrierGen(VkImage image,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkImageLayout oldLayout,VkImageLayout newLayout,VkImageAspectFlags aspectMask) const1131 void ImageClearingTestInstance::pipelineImageBarrierGen(VkImage image, VkPipelineStageFlags srcStageMask,
1132 VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask,
1133 VkAccessFlags dstAccessMask, VkImageLayout oldLayout,
1134 VkImageLayout newLayout, VkImageAspectFlags aspectMask) const
1135 {
1136 if (!aspectMask || m_params.separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE)
1137 aspectMask = m_imageAspectFlags;
1138
1139 const VkImageMemoryBarrier imageBarrier = {
1140 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
1141 DE_NULL, // const void* pNext;
1142 srcAccessMask, // VkAccessFlags srcAccessMask;
1143 dstAccessMask, // VkAccessFlags dstAccessMask;
1144 oldLayout, // VkImageLayout oldLayout;
1145 newLayout, // VkImageLayout newLayout;
1146 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1147 VK_QUEUE_FAMILY_IGNORED, // uint32_t destQueueFamilyIndex;
1148 image, // VkImage image;
1149 {
1150 aspectMask, // VkImageAspectFlags aspectMask;
1151 0u, // uint32_t baseMipLevel;
1152 VK_REMAINING_MIP_LEVELS, // uint32_t levelCount;
1153 0u, // uint32_t baseArrayLayer;
1154 VK_REMAINING_ARRAY_LAYERS, // uint32_t layerCount;
1155 }, // VkImageSubresourceRange subresourceRange;
1156 };
1157
1158 m_vkd.cmdPipelineBarrier(*m_commandBuffer, srcStageMask, dstStageMask, 0, 0, DE_NULL, 0, DE_NULL, 1, &imageBarrier);
1159 }
1160
pipelineImageBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkImageLayout oldLayout,VkImageLayout newLayout,VkImageAspectFlags aspectMask) const1161 void ImageClearingTestInstance::pipelineImageBarrier(VkPipelineStageFlags srcStageMask,
1162 VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask,
1163 VkAccessFlags dstAccessMask, VkImageLayout oldLayout,
1164 VkImageLayout newLayout, VkImageAspectFlags aspectMask) const
1165 {
1166 pipelineImageBarrierGen(*m_image, srcStageMask, dstStageMask, srcAccessMask, dstAccessMask, oldLayout, newLayout,
1167 aspectMask);
1168 }
1169
pipelineMultisampleImageBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkAccessFlags srcAccessMask,VkAccessFlags dstAccessMask,VkImageLayout oldLayout,VkImageLayout newLayout,VkImageAspectFlags aspectMask) const1170 void ImageClearingTestInstance::pipelineMultisampleImageBarrier(
1171 VkPipelineStageFlags srcStageMask, VkPipelineStageFlags dstStageMask, VkAccessFlags srcAccessMask,
1172 VkAccessFlags dstAccessMask, VkImageLayout oldLayout, VkImageLayout newLayout, VkImageAspectFlags aspectMask) const
1173 {
1174 pipelineImageBarrierGen(*m_multisampleImage, srcStageMask, dstStageMask, srcAccessMask, dstAccessMask, oldLayout,
1175 newLayout, aspectMask);
1176 }
1177
readImage(VkImageAspectFlags aspectMask,uint32_t arrayLayer) const1178 de::MovePtr<TextureLevelPyramid> ImageClearingTestInstance::readImage(VkImageAspectFlags aspectMask,
1179 uint32_t arrayLayer) const
1180 {
1181 const TextureFormat tcuFormat =
1182 aspectMask == VK_IMAGE_ASPECT_COLOR_BIT ? mapVkFormat(m_params.imageFormat) :
1183 aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT ? getDepthCopyFormat(m_params.imageFormat) :
1184 aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT ? getStencilCopyFormat(m_params.imageFormat) :
1185 TextureFormat();
1186 const uint32_t pixelSize = getPixelSize(tcuFormat);
1187 uint32_t alignment = 4; // subsequent mip levels aligned to 4 bytes
1188
1189 if (!getIsDepthFormat(m_params.imageFormat) && !getIsStencilFormat(m_params.imageFormat))
1190 alignment = lowestCommonMultiple(pixelSize, alignment); // alignment must be multiple of pixel size, if not D/S.
1191
1192 const std::vector<uint32_t> mipLevelSizes =
1193 getImageMipLevelSizes(pixelSize, m_params.imageExtent, m_imageMipLevels, alignment);
1194 const VkDeviceSize imageTotalSize = std::accumulate(mipLevelSizes.begin(), mipLevelSizes.end(), 0u);
1195
1196 de::MovePtr<TextureLevelPyramid> result(new TextureLevelPyramid(tcuFormat, m_imageMipLevels));
1197 Move<VkBuffer> buffer;
1198 de::MovePtr<Allocation> bufferAlloc;
1199
1200 // Create destination buffer
1201 {
1202 const VkBufferCreateInfo bufferParams = {
1203 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1204 DE_NULL, // const void* pNext;
1205 0u, // VkBufferCreateFlags flags;
1206 imageTotalSize, // VkDeviceSize size;
1207 VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1208 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1209 0u, // uint32_t queueFamilyIndexCount;
1210 DE_NULL // const uint32_t* pQueueFamilyIndices;
1211 };
1212
1213 buffer = createBuffer(m_vkd, m_device, &bufferParams);
1214 bufferAlloc = allocateBuffer(m_vki, m_vkd, m_context.getPhysicalDevice(), m_device, *buffer,
1215 MemoryRequirement::HostVisible, m_allocator, m_params.allocationKind);
1216 VK_CHECK(m_vkd.bindBufferMemory(m_device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset()));
1217 }
1218
1219 // Barriers for copying image to buffer
1220
1221 const VkBufferMemoryBarrier bufferBarrier = {
1222 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
1223 DE_NULL, // const void* pNext;
1224 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask;
1225 VK_ACCESS_HOST_READ_BIT, // VkAccessFlags dstAccessMask;
1226 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex;
1227 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex;
1228 *buffer, // VkBuffer buffer;
1229 0u, // VkDeviceSize offset;
1230 imageTotalSize, // VkDeviceSize size;
1231 };
1232
1233 // Copy image to buffer
1234 std::vector<VkBufferImageCopy> copyRegions;
1235 {
1236 uint32_t offset = 0u;
1237 for (uint32_t mipLevel = 0; mipLevel < m_imageMipLevels; ++mipLevel)
1238 {
1239 const VkExtent3D extent = getMipLevelExtent(m_params.imageExtent, mipLevel);
1240 const VkBufferImageCopy region = {
1241 offset, // VkDeviceSize bufferOffset;
1242 0u, // uint32_t bufferRowLength;
1243 0u, // uint32_t bufferImageHeight;
1244 {aspectMask, mipLevel, arrayLayer, 1u}, // VkImageSubresourceLayers imageSubresource;
1245 {0, 0, 0}, // VkOffset3D imageOffset;
1246 extent // VkExtent3D imageExtent;
1247 };
1248 copyRegions.push_back(region);
1249 offset += mipLevelSizes[mipLevel];
1250 }
1251 }
1252
1253 beginCommandBuffer(0);
1254
1255 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_WRITE_BIT,
1256 VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
1257 aspectMask);
1258
1259 m_vkd.cmdCopyImageToBuffer(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer,
1260 static_cast<uint32_t>(copyRegions.size()), ©Regions[0]);
1261 m_vkd.cmdPipelineBarrier(*m_commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_HOST_BIT,
1262 (VkDependencyFlags)0, 0, (const VkMemoryBarrier *)DE_NULL, 1, &bufferBarrier, 0,
1263 (const VkImageMemoryBarrier *)DE_NULL);
1264
1265 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_ACCESS_TRANSFER_READ_BIT,
1266 VK_ACCESS_TRANSFER_READ_BIT, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, VK_IMAGE_LAYOUT_GENERAL,
1267 aspectMask);
1268
1269 endCommandBuffer();
1270 submitCommandBuffer();
1271
1272 invalidateAlloc(m_vkd, m_device, *bufferAlloc);
1273
1274 {
1275 uint32_t offset = 0u;
1276 for (uint32_t mipLevel = 0; mipLevel < m_imageMipLevels; ++mipLevel)
1277 {
1278 const VkExtent3D extent = getMipLevelExtent(m_params.imageExtent, mipLevel);
1279 const void *pLevelData =
1280 static_cast<const void *>(reinterpret_cast<uint8_t *>(bufferAlloc->getHostPtr()) + offset);
1281
1282 result->allocLevel(mipLevel, extent.width, extent.height, extent.depth);
1283 copy(result->getLevel(mipLevel),
1284 ConstPixelBufferAccess(result->getFormat(), result->getLevel(mipLevel).getSize(), pLevelData));
1285
1286 offset += mipLevelSizes[mipLevel];
1287 }
1288 }
1289
1290 return result;
1291 }
1292
verifyResultImage(const std::string & successMessage,const UVec4 & clearCoords) const1293 tcu::TestStatus ImageClearingTestInstance::verifyResultImage(const std::string &successMessage,
1294 const UVec4 &clearCoords) const
1295 {
1296 DE_ASSERT((clearCoords == UVec4()) || m_params.imageExtent.depth == 1u);
1297
1298 tcu::TestStatus result = tcu::TestStatus::pass(successMessage);
1299 bool errorsPresent = false;
1300
1301 if (getIsDepthFormat(m_params.imageFormat) &&
1302 m_params.separateDepthStencilLayoutMode != SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_STENCIL)
1303 {
1304 DE_ASSERT(m_imageMipLevels == 1u);
1305
1306 for (uint32_t arrayLayer = 0; arrayLayer < m_params.imageLayerCount && !errorsPresent; ++arrayLayer)
1307 {
1308 de::MovePtr<TextureLevelPyramid> image = readImage(VK_IMAGE_ASPECT_DEPTH_BIT, arrayLayer);
1309 std::string message;
1310 float depthValue;
1311
1312 #ifdef CTS_USES_VULKANSC
1313 if (!m_context.getTestContext().getCommandLine().isSubProcess())
1314 continue;
1315 #endif // CTS_USES_VULKANSC
1316
1317 for (uint32_t z = 0; z < m_params.imageExtent.depth && !errorsPresent; ++z)
1318 for (uint32_t y = 0; y < m_params.imageExtent.height && !errorsPresent; ++y)
1319 for (uint32_t x = 0; x < m_params.imageExtent.width && !errorsPresent; ++x)
1320 {
1321 if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange,
1322 m_params.clearLayerRange))
1323 depthValue = m_params.clearValue[0].depthStencil.depth;
1324 else if (isInInitialClearRange(0u /* mipLevel */, arrayLayer, m_params.imageViewLayerRange))
1325 {
1326 depthValue = m_params.initValue.depthStencil.depth;
1327 }
1328 else
1329 continue;
1330
1331 if (!comparePixelToDepthClearValue(image->getLevel(0), x, y, z, depthValue, message))
1332 {
1333 result = TestStatus::fail("Depth value mismatch! " + message);
1334 errorsPresent = true;
1335 }
1336 }
1337 }
1338 }
1339
1340 if (getIsStencilFormat(m_params.imageFormat) &&
1341 m_params.separateDepthStencilLayoutMode != SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_DEPTH)
1342 {
1343 DE_ASSERT(m_imageMipLevels == 1u);
1344
1345 for (uint32_t arrayLayer = 0; arrayLayer < m_params.imageLayerCount && !errorsPresent; ++arrayLayer)
1346 {
1347 de::MovePtr<TextureLevelPyramid> image = readImage(VK_IMAGE_ASPECT_STENCIL_BIT, arrayLayer);
1348 std::string message;
1349 uint32_t stencilValue;
1350
1351 #ifdef CTS_USES_VULKANSC
1352 if (!m_context.getTestContext().getCommandLine().isSubProcess())
1353 continue;
1354 #endif // CTS_USES_VULKANSC
1355
1356 for (uint32_t z = 0; z < m_params.imageExtent.depth && !errorsPresent; ++z)
1357 for (uint32_t y = 0; y < m_params.imageExtent.height && !errorsPresent; ++y)
1358 for (uint32_t x = 0; x < m_params.imageExtent.width && !errorsPresent; ++x)
1359 {
1360 if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange,
1361 m_params.clearLayerRange))
1362 stencilValue = m_params.clearValue[0].depthStencil.stencil;
1363 else if (isInInitialClearRange(0u /* mipLevel */, arrayLayer, m_params.imageViewLayerRange))
1364 {
1365 stencilValue = m_params.initValue.depthStencil.stencil;
1366 }
1367 else
1368 continue;
1369
1370 if (!comparePixelToStencilClearValue(image->getLevel(0), x, y, z, stencilValue, message))
1371 {
1372 result = TestStatus::fail("Stencil value mismatch! " + message);
1373 errorsPresent = true;
1374 }
1375 }
1376 }
1377 }
1378
1379 if (!isDepthStencilFormat(m_params.imageFormat))
1380 {
1381 const TextureFormat format = mapVkFormat(m_params.imageFormat);
1382 const TextureChannelClass channelClass = getTextureChannelClass(format.type);
1383 const BVec4 channelMask = getTextureFormatChannelMask(format);
1384 Threshold threshold{Vec4(0)};
1385 switch (channelClass)
1386 {
1387 case TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
1388 case TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
1389 {
1390 const IVec4 formatDepth = getTextureFormatBitDepth(format);
1391 const int modifier = (channelClass == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT) ? 0 : 1;
1392 threshold.vec4 = {formatDepth[0] > 0 ? 1.0f / ((float)(1 << (formatDepth[0] - modifier)) - 1.0f) : 1.0f,
1393 formatDepth[1] > 0 ? 1.0f / ((float)(1 << (formatDepth[1] - modifier)) - 1.0f) : 1.0f,
1394 formatDepth[2] > 0 ? 1.0f / ((float)(1 << (formatDepth[2] - modifier)) - 1.0f) : 1.0f,
1395 formatDepth[3] > 0 ? 1.0f / ((float)(1 << (formatDepth[3] - modifier)) - 1.0f) : 1.0f};
1396 break;
1397 }
1398 case TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
1399 {
1400 threshold.uvec4 = UVec4(1U);
1401 break;
1402 }
1403 case TEXTURECHANNELCLASS_SIGNED_INTEGER:
1404 {
1405 threshold.ivec4 = IVec4(1);
1406 break;
1407 }
1408 case TEXTURECHANNELCLASS_FLOATING_POINT:
1409 {
1410 const IVec4 &mantissaBits = getTextureFormatMantissaBitDepth(format);
1411 threshold.ivec4 = IVec4(10 * IVec4(1) << (23 - mantissaBits));
1412 break;
1413 }
1414 default:
1415 DE_FATAL("Invalid channel class");
1416 }
1417
1418 for (uint32_t arrayLayer = 0; arrayLayer < m_params.imageLayerCount && !errorsPresent; ++arrayLayer)
1419 {
1420 de::MovePtr<TextureLevelPyramid> image = readImage(VK_IMAGE_ASPECT_COLOR_BIT, arrayLayer);
1421 std::string message;
1422 const VkClearColorValue *pColorValue;
1423
1424 #ifdef CTS_USES_VULKANSC
1425 if (!m_context.getTestContext().getCommandLine().isSubProcess())
1426 continue;
1427 #endif // CTS_USES_VULKANSC
1428
1429 for (uint32_t mipLevel = 0; mipLevel < m_imageMipLevels && !errorsPresent; ++mipLevel)
1430 {
1431 const int clearColorNdx =
1432 ((mipLevel < m_thresholdMipLevel || m_params.isColorMultipleSubresourceRangeTest) ? 0 : 1);
1433 const VkExtent3D extent = getMipLevelExtent(m_params.imageExtent, mipLevel);
1434 const VkClearColorValue *pExpectedColorValue =
1435 &(m_params.useSeparateExpectedClearValue ? m_params.expectedClearValue :
1436 m_params.clearValue)[clearColorNdx]
1437 .color;
1438 const auto &pixelBufferAccess = image->getLevel(mipLevel);
1439
1440 for (uint32_t z = 0; z < extent.depth && !errorsPresent; ++z)
1441 for (uint32_t y = 0; y < extent.height && !errorsPresent; ++y)
1442 for (uint32_t x = 0; x < extent.width && !errorsPresent; ++x)
1443 {
1444 if (isInClearRange(clearCoords, x, y, arrayLayer, m_params.imageViewLayerRange,
1445 m_params.clearLayerRange))
1446 {
1447 pColorValue = pExpectedColorValue;
1448 }
1449 else
1450 {
1451 if (isInInitialClearRange(mipLevel, arrayLayer, m_params.imageViewLayerRange))
1452 {
1453 pColorValue = &m_params.initValue.color;
1454 }
1455 else
1456 {
1457 continue;
1458 }
1459 }
1460 if (!comparePixelToColorClearValue(pixelBufferAccess, x, y, z, *pColorValue, message,
1461 threshold, channelMask, channelClass))
1462 {
1463 errorsPresent = true;
1464 result = TestStatus::fail("Color value mismatch! " + message);
1465 }
1466 }
1467 }
1468 }
1469 }
1470
1471 return result;
1472 }
1473
createImageClearingBuffer(const DeviceInterface & vkd,const VkDevice device)1474 Move<VkBuffer> ImageClearingTestInstance::createImageClearingBuffer(const DeviceInterface &vkd, const VkDevice device)
1475 {
1476 Move<VkBuffer> stagingBuffer;
1477 de::MovePtr<Allocation> stagingBufferAlloc;
1478 const VkDeviceSize stagingBufferSize = m_params.imageExtent.width * m_params.imageExtent.height *
1479 m_params.imageExtent.depth *
1480 getPixelSize(mapVkFormat(m_params.imageFormat)) * m_params.imageLayerCount;
1481 // Create image clearing buffer
1482 {
1483 const VkBufferCreateInfo bufferParams = {
1484 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1485 DE_NULL, // const void* pNext;
1486 0u, // VkBufferCreateFlags flags;
1487 stagingBufferSize, // VkDeviceSize size;
1488 VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage;
1489 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1490 0u, // uint32_t queueFamilyIndexCount;
1491 DE_NULL // const uint32_t* pQueueFamilyIndices;
1492 };
1493 stagingBuffer = createBuffer(vkd, device, &bufferParams);
1494 }
1495 return stagingBuffer;
1496 }
1497
preClearImage(const uint32_t imageMipLevels,VkExtent3D imageExtent,uint32_t imageLayerCount,Unique<VkCommandBuffer> & commandBuffer) const1498 void ImageClearingTestInstance::preClearImage(const uint32_t imageMipLevels, VkExtent3D imageExtent,
1499 uint32_t imageLayerCount, Unique<VkCommandBuffer> &commandBuffer) const
1500 {
1501 std::vector<VkBufferImageCopy> copyRegions;
1502 std::vector<VkImageAspectFlags> aspectMasks;
1503
1504 if (getIsDepthFormat(m_params.imageFormat))
1505 aspectMasks.push_back(VK_IMAGE_ASPECT_DEPTH_BIT);
1506 if (getIsStencilFormat(m_params.imageFormat))
1507 aspectMasks.push_back(VK_IMAGE_ASPECT_STENCIL_BIT);
1508 if (aspectMasks.empty())
1509 aspectMasks.push_back(VK_IMAGE_ASPECT_COLOR_BIT);
1510
1511 for (uint32_t mipLevel = 0; mipLevel < imageMipLevels; ++mipLevel)
1512 {
1513 const VkExtent3D extent = getMipLevelExtent(imageExtent, mipLevel);
1514 for (auto mask : aspectMasks)
1515 {
1516 const VkImageSubresourceLayers imageSubResource = {
1517 mask, // VkImageAspectFlags aspectMask
1518 mipLevel, // uint32_t mipLevel
1519 0u, // uint32_t baseArrayLayer
1520 imageLayerCount // uint32_t layerCount
1521 };
1522 const VkBufferImageCopy region = {
1523 0u, // VkDeviceSize bufferOffset;
1524 0u, // uint32_t bufferRowLength;
1525 0u, // uint32_t bufferImageHeight;
1526 imageSubResource, // VkImageSubresourceLayers imageSubresource;
1527 {0, 0, 0}, // VkOffset3D imageOffset;
1528 extent // VkExtent3D imageExtent;
1529 };
1530 copyRegions.push_back(region);
1531 }
1532 }
1533
1534 m_vkd.cmdFillBuffer(*commandBuffer, *m_stagingBuffer, 0u, VK_WHOLE_SIZE, 0u);
1535
1536 const vk::VkBufferMemoryBarrier copyBufferBarrier = {
1537 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType
1538 DE_NULL, // const void* pNext
1539 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1540 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1541 VK_QUEUE_FAMILY_IGNORED, // uint32_t srcQueueFamilyIndex
1542 VK_QUEUE_FAMILY_IGNORED, // uint32_t dstQueueFamilyIndex
1543 *m_stagingBuffer, // VkBuffer buffer
1544 0u, // VkDeviceSize offset
1545 VK_WHOLE_SIZE, // VkDeviceSize size
1546 };
1547
1548 m_vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
1549 (VkDependencyFlags)0, 0, (const vk::VkMemoryBarrier *)DE_NULL, 1, ©BufferBarrier, 0,
1550 (const vk::VkImageMemoryBarrier *)DE_NULL);
1551
1552 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1553 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1554 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1555 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1556 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1557 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1558
1559 m_vkd.cmdCopyBufferToImage(*commandBuffer, *m_stagingBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1560 static_cast<uint32_t>(copyRegions.size()), ©Regions[0]);
1561 }
1562
beginRenderPass(VkSubpassContents content,VkClearValue clearValue) const1563 void ImageClearingTestInstance::beginRenderPass(VkSubpassContents content, VkClearValue clearValue) const
1564 {
1565 vk::beginRenderPass(m_vkd, *m_commandBuffer, *m_renderPass, *m_frameBuffer,
1566 makeRect2D(0, 0, m_params.imageExtent.width, m_params.imageExtent.height), clearValue, content);
1567 }
1568
1569 class ClearColorImageTestInstance : public ImageClearingTestInstance
1570 {
1571 public:
ClearColorImageTestInstance(Context & context,const TestParams & testParams,bool twoStep=false)1572 ClearColorImageTestInstance(Context &context, const TestParams &testParams, bool twoStep = false)
1573 : ImageClearingTestInstance(context, testParams)
1574 , m_twoStep(twoStep)
1575 {
1576 }
1577 virtual TestStatus iterate(void);
1578
1579 protected:
1580 bool m_twoStep;
1581 };
1582
1583 class TwoStepClearColorImageTestInstance : public ClearColorImageTestInstance
1584 {
1585 public:
TwoStepClearColorImageTestInstance(Context & context,const TestParams & testParams)1586 TwoStepClearColorImageTestInstance(Context &context, const TestParams &testParams)
1587 : ClearColorImageTestInstance(context, testParams, true)
1588 {
1589 }
1590 };
1591
1592 class ClearColorImageMultipleSubresourceRangeTestInstance : public ClearColorImageTestInstance
1593 {
1594 public:
ClearColorImageMultipleSubresourceRangeTestInstance(Context & context,const TestParams & testParams)1595 ClearColorImageMultipleSubresourceRangeTestInstance(Context &context, const TestParams &testParams)
1596 : ClearColorImageTestInstance(context, testParams, false)
1597 {
1598 }
1599 virtual TestStatus iterate(void);
1600 };
1601
iterate(void)1602 TestStatus ClearColorImageMultipleSubresourceRangeTestInstance::iterate(void)
1603 {
1604 std::vector<VkImageSubresourceRange> subresourceRanges;
1605
1606 DE_ASSERT(m_imageMipLevels > 1u);
1607
1608 uint32_t mipLevel = 0u;
1609 // Create a subresource range per mipmap level.
1610 do
1611 {
1612 subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, mipLevel++, 1u,
1613 m_params.clearLayerRange.baseArrayLayer,
1614 m_params.clearLayerRange.layerCount));
1615 } while (mipLevel < m_imageMipLevels);
1616
1617 beginCommandBuffer(0);
1618
1619 pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
1620 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
1621 0, // VkAccessFlags srcAccessMask
1622 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1623 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1624 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1625
1626 preClearImage(m_imageMipLevels, m_params.imageExtent, m_params.imageLayerCount, m_commandBuffer);
1627
1628 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1629 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1630 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1631 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1632 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1633 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1634
1635 // Test clear color in all ranges
1636 m_vkd.cmdClearColorImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1637 &m_params.clearValue[0].color, static_cast<uint32_t>(subresourceRanges.size()),
1638 subresourceRanges.data());
1639
1640 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1641 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1642 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1643 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1644 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1645 VK_IMAGE_LAYOUT_GENERAL); // VkImageLayout newLayout;
1646
1647 endCommandBuffer();
1648 submitCommandBuffer();
1649
1650 return verifyResultImage("cmdClearColorImage passed");
1651 }
1652
iterate(void)1653 TestStatus ClearColorImageTestInstance::iterate(void)
1654 {
1655 std::vector<VkImageSubresourceRange> subresourceRanges;
1656 std::vector<VkImageSubresourceRange> steptwoRanges;
1657
1658 if (m_imageMipLevels == 1)
1659 {
1660 subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, 0u, 1u,
1661 m_params.clearLayerRange.baseArrayLayer,
1662 m_twoStep ? 1 : m_params.clearLayerRange.layerCount));
1663 steptwoRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, 0u, VK_REMAINING_MIP_LEVELS,
1664 m_params.clearLayerRange.baseArrayLayer,
1665 VK_REMAINING_ARRAY_LAYERS));
1666 }
1667 else
1668 {
1669 subresourceRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, 0u, m_thresholdMipLevel,
1670 m_params.clearLayerRange.baseArrayLayer,
1671 m_params.clearLayerRange.layerCount));
1672 subresourceRanges.push_back(
1673 makeImageSubresourceRange(m_imageAspectFlags, m_thresholdMipLevel, VK_REMAINING_MIP_LEVELS,
1674 m_params.clearLayerRange.baseArrayLayer, m_params.clearLayerRange.layerCount));
1675 steptwoRanges.push_back(makeImageSubresourceRange(m_imageAspectFlags, 0u, m_thresholdMipLevel,
1676 m_params.clearLayerRange.baseArrayLayer,
1677 VK_REMAINING_ARRAY_LAYERS));
1678 steptwoRanges.push_back(
1679 makeImageSubresourceRange(m_imageAspectFlags, m_thresholdMipLevel, VK_REMAINING_MIP_LEVELS,
1680 m_params.clearLayerRange.baseArrayLayer, VK_REMAINING_ARRAY_LAYERS));
1681 }
1682
1683 beginCommandBuffer(0);
1684
1685 pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
1686 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
1687 0, // VkAccessFlags srcAccessMask
1688 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1689 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1690 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1691
1692 preClearImage(m_imageMipLevels, m_params.imageExtent, m_params.imageLayerCount, m_commandBuffer);
1693
1694 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1695 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1696 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1697 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1698 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1699 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1700
1701 // Different clear color per range
1702 for (std::size_t i = 0u; i < subresourceRanges.size(); ++i)
1703 {
1704 m_vkd.cmdClearColorImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1705 &m_params.clearValue[i].color, 1, &subresourceRanges[i]);
1706
1707 if (m_twoStep)
1708 {
1709 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1710 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1711 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1712 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1713 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1714 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1715
1716 m_vkd.cmdClearColorImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1717 &m_params.clearValue[i].color, 1, &steptwoRanges[i]);
1718 }
1719 }
1720
1721 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1722 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1723 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1724 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1725 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1726 VK_IMAGE_LAYOUT_GENERAL); // VkImageLayout newLayout;
1727
1728 endCommandBuffer();
1729 submitCommandBuffer();
1730
1731 return verifyResultImage("cmdClearColorImage passed");
1732 }
1733
1734 class ClearDepthStencilImageTestInstance : public ImageClearingTestInstance
1735 {
1736 public:
ClearDepthStencilImageTestInstance(Context & context,const TestParams & testParams,bool twoStep=false)1737 ClearDepthStencilImageTestInstance(Context &context, const TestParams &testParams, bool twoStep = false)
1738 : ImageClearingTestInstance(context, testParams)
1739 , m_twoStep(twoStep)
1740 {
1741 }
1742 virtual TestStatus iterate(void);
1743
1744 protected:
1745 bool m_twoStep;
1746 };
1747
1748 class TwoStepClearDepthStencilImageTestInstance : public ClearDepthStencilImageTestInstance
1749 {
1750 public:
TwoStepClearDepthStencilImageTestInstance(Context & context,const TestParams & testParams)1751 TwoStepClearDepthStencilImageTestInstance(Context &context, const TestParams &testParams)
1752 : ClearDepthStencilImageTestInstance(context, testParams, true)
1753 {
1754 }
1755 };
1756
1757 class ClearDepthStencilImageMultipleSubresourceRangeTestInstance : public ClearDepthStencilImageTestInstance
1758 {
1759 public:
ClearDepthStencilImageMultipleSubresourceRangeTestInstance(Context & context,const TestParams & testParams)1760 ClearDepthStencilImageMultipleSubresourceRangeTestInstance(Context &context, const TestParams &testParams)
1761 : ClearDepthStencilImageTestInstance(context, testParams, false)
1762 {
1763 }
1764 virtual TestStatus iterate(void);
1765 };
1766
iterate(void)1767 TestStatus ClearDepthStencilImageMultipleSubresourceRangeTestInstance::iterate(void)
1768 {
1769 VkImageAspectFlags aspectMask = m_imageAspectFlags;
1770
1771 // Depth/Stencil formats only. No separate layout modes.
1772 DE_ASSERT(m_params.separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE);
1773
1774 std::vector<VkImageSubresourceRange> subresourceRanges;
1775
1776 subresourceRanges.push_back(makeImageSubresourceRange(VK_IMAGE_ASPECT_STENCIL_BIT, 0u, 1u,
1777 m_params.clearLayerRange.baseArrayLayer,
1778 m_params.clearLayerRange.layerCount));
1779 subresourceRanges.push_back(makeImageSubresourceRange(VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u,
1780 m_params.clearLayerRange.baseArrayLayer,
1781 m_params.clearLayerRange.layerCount));
1782
1783 beginCommandBuffer(0);
1784
1785 pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
1786 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
1787 0, // VkAccessFlags srcAccessMask
1788 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1789 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1790 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1791
1792 preClearImage(m_imageMipLevels, m_params.imageExtent, m_params.imageLayerCount, m_commandBuffer);
1793
1794 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1795 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1796 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1797 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1798 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1799 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1800
1801 m_vkd.cmdClearDepthStencilImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1802 &m_params.clearValue[0].depthStencil,
1803 static_cast<uint32_t>(subresourceRanges.size()), subresourceRanges.data());
1804
1805 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1806 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1807 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1808 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1809 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1810 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
1811 aspectMask); // VkImageAspectFlags aspectMask;
1812
1813 endCommandBuffer();
1814 submitCommandBuffer();
1815
1816 return verifyResultImage("cmdClearDepthStencilImage passed");
1817 }
1818
iterate(void)1819 TestStatus ClearDepthStencilImageTestInstance::iterate(void)
1820 {
1821 VkImageAspectFlags aspectMask = m_imageAspectFlags;
1822 if (m_params.separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_DEPTH)
1823 {
1824 aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1825 }
1826 else if (m_params.separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_STENCIL)
1827 {
1828 aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1829 }
1830
1831 const VkImageSubresourceRange subresourceRange =
1832 makeImageSubresourceRange(aspectMask, 0u, 1u, m_params.clearLayerRange.baseArrayLayer,
1833 m_twoStep ? 1 : m_params.clearLayerRange.layerCount);
1834 const VkImageSubresourceRange steptwoRange = makeImageSubresourceRange(
1835 aspectMask, 0u, VK_REMAINING_MIP_LEVELS, m_params.clearLayerRange.baseArrayLayer, VK_REMAINING_ARRAY_LAYERS);
1836
1837 beginCommandBuffer(0);
1838
1839 pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
1840 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
1841 0, // VkAccessFlags srcAccessMask
1842 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1843 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1844 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1845
1846 preClearImage(m_imageMipLevels, m_params.imageExtent, m_params.imageLayerCount, m_commandBuffer);
1847
1848 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1849 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1850 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1851 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1852 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1853 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1854
1855 m_vkd.cmdClearDepthStencilImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1856 &m_params.clearValue[0].depthStencil, 1, &subresourceRange);
1857
1858 if (m_twoStep)
1859 {
1860 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1861 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1862 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1863 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags dstAccessMask
1864 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1865 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); // VkImageLayout newLayout;
1866
1867 m_vkd.cmdClearDepthStencilImage(*m_commandBuffer, *m_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
1868 &m_params.clearValue[0].depthStencil, 1, &steptwoRange);
1869 }
1870
1871 pipelineImageBarrier(VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags srcStageMask
1872 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
1873 VK_ACCESS_TRANSFER_WRITE_BIT, // VkAccessFlags srcAccessMask
1874 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
1875 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // VkImageLayout oldLayout;
1876 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
1877 aspectMask); // VkImageAspectFlags aspectMask;
1878
1879 endCommandBuffer();
1880 submitCommandBuffer();
1881
1882 return verifyResultImage("cmdClearDepthStencilImage passed");
1883 }
1884
1885 class ClearAttachmentTestInstance : public ImageClearingTestInstance
1886 {
1887 public:
1888 enum ClearType
1889 {
1890 FULL_CLEAR,
1891 PARTIAL_CLEAR,
1892 };
1893
ClearAttachmentTestInstance(Context & context,const TestParams & testParams,const ClearType clearType=FULL_CLEAR)1894 ClearAttachmentTestInstance(Context &context, const TestParams &testParams, const ClearType clearType = FULL_CLEAR)
1895 : ImageClearingTestInstance(context, testParams)
1896 , m_clearType(clearType)
1897 {
1898 if (!m_isAttachmentFormat)
1899 TCU_THROW(NotSupportedError, "Format not renderable");
1900 }
1901
iterate(void)1902 TestStatus iterate(void)
1903 {
1904 const bool isDepthStencil = isDepthStencilFormat(m_params.imageFormat);
1905 const VkAccessFlags accessMask =
1906 (isDepthStencil ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT : VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT);
1907 VkImageLayout attachmentLayout = (isDepthStencil ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL :
1908 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
1909 VkImageAspectFlags aspectMask = m_imageAspectFlags;
1910
1911 if (m_params.separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_DEPTH)
1912 {
1913 attachmentLayout = VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL;
1914 aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT;
1915 }
1916 else if (m_params.separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_STENCIL)
1917 {
1918 attachmentLayout = VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL;
1919 aspectMask = VK_IMAGE_ASPECT_STENCIL_BIT;
1920 }
1921
1922 const VkClearAttachment clearAttachment = {
1923 aspectMask, // VkImageAspectFlags aspectMask;
1924 0u, // uint32_t colorAttachment;
1925 m_params.clearValue[0] // VkClearValue clearValue;
1926 };
1927
1928 UVec4 clearCoords;
1929 std::vector<VkClearRect> clearRects;
1930
1931 if (m_clearType == FULL_CLEAR)
1932 {
1933 const VkClearRect rect = {
1934 {
1935 {0, 0}, // VkOffset2D offset;
1936 {m_params.imageExtent.width, m_params.imageExtent.height} // VkExtent2D extent;
1937 }, // VkRect2D rect;
1938 m_params.clearLayerRange.baseArrayLayer, // uint32_t baseArrayLayer;
1939 m_params.clearLayerRange.layerCount, // uint32_t layerCount;
1940 };
1941
1942 clearRects.push_back(rect);
1943 }
1944 else
1945 {
1946 const uint32_t clearX = m_params.imageExtent.width / 8u;
1947 const uint32_t clearY = m_params.imageExtent.height / 8u;
1948 const uint32_t clearWidth = m_params.imageExtent.width / 2u;
1949 const uint32_t clearHeight = m_params.imageExtent.height / 2u;
1950
1951 clearCoords = UVec4(clearX, clearY, clearX + clearWidth, clearY + clearHeight);
1952
1953 const VkClearRect rects[2] = {{
1954 {
1955 {0, static_cast<int32_t>(clearY)}, // VkOffset2D offset;
1956 {m_params.imageExtent.width, clearHeight} // VkExtent2D extent;
1957 }, // VkRect2D rect;
1958 m_params.clearLayerRange.baseArrayLayer, // uint32_t baseArrayLayer;
1959 m_params.clearLayerRange.layerCount // uint32_t layerCount;
1960 },
1961 {
1962 {
1963 {static_cast<int32_t>(clearX), 0}, // VkOffset2D offset;
1964 {clearWidth, m_params.imageExtent.height} // VkExtent2D extent;
1965 }, // VkRect2D rect;
1966 m_params.clearLayerRange.baseArrayLayer, // uint32_t baseArrayLayer;
1967 m_params.clearLayerRange.layerCount // uint32_t layerCount;
1968 }};
1969
1970 clearRects.push_back(rects[0]);
1971 clearRects.push_back(rects[1]);
1972 }
1973
1974 beginCommandBuffer(0);
1975
1976 pipelineImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
1977 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
1978 0, // VkAccessFlags srcAccessMask
1979 accessMask, // VkAccessFlags dstAccessMask
1980 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1981 attachmentLayout, // VkImageLayout newLayout;
1982 aspectMask); // VkImageAspectFlags aspectMask;
1983
1984 if (!isDepthStencil && (m_params.imageSampleCount > VK_SAMPLE_COUNT_1_BIT))
1985 pipelineMultisampleImageBarrier(VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, // VkPipelineStageFlags srcStageMask
1986 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, // VkPipelineStageFlags dstStageMask
1987 0, // VkAccessFlags srcAccessMask
1988 accessMask, // VkAccessFlags dstAccessMask
1989 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout;
1990 attachmentLayout, // VkImageLayout newLayout;
1991 aspectMask); // VkImageAspectFlags aspectMask;
1992
1993 beginRenderPass(VK_SUBPASS_CONTENTS_INLINE, m_params.initValue);
1994 m_vkd.cmdClearAttachments(*m_commandBuffer, 1, &clearAttachment, static_cast<uint32_t>(clearRects.size()),
1995 &clearRects[0]);
1996 endRenderPass(m_vkd, *m_commandBuffer);
1997
1998 pipelineImageBarrier(VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, // VkPipelineStageFlags srcStageMask
1999 VK_PIPELINE_STAGE_TRANSFER_BIT, // VkPipelineStageFlags dstStageMask
2000 accessMask, // VkAccessFlags srcAccessMask
2001 VK_ACCESS_TRANSFER_READ_BIT, // VkAccessFlags dstAccessMask
2002 attachmentLayout, // VkImageLayout oldLayout;
2003 VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout newLayout;
2004 aspectMask); // VkImageAspectFlags aspectMask;
2005
2006 endCommandBuffer();
2007 submitCommandBuffer();
2008
2009 return verifyResultImage("cmdClearAttachments passed", clearCoords);
2010 }
2011
2012 private:
2013 const ClearType m_clearType;
2014 };
2015
2016 class PartialClearAttachmentTestInstance : public ClearAttachmentTestInstance
2017 {
2018 public:
PartialClearAttachmentTestInstance(Context & context,const TestParams & testParams)2019 PartialClearAttachmentTestInstance(Context &context, const TestParams &testParams)
2020 : ClearAttachmentTestInstance(context, testParams, PARTIAL_CLEAR)
2021 {
2022 }
2023 };
2024
makeClearColorValue(VkFormat format,float r,float g,float b,float a)2025 VkClearValue makeClearColorValue(VkFormat format, float r, float g, float b, float a)
2026 {
2027 const TextureFormat tcuFormat = mapVkFormat(format);
2028 VkClearValue clearValue;
2029
2030 if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_FLOATING_POINT ||
2031 getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_SIGNED_FIXED_POINT ||
2032 getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT)
2033 {
2034 clearValue.color.float32[0] = r;
2035 clearValue.color.float32[1] = g;
2036 clearValue.color.float32[2] = b;
2037 clearValue.color.float32[3] = a;
2038 }
2039 else if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2040 {
2041 UVec4 maxValues = getFormatMaxUintValue(tcuFormat);
2042
2043 clearValue.color.uint32[0] = (uint32_t)((float)maxValues[0] * r);
2044 clearValue.color.uint32[1] = (uint32_t)((float)maxValues[1] * g);
2045 clearValue.color.uint32[2] = (uint32_t)((float)maxValues[2] * b);
2046 clearValue.color.uint32[3] = (uint32_t)((float)maxValues[3] * a);
2047 }
2048 else if (getTextureChannelClass(tcuFormat.type) == TEXTURECHANNELCLASS_SIGNED_INTEGER)
2049 {
2050 IVec4 maxValues = getFormatMaxIntValue(tcuFormat);
2051
2052 clearValue.color.int32[0] = (uint32_t)((float)maxValues[0] * r);
2053 clearValue.color.int32[1] = (uint32_t)((float)maxValues[1] * g);
2054 clearValue.color.int32[2] = (uint32_t)((float)maxValues[2] * b);
2055 clearValue.color.int32[3] = (uint32_t)((float)maxValues[3] * a);
2056 }
2057 else
2058 DE_FATAL("Unknown channel class");
2059
2060 return clearValue;
2061 }
2062
2063 enum class ClearColor64BitCase
2064 {
2065 PACK,
2066 INIT,
2067 };
2068
2069 // The expected value will always use the packed format, for clarity. We will handle it that way when verifying values.
makeClearColorValue64(uint32_t level,ClearColor64BitCase case64,VkClearValue * clear,VkClearValue * expected=nullptr)2070 void makeClearColorValue64(uint32_t level, ClearColor64BitCase case64, VkClearValue *clear,
2071 VkClearValue *expected = nullptr)
2072 {
2073 DE_ASSERT(level <= 1u);
2074
2075 if (case64 == ClearColor64BitCase::PACK)
2076 {
2077 // We can pack 2 colors in the 4 elements.
2078 const uint32_t lsb[2] = {0x7FFFFFFFu - level, 0x7FFFFFF7u - level}; // Low bits for each number.
2079 const uint32_t msb[2] = {0xFFFFFFFFu, 0xFFFFFFFFu}; // High bits for each number.
2080
2081 const uint64_t colors[2] = {
2082 ((static_cast<uint64_t>(msb[0]) << 32u) | static_cast<uint64_t>(lsb[0])),
2083 ((static_cast<uint64_t>(msb[1]) << 32u) | static_cast<uint64_t>(lsb[1])),
2084 };
2085
2086 deMemcpy(&(clear->color.uint32[0]), &(colors[0]), sizeof(uint64_t));
2087 deMemcpy(&(clear->color.uint32[2]), &(colors[1]), sizeof(uint64_t));
2088
2089 if (expected)
2090 {
2091 *expected = *clear;
2092 }
2093 }
2094 else if (case64 == ClearColor64BitCase::INIT)
2095 {
2096 deMemset(clear, 0, sizeof(*clear));
2097 if (expected)
2098 *expected = *clear;
2099 }
2100 else
2101 DE_ASSERT(false);
2102 }
2103
getFormatCaseName(VkFormat format)2104 std::string getFormatCaseName(VkFormat format)
2105 {
2106 return de::toLower(de::toString(getFormatStr(format)).substr(10));
2107 }
2108
getImageTypeCaseName(VkImageType type)2109 const char *getImageTypeCaseName(VkImageType type)
2110 {
2111 const char *s_names[] = {"1d", "2d", "3d"};
2112 return de::getSizedArrayElement<VK_CORE_IMAGE_TYPE_LAST>(s_names, type);
2113 }
2114
getImageTilingCaseName(VkImageTiling tiling)2115 const char *getImageTilingCaseName(VkImageTiling tiling)
2116 {
2117 const char *s_names[] = {
2118 "optimal",
2119 "linear",
2120 };
2121 return de::getSizedArrayElement<VK_CORE_IMAGE_TILING_LAST>(s_names, tiling);
2122 }
2123
getSampleCountName(VkSampleCountFlagBits count)2124 std::string getSampleCountName(VkSampleCountFlagBits count)
2125 {
2126 return "sample_count_" + std::to_string(static_cast<int>(count));
2127 }
2128
createImageClearingTestsCommon(TestContext & testCtx,tcu::TestCaseGroup * imageClearingTests,AllocationKind allocationKind)2129 TestCaseGroup *createImageClearingTestsCommon(TestContext &testCtx, tcu::TestCaseGroup *imageClearingTests,
2130 AllocationKind allocationKind)
2131 {
2132 de::MovePtr<TestCaseGroup> colorImageClearTests(new TestCaseGroup(testCtx, "clear_color_image"));
2133 de::MovePtr<TestCaseGroup> depthStencilImageClearTests(new TestCaseGroup(testCtx, "clear_depth_stencil_image"));
2134 de::MovePtr<TestCaseGroup> colorAttachmentClearTests(new TestCaseGroup(testCtx, "clear_color_attachment"));
2135 de::MovePtr<TestCaseGroup> depthStencilAttachmentClearTests(
2136 new TestCaseGroup(testCtx, "clear_depth_stencil_attachment"));
2137 de::MovePtr<TestCaseGroup> partialColorAttachmentClearTests(
2138 new TestCaseGroup(testCtx, "partial_clear_color_attachment"));
2139 de::MovePtr<TestCaseGroup> partialDepthStencilAttachmentClearTests(
2140 new TestCaseGroup(testCtx, "partial_clear_depth_stencil_attachment"));
2141
2142 // Some formats are commented out due to the tcu::TextureFormat does not support them yet.
2143 const VkFormat colorImageFormatsToTest[] = {
2144 VK_FORMAT_R4G4_UNORM_PACK8,
2145 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
2146 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
2147 VK_FORMAT_R5G6B5_UNORM_PACK16,
2148 VK_FORMAT_B5G6R5_UNORM_PACK16,
2149 VK_FORMAT_R5G5B5A1_UNORM_PACK16,
2150 VK_FORMAT_B5G5R5A1_UNORM_PACK16,
2151 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
2152 #ifndef CTS_USES_VULKANSC
2153 VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR,
2154 #endif // CTS_USES_VULKANSC
2155 VK_FORMAT_R8_UNORM,
2156 VK_FORMAT_R8_SNORM,
2157 VK_FORMAT_R8_USCALED,
2158 VK_FORMAT_R8_SSCALED,
2159 VK_FORMAT_R8_UINT,
2160 VK_FORMAT_R8_SINT,
2161 VK_FORMAT_R8_SRGB,
2162 #ifndef CTS_USES_VULKANSC
2163 VK_FORMAT_A8_UNORM_KHR,
2164 #endif // CTS_USES_VULKANSC
2165 VK_FORMAT_R8G8_UNORM,
2166 VK_FORMAT_R8G8_SNORM,
2167 VK_FORMAT_R8G8_USCALED,
2168 VK_FORMAT_R8G8_SSCALED,
2169 VK_FORMAT_R8G8_UINT,
2170 VK_FORMAT_R8G8_SINT,
2171 VK_FORMAT_R8G8_SRGB,
2172 VK_FORMAT_R8G8B8_UNORM,
2173 VK_FORMAT_R8G8B8_SNORM,
2174 VK_FORMAT_R8G8B8_USCALED,
2175 VK_FORMAT_R8G8B8_SSCALED,
2176 VK_FORMAT_R8G8B8_UINT,
2177 VK_FORMAT_R8G8B8_SINT,
2178 VK_FORMAT_R8G8B8_SRGB,
2179 VK_FORMAT_B8G8R8_UNORM,
2180 VK_FORMAT_B8G8R8_SNORM,
2181 VK_FORMAT_B8G8R8_USCALED,
2182 VK_FORMAT_B8G8R8_SSCALED,
2183 VK_FORMAT_B8G8R8_UINT,
2184 VK_FORMAT_B8G8R8_SINT,
2185 VK_FORMAT_B8G8R8_SRGB,
2186 VK_FORMAT_R8G8B8A8_UNORM,
2187 VK_FORMAT_R8G8B8A8_SNORM,
2188 VK_FORMAT_R8G8B8A8_USCALED,
2189 VK_FORMAT_R8G8B8A8_SSCALED,
2190 VK_FORMAT_R8G8B8A8_UINT,
2191 VK_FORMAT_R8G8B8A8_SINT,
2192 VK_FORMAT_R8G8B8A8_SRGB,
2193 VK_FORMAT_B8G8R8A8_UNORM,
2194 VK_FORMAT_B8G8R8A8_SNORM,
2195 VK_FORMAT_B8G8R8A8_USCALED,
2196 VK_FORMAT_B8G8R8A8_SSCALED,
2197 VK_FORMAT_B8G8R8A8_UINT,
2198 VK_FORMAT_B8G8R8A8_SINT,
2199 VK_FORMAT_B8G8R8A8_SRGB,
2200 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
2201 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
2202 VK_FORMAT_A8B8G8R8_USCALED_PACK32,
2203 VK_FORMAT_A8B8G8R8_SSCALED_PACK32,
2204 VK_FORMAT_A8B8G8R8_UINT_PACK32,
2205 VK_FORMAT_A8B8G8R8_SINT_PACK32,
2206 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
2207 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
2208 VK_FORMAT_A2R10G10B10_SNORM_PACK32,
2209 VK_FORMAT_A2R10G10B10_USCALED_PACK32,
2210 VK_FORMAT_A2R10G10B10_SSCALED_PACK32,
2211 VK_FORMAT_A2R10G10B10_UINT_PACK32,
2212 VK_FORMAT_A2R10G10B10_SINT_PACK32,
2213 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
2214 VK_FORMAT_A2B10G10R10_SNORM_PACK32,
2215 VK_FORMAT_A2B10G10R10_USCALED_PACK32,
2216 VK_FORMAT_A2B10G10R10_SSCALED_PACK32,
2217 VK_FORMAT_A2B10G10R10_UINT_PACK32,
2218 VK_FORMAT_A2B10G10R10_SINT_PACK32,
2219 VK_FORMAT_R16_UNORM,
2220 VK_FORMAT_R16_SNORM,
2221 VK_FORMAT_R16_USCALED,
2222 VK_FORMAT_R16_SSCALED,
2223 VK_FORMAT_R16_UINT,
2224 VK_FORMAT_R16_SINT,
2225 VK_FORMAT_R16_SFLOAT,
2226 VK_FORMAT_R16G16_UNORM,
2227 VK_FORMAT_R16G16_SNORM,
2228 VK_FORMAT_R16G16_USCALED,
2229 VK_FORMAT_R16G16_SSCALED,
2230 VK_FORMAT_R16G16_UINT,
2231 VK_FORMAT_R16G16_SINT,
2232 VK_FORMAT_R16G16_SFLOAT,
2233 VK_FORMAT_R16G16B16_UNORM,
2234 VK_FORMAT_R16G16B16_SNORM,
2235 VK_FORMAT_R16G16B16_USCALED,
2236 VK_FORMAT_R16G16B16_SSCALED,
2237 VK_FORMAT_R16G16B16_UINT,
2238 VK_FORMAT_R16G16B16_SINT,
2239 VK_FORMAT_R16G16B16_SFLOAT,
2240 VK_FORMAT_R16G16B16A16_UNORM,
2241 VK_FORMAT_R16G16B16A16_SNORM,
2242 VK_FORMAT_R16G16B16A16_USCALED,
2243 VK_FORMAT_R16G16B16A16_SSCALED,
2244 VK_FORMAT_R16G16B16A16_UINT,
2245 VK_FORMAT_R16G16B16A16_SINT,
2246 VK_FORMAT_R16G16B16A16_SFLOAT,
2247 VK_FORMAT_R32_UINT,
2248 VK_FORMAT_R32_SINT,
2249 VK_FORMAT_R32_SFLOAT,
2250 VK_FORMAT_R32G32_UINT,
2251 VK_FORMAT_R32G32_SINT,
2252 VK_FORMAT_R32G32_SFLOAT,
2253 VK_FORMAT_R32G32B32_UINT,
2254 VK_FORMAT_R32G32B32_SINT,
2255 VK_FORMAT_R32G32B32_SFLOAT,
2256 VK_FORMAT_R32G32B32A32_UINT,
2257 VK_FORMAT_R32G32B32A32_SINT,
2258 VK_FORMAT_R32G32B32A32_SFLOAT,
2259 VK_FORMAT_R64_UINT,
2260 VK_FORMAT_R64_SINT,
2261 // VK_FORMAT_R64_SFLOAT,
2262 VK_FORMAT_R64G64_UINT,
2263 VK_FORMAT_R64G64_SINT,
2264 // VK_FORMAT_R64G64_SFLOAT,
2265 // VK_FORMAT_R64G64B64_UINT,
2266 // VK_FORMAT_R64G64B64_SINT,
2267 // VK_FORMAT_R64G64B64_SFLOAT,
2268 // VK_FORMAT_R64G64B64A64_UINT,
2269 // VK_FORMAT_R64G64B64A64_SINT,
2270 // VK_FORMAT_R64G64B64A64_SFLOAT,
2271 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
2272 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
2273 // VK_FORMAT_BC1_RGB_UNORM_BLOCK,
2274 // VK_FORMAT_BC1_RGB_SRGB_BLOCK,
2275 // VK_FORMAT_BC1_RGBA_UNORM_BLOCK,
2276 // VK_FORMAT_BC1_RGBA_SRGB_BLOCK,
2277 // VK_FORMAT_BC2_UNORM_BLOCK,
2278 // VK_FORMAT_BC2_SRGB_BLOCK,
2279 // VK_FORMAT_BC3_UNORM_BLOCK,
2280 // VK_FORMAT_BC3_SRGB_BLOCK,
2281 // VK_FORMAT_BC4_UNORM_BLOCK,
2282 // VK_FORMAT_BC4_SNORM_BLOCK,
2283 // VK_FORMAT_BC5_UNORM_BLOCK,
2284 // VK_FORMAT_BC5_SNORM_BLOCK,
2285 // VK_FORMAT_BC6H_UFLOAT_BLOCK,
2286 // VK_FORMAT_BC6H_SFLOAT_BLOCK,
2287 // VK_FORMAT_BC7_UNORM_BLOCK,
2288 // VK_FORMAT_BC7_SRGB_BLOCK,
2289 // VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK,
2290 // VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK,
2291 // VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK,
2292 // VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK,
2293 // VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK,
2294 // VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK,
2295 // VK_FORMAT_EAC_R11_UNORM_BLOCK,
2296 // VK_FORMAT_EAC_R11_SNORM_BLOCK,
2297 // VK_FORMAT_EAC_R11G11_UNORM_BLOCK,
2298 // VK_FORMAT_EAC_R11G11_SNORM_BLOCK,
2299 // VK_FORMAT_ASTC_4x4_UNORM_BLOCK,
2300 // VK_FORMAT_ASTC_4x4_SRGB_BLOCK,
2301 // VK_FORMAT_ASTC_5x4_UNORM_BLOCK,
2302 // VK_FORMAT_ASTC_5x4_SRGB_BLOCK,
2303 // VK_FORMAT_ASTC_5x5_UNORM_BLOCK,
2304 // VK_FORMAT_ASTC_5x5_SRGB_BLOCK,
2305 // VK_FORMAT_ASTC_6x5_UNORM_BLOCK,
2306 // VK_FORMAT_ASTC_6x5_SRGB_BLOCK,
2307 // VK_FORMAT_ASTC_6x6_UNORM_BLOCK,
2308 // VK_FORMAT_ASTC_6x6_SRGB_BLOCK,
2309 // VK_FORMAT_ASTC_8x5_UNORM_BLOCK,
2310 // VK_FORMAT_ASTC_8x5_SRGB_BLOCK,
2311 // VK_FORMAT_ASTC_8x6_UNORM_BLOCK,
2312 // VK_FORMAT_ASTC_8x6_SRGB_BLOCK,
2313 // VK_FORMAT_ASTC_8x8_UNORM_BLOCK,
2314 // VK_FORMAT_ASTC_8x8_SRGB_BLOCK,
2315 // VK_FORMAT_ASTC_10x5_UNORM_BLOCK,
2316 // VK_FORMAT_ASTC_10x5_SRGB_BLOCK,
2317 // VK_FORMAT_ASTC_10x6_UNORM_BLOCK,
2318 // VK_FORMAT_ASTC_10x6_SRGB_BLOCK,
2319 // VK_FORMAT_ASTC_10x8_UNORM_BLOCK,
2320 // VK_FORMAT_ASTC_10x8_SRGB_BLOCK,
2321 // VK_FORMAT_ASTC_10x10_UNORM_BLOCK,
2322 // VK_FORMAT_ASTC_10x10_SRGB_BLOCK,
2323 // VK_FORMAT_ASTC_12x10_UNORM_BLOCK,
2324 // VK_FORMAT_ASTC_12x10_SRGB_BLOCK,
2325 // VK_FORMAT_ASTC_12x12_UNORM_BLOCK,
2326 // VK_FORMAT_ASTC_12x12_SRGB_BLOCK,
2327
2328 VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT,
2329 VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT,
2330 };
2331 const size_t numOfColorImageFormatsToTest = DE_LENGTH_OF_ARRAY(colorImageFormatsToTest);
2332
2333 const VkFormat depthStencilImageFormatsToTest[] = {
2334 VK_FORMAT_D16_UNORM, VK_FORMAT_X8_D24_UNORM_PACK32, VK_FORMAT_D32_SFLOAT, VK_FORMAT_S8_UINT,
2335 VK_FORMAT_D16_UNORM_S8_UINT, VK_FORMAT_D24_UNORM_S8_UINT, VK_FORMAT_D32_SFLOAT_S8_UINT};
2336 const size_t numOfDepthStencilImageFormatsToTest = DE_LENGTH_OF_ARRAY(depthStencilImageFormatsToTest);
2337
2338 struct ClearTestColorParams
2339 {
2340 bool matchTextureChannelClass;
2341 TextureChannelClass textureChannelClass;
2342 const char *testNameSuffix;
2343 float clearColors[2][4];
2344 bool useSeparateExpectedColors;
2345 float expectedColors[2][4];
2346 };
2347 const ClearTestColorParams clearColorsToTest[] = {{
2348 false, // matchTextureChannelClass
2349 TEXTURECHANNELCLASS_LAST, // textureChannelClass
2350 "", // testNameSuffix
2351 {
2352 {0.1f, 0.5f, 0.3f, 0.9f}, // clearColors[0]
2353 {0.3f, 0.6f, 0.2f, 0.7f}, // clearColors[1]
2354 },
2355 false, // useSeparateExpectedColors
2356 {} // expectedColors
2357 },
2358 {true, // matchTextureChannelClass
2359 TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT, // textureChannelClass
2360 "_clamp_input", // testNameSuffix
2361 {
2362 {-0.1f, -1e6f, -0.3f, -1.5f}, // clearColors[0]
2363 {-1.5f, -0.6f, -1e6f, -0.7f}, // clearColors[1]
2364 },
2365 true, // useSeparateExpectedColors
2366 {
2367 {0.0f, 0.0f, 0.0f, 0.0f}, // expectedColors[0]
2368 {0.0f, 0.0f, 0.0f, 0.0f}, // expectedColors[1]
2369 }}};
2370 const size_t numOfClearColorsToTest = DE_LENGTH_OF_ARRAY(clearColorsToTest);
2371
2372 std::vector<VkSampleCountFlagBits> sampleCountsToTest = {VK_SAMPLE_COUNT_2_BIT, VK_SAMPLE_COUNT_4_BIT,
2373 VK_SAMPLE_COUNT_8_BIT, VK_SAMPLE_COUNT_16_BIT,
2374 VK_SAMPLE_COUNT_32_BIT, VK_SAMPLE_COUNT_64_BIT};
2375
2376 struct ImageLayerParams
2377 {
2378 uint32_t imageLayerCount;
2379 LayerRange imageViewRange;
2380 LayerRange clearLayerRange;
2381 bool twoStep;
2382 const char *testName;
2383 bool isCube;
2384 };
2385 const ImageLayerParams imageLayerParamsToTest[] = {{
2386 1u, // imageLayerCount
2387 {0u, 1u}, // imageViewRange
2388 {0u, 1u}, // clearLayerRange
2389 false, // twoStep
2390 "single_layer", // testName
2391 false // isCube
2392 },
2393 {
2394 16u, // imageLayerCount
2395 {3u, 12u}, // imageViewRange
2396 {2u, 5u}, // clearLayerRange
2397 false, // twoStep
2398 "multiple_layers", // testName
2399 false // isCube
2400 },
2401 {
2402 15u, // imageLayerCount
2403 {3u, 6u}, // imageViewRange
2404 {2u, 1u}, // clearLayerRange
2405 false, // twoStep
2406 "cube_layers", // testName
2407 true // isCube
2408 },
2409 {
2410 16u, // imageLayerCount
2411 {3u, 12u}, // imageViewRange
2412 {8u, VK_REMAINING_ARRAY_LAYERS}, // clearLayerRange
2413 false, // twoStep
2414 "remaining_array_layers", // testName
2415 false // isCube
2416 },
2417 {
2418 16u, // imageLayerCount
2419 {3u, 12u}, // imageViewRange
2420 {8u, VK_REMAINING_ARRAY_LAYERS}, // clearLayerRange
2421 true, // twoStep
2422 "remaining_array_layers_twostep", // testName
2423 false // isCube
2424 }};
2425
2426 // Include test cases with VK_REMAINING_ARRAY_LAYERS when using vkCmdClearColorImage
2427 const size_t numOfImageLayerParamsToTest = DE_LENGTH_OF_ARRAY(imageLayerParamsToTest);
2428
2429 // Exclude test cases with VK_REMAINING_ARRAY_LAYERS when using vkCmdClearAttachments
2430 const size_t numOfAttachmentLayerParamsToTest = numOfImageLayerParamsToTest - 2;
2431
2432 const VkExtent3D imageDimensions[] = {{256, 1, 1}, {256, 256, 1}, {256, 256, 16}, {200, 1, 1},
2433 {200, 180, 1}, {200, 180, 16}, {71, 1, 1}, {1, 33, 1},
2434 {55, 21, 11}, {64, 11, 1}, {33, 128, 1}, {32, 29, 3}};
2435
2436 // Clear color image
2437 {
2438 const VkImageType imageTypesToTest[] = {VK_IMAGE_TYPE_1D, VK_IMAGE_TYPE_2D, VK_IMAGE_TYPE_3D};
2439 const size_t numOfImageTypesToTest = DE_LENGTH_OF_ARRAY(imageTypesToTest);
2440
2441 const VkImageTiling imageTilingsToTest[] = {
2442 VK_IMAGE_TILING_OPTIMAL,
2443 VK_IMAGE_TILING_LINEAR,
2444 };
2445 const size_t numOfImageTilingsToTest = DE_LENGTH_OF_ARRAY(imageTilingsToTest);
2446
2447 for (size_t imageTypeIndex = 0; imageTypeIndex < numOfImageTypesToTest; ++imageTypeIndex)
2448 {
2449 de::MovePtr<TestCaseGroup> imageTypeGroup(
2450 new TestCaseGroup(testCtx, getImageTypeCaseName(imageTypesToTest[imageTypeIndex])));
2451
2452 for (size_t imageTilingIndex = 0; imageTilingIndex < numOfImageTilingsToTest; ++imageTilingIndex)
2453 {
2454 de::MovePtr<TestCaseGroup> imageTilingGroup(
2455 new TestCaseGroup(testCtx, getImageTilingCaseName(imageTilingsToTest[imageTilingIndex])));
2456
2457 for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfImageLayerParamsToTest;
2458 ++imageLayerParamsIndex)
2459 {
2460 // 3D ARRAY images are not supported
2461 if (imageLayerParamsToTest[imageLayerParamsIndex].imageLayerCount > 1u &&
2462 imageTypesToTest[imageTypeIndex] == VK_IMAGE_TYPE_3D)
2463 continue;
2464
2465 // CUBE images are not tested in clear image tests (they are tested in clear attachment tests)
2466 if (imageLayerParamsToTest[imageLayerParamsIndex].isCube)
2467 continue;
2468
2469 de::MovePtr<TestCaseGroup> imageLayersGroup(
2470 new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName));
2471
2472 for (size_t imageDimensionsIndex = 0; imageDimensionsIndex < DE_LENGTH_OF_ARRAY(imageDimensions);
2473 ++imageDimensionsIndex)
2474 {
2475 const VkExtent3D dimensions = imageDimensions[imageDimensionsIndex];
2476 const std::string dimensionsString =
2477 extentToString(dimensions, imageTypesToTest[imageTypeIndex]);
2478
2479 if (imageTypesToTest[imageTypeIndex] == VK_IMAGE_TYPE_1D && dimensions.height > 1)
2480 continue;
2481 if (imageTypesToTest[imageTypeIndex] == VK_IMAGE_TYPE_2D &&
2482 (dimensions.depth > 1 || dimensions.height == 1))
2483 continue;
2484 if (imageTypesToTest[imageTypeIndex] == VK_IMAGE_TYPE_3D && dimensions.depth == 1)
2485 continue;
2486
2487 for (size_t imageFormatIndex = 0; imageFormatIndex < numOfColorImageFormatsToTest;
2488 ++imageFormatIndex)
2489 {
2490 const VkFormat format = colorImageFormatsToTest[imageFormatIndex];
2491 const TextureFormat tcuFormat = mapVkFormat(format);
2492 const TextureChannelClass channelClass = getTextureChannelClass(tcuFormat.type);
2493 const bool is64Bit = is64Format(tcuFormat);
2494
2495 if (!is64Bit)
2496 {
2497 for (size_t clearColorIndex = 0; clearColorIndex < numOfClearColorsToTest;
2498 ++clearColorIndex)
2499 {
2500 const ClearTestColorParams &colorParams = clearColorsToTest[clearColorIndex];
2501
2502 if (colorParams.matchTextureChannelClass &&
2503 channelClass != colorParams.textureChannelClass)
2504 continue;
2505
2506 VkClearValue clearColors[2] = {
2507 makeClearColorValue(
2508 format, colorParams.clearColors[0][0], colorParams.clearColors[0][1],
2509 colorParams.clearColors[0][2], colorParams.clearColors[0][3]),
2510 makeClearColorValue(
2511 format, colorParams.clearColors[1][0], colorParams.clearColors[1][1],
2512 colorParams.clearColors[1][2], colorParams.clearColors[1][3]),
2513 };
2514 VkClearValue expectedColors[2];
2515 if (clearColorsToTest[clearColorIndex].useSeparateExpectedColors)
2516 {
2517 expectedColors[0] = makeClearColorValue(
2518 format, colorParams.expectedColors[0][0], colorParams.expectedColors[0][1],
2519 colorParams.expectedColors[0][2], colorParams.expectedColors[0][3]);
2520 expectedColors[1] = makeClearColorValue(
2521 format, colorParams.expectedColors[1][0], colorParams.expectedColors[1][1],
2522 colorParams.expectedColors[1][2], colorParams.expectedColors[1][3]);
2523 }
2524 else
2525 {
2526 expectedColors[0] = clearColors[0];
2527 expectedColors[1] = clearColors[1];
2528 }
2529
2530 std::string testCaseName =
2531 getFormatCaseName(format) + dimensionsString + colorParams.testNameSuffix;
2532 TestParams testParams = {
2533 false, // bool useSingleMipLevel;
2534 imageTypesToTest[imageTypeIndex], // VkImageType imageType;
2535 format, // VkFormat imageFormat;
2536 imageTilingsToTest[imageTilingIndex], // VkImageTiling imageTiling;
2537 dimensions, // VkExtent3D imageExtent;
2538 imageLayerParamsToTest[imageLayerParamsIndex]
2539 .imageLayerCount, // uint32_t imageLayerCount;
2540 {0u, imageLayerParamsToTest[imageLayerParamsIndex]
2541 .imageLayerCount}, // LayerRange imageViewLayerRange;
2542 makeClearColorValue(format, 0.0f, 0.0f, 0.0f,
2543 0.0f), // VkClearValue initValue;
2544 {
2545 clearColors[0], // VkClearValue clearValue[0];
2546 clearColors[1], // VkClearValue clearValue[1];
2547 },
2548 clearColorsToTest[clearColorIndex]
2549 .useSeparateExpectedColors, // bool useSeparateExpectedClearValue;
2550 {
2551 expectedColors[0], // VkClearValue expectedClearValue[0];
2552 expectedColors[1], // VkClearValue expectedClearValue[1];
2553 },
2554 imageLayerParamsToTest[imageLayerParamsIndex]
2555 .clearLayerRange, // LayerRange clearLayerRange;
2556 allocationKind, // AllocationKind allocationKind;
2557 false, // bool isCube;
2558 SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE, // SeparateDepthStencilLayoutMode separateDepthStencilLayoutMode;
2559 false, // bool isColorMultipleSubresourceRangeTest;
2560 VK_SAMPLE_COUNT_1_BIT // VkSampleCountFlagBits imageSampleCount
2561 };
2562
2563 if (!imageLayerParamsToTest[imageLayerParamsIndex].twoStep)
2564 {
2565 // Clear Color Image
2566 imageLayersGroup->addChild(
2567 new ImageClearingTestCase<ClearColorImageTestInstance>(
2568 testCtx, testCaseName, testParams));
2569
2570 // Removing linear images as the miplevels may be 1
2571 if (imageTilingsToTest[imageTilingIndex] == VK_IMAGE_TILING_OPTIMAL)
2572 {
2573 testParams.isColorMultipleSubresourceRangeTest = true;
2574 testCaseName += "_multiple_subresourcerange";
2575 // Clear Color Image with two ranges
2576 imageLayersGroup->addChild(
2577 new ImageClearingTestCase<
2578 ClearColorImageMultipleSubresourceRangeTestInstance>(
2579 testCtx, testCaseName, testParams));
2580 }
2581 }
2582 else
2583 {
2584 // Clear Color Image
2585 imageLayersGroup->addChild(
2586 new ImageClearingTestCase<TwoStepClearColorImageTestInstance>(
2587 testCtx, testCaseName, testParams));
2588 }
2589 }
2590 }
2591 else
2592 {
2593 {
2594 // The expected values will be packed, so we cannot verify more than 2 channels.
2595 const auto numUsedChannels = tcu::getNumUsedChannels(tcuFormat.order);
2596 DE_UNREF(numUsedChannels); // For release builds.
2597 DE_ASSERT(numUsedChannels <= 2);
2598 }
2599
2600 {
2601 VkClearValue initValue;
2602 deMemset(&initValue, 0, sizeof(initValue));
2603 makeClearColorValue64(0u, ClearColor64BitCase::INIT, &initValue);
2604
2605 VkClearValue clearColors[2];
2606 VkClearValue expectedColors[2];
2607
2608 deMemset(clearColors, 0, sizeof(clearColors));
2609 deMemset(expectedColors, 0, sizeof(expectedColors));
2610
2611 for (size_t i = 0; i < de::arrayLength(clearColors); ++i)
2612 makeClearColorValue64(static_cast<uint32_t>(i), ClearColor64BitCase::PACK,
2613 clearColors + i, expectedColors + i);
2614
2615 std::string testCaseName = getFormatCaseName(format) + dimensionsString;
2616 TestParams testParams = {
2617 false, // bool useSingleMipLevel;
2618 imageTypesToTest[imageTypeIndex], // VkImageType imageType;
2619 format, // VkFormat imageFormat;
2620 imageTilingsToTest[imageTilingIndex], // VkImageTiling imageTiling;
2621 dimensions, // VkExtent3D imageExtent;
2622 imageLayerParamsToTest[imageLayerParamsIndex]
2623 .imageLayerCount, // uint32_t imageLayerCount;
2624 {0u, imageLayerParamsToTest[imageLayerParamsIndex]
2625 .imageLayerCount}, // LayerRange imageViewLayerRange;
2626 initValue, // VkClearValue initValue;
2627 {
2628 clearColors[0], // VkClearValue clearValue[0];
2629 clearColors[1], // VkClearValue clearValue[1];
2630 },
2631 true, // bool useSeparateExpectedClearValue;
2632 {
2633 expectedColors[0], // VkClearValue expectedClearValue[0];
2634 expectedColors[1], // VkClearValue expectedClearValue[1];
2635 },
2636 imageLayerParamsToTest[imageLayerParamsIndex]
2637 .clearLayerRange, // LayerRange clearLayerRange;
2638 allocationKind, // AllocationKind allocationKind;
2639 false, // bool isCube;
2640 SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE, // SeparateDepthStencilLayoutMode separateDepthStencilLayoutMode;
2641 false, // bool isColorMultipleSubresourceRangeTest;
2642 VK_SAMPLE_COUNT_1_BIT // VkSampleCountFlagBits imageSampleCount
2643 };
2644
2645 if (!imageLayerParamsToTest[imageLayerParamsIndex].twoStep)
2646 {
2647 // Clear Color Image
2648 imageLayersGroup->addChild(
2649 new ImageClearingTestCase<ClearColorImageTestInstance>(
2650 testCtx, testCaseName, testParams));
2651
2652 // Removing linear images as the miplevels may be 1
2653 if (imageTilingsToTest[imageTilingIndex] == VK_IMAGE_TILING_OPTIMAL)
2654 {
2655 testParams.isColorMultipleSubresourceRangeTest = true;
2656 testCaseName += "_multiple_subresourcerange";
2657 // Clear Color Image with two ranges
2658 imageLayersGroup->addChild(
2659 new ImageClearingTestCase<
2660 ClearColorImageMultipleSubresourceRangeTestInstance>(
2661 testCtx, testCaseName, testParams));
2662 }
2663 }
2664 else
2665 {
2666 // Clear Color Image
2667 imageLayersGroup->addChild(
2668 new ImageClearingTestCase<TwoStepClearColorImageTestInstance>(
2669 testCtx, testCaseName, testParams));
2670 }
2671 }
2672 }
2673 }
2674 }
2675 imageTilingGroup->addChild(imageLayersGroup.release());
2676 }
2677 imageTypeGroup->addChild(imageTilingGroup.release());
2678 }
2679 colorImageClearTests->addChild(imageTypeGroup.release());
2680 }
2681 imageClearingTests->addChild(colorImageClearTests.release());
2682 }
2683
2684 // Clear depth/stencil image
2685 {
2686 const VkImageType imageTypesToTest[]{VK_IMAGE_TYPE_2D, VK_IMAGE_TYPE_3D};
2687 const size_t numOfImageTypesToTest = DE_LENGTH_OF_ARRAY(imageTypesToTest);
2688
2689 for (size_t imageTypeIndex = 0; imageTypeIndex < numOfImageTypesToTest; ++imageTypeIndex)
2690 {
2691 de::MovePtr<TestCaseGroup> imageTypeGroup(
2692 new TestCaseGroup(testCtx, getImageTypeCaseName(imageTypesToTest[imageTypeIndex])));
2693
2694 for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfImageLayerParamsToTest;
2695 ++imageLayerParamsIndex)
2696 {
2697 // CUBE images are not tested in clear image tests (they are tested in clear attachment tests)
2698 if (imageLayerParamsToTest[imageLayerParamsIndex].isCube)
2699 continue;
2700
2701 de::MovePtr<TestCaseGroup> imageLayersGroup(
2702 new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName));
2703
2704 for (size_t imageDimensionsIndex = 0; imageDimensionsIndex < DE_LENGTH_OF_ARRAY(imageDimensions);
2705 ++imageDimensionsIndex)
2706 {
2707 const VkImageType imageType = imageTypesToTest[imageTypeIndex];
2708 const VkExtent3D dimensions = imageDimensions[imageDimensionsIndex];
2709 const std::string dimensionsString = extentToString(dimensions, imageType);
2710
2711 if (imageType == VK_IMAGE_TYPE_2D && (dimensions.depth > 1 || dimensions.height == 1))
2712 continue;
2713 if (imageType == VK_IMAGE_TYPE_3D && dimensions.depth == 1)
2714 continue;
2715
2716 for (size_t imageFormatIndex = 0; imageFormatIndex < numOfDepthStencilImageFormatsToTest;
2717 ++imageFormatIndex)
2718 {
2719 const VkFormat format = depthStencilImageFormatsToTest[imageFormatIndex];
2720 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(format).order);
2721 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(format).order);
2722 const int separateLayoutsLoopCount = (hasDepth && hasStencil) ? 3 : 1;
2723
2724 for (int separateDepthStencilLayoutMode = 0;
2725 separateDepthStencilLayoutMode < separateLayoutsLoopCount;
2726 ++separateDepthStencilLayoutMode)
2727 {
2728 const std::string testCaseName =
2729 getFormatCaseName(format) +
2730 ((separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_DEPTH) ?
2731 "_separate_layouts_depth" :
2732 (separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_STENCIL) ?
2733 "_separate_layouts_stencil" :
2734 "") +
2735 dimensionsString;
2736 TestParams testParams{
2737 true, // bool useSingleMipLevel;
2738 imageType, // VkImageType imageType;
2739 format, // VkFormat format;
2740 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2741 dimensions, // VkExtent3D extent;
2742 imageLayerParamsToTest[imageLayerParamsIndex]
2743 .imageLayerCount, // uint32_t imageLayerCount;
2744 {0u, imageLayerParamsToTest[imageLayerParamsIndex]
2745 .imageLayerCount}, // LayerRange imageViewLayerRange;
2746 makeClearValueDepthStencil(0.0f, 0u), // VkClearValue initValue
2747 {
2748 makeClearValueDepthStencil(0.1f,
2749 0x06), // VkClearValue clearValue[0];
2750 makeClearValueDepthStencil(0.3f,
2751 0x04), // VkClearValue clearValue[1];
2752 },
2753 false, // bool useSeparateExpectedClearValue;
2754 {}, // VkClearValue[2] expectedClearValue;
2755 imageLayerParamsToTest[imageLayerParamsIndex]
2756 .clearLayerRange, // LayerRange clearLayerRange;
2757 allocationKind, // AllocationKind allocationKind;
2758 false, // bool isCube;
2759 SeparateDepthStencilLayoutMode(
2760 separateDepthStencilLayoutMode), // SeparateDepthStencilLayoutMode separateDepthStencilLayoutMode;
2761 false, // bool isColorMultipleSubresourceRangeTest;
2762 VK_SAMPLE_COUNT_1_BIT // VkSampleCountFlagBits imageSampleCount
2763 };
2764
2765 if (!imageLayerParamsToTest[imageLayerParamsIndex].twoStep)
2766 {
2767 // Clear Depth/Stencil Image
2768 imageLayersGroup->addChild(
2769 new ImageClearingTestCase<ClearDepthStencilImageTestInstance>(testCtx, testCaseName,
2770 testParams));
2771
2772 if (separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE &&
2773 hasDepth && hasStencil)
2774 {
2775 const std::string testCaseNameRanges =
2776 getFormatCaseName(format) + dimensionsString + "_multiple_subresourcerange";
2777 // Clear Depth/Stencil Image with ranges
2778 imageLayersGroup->addChild(
2779 new ImageClearingTestCase<
2780 ClearDepthStencilImageMultipleSubresourceRangeTestInstance>(
2781 testCtx, testCaseNameRanges, testParams));
2782 }
2783 }
2784 else
2785 {
2786 // Clear Depth/Stencil Image
2787 imageLayersGroup->addChild(
2788 new ImageClearingTestCase<TwoStepClearDepthStencilImageTestInstance>(
2789 testCtx, testCaseName, testParams));
2790 }
2791 }
2792 }
2793 }
2794 imageTypeGroup->addChild(imageLayersGroup.release());
2795 }
2796 depthStencilImageClearTests->addChild(imageTypeGroup.release());
2797 }
2798 imageClearingTests->addChild(depthStencilImageClearTests.release());
2799 }
2800
2801 // Clear color attachment
2802 {
2803 for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfAttachmentLayerParamsToTest;
2804 ++imageLayerParamsIndex)
2805 {
2806 if (!imageLayerParamsToTest[imageLayerParamsIndex].twoStep)
2807 {
2808 de::MovePtr<TestCaseGroup> colorAttachmentClearLayersGroup(
2809 new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName));
2810 de::MovePtr<TestCaseGroup> partialColorAttachmentClearLayersGroup(
2811 new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName));
2812
2813 for (size_t imageDimensionsIndex = 0; imageDimensionsIndex < DE_LENGTH_OF_ARRAY(imageDimensions);
2814 ++imageDimensionsIndex)
2815 {
2816 const VkExtent3D dimensions = imageDimensions[imageDimensionsIndex];
2817 const std::string dimensionsString = extentToString(dimensions, VK_IMAGE_TYPE_2D);
2818
2819 if (dimensions.height == 1 || dimensions.depth > 1)
2820 continue;
2821
2822 if (imageLayerParamsToTest[imageLayerParamsIndex].isCube && dimensions.width != dimensions.height)
2823 continue;
2824
2825 for (size_t imageFormatIndex = 0; imageFormatIndex < numOfColorImageFormatsToTest;
2826 ++imageFormatIndex)
2827 {
2828 const VkFormat format = colorImageFormatsToTest[imageFormatIndex];
2829 const TextureFormat tcuFormat = mapVkFormat(format);
2830 const TextureChannelClass channelClass = getTextureChannelClass(tcuFormat.type);
2831 const bool is64Bit = is64Format(tcuFormat);
2832
2833 // We will not check color attachments.
2834 if (is64Bit)
2835 continue;
2836
2837 for (size_t clearColorIndex = 0; clearColorIndex < numOfClearColorsToTest; ++clearColorIndex)
2838 {
2839 const ClearTestColorParams &colorParams = clearColorsToTest[clearColorIndex];
2840
2841 if (colorParams.matchTextureChannelClass && channelClass != colorParams.textureChannelClass)
2842 continue;
2843
2844 VkClearValue clearColors[2] = {
2845 makeClearColorValue(format, colorParams.clearColors[0][0],
2846 colorParams.clearColors[0][1], colorParams.clearColors[0][2],
2847 colorParams.clearColors[0][3]),
2848 makeClearColorValue(format, colorParams.clearColors[1][0],
2849 colorParams.clearColors[1][1], colorParams.clearColors[1][2],
2850 colorParams.clearColors[1][3]),
2851 };
2852 VkClearValue expectedColors[2];
2853 if (clearColorsToTest[clearColorIndex].useSeparateExpectedColors)
2854 {
2855 expectedColors[0] = makeClearColorValue(
2856 format, colorParams.expectedColors[0][0], colorParams.expectedColors[0][1],
2857 colorParams.expectedColors[0][2], colorParams.expectedColors[0][3]);
2858 expectedColors[1] = makeClearColorValue(
2859 format, colorParams.expectedColors[1][0], colorParams.expectedColors[1][1],
2860 colorParams.expectedColors[1][2], colorParams.expectedColors[1][3]);
2861 }
2862 else
2863 {
2864 expectedColors[0] = clearColors[0];
2865 expectedColors[1] = clearColors[1];
2866 }
2867
2868 std::string testCaseName =
2869 getFormatCaseName(format) + dimensionsString + colorParams.testNameSuffix;
2870 TestParams testParams = {
2871 true, // bool useSingleMipLevel;
2872 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2873 format, // VkFormat format;
2874 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2875 dimensions, // VkExtent3D extent;
2876 imageLayerParamsToTest[imageLayerParamsIndex]
2877 .imageLayerCount, // uint32_t imageLayerCount;
2878 imageLayerParamsToTest[imageLayerParamsIndex]
2879 .imageViewRange, // LayerRange imageViewLayerRange;
2880 makeClearColorValue(format, 0.2f, 0.1f, 0.7f,
2881 0.8f), // VkClearValue initValue
2882 {
2883 clearColors[0], // VkClearValue clearValue[0];
2884 clearColors[1] // VkClearValue clearValue[1];
2885 },
2886 colorParams.useSeparateExpectedColors, // bool useSeparateExpectedClearValue;
2887 {
2888 expectedColors[0], // VkClearValue expectedClearValue[0];
2889 expectedColors[1] // VkClearValue expectedClearValue[1];
2890 },
2891 imageLayerParamsToTest[imageLayerParamsIndex]
2892 .clearLayerRange, // LayerRange clearLayerRange;
2893 allocationKind, // AllocationKind allocationKind;
2894 imageLayerParamsToTest[imageLayerParamsIndex].isCube, // bool isCube;
2895 SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_NONE, // SeparateDepthStencilLayoutMode separateDepthStencilLayoutMode;
2896 false, // bool isColorMultipleSubresourceRangeTest;
2897 VK_SAMPLE_COUNT_1_BIT // VkSampleCountFlagBits imageSampleCount
2898 };
2899 // Clear Color Attachment
2900 colorAttachmentClearLayersGroup->addChild(
2901 new ImageClearingTestCase<ClearAttachmentTestInstance>(testCtx, testCaseName,
2902 testParams));
2903 if (dimensions.width > 1)
2904 // Partial Clear Color Attachment
2905 partialColorAttachmentClearLayersGroup->addChild(
2906 new ImageClearingTestCase<PartialClearAttachmentTestInstance>(testCtx, testCaseName,
2907 testParams));
2908
2909 if (!imageLayerParamsToTest[imageLayerParamsIndex].isCube &&
2910 !(imageLayerParamsToTest[imageLayerParamsIndex].clearLayerRange.layerCount ==
2911 VK_REMAINING_ARRAY_LAYERS) &&
2912 (dimensions.width > dimensions.height))
2913 {
2914 for (const auto &sampleCount : sampleCountsToTest)
2915 {
2916 const std::string msaaTestCaseName =
2917 testCaseName + "_" + getSampleCountName(sampleCount);
2918 testParams.imageSampleCount = sampleCount;
2919 // Clear Multisample Color Attachment
2920 colorAttachmentClearLayersGroup->addChild(
2921 new ImageClearingTestCase<ClearAttachmentTestInstance>(
2922 testCtx, msaaTestCaseName, testParams));
2923 }
2924 }
2925 }
2926 }
2927 }
2928 colorAttachmentClearTests->addChild(colorAttachmentClearLayersGroup.release());
2929 partialColorAttachmentClearTests->addChild(partialColorAttachmentClearLayersGroup.release());
2930 }
2931 }
2932 imageClearingTests->addChild(colorAttachmentClearTests.release());
2933 imageClearingTests->addChild(partialColorAttachmentClearTests.release());
2934 }
2935
2936 // Clear depth/stencil attachment
2937 {
2938 for (size_t imageLayerParamsIndex = 0; imageLayerParamsIndex < numOfAttachmentLayerParamsToTest;
2939 ++imageLayerParamsIndex)
2940 {
2941 if (!imageLayerParamsToTest[imageLayerParamsIndex].twoStep)
2942 {
2943 de::MovePtr<TestCaseGroup> depthStencilLayersGroup(
2944 new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName));
2945 de::MovePtr<TestCaseGroup> partialDepthStencilLayersGroup(
2946 new TestCaseGroup(testCtx, imageLayerParamsToTest[imageLayerParamsIndex].testName));
2947
2948 for (size_t imageDimensionsIndex = 0; imageDimensionsIndex < DE_LENGTH_OF_ARRAY(imageDimensions);
2949 ++imageDimensionsIndex)
2950 {
2951 const VkExtent3D dimensions = imageDimensions[imageDimensionsIndex];
2952 const std::string dimensionsString = extentToString(dimensions, VK_IMAGE_TYPE_2D);
2953
2954 if (dimensions.height == 1 || dimensions.depth > 1)
2955 continue;
2956
2957 if (imageLayerParamsToTest[imageLayerParamsIndex].isCube && dimensions.width != dimensions.height)
2958 continue;
2959
2960 for (size_t imageFormatIndex = 0; imageFormatIndex < numOfDepthStencilImageFormatsToTest;
2961 ++imageFormatIndex)
2962 {
2963 const VkFormat format = depthStencilImageFormatsToTest[imageFormatIndex];
2964 const bool hasDepth = tcu::hasDepthComponent(mapVkFormat(format).order);
2965 const bool hasStencil = tcu::hasStencilComponent(mapVkFormat(format).order);
2966 const int separateLayoutsLoopCount = (hasDepth && hasStencil) ? 3 : 1;
2967
2968 for (int separateDepthStencilLayoutMode = 0;
2969 separateDepthStencilLayoutMode < separateLayoutsLoopCount;
2970 ++separateDepthStencilLayoutMode)
2971 {
2972 const std::string testCaseName =
2973 getFormatCaseName(format) +
2974 ((separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_DEPTH) ?
2975 "_separate_layouts_depth" :
2976 (separateDepthStencilLayoutMode == SEPARATE_DEPTH_STENCIL_LAYOUT_MODE_STENCIL) ?
2977 "_separate_layouts_stencil" :
2978 "") +
2979 dimensionsString;
2980
2981 const TestParams testParams = {
2982 true, // bool useSingleMipLevel;
2983 VK_IMAGE_TYPE_2D, // VkImageType imageType;
2984 format, // VkFormat format;
2985 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
2986 dimensions, // VkExtent3D extent;
2987 imageLayerParamsToTest[imageLayerParamsIndex]
2988 .imageLayerCount, // uint32_t imageLayerCount;
2989 imageLayerParamsToTest[imageLayerParamsIndex]
2990 .imageViewRange, // LayerRange imageViewLayerRange;
2991 makeClearValueDepthStencil(0.0f, 0u), // VkClearValue initValue
2992 {
2993 makeClearValueDepthStencil(0.1f,
2994 0x06), // VkClearValue clearValue[0];
2995 makeClearValueDepthStencil(0.3f,
2996 0x04), // VkClearValue clearValue[1];
2997 },
2998 false, // bool useSeparateExpectedClearValue;
2999 {}, // VkClearValue[2] expectedClearValue;
3000 imageLayerParamsToTest[imageLayerParamsIndex]
3001 .clearLayerRange, // LayerRange clearLayerRange;
3002 allocationKind, // AllocationKind allocationKind;
3003 imageLayerParamsToTest[imageLayerParamsIndex].isCube, // bool isCube;
3004 SeparateDepthStencilLayoutMode(
3005 separateDepthStencilLayoutMode), // SeparateDepthStencilLayoutMode separateDepthStencilLayoutMode;
3006 false, // bool isColorMultipleSubresourceRangeTest;
3007 VK_SAMPLE_COUNT_1_BIT // VkSampleCountFlagBits imageSampleCount
3008 };
3009 // Clear Depth/Stencil Attachment
3010 depthStencilLayersGroup->addChild(new ImageClearingTestCase<ClearAttachmentTestInstance>(
3011 testCtx, testCaseName, testParams));
3012 if (dimensions.width > 1)
3013 // Partial Clear Depth/Stencil Attachment
3014 partialDepthStencilLayersGroup->addChild(
3015 new ImageClearingTestCase<PartialClearAttachmentTestInstance>(testCtx, testCaseName,
3016 testParams));
3017 }
3018 }
3019 }
3020 depthStencilAttachmentClearTests->addChild(depthStencilLayersGroup.release());
3021 partialDepthStencilAttachmentClearTests->addChild(partialDepthStencilLayersGroup.release());
3022 }
3023 }
3024 imageClearingTests->addChild(depthStencilAttachmentClearTests.release());
3025 imageClearingTests->addChild(partialDepthStencilAttachmentClearTests.release());
3026 }
3027
3028 return imageClearingTests;
3029 }
3030
createCoreImageClearingTests(tcu::TestCaseGroup * group)3031 void createCoreImageClearingTests(tcu::TestCaseGroup *group)
3032 {
3033 createImageClearingTestsCommon(group->getTestContext(), group, ALLOCATION_KIND_SUBALLOCATED);
3034 }
3035
createDedicatedAllocationImageClearingTests(tcu::TestCaseGroup * group)3036 void createDedicatedAllocationImageClearingTests(tcu::TestCaseGroup *group)
3037 {
3038 createImageClearingTestsCommon(group->getTestContext(), group, ALLOCATION_KIND_DEDICATED);
3039 }
3040
3041 } // namespace
3042
createImageClearingTests(TestContext & testCtx)3043 TestCaseGroup *createImageClearingTests(TestContext &testCtx)
3044 {
3045 de::MovePtr<TestCaseGroup> imageClearingTests(new TestCaseGroup(testCtx, "image_clearing"));
3046
3047 // Core Image Clearing Tests
3048 imageClearingTests->addChild(createTestGroup(testCtx, "core", createCoreImageClearingTests));
3049 // Image Clearing Tests For Dedicated Memory Allocation
3050 imageClearingTests->addChild(
3051 createTestGroup(testCtx, "dedicated_allocation", createDedicatedAllocationImageClearingTests));
3052
3053 return imageClearingTests.release();
3054 }
3055
3056 } // namespace api
3057 } // namespace vkt
3058