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