1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2021 Valve Corporation.
6 * Copyright (c) 2023 LunarG, Inc.
7 * Copyright (c) 2023 Nintendo
8 *
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
12 *
13 * http://www.apache.org/licenses/LICENSE-2.0
14 *
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 *
21 *//*!
22 * \file
23 * \brief VK_EXT_attachment_feedback_loop_layout Tests
24 *//*--------------------------------------------------------------------*/
25
26 #include "vktPipelineAttachmentFeedbackLoopLayoutTests.hpp"
27 #include "vktPipelineImageSamplingInstance.hpp"
28 #include "vktPipelineImageUtil.hpp"
29 #include "vktPipelineVertexUtil.hpp"
30 #include "vktTestCase.hpp"
31 #include "vktPipelineClearUtil.hpp"
32
33 #include "vkImageUtil.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkObjUtil.hpp"
37 #include "vkBuilderUtil.hpp"
38 #include "vkBarrierUtil.hpp"
39 #include "vkCmdUtil.hpp"
40 #include "vkPrograms.hpp"
41 #include "vkImageWithMemory.hpp"
42 #include "vkBufferWithMemory.hpp"
43
44 #include "tcuPlatform.hpp"
45 #include "tcuImageCompare.hpp"
46 #include "tcuTextureUtil.hpp"
47 #include "tcuTestLog.hpp"
48 #include "tcuMaybe.hpp"
49
50 #include "deStringUtil.hpp"
51 #include "deMemory.h"
52
53 #include <iomanip>
54 #include <sstream>
55 #include <vector>
56 #include <string>
57 #include <memory>
58 #include <utility>
59 #include <algorithm>
60
61 namespace vkt
62 {
63 namespace pipeline
64 {
65
66 using namespace vk;
67 using de::MovePtr;
68
69 namespace
70 {
71
72 enum TestMode
73 {
74 TEST_MODE_READ_ONLY = 0,
75 TEST_MODE_WRITE_ONLY = 1,
76 TEST_MODE_READ_WRITE_SAME_PIXEL = 2, // Sample from and write to the same pixel
77 TEST_MODE_READ_WRITE_DIFFERENT_AREAS = 3, // Sample from one half of the image and write the values to the other half
78 };
79
80 enum ImageAspectTestMode
81 {
82 IMAGE_ASPECT_TEST_COLOR = 0,
83 IMAGE_ASPECT_TEST_DEPTH = 1,
84 IMAGE_ASPECT_TEST_STENCIL = 2,
85 };
86
testModeToAspectFlags(ImageAspectTestMode testMode)87 VkImageAspectFlagBits testModeToAspectFlags (ImageAspectTestMode testMode)
88 {
89 switch (testMode)
90 {
91 case IMAGE_ASPECT_TEST_COLOR: return VK_IMAGE_ASPECT_COLOR_BIT;
92 case IMAGE_ASPECT_TEST_DEPTH: return VK_IMAGE_ASPECT_DEPTH_BIT;
93 case IMAGE_ASPECT_TEST_STENCIL: return VK_IMAGE_ASPECT_STENCIL_BIT;
94 default: break;
95 }
96
97 DE_ASSERT(false);
98 return VK_IMAGE_ASPECT_FLAG_BITS_MAX_ENUM;
99 }
100
101 enum class PipelineStateMode
102 {
103 STATIC = 0, // Static only.
104 DYNAMIC_WITH_ZERO_STATIC, // Dynamic, with static flags 0.
105 DYNAMIC_WITH_CONTRADICTORY_STATIC, // Dynamic, with static flags contradicting the dynamic state (see below).
106 };
107
aspectFlagsToPipelineCreateFlags(VkImageAspectFlags aspectFlags)108 VkPipelineCreateFlags aspectFlagsToPipelineCreateFlags (VkImageAspectFlags aspectFlags)
109 {
110 VkPipelineCreateFlags pipelineFlags = 0u;
111
112 if ((aspectFlags & VK_IMAGE_ASPECT_COLOR_BIT) != 0u)
113 pipelineFlags |= VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
114
115 if ((aspectFlags & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) != 0u)
116 pipelineFlags |= VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
117
118 return pipelineFlags;
119 }
120
getStaticPipelineCreateFlags(VkImageAspectFlags usedFlags, PipelineStateMode stateMode)121 VkPipelineCreateFlags getStaticPipelineCreateFlags (VkImageAspectFlags usedFlags, PipelineStateMode stateMode)
122 {
123 if (stateMode == PipelineStateMode::STATIC)
124 return aspectFlagsToPipelineCreateFlags(usedFlags);
125
126 if (stateMode == PipelineStateMode::DYNAMIC_WITH_ZERO_STATIC)
127 return 0u;
128
129 // Statically include all flags which are not present in the used flags that will be set dynamically.
130 VkPipelineCreateFlags pipelineStaticFlags = (VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT);
131 VkPipelineCreateFlags pipelineUsedFlags = aspectFlagsToPipelineCreateFlags(usedFlags);
132
133 pipelineStaticFlags &= (~pipelineUsedFlags);
134 return pipelineStaticFlags;
135 }
136
137 // Output images are a square of this size
138 const int outputImageSize = 256;
139
getImageAspectTestMode(const VkFormat format)140 ImageAspectTestMode getImageAspectTestMode (const VkFormat format)
141 {
142 if (tcu::hasDepthComponent(mapVkFormat(format).order))
143 return IMAGE_ASPECT_TEST_DEPTH;
144
145 if (tcu::hasStencilComponent(mapVkFormat(format).order))
146 return IMAGE_ASPECT_TEST_STENCIL;
147
148 return IMAGE_ASPECT_TEST_COLOR;
149 };
150
151 class SamplerViewType {
152 public:
SamplerViewType(vk::VkImageViewType type, bool normalized = true)153 SamplerViewType (vk::VkImageViewType type, bool normalized = true)
154 : m_viewType(type), m_normalized(normalized)
155 {
156 if (!normalized)
157 DE_ASSERT(type == vk::VK_IMAGE_VIEW_TYPE_2D || type == vk::VK_IMAGE_VIEW_TYPE_1D);
158 }
159
operator vk::VkImageViewType() const160 operator vk::VkImageViewType () const
161 {
162 return m_viewType;
163 }
164
isNormalized() const165 bool isNormalized () const
166 {
167 return m_normalized;
168 }
169
170 private:
171 vk::VkImageViewType m_viewType;
172 bool m_normalized;
173 };
174
allocateImage(const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkImage& image, const MemoryRequirement requirement, Allocator& allocator, AllocationKind allocationKind)175 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki,
176 const DeviceInterface& vkd,
177 const VkPhysicalDevice& physDevice,
178 const VkDevice device,
179 const VkImage& image,
180 const MemoryRequirement requirement,
181 Allocator& allocator,
182 AllocationKind allocationKind)
183 {
184 switch (allocationKind)
185 {
186 case ALLOCATION_KIND_SUBALLOCATED:
187 {
188 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
189
190 return allocator.allocate(memoryRequirements, requirement);
191 }
192
193 case ALLOCATION_KIND_DEDICATED:
194 {
195 return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
196 }
197
198 default:
199 {
200 TCU_THROW(InternalError, "Invalid allocation kind");
201 }
202 }
203 }
204
allocateBuffer(const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice& physDevice, const VkDevice device, const VkBuffer& buffer, const MemoryRequirement requirement, Allocator& allocator, AllocationKind allocationKind)205 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki,
206 const DeviceInterface& vkd,
207 const VkPhysicalDevice& physDevice,
208 const VkDevice device,
209 const VkBuffer& buffer,
210 const MemoryRequirement requirement,
211 Allocator& allocator,
212 AllocationKind allocationKind)
213 {
214 switch (allocationKind)
215 {
216 case ALLOCATION_KIND_SUBALLOCATED:
217 {
218 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
219
220 return allocator.allocate(memoryRequirements, requirement);
221 }
222
223 case ALLOCATION_KIND_DEDICATED:
224 {
225 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
226 }
227
228 default:
229 {
230 TCU_THROW(InternalError, "Invalid allocation kind");
231 }
232 }
233 }
234
getCompatibleImageType(VkImageViewType viewType)235 static VkImageType getCompatibleImageType (VkImageViewType viewType)
236 {
237 switch (viewType)
238 {
239 case VK_IMAGE_VIEW_TYPE_1D: return VK_IMAGE_TYPE_1D;
240 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return VK_IMAGE_TYPE_1D;
241 case VK_IMAGE_VIEW_TYPE_2D: return VK_IMAGE_TYPE_2D;
242 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return VK_IMAGE_TYPE_2D;
243 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D;
244 case VK_IMAGE_VIEW_TYPE_CUBE: return VK_IMAGE_TYPE_2D;
245 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D;
246 default:
247 break;
248 }
249
250 DE_ASSERT(false);
251 return VK_IMAGE_TYPE_1D;
252 }
253
254 template<typename TcuFormatType>
createTestTexture(const TcuFormatType format, VkImageViewType viewType, const tcu::IVec3& size, int layerCount)255 static MovePtr<TestTexture> createTestTexture (const TcuFormatType format, VkImageViewType viewType, const tcu::IVec3& size, int layerCount)
256 {
257 MovePtr<TestTexture> texture;
258 const VkImageType imageType = getCompatibleImageType(viewType);
259
260 switch (imageType)
261 {
262 case VK_IMAGE_TYPE_1D:
263 if (layerCount == 1)
264 texture = MovePtr<TestTexture>(new TestTexture1D(format, size.x()));
265 else
266 texture = MovePtr<TestTexture>(new TestTexture1DArray(format, size.x(), layerCount));
267
268 break;
269
270 case VK_IMAGE_TYPE_2D:
271 if (layerCount == 1)
272 {
273 texture = MovePtr<TestTexture>(new TestTexture2D(format, size.x(), size.y()));
274 }
275 else
276 {
277 if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
278 {
279 if (layerCount == tcu::CUBEFACE_LAST && viewType == VK_IMAGE_VIEW_TYPE_CUBE)
280 {
281 texture = MovePtr<TestTexture>(new TestTextureCube(format, size.x()));
282 }
283 else
284 {
285 DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
286
287 texture = MovePtr<TestTexture>(new TestTextureCubeArray(format, size.x(), layerCount));
288 }
289 }
290 else
291 {
292 texture = MovePtr<TestTexture>(new TestTexture2DArray(format, size.x(), size.y(), layerCount));
293 }
294 }
295
296 break;
297
298 case VK_IMAGE_TYPE_3D:
299 texture = MovePtr<TestTexture>(new TestTexture3D(format, size.x(), size.y(), size.z()));
300 break;
301
302 default:
303 DE_ASSERT(false);
304 }
305
306 return texture;
307 }
308
getAspectFlags(tcu::TextureFormat format)309 VkImageAspectFlags getAspectFlags (tcu::TextureFormat format)
310 {
311 VkImageAspectFlags aspectFlag = 0;
312 aspectFlag |= (tcu::hasDepthComponent(format.order)? VK_IMAGE_ASPECT_DEPTH_BIT : 0);
313 aspectFlag |= (tcu::hasStencilComponent(format.order)? VK_IMAGE_ASPECT_STENCIL_BIT : 0);
314
315 if (!aspectFlag)
316 aspectFlag = VK_IMAGE_ASPECT_COLOR_BIT;
317
318 return aspectFlag;
319 }
320
getAspectFlags(VkFormat format)321 VkImageAspectFlags getAspectFlags (VkFormat format)
322 {
323 if (isCompressedFormat(format))
324 return VK_IMAGE_ASPECT_COLOR_BIT;
325 else
326 return getAspectFlags(mapVkFormat(format));
327 }
328
getSizeCompatibleTcuTextureFormat(VkFormat format)329 tcu::TextureFormat getSizeCompatibleTcuTextureFormat (VkFormat format)
330 {
331 if (isCompressedFormat(format))
332 return (getBlockSizeInBytes(format) == 8) ? mapVkFormat(VK_FORMAT_R16G16B16A16_UINT) : mapVkFormat(VK_FORMAT_R32G32B32A32_UINT);
333 else
334 return mapVkFormat(format);
335 }
336
337 // Utilities to create test nodes
getFormatCaseName(const VkFormat format)338 std::string getFormatCaseName (const VkFormat format)
339 {
340 const std::string fullName = getFormatName(format);
341
342 DE_ASSERT(de::beginsWith(fullName, "VK_FORMAT_"));
343
344 return de::toLower(fullName.substr(10));
345 }
346
347 class AttachmentFeedbackLoopLayoutImageSamplingInstance : public ImageSamplingInstance
348 {
349 public:
350 AttachmentFeedbackLoopLayoutImageSamplingInstance (Context& context,
351 ImageSamplingInstanceParams params,
352 bool useImageAsColorOrDSAttachment_,
353 bool useDifferentAreasSampleWrite_,
354 bool interleaveReadWriteComponents_,
355 ImageAspectTestMode imageAspectTestMode,
356 PipelineStateMode pipelineStateMode,
357 bool useMaintenance5_);
358
359 virtual ~AttachmentFeedbackLoopLayoutImageSamplingInstance (void);
360
361 virtual tcu::TestStatus iterate (void) override;
362
363 protected:
364 virtual tcu::TestStatus verifyImage (void) override;
365 virtual void setup (void) override;
366
367 ImageSamplingInstanceParams m_params;
368 const bool m_useImageAsColorOrDSAttachment;
369 const bool m_useDifferentAreasSampleWrite;
370 const bool m_interleaveReadWriteComponents;
371 const ImageAspectTestMode m_imageAspectTestMode;
372 const PipelineStateMode m_pipelineStateMode;
373 const bool m_useMaintenance5;
374 };
375
376 class AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance : public AttachmentFeedbackLoopLayoutImageSamplingInstance
377 {
378 public:
379 AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance (Context& context,
380 ImageSamplingInstanceParams params,
381 bool useImageAsColorOrDSAttachment_,
382 bool useDifferentAreasSampleWrite_,
383 bool interleaveReadWriteComponents_,
384 ImageAspectTestMode imageAspectTestMode,
385 PipelineStateMode pipelineStateMode,
386 bool useMaintenance5_);
387
388 virtual ~AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance (void);
389
390 virtual tcu::TestStatus iterate (void) override;
391
392 protected:
393 virtual tcu::TestStatus verifyImage (void) override;
394 virtual void setup (void) override;
395
396 bool m_separateStencilUsage;
397
398 std::vector<SharedImagePtr> m_dsImages;
399 std::vector<SharedAllocPtr> m_dsImageAllocs;
400 std::vector<SharedImageViewPtr> m_dsAttachmentViews;
401 };
402
AttachmentFeedbackLoopLayoutImageSamplingInstance(Context& context, ImageSamplingInstanceParams params, bool useImageAsColorOrDSAttachment_, bool useDifferentAreasSampleWrite_, bool interleaveReadWriteComponents_, ImageAspectTestMode imageAspectTestMode, PipelineStateMode pipelineStateMode, bool useMaintenance5_)403 AttachmentFeedbackLoopLayoutImageSamplingInstance::AttachmentFeedbackLoopLayoutImageSamplingInstance (Context& context,
404 ImageSamplingInstanceParams params,
405 bool useImageAsColorOrDSAttachment_,
406 bool useDifferentAreasSampleWrite_,
407 bool interleaveReadWriteComponents_,
408 ImageAspectTestMode imageAspectTestMode,
409 PipelineStateMode pipelineStateMode,
410 bool useMaintenance5_)
411 : ImageSamplingInstance (context, params)
412 , m_params (params)
413 , m_useImageAsColorOrDSAttachment (useImageAsColorOrDSAttachment_)
414 , m_useDifferentAreasSampleWrite (useDifferentAreasSampleWrite_)
415 , m_interleaveReadWriteComponents (interleaveReadWriteComponents_)
416 , m_imageAspectTestMode (imageAspectTestMode)
417 , m_pipelineStateMode (pipelineStateMode)
418 , m_useMaintenance5 (useMaintenance5_)
419 {
420 }
421
setup(void)422 void AttachmentFeedbackLoopLayoutImageSamplingInstance::setup (void)
423 {
424 const InstanceInterface& vki = m_context.getInstanceInterface();
425 const DeviceInterface& vk = m_context.getDeviceInterface();
426 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
427 const VkDevice vkDevice = m_context.getDevice();
428 const VkQueue queue = m_context.getUniversalQueue();
429 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
430 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
431 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
432 tcu::UVec2 renderSize = m_useImageAsColorOrDSAttachment ? tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() }) : m_renderSize;
433
434 DE_ASSERT(m_samplerParams.pNext == DE_NULL);
435
436 // Create texture images, views and samplers
437 {
438 VkImageCreateFlags imageFlags = 0u;
439
440 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
441 imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
442
443 // Initialize texture data
444 if (isCompressedFormat(m_imageFormat))
445 m_texture = createTestTexture(mapVkCompressedFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
446 else
447 m_texture = createTestTexture(mapVkFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
448
449 VkImageUsageFlags imageUsageFlags = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
450 VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
451
452 if (isDepthStencilFormat(m_imageFormat))
453 imageUsageFlags |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
454 else
455 imageUsageFlags |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
456
457 const VkImageCreateInfo imageParams =
458 {
459 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
460 DE_NULL, // const void* pNext;
461 imageFlags, // VkImageCreateFlags flags;
462 getCompatibleImageType(m_imageViewType), // VkImageType imageType;
463 m_imageFormat, // VkFormat format;
464 { // VkExtent3D extent;
465 (deUint32)m_imageSize.x(),
466 (deUint32)m_imageSize.y(),
467 (deUint32)m_imageSize.z()
468 },
469 (deUint32)m_texture->getNumLevels(), // deUint32 mipLevels;
470 (deUint32)m_layerCount, // deUint32 arrayLayers;
471 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
472 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
473 imageUsageFlags, // VkImageUsageFlags usage;
474 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
475 1u, // deUint32 queueFamilyIndexCount;
476 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
477 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
478 };
479
480 checkImageSupport(vki, physDevice, imageParams);
481
482 m_images.resize(m_imageCount);
483 m_imageAllocs.resize(m_imageCount);
484 m_imageViews.resize(m_imageCount);
485
486 // Create command pool
487 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
488 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
489
490 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
491 {
492 m_images[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &imageParams)));
493 m_imageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_images[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
494 VK_CHECK(vk.bindImageMemory(vkDevice, **m_images[imgNdx], (*m_imageAllocs[imgNdx])->getMemory(), (*m_imageAllocs[imgNdx])->getOffset()));
495
496 // Upload texture data
497 uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, **m_images[imgNdx], m_imageLayout);
498
499 // Create image view and sampler
500 const VkImageViewCreateInfo imageViewParams =
501 {
502 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
503 DE_NULL, // const void* pNext;
504 0u, // VkImageViewCreateFlags flags;
505 **m_images[imgNdx], // VkImage image;
506 m_imageViewType, // VkImageViewType viewType;
507 m_imageFormat, // VkFormat format;
508 m_componentMapping, // VkComponentMapping components;
509 m_subresourceRange, // VkImageSubresourceRange subresourceRange;
510 };
511
512 m_imageViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &imageViewParams)));
513 }
514
515 m_sampler = createSampler(vk, vkDevice, &m_samplerParams);
516 }
517
518 // Create descriptor set for image and sampler
519 {
520 DescriptorPoolBuilder descriptorPoolBuilder;
521 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
522 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER, 1u);
523 descriptorPoolBuilder.addType(m_samplingType, m_imageCount);
524 m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
525 m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? m_imageCount + 1u : m_imageCount);
526
527 DescriptorSetLayoutBuilder setLayoutBuilder;
528 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
529 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
530 setLayoutBuilder.addArrayBinding(m_samplingType, m_imageCount, VK_SHADER_STAGE_FRAGMENT_BIT);
531 m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
532
533 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
534 {
535 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
536 DE_NULL, // const void* pNext;
537 *m_descriptorPool, // VkDescriptorPool descriptorPool;
538 1u, // deUint32 setLayoutCount;
539 &m_descriptorSetLayout.get() // const VkDescriptorSetLayout* pSetLayouts;
540 };
541
542 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
543
544 const VkSampler sampler = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? DE_NULL : *m_sampler;
545 std::vector<VkDescriptorImageInfo> descriptorImageInfo(m_imageCount);
546 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
547 {
548 descriptorImageInfo[imgNdx].sampler = sampler; // VkSampler sampler;
549 descriptorImageInfo[imgNdx].imageView = **m_imageViews[imgNdx]; // VkImageView imageView;
550 descriptorImageInfo[imgNdx].imageLayout = m_imageLayout; // VkImageLayout imageLayout;
551 }
552
553 DescriptorSetUpdateBuilder setUpdateBuilder;
554 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
555 {
556 const VkDescriptorImageInfo descriptorSamplerInfo =
557 {
558 *m_sampler, // VkSampler sampler;
559 DE_NULL, // VkImageView imageView;
560 m_imageLayout, // VkImageLayout imageLayout;
561 };
562 setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_SAMPLER, &descriptorSamplerInfo);
563 }
564
565 const deUint32 binding = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? 1u : 0u;
566 setUpdateBuilder.writeArray(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(binding), m_samplingType, m_imageCount, descriptorImageInfo.data());
567 setUpdateBuilder.update(vk, vkDevice);
568 }
569
570 // Create color images and views
571 {
572 const VkImageCreateInfo colorImageParams =
573 {
574 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
575 DE_NULL, // const void* pNext;
576 0u, // VkImageCreateFlags flags;
577 VK_IMAGE_TYPE_2D, // VkImageType imageType;
578 m_colorFormat, // VkFormat format;
579 { (deUint32)renderSize.x(), (deUint32)renderSize.y(), 1u }, // VkExtent3D extent;
580 1u, // deUint32 mipLevels;
581 1u, // deUint32 arrayLayers;
582 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
583 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
584 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
585 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
586 1u, // deUint32 queueFamilyIndexCount;
587 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
588 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
589 };
590
591 checkImageSupport(vki, physDevice, colorImageParams);
592
593 m_colorImages.resize(m_imageCount);
594 m_colorImageAllocs.resize(m_imageCount);
595 m_colorAttachmentViews.resize(m_imageCount);
596
597 if (m_useImageAsColorOrDSAttachment)
598 {
599 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
600 {
601 m_colorImages[imgNdx] = m_images[imgNdx];
602 m_colorImageAllocs[imgNdx] = m_imageAllocs[imgNdx];
603 m_colorAttachmentViews[imgNdx] = m_imageViews[imgNdx];
604 }
605 }
606 else
607 {
608 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
609 {
610 m_colorImages[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &colorImageParams)));
611 m_colorImageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_colorImages[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
612 VK_CHECK(vk.bindImageMemory(vkDevice, **m_colorImages[imgNdx], (*m_colorImageAllocs[imgNdx])->getMemory(), (*m_colorImageAllocs[imgNdx])->getOffset()));
613
614 const VkImageViewCreateInfo colorAttachmentViewParams =
615 {
616 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
617 DE_NULL, // const void* pNext;
618 0u, // VkImageViewCreateFlags flags;
619 **m_colorImages[imgNdx], // VkImage image;
620 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
621 m_colorFormat, // VkFormat format;
622 componentMappingRGBA, // VkComponentMapping components;
623 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
624 };
625
626 m_colorAttachmentViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &colorAttachmentViewParams)));
627 }
628 }
629 }
630
631 // Create render pass
632 {
633 std::vector<VkAttachmentDescription> attachmentDescriptions(m_imageCount);
634 std::vector<VkAttachmentReference> attachmentReferences(m_imageCount);
635
636 VkAttachmentLoadOp loadOp = m_useImageAsColorOrDSAttachment ? VK_ATTACHMENT_LOAD_OP_LOAD : VK_ATTACHMENT_LOAD_OP_CLEAR;
637 VkImageLayout imageLayout = m_useImageAsColorOrDSAttachment ? m_imageLayout : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
638
639 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
640 {
641 attachmentDescriptions[imgNdx].flags = 0u; // VkAttachmentDescriptionFlags flags;
642 attachmentDescriptions[imgNdx].format = m_useImageAsColorOrDSAttachment ? m_imageFormat : m_colorFormat; // VkFormat format;
643 attachmentDescriptions[imgNdx].samples = VK_SAMPLE_COUNT_1_BIT; // VkSampleCountFlagBits samples;
644 attachmentDescriptions[imgNdx].loadOp = loadOp; // VkAttachmentLoadOp loadOp;
645 attachmentDescriptions[imgNdx].storeOp = VK_ATTACHMENT_STORE_OP_STORE; // VkAttachmentStoreOp storeOp;
646 attachmentDescriptions[imgNdx].stencilLoadOp = loadOp; // VkAttachmentLoadOp stencilLoadOp;
647 attachmentDescriptions[imgNdx].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; // VkAttachmentStoreOp stencilStoreOp;
648 attachmentDescriptions[imgNdx].initialLayout = imageLayout; // VkImageLayout initialLayout;
649 attachmentDescriptions[imgNdx].finalLayout = imageLayout; // VkImageLayout finalLayout;
650
651 attachmentReferences[imgNdx].attachment = (deUint32)imgNdx; // deUint32 attachment;
652 attachmentReferences[imgNdx].layout = imageLayout; // VkImageLayout layout;
653 }
654
655 const VkSubpassDescription subpassDescription =
656 {
657 0u, // VkSubpassDescriptionFlags flags;
658 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
659 0u, // deUint32 inputAttachmentCount;
660 DE_NULL, // const VkAttachmentReference* pInputAttachments;
661 (deUint32)m_imageCount, // deUint32 colorAttachmentCount;
662 &attachmentReferences[0], // const VkAttachmentReference* pColorAttachments;
663 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
664 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
665 0u, // deUint32 preserveAttachmentCount;
666 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
667 };
668
669 std::vector<VkSubpassDependency> subpassDependencies;
670
671 if (m_useImageAsColorOrDSAttachment)
672 {
673 const VkSubpassDependency spdVal =
674 {
675 0u, // uint32_t srcSubpass;
676 0u, // uint32_t dstSubpass;
677 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT, // VkPipelineStageFlags srcStageMask;
678 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, // VkPipelineStageFlags dstStageMask;
679 VK_ACCESS_SHADER_READ_BIT, // VkAccessFlags srcAccessMask;
680 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask;
681 VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT | VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags;
682 };
683
684 subpassDependencies.push_back(spdVal);
685 }
686
687 const VkRenderPassCreateInfo renderPassParams =
688 {
689 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
690 DE_NULL, // const void* pNext;
691 0u, // VkRenderPassCreateFlags flags;
692 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
693 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
694 1u, // deUint32 subpassCount;
695 &subpassDescription, // const VkSubpassDescription* pSubpasses;
696 static_cast<uint32_t>(subpassDependencies.size()), // deUint32 dependencyCount;
697 de::dataOrNull(subpassDependencies), // const VkSubpassDependency* pDependencies;
698 };
699
700 m_renderPass = RenderPassWrapper(m_pipelineConstructionType, vk, vkDevice, &renderPassParams);
701 }
702
703 // Create framebuffer
704 {
705 std::vector<VkImage> images(m_imageCount);
706 std::vector<VkImageView> pAttachments(m_imageCount);
707 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
708 {
709 images[imgNdx] = m_colorImages[imgNdx]->get();
710 pAttachments[imgNdx] = m_colorAttachmentViews[imgNdx]->get();
711 }
712
713 const VkFramebufferCreateInfo framebufferParams =
714 {
715 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
716 DE_NULL, // const void* pNext;
717 0u, // VkFramebufferCreateFlags flags;
718 *m_renderPass, // VkRenderPass renderPass;
719 (deUint32)m_imageCount, // deUint32 attachmentCount;
720 &pAttachments[0], // const VkImageView* pAttachments;
721 (deUint32)renderSize.x(), // deUint32 width;
722 (deUint32)renderSize.y(), // deUint32 height;
723 1u // deUint32 layers;
724 };
725
726 m_renderPass.createFramebuffer(vk, vkDevice, &framebufferParams, images);
727 }
728
729 // Create pipeline layouts
730 {
731 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
732 {
733 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
734 DE_NULL, // const void* pNext;
735 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, // VkPipelineLayoutCreateFlags flags;
736 0u, // deUint32 setLayoutCount;
737 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
738 0u, // deUint32 pushConstantRangeCount;
739 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
740 };
741
742 m_preRasterizationStatePipelineLayout = PipelineLayoutWrapper(m_pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
743 }
744 {
745 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
746 {
747 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
748 DE_NULL, // const void* pNext;
749 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, // VkPipelineLayoutCreateFlags flags;
750 1u, // deUint32 setLayoutCount;
751 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
752 0u, // deUint32 pushConstantRangeCount;
753 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
754 };
755
756 m_fragmentStatePipelineLayout = PipelineLayoutWrapper(m_pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
757 }
758
759 m_vertexShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
760 m_fragmentShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
761
762 // Create pipeline
763 {
764 const VkVertexInputBindingDescription vertexInputBindingDescription =
765 {
766 0u, // deUint32 binding;
767 sizeof(Vertex4Tex4), // deUint32 strideInBytes;
768 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
769 };
770
771 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
772 {
773 {
774 0u, // deUint32 location;
775 0u, // deUint32 binding;
776 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
777 0u // deUint32 offset;
778 },
779 {
780 1u, // deUint32 location;
781 0u, // deUint32 binding;
782 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
783 DE_OFFSET_OF(Vertex4Tex4, texCoord), // deUint32 offset;
784 }
785 };
786
787 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
788 {
789 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
790 DE_NULL, // const void* pNext;
791 0u, // VkPipelineVertexInputStateCreateFlags flags;
792 1u, // deUint32 vertexBindingDescriptionCount;
793 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
794 2u, // deUint32 vertexAttributeDescriptionCount;
795 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
796 };
797
798 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
799 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
800
801 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(m_imageCount);
802
803 VkColorComponentFlags colorComponents = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
804
805 if (m_interleaveReadWriteComponents)
806 colorComponents = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_B_BIT;
807
808 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
809 {
810 colorBlendAttachmentStates[imgNdx].blendEnable = false; // VkBool32 blendEnable;
811 colorBlendAttachmentStates[imgNdx].srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcColorBlendFactor;
812 colorBlendAttachmentStates[imgNdx].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstColorBlendFactor;
813 colorBlendAttachmentStates[imgNdx].colorBlendOp = VK_BLEND_OP_ADD; // VkBlendOp colorBlendOp;
814 colorBlendAttachmentStates[imgNdx].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcAlphaBlendFactor;
815 colorBlendAttachmentStates[imgNdx].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstAlphaBlendFactor;
816 colorBlendAttachmentStates[imgNdx].alphaBlendOp = VK_BLEND_OP_ADD; // VkBlendOp alphaBlendOp;
817 colorBlendAttachmentStates[imgNdx].colorWriteMask = colorComponents; // VkColorComponentFlags colorWriteMask;
818 }
819
820 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
821 {
822 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
823 DE_NULL, // const void* pNext;
824 0u, // VkPipelineColorBlendStateCreateFlags flags;
825 false, // VkBool32 logicOpEnable;
826 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
827 (deUint32)m_imageCount, // deUint32 attachmentCount;
828 &colorBlendAttachmentStates[0], // const VkPipelineColorBlendAttachmentState* pAttachments;
829 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
830 };
831
832 std::vector<VkDynamicState> dynamicStates;
833 if (m_pipelineStateMode != PipelineStateMode::STATIC)
834 dynamicStates.push_back(VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT);
835
836 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
837 {
838 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
839 nullptr,
840 0u,
841 de::sizeU32(dynamicStates),
842 de::dataOrNull(dynamicStates),
843 };
844
845 if (m_useMaintenance5)
846 m_graphicsPipeline.setPipelineCreateFlags2(translateCreateFlag(m_params.pipelineCreateFlags));
847
848 m_graphicsPipeline.setDynamicState(&dynamicStateInfo)
849 .setMonolithicPipelineLayout(m_fragmentStatePipelineLayout)
850 .setDefaultDepthStencilState()
851 .setDefaultRasterizationState()
852 .setDefaultMultisampleState()
853 .setupVertexInputState(&vertexInputStateParams)
854 .setupPreRasterizationShaderState(viewports,
855 scissors,
856 m_preRasterizationStatePipelineLayout,
857 *m_renderPass,
858 0u,
859 m_vertexShaderModule)
860 .setupFragmentShaderState(m_fragmentStatePipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule)
861 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateParams)
862 .buildPipeline();
863 }
864
865 // Create vertex buffer
866 {
867 const VkDeviceSize vertexBufferSize = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
868 const VkBufferCreateInfo vertexBufferParams =
869 {
870 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
871 DE_NULL, // const void* pNext;
872 0u, // VkBufferCreateFlags flags;
873 vertexBufferSize, // VkDeviceSize size;
874 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
875 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
876 1u, // deUint32 queueFamilyIndexCount;
877 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
878 };
879
880 DE_ASSERT(vertexBufferSize > 0);
881
882 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
883 m_vertexBufferAlloc = allocateBuffer(vki, vk, physDevice, vkDevice, *m_vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_allocationKind);
884 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
885
886 // Load vertices into vertex buffer
887 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
888 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
889 }
890
891 // Create command buffer
892 {
893 VkFormat clearFormat = m_useImageAsColorOrDSAttachment ? m_imageFormat : m_colorFormat;
894 const std::vector<VkClearValue> attachmentClearValues (m_imageCount, defaultClearValue(clearFormat));
895
896 std::vector<VkImageMemoryBarrier> preAttachmentBarriers(m_imageCount);
897
898 VkAccessFlags dstAccessMask = isDepthStencilFormat(m_imageFormat) ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT : VK_ACCESS_SHADER_READ_BIT;
899 VkPipelineStageFlags pipelineStageFlags = isDepthStencilFormat(m_imageFormat) ? VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT : VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
900
901 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
902 {
903 preAttachmentBarriers[imgNdx].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; // VkStructureType sType;
904 preAttachmentBarriers[imgNdx].pNext = DE_NULL; // const void* pNext;
905 preAttachmentBarriers[imgNdx].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; // VkAccessFlags srcAccessMask;
906 preAttachmentBarriers[imgNdx].dstAccessMask = dstAccessMask; // VkAccessFlags dstAccessMask;
907 preAttachmentBarriers[imgNdx].oldLayout = m_imageLayout; // VkImageLayout oldLayout;
908 preAttachmentBarriers[imgNdx].newLayout = m_imageLayout; // VkImageLayout newLayout;
909 preAttachmentBarriers[imgNdx].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 srcQueueFamilyIndex;
910 preAttachmentBarriers[imgNdx].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 dstQueueFamilyIndex;
911 preAttachmentBarriers[imgNdx].image = **m_images[imgNdx]; // VkImage image;
912 preAttachmentBarriers[imgNdx].subresourceRange = m_subresourceRange; // VkImageSubresourceRange subresourceRange;
913 }
914
915 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
916
917 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, pipelineStageFlags, (VkDependencyFlags)0,
918 0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
919
920 if (!m_useImageAsColorOrDSAttachment)
921 {
922 // Pipeline barrier for the color attachment, which is a different image than the sampled one.
923 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
924 {
925 preAttachmentBarriers[imgNdx].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; // VkStructureType sType;
926 preAttachmentBarriers[imgNdx].pNext = DE_NULL; // const void* pNext;
927 preAttachmentBarriers[imgNdx].srcAccessMask = (VkAccessFlagBits)0u; // VkAccessFlags srcAccessMask;
928 preAttachmentBarriers[imgNdx].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // VkAccessFlags dstAccessMask;
929 preAttachmentBarriers[imgNdx].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; // VkImageLayout oldLayout;
930 preAttachmentBarriers[imgNdx].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VkImageLayout newLayout;
931 preAttachmentBarriers[imgNdx].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 srcQueueFamilyIndex;
932 preAttachmentBarriers[imgNdx].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 dstQueueFamilyIndex;
933 preAttachmentBarriers[imgNdx].image = **m_colorImages[imgNdx]; // VkImage image;
934 preAttachmentBarriers[imgNdx].subresourceRange.aspectMask = getAspectFlags(m_colorFormat); // VkImageSubresourceRange subresourceRange;
935 preAttachmentBarriers[imgNdx].subresourceRange.baseMipLevel = 0u;
936 preAttachmentBarriers[imgNdx].subresourceRange.levelCount = 1u;
937 preAttachmentBarriers[imgNdx].subresourceRange.baseArrayLayer = 0u;
938 preAttachmentBarriers[imgNdx].subresourceRange.layerCount = 1u;
939 }
940
941 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
942 0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
943
944 m_renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), (deUint32)attachmentClearValues.size(), &attachmentClearValues[0]);
945 }
946 else
947 {
948 // Do not clear the color attachments as we are using the sampled texture as color attachment as well.
949 m_renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), 0u, DE_NULL);
950 }
951
952 m_graphicsPipeline.bind(*m_cmdBuffer);
953
954 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
955
956 const VkDeviceSize vertexBufferOffset = 0;
957 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
958
959 if (m_pipelineStateMode != PipelineStateMode::STATIC)
960 vk.cmdSetAttachmentFeedbackLoopEnableEXT(*m_cmdBuffer, testModeToAspectFlags(m_imageAspectTestMode));
961
962 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
963
964 m_renderPass.end(vk, *m_cmdBuffer);
965 endCommandBuffer(vk, *m_cmdBuffer);
966 }
967 }
968
AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(Context& context, ImageSamplingInstanceParams params, bool useImageAsColorOrDSAttachment_, bool useDifferentAreasSampleWrite_, bool interleaveReadWriteComponents_, ImageAspectTestMode imageAspectTestMode, PipelineStateMode pipelineStateMode, bool useMaintenance5_)969 AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance (Context& context,
970 ImageSamplingInstanceParams params,
971 bool useImageAsColorOrDSAttachment_,
972 bool useDifferentAreasSampleWrite_,
973 bool interleaveReadWriteComponents_,
974 ImageAspectTestMode imageAspectTestMode,
975 PipelineStateMode pipelineStateMode,
976 bool useMaintenance5_)
977 : AttachmentFeedbackLoopLayoutImageSamplingInstance (context, params, useImageAsColorOrDSAttachment_, useDifferentAreasSampleWrite_, interleaveReadWriteComponents_, imageAspectTestMode, pipelineStateMode, useMaintenance5_)
978 , m_separateStencilUsage (params.separateStencilUsage)
979 {
980 }
981
~AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(void)982 AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::~AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance (void)
983 {
984 }
985
setup(void)986 void AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::setup (void)
987 {
988 const InstanceInterface& vki = m_context.getInstanceInterface();
989 const DeviceInterface& vk = m_context.getDeviceInterface();
990 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
991 const VkDevice vkDevice = m_context.getDevice();
992 const VkQueue queue = m_context.getUniversalQueue();
993 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
994 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
995 tcu::UVec2 renderSize = tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
996
997 DE_ASSERT(m_useImageAsColorOrDSAttachment && isDepthStencilFormat(m_imageFormat));
998 DE_ASSERT(m_samplerParams.pNext == DE_NULL);
999
1000 // Create texture images, views
1001 {
1002 VkImageCreateFlags imageFlags = 0u;
1003
1004 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
1005 imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
1006
1007 // Initialize texture data
1008 if (isCompressedFormat(m_imageFormat))
1009 m_texture = createTestTexture(mapVkCompressedFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
1010 else
1011 m_texture = createTestTexture(mapVkFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
1012
1013 VkImageUsageFlags imageUsageFlags =
1014 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
1015 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
1016
1017 const VkImageCreateInfo imageParams =
1018 {
1019 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
1020 DE_NULL, // const void* pNext;
1021 imageFlags, // VkImageCreateFlags flags;
1022 getCompatibleImageType(m_imageViewType), // VkImageType imageType;
1023 m_imageFormat, // VkFormat format;
1024 { // VkExtent3D extent;
1025 (deUint32)m_imageSize.x(),
1026 (deUint32)m_imageSize.y(),
1027 (deUint32)m_imageSize.z()
1028 },
1029 (deUint32)m_texture->getNumLevels(), // deUint32 mipLevels;
1030 (deUint32)m_layerCount, // deUint32 arrayLayers;
1031 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
1032 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
1033 imageUsageFlags, // VkImageUsageFlags usage;
1034 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1035 1u, // deUint32 queueFamilyIndexCount;
1036 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
1037 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
1038 };
1039
1040 checkImageSupport(vki, physDevice, imageParams);
1041
1042 m_images.resize(m_imageCount);
1043 m_imageAllocs.resize(m_imageCount);
1044
1045 // Create command pool
1046 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
1047 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
1048
1049 int numImageViews = m_interleaveReadWriteComponents ? m_imageCount + 1 : m_imageCount;
1050 m_imageViews.resize(numImageViews);
1051
1052 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1053 {
1054 m_images[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &imageParams)));
1055 m_imageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_images[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
1056 VK_CHECK(vk.bindImageMemory(vkDevice, **m_images[imgNdx], (*m_imageAllocs[imgNdx])->getMemory(), (*m_imageAllocs[imgNdx])->getOffset()));
1057
1058 // Upload texture data
1059 uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, **m_images[imgNdx], m_imageLayout);
1060
1061 }
1062
1063 for (int imgNdx = 0; imgNdx < numImageViews; ++imgNdx)
1064 {
1065 VkImage image = (m_interleaveReadWriteComponents && imgNdx == m_imageCount) ? **m_images[imgNdx - 1] : **m_images[imgNdx];
1066
1067 // Create image view and sampler
1068 VkImageViewCreateInfo imageViewParams =
1069 {
1070 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
1071 DE_NULL, // const void* pNext;
1072 0u, // VkImageViewCreateFlags flags;
1073 image, // VkImage image;
1074 m_imageViewType, // VkImageViewType viewType;
1075 m_imageFormat, // VkFormat format;
1076 m_componentMapping, // VkComponentMapping components;
1077 m_subresourceRange, // VkImageSubresourceRange subresourceRange;
1078 };
1079
1080 if (m_interleaveReadWriteComponents && imgNdx == m_imageCount)
1081 {
1082 imageViewParams.subresourceRange.aspectMask = getImageAspectFlags(mapVkFormat(m_imageFormat));
1083 }
1084
1085 m_imageViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &imageViewParams)));
1086 }
1087
1088 m_sampler = createSampler(vk, vkDevice, &m_samplerParams);
1089 }
1090
1091 // Create descriptor set for image and sampler
1092 {
1093 DescriptorPoolBuilder descriptorPoolBuilder;
1094 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1095 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER, 1u);
1096 descriptorPoolBuilder.addType(m_samplingType, m_imageCount);
1097 m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1098 m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? m_imageCount + 1u : m_imageCount);
1099
1100 DescriptorSetLayoutBuilder setLayoutBuilder;
1101 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1102 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
1103 setLayoutBuilder.addArrayBinding(m_samplingType, m_imageCount, VK_SHADER_STAGE_FRAGMENT_BIT);
1104 m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
1105
1106 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
1107 {
1108 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
1109 DE_NULL, // const void* pNext;
1110 *m_descriptorPool, // VkDescriptorPool descriptorPool;
1111 1u, // deUint32 setLayoutCount;
1112 &m_descriptorSetLayout.get() // const VkDescriptorSetLayout* pSetLayouts;
1113 };
1114
1115 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
1116
1117 const VkSampler sampler = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? DE_NULL : *m_sampler;
1118 std::vector<VkDescriptorImageInfo> descriptorImageInfo(m_imageCount);
1119 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1120 {
1121 descriptorImageInfo[imgNdx].sampler = sampler; // VkSampler sampler;
1122 descriptorImageInfo[imgNdx].imageView = **m_imageViews[imgNdx]; // VkImageView imageView;
1123 descriptorImageInfo[imgNdx].imageLayout = m_imageLayout; // VkImageLayout imageLayout;
1124 }
1125
1126 DescriptorSetUpdateBuilder setUpdateBuilder;
1127 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1128 {
1129 const VkDescriptorImageInfo descriptorSamplerInfo =
1130 {
1131 *m_sampler, // VkSampler sampler;
1132 DE_NULL, // VkImageView imageView;
1133 m_imageLayout, // VkImageLayout imageLayout;
1134 };
1135 setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_SAMPLER, &descriptorSamplerInfo);
1136 }
1137
1138 const deUint32 binding = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? 1u : 0u;
1139 setUpdateBuilder.writeArray(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(binding), m_samplingType, m_imageCount, descriptorImageInfo.data());
1140 setUpdateBuilder.update(vk, vkDevice);
1141 }
1142
1143 // Create depth-stencil images and views, no color attachment
1144 {
1145 m_dsImages.resize(m_imageCount);
1146 m_dsImageAllocs.resize(m_imageCount);
1147 m_dsAttachmentViews.resize(m_imageCount);
1148
1149 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1150 {
1151 m_dsImages[imgNdx] = m_images[imgNdx];
1152 m_dsImageAllocs[imgNdx] = m_imageAllocs[imgNdx];
1153 m_dsAttachmentViews[imgNdx] = m_interleaveReadWriteComponents ? m_imageViews[imgNdx + 1] : m_imageViews[imgNdx];
1154 }
1155 }
1156
1157 // Create render pass
1158 {
1159 std::vector<VkAttachmentDescription> attachmentDescriptions(m_imageCount);
1160 std::vector<VkAttachmentReference> attachmentReferences(m_imageCount);
1161
1162 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1163 {
1164 attachmentDescriptions[imgNdx].flags = 0u; // VkAttachmentDescriptionFlags flags;
1165 attachmentDescriptions[imgNdx].format = m_useImageAsColorOrDSAttachment ? m_imageFormat : m_colorFormat; // VkFormat format;
1166 attachmentDescriptions[imgNdx].samples = VK_SAMPLE_COUNT_1_BIT; // VkSampleCountFlagBits samples;
1167 attachmentDescriptions[imgNdx].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // VkAttachmentLoadOp loadOp;
1168 attachmentDescriptions[imgNdx].storeOp = VK_ATTACHMENT_STORE_OP_STORE; // VkAttachmentStoreOp storeOp;
1169 attachmentDescriptions[imgNdx].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // VkAttachmentLoadOp stencilLoadOp;
1170 attachmentDescriptions[imgNdx].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; // VkAttachmentStoreOp stencilStoreOp;
1171 attachmentDescriptions[imgNdx].initialLayout = m_imageLayout; // VkImageLayout initialLayout;
1172 attachmentDescriptions[imgNdx].finalLayout = m_imageLayout; // VkImageLayout finalLayout;
1173
1174 attachmentReferences[imgNdx].attachment = (deUint32)imgNdx; // deUint32 attachment;
1175 attachmentReferences[imgNdx].layout = m_imageLayout; // VkImageLayout layout;
1176 }
1177
1178 const VkSubpassDescription subpassDescription =
1179 {
1180 0u, // VkSubpassDescriptionFlags flags;
1181 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1182 0u, // deUint32 inputAttachmentCount;
1183 DE_NULL, // const VkAttachmentReference* pInputAttachments;
1184 0u, // deUint32 colorAttachmentCount;
1185 DE_NULL, // const VkAttachmentReference* pColorAttachments;
1186 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
1187 &attachmentReferences[0], // const VkAttachmentReference* pDepthStencilAttachment;
1188 0u, // deUint32 preserveAttachmentCount;
1189 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
1190 };
1191
1192 std::vector<VkSubpassDependency> subpassDependencies;
1193
1194 if (m_useImageAsColorOrDSAttachment)
1195 {
1196 const auto srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
1197 const auto srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
1198 const auto dstStageMask = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1199 const auto dstAccessMask = (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT);
1200
1201 const VkSubpassDependency spdVal =
1202 {
1203 0u, // uint32_t srcSubpass;
1204 0u, // uint32_t dstSubpass;
1205 srcStageMask, // VkPipelineStageFlags srcStageMask;
1206 dstStageMask, // VkPipelineStageFlags dstStageMask;
1207 srcAccessMask, // VkAccessFlags srcAccessMask;
1208 dstAccessMask, // VkAccessFlags dstAccessMask;
1209 VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT | VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags;
1210 };
1211
1212 subpassDependencies.push_back(spdVal);
1213 }
1214
1215 const VkRenderPassCreateInfo renderPassParams =
1216 {
1217 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1218 DE_NULL, // const void* pNext;
1219 0u, // VkRenderPassCreateFlags flags;
1220 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
1221 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
1222 1u, // deUint32 subpassCount;
1223 &subpassDescription, // const VkSubpassDescription* pSubpasses;
1224 static_cast<uint32_t>(subpassDependencies.size()), // deUint32 dependencyCount;
1225 de::dataOrNull(subpassDependencies), // const VkSubpassDependency* pDependencies;
1226 };
1227
1228 m_renderPass = RenderPassWrapper(m_pipelineConstructionType, vk, vkDevice, &renderPassParams);
1229 }
1230
1231 // Create framebuffer
1232 {
1233 std::vector<VkImage> images(m_imageCount);
1234 std::vector<VkImageView> pAttachments(m_imageCount);
1235 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1236 {
1237 images[imgNdx] = m_dsImages[imgNdx]->get();
1238 pAttachments[imgNdx] = m_dsAttachmentViews[imgNdx]->get();
1239 }
1240
1241 const VkFramebufferCreateInfo framebufferParams =
1242 {
1243 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1244 DE_NULL, // const void* pNext;
1245 0u, // VkFramebufferCreateFlags flags;
1246 *m_renderPass, // VkRenderPass renderPass;
1247 (deUint32)m_imageCount, // deUint32 attachmentCount;
1248 &pAttachments[0], // const VkImageView* pAttachments;
1249 (deUint32)renderSize.x(), // deUint32 width;
1250 (deUint32)renderSize.y(), // deUint32 height;
1251 1u // deUint32 layers;
1252 };
1253
1254 m_renderPass.createFramebuffer(vk, vkDevice, &framebufferParams, images);
1255 }
1256
1257 // Create pipeline layouts
1258 {
1259 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1260 {
1261 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1262 DE_NULL, // const void* pNext;
1263 0u, // VkPipelineLayoutCreateFlags flags;
1264 0u, // deUint32 setLayoutCount;
1265 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
1266 0u, // deUint32 pushConstantRangeCount;
1267 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1268 };
1269
1270 m_preRasterizationStatePipelineLayout = PipelineLayoutWrapper(m_pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
1271 }
1272 {
1273 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1274 {
1275 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1276 DE_NULL, // const void* pNext;
1277 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, // VkPipelineLayoutCreateFlags flags;
1278 0u, // deUint32 setLayoutCount;
1279 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
1280 0u, // deUint32 pushConstantRangeCount;
1281 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1282 };
1283
1284 m_preRasterizationStatePipelineLayout = PipelineLayoutWrapper(m_pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
1285 }
1286 {
1287 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1288 {
1289 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1290 DE_NULL, // const void* pNext;
1291 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, // VkPipelineLayoutCreateFlags flags;
1292 1u, // deUint32 setLayoutCount;
1293 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
1294 0u, // deUint32 pushConstantRangeCount;
1295 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1296 };
1297
1298 m_fragmentStatePipelineLayout = PipelineLayoutWrapper(m_pipelineConstructionType, vk, vkDevice, &pipelineLayoutParams);
1299 }
1300
1301 m_vertexShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
1302 m_fragmentShaderModule = ShaderWrapper(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
1303
1304 // Create pipeline
1305 {
1306 const VkVertexInputBindingDescription vertexInputBindingDescription =
1307 {
1308 0u, // deUint32 binding;
1309 sizeof(Vertex4Tex4), // deUint32 strideInBytes;
1310 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
1311 };
1312
1313 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1314 {
1315 {
1316 0u, // deUint32 location;
1317 0u, // deUint32 binding;
1318 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1319 0u // deUint32 offset;
1320 },
1321 {
1322 1u, // deUint32 location;
1323 0u, // deUint32 binding;
1324 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1325 DE_OFFSET_OF(Vertex4Tex4, texCoord), // deUint32 offset;
1326 }
1327 };
1328
1329 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1330 {
1331 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1332 DE_NULL, // const void* pNext;
1333 0u, // VkPipelineVertexInputStateCreateFlags flags;
1334 1u, // deUint32 vertexBindingDescriptionCount;
1335 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1336 2u, // deUint32 vertexAttributeDescriptionCount;
1337 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1338 };
1339
1340 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
1341 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
1342
1343 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(m_imageCount);
1344
1345 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1346 {
1347 colorBlendAttachmentStates[imgNdx].blendEnable = false; // VkBool32 blendEnable;
1348 colorBlendAttachmentStates[imgNdx].srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcColorBlendFactor;
1349 colorBlendAttachmentStates[imgNdx].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstColorBlendFactor;
1350 colorBlendAttachmentStates[imgNdx].colorBlendOp = VK_BLEND_OP_ADD; // VkBlendOp colorBlendOp;
1351 colorBlendAttachmentStates[imgNdx].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcAlphaBlendFactor;
1352 colorBlendAttachmentStates[imgNdx].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstAlphaBlendFactor;
1353 colorBlendAttachmentStates[imgNdx].alphaBlendOp = VK_BLEND_OP_ADD; // VkBlendOp alphaBlendOp;
1354 colorBlendAttachmentStates[imgNdx].colorWriteMask = 0u; // VkColorComponentFlags colorWriteMask;
1355 }
1356
1357 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1358 {
1359 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1360 DE_NULL, // const void* pNext;
1361 0u, // VkPipelineColorBlendStateCreateFlags flags;
1362 false, // VkBool32 logicOpEnable;
1363 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1364 0u, // deUint32 attachmentCount;
1365 DE_NULL, // const VkPipelineColorBlendAttachmentState* pAttachments;
1366 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
1367 };
1368
1369 VkBool32 depthTestEnable =
1370 ((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && !m_interleaveReadWriteComponents) ||
1371 ((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && m_interleaveReadWriteComponents);
1372
1373 VkBool32 stencilTestEnable =
1374 ((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && !m_interleaveReadWriteComponents) ||
1375 ((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && m_interleaveReadWriteComponents);
1376
1377 const auto stencilFrontOpState = makeStencilOpState(vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_NEVER, 0xFFu, 0xFFu, 0u);
1378 const auto stencilBackOpState = makeStencilOpState(vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_REPLACE, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0xFFu, 0xFFu, 0u);
1379
1380 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
1381 {
1382 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1383 DE_NULL, // const void* pNext
1384 0u, // VkPipelineDepthStencilStateCreateFlags flags
1385 depthTestEnable, // VkBool32 depthTestEnable
1386 depthTestEnable, // VkBool32 depthWriteEnable
1387 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp
1388 DE_FALSE, // VkBool32 depthBoundsTestEnable
1389 stencilTestEnable, // VkBool32 stencilTestEnable
1390 stencilFrontOpState, // VkStencilOpState front
1391 stencilBackOpState, // VkStencilOpState back
1392 0.0f, // float minDepthBounds
1393 1.0f, // float maxDepthBounds;
1394 };
1395
1396 std::vector<VkDynamicState> dynamicStates;
1397 if (m_pipelineStateMode != PipelineStateMode::STATIC)
1398 dynamicStates.push_back(VK_DYNAMIC_STATE_ATTACHMENT_FEEDBACK_LOOP_ENABLE_EXT);
1399
1400 const VkPipelineDynamicStateCreateInfo dynamicStateInfo =
1401 {
1402 VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1403 nullptr,
1404 0u,
1405 de::sizeU32(dynamicStates),
1406 de::dataOrNull(dynamicStates),
1407 };
1408
1409 if (m_useMaintenance5)
1410 m_graphicsPipeline.setPipelineCreateFlags2(translateCreateFlag(m_params.pipelineCreateFlags));
1411
1412 m_graphicsPipeline.setDynamicState(&dynamicStateInfo)
1413 .setMonolithicPipelineLayout(m_fragmentStatePipelineLayout)
1414 .setDefaultDepthStencilState()
1415 .setDefaultRasterizationState()
1416 .setDefaultMultisampleState()
1417 .setupVertexInputState(&vertexInputStateParams)
1418 .setupPreRasterizationShaderState(viewports,
1419 scissors,
1420 m_preRasterizationStatePipelineLayout,
1421 *m_renderPass,
1422 0u,
1423 m_vertexShaderModule)
1424 .setupFragmentShaderState(m_fragmentStatePipelineLayout, *m_renderPass, 0u, m_fragmentShaderModule, &depthStencilStateCreateInfo)
1425 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateParams)
1426 .buildPipeline();
1427
1428 }
1429
1430 // Create vertex buffer
1431 {
1432 const VkDeviceSize vertexBufferSize = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
1433 const VkBufferCreateInfo vertexBufferParams =
1434 {
1435 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1436 DE_NULL, // const void* pNext;
1437 0u, // VkBufferCreateFlags flags;
1438 vertexBufferSize, // VkDeviceSize size;
1439 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1440 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1441 1u, // deUint32 queueFamilyIndexCount;
1442 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1443 };
1444
1445 DE_ASSERT(vertexBufferSize > 0);
1446
1447 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
1448 m_vertexBufferAlloc = allocateBuffer(vki, vk, physDevice, vkDevice, *m_vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_allocationKind);
1449 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1450
1451 // Load vertices into vertex buffer
1452 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
1453 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
1454 }
1455
1456 // Create command buffer
1457 {
1458 std::vector<VkImageMemoryBarrier> preAttachmentBarriers(m_imageCount);
1459
1460 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1461 {
1462 preAttachmentBarriers[imgNdx].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; // VkStructureType sType;
1463 preAttachmentBarriers[imgNdx].pNext = DE_NULL; // const void* pNext;
1464 preAttachmentBarriers[imgNdx].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; // VkAccessFlags srcAccessMask;
1465 preAttachmentBarriers[imgNdx].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; // VkAccessFlags dstAccessMask;
1466 preAttachmentBarriers[imgNdx].oldLayout = m_imageLayout; // VkImageLayout oldLayout;
1467 preAttachmentBarriers[imgNdx].newLayout = m_imageLayout; // VkImageLayout newLayout;
1468 preAttachmentBarriers[imgNdx].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 srcQueueFamilyIndex;
1469 preAttachmentBarriers[imgNdx].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 dstQueueFamilyIndex;
1470 preAttachmentBarriers[imgNdx].image = **m_dsImages[imgNdx]; // VkImage image;
1471 preAttachmentBarriers[imgNdx].subresourceRange.aspectMask = getAspectFlags(m_imageFormat); // VkImageSubresourceRange subresourceRange;
1472 preAttachmentBarriers[imgNdx].subresourceRange.baseMipLevel = 0u;
1473 preAttachmentBarriers[imgNdx].subresourceRange.levelCount = 1u;
1474 preAttachmentBarriers[imgNdx].subresourceRange.baseArrayLayer = 0u;
1475 preAttachmentBarriers[imgNdx].subresourceRange.layerCount = 1u;
1476 }
1477
1478 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1479
1480 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1481 0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
1482
1483 // Do not clear the color attachments as we are using the texture as color attachment.
1484 m_renderPass.begin(vk, *m_cmdBuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), 0u, DE_NULL);
1485
1486 m_graphicsPipeline.bind(*m_cmdBuffer);
1487
1488 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
1489
1490 const VkDeviceSize vertexBufferOffset = 0;
1491 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1492
1493 if (m_pipelineStateMode != PipelineStateMode::STATIC)
1494 vk.cmdSetAttachmentFeedbackLoopEnableEXT(*m_cmdBuffer, testModeToAspectFlags(m_imageAspectTestMode));
1495
1496 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
1497
1498 m_renderPass.end(vk, *m_cmdBuffer);
1499 endCommandBuffer(vk, *m_cmdBuffer);
1500 }
1501 }
1502
verifyImage(void)1503 tcu::TestStatus AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::verifyImage(void)
1504 {
1505 const tcu::TextureFormat tcuFormat = getSizeCompatibleTcuTextureFormat(m_imageFormat);
1506 const bool isDepth = (!m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)) ||
1507 (m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT));
1508 const bool isStencil = (!m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)) ||
1509 (m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT));
1510 // ImageSamplingInstance::verifyImage() doesn't support stencil sampling.
1511 if (!m_useImageAsColorOrDSAttachment && !isStencil)
1512 return ImageSamplingInstance::verifyImage();
1513
1514 const tcu::Vec4 fThreshold (0.005f);
1515 const tcu::UVec4 uThreshold (0u); // Due to unsigned normalized fixed-point integers conversion to floats and viceversa.
1516 tcu::UVec2 renderSize = tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
1517
1518 de::MovePtr<tcu::TextureLevel> referenceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(tcuFormat,
1519 m_imageSize.x(),
1520 m_imageSize.y(),
1521 m_imageSize.z()));
1522
1523 for (int z = 0; z < m_imageSize.z(); z++)
1524 for (int y = 0; y < m_imageSize.y(); y++)
1525 for (int x = 0; x < m_imageSize.x(); x++)
1526 {
1527 if (isDepth)
1528 {
1529 float depth = 0.0f;
1530 if (m_interleaveReadWriteComponents)
1531 {
1532 int stencil = 1 + m_texture->getLevel(0, 0).getPixStencil(x, y, z);
1533 depth = static_cast<float>(stencil) / 255.0f;
1534 }
1535 else
1536 {
1537 if (m_useDifferentAreasSampleWrite && x < m_imageSize.x() / 2)
1538 depth = m_texture->getLevel(0, 0).getPixDepth(x + (m_imageSize.x() / 2), y, z) + 0.1f;
1539 else
1540 depth = m_texture->getLevel(0, 0).getPixDepth(x, y, z);
1541
1542 if (!m_useDifferentAreasSampleWrite)
1543 depth += 0.1f;
1544 }
1545
1546 depth = deFloatClamp(depth, 0.0f, 1.0f);
1547 referenceTextureLevel->getAccess().setPixDepth(depth, x, y, z);
1548 }
1549 if (isStencil)
1550 {
1551 int stencil = 0;
1552 if (m_interleaveReadWriteComponents)
1553 {
1554 float depth = m_texture->getLevel(0, 0).getPixDepth(x, y, z) + 0.1f;
1555 stencil = static_cast<int>(depth * 255.0f);
1556 }
1557 else
1558 {
1559 if (m_useDifferentAreasSampleWrite && x < m_imageSize.x() / 2)
1560 stencil = 1 + m_texture->getLevel(0, 0).getPixStencil(x + (m_imageSize.x() / 2), y, z);
1561 else
1562 stencil = m_texture->getLevel(0, 0).getPixStencil(x, y, z);
1563
1564 if (!m_useDifferentAreasSampleWrite)
1565 stencil += 1;
1566
1567 stencil = deClamp32(stencil, 0, 255);
1568 }
1569
1570 referenceTextureLevel->getAccess().setPixStencil(stencil, x, y, z);
1571 }
1572 }
1573
1574 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1575 {
1576 if (isDepth)
1577 {
1578 // Read back result image
1579 de::MovePtr<tcu::TextureLevel> resultTexture (readDepthAttachment(m_context.getDeviceInterface(),
1580 m_context.getDevice(),
1581 m_context.getUniversalQueue(),
1582 m_context.getUniversalQueueFamilyIndex(),
1583 m_context.getDefaultAllocator(),
1584 **m_dsImages[imgNdx],
1585 m_imageFormat,
1586 renderSize,
1587 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1588
1589 const tcu::ConstPixelBufferAccess result = resultTexture->getAccess();
1590 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1591 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1592 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(referenceTextureLevel->getAccess(), mode);
1593 bool isIntegerFormat = isUintFormat(mapTextureFormat(depthResult.getFormat())) || isIntFormat(mapTextureFormat(depthResult.getFormat()));
1594
1595 if (!isIntegerFormat)
1596 {
1597 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1598 return tcu::TestStatus::fail("Failed depth");
1599 }
1600 else
1601 {
1602 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1603 return tcu::TestStatus::fail("Failed depth");
1604 }
1605 }
1606
1607 if (isStencil)
1608 {
1609 // Read back result image
1610 de::MovePtr<tcu::TextureLevel> resultTexture (readStencilAttachment(m_context.getDeviceInterface(),
1611 m_context.getDevice(),
1612 m_context.getUniversalQueue(),
1613 m_context.getUniversalQueueFamilyIndex(),
1614 m_context.getDefaultAllocator(),
1615 **m_dsImages[imgNdx],
1616 m_imageFormat,
1617 renderSize,
1618 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1619
1620 const tcu::ConstPixelBufferAccess result = resultTexture->getAccess();
1621 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1622 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1623 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(referenceTextureLevel->getAccess(), mode);
1624 bool isIntegerFormat = isUintFormat(mapTextureFormat(stencilResult.getFormat())) || isIntFormat(mapTextureFormat(stencilResult.getFormat()));
1625
1626 if (!isIntegerFormat)
1627 {
1628 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1629 return tcu::TestStatus::fail("Failed stencil");
1630 }
1631 else
1632 {
1633 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1634 return tcu::TestStatus::fail("Failed stencil");
1635 }
1636 }
1637 }
1638
1639 return tcu::TestStatus::pass("Pass");
1640 }
1641
iterate(void)1642 tcu::TestStatus AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::iterate (void)
1643 {
1644 const DeviceInterface& vk = m_context.getDeviceInterface();
1645 const VkDevice vkDevice = m_context.getDevice();
1646 const VkQueue queue = m_context.getUniversalQueue();
1647
1648 setup();
1649 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1650
1651 return verifyImage();
1652 }
1653
verifyImage(void)1654 tcu::TestStatus AttachmentFeedbackLoopLayoutImageSamplingInstance::verifyImage(void)
1655 {
1656 if (!m_useImageAsColorOrDSAttachment)
1657 return ImageSamplingInstance::verifyImage();
1658
1659 const tcu::Vec4 fThreshold (0.01f);
1660 const tcu::UVec4 uThreshold (1u);
1661 tcu::UVec2 renderSize = tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
1662
1663 const tcu::TextureFormat tcuFormat = getSizeCompatibleTcuTextureFormat(m_imageFormat);
1664 de::MovePtr<tcu::TextureLevel> referenceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(tcuFormat,
1665 m_imageSize.x(),
1666 m_imageSize.y(),
1667 m_imageSize.z()));
1668
1669 for (int z = 0; z < m_imageSize.z(); z++)
1670 for (int y = 0; y < m_imageSize.y(); y++)
1671 for (int x = 0; x < m_imageSize.x(); x++)
1672 {
1673 tcu::Vec4 color = tcu::Vec4(1.0f);
1674
1675 if (m_useDifferentAreasSampleWrite && (x < m_imageSize.x() / 2))
1676 color = m_texture->getLevel(0, 0).getPixel(x + (m_imageSize.x() / 2), y, z) + tcu::Vec4(0.1f);
1677 else
1678 color = m_texture->getLevel(0, 0).getPixel(x, y, z);
1679
1680 if (!m_useDifferentAreasSampleWrite)
1681 color += tcu::Vec4(0.1f);
1682
1683 if (m_interleaveReadWriteComponents)
1684 {
1685 tcu::Vec4 sampledColor = m_texture->getLevel(0, 0).getPixel(x, y, z);
1686 color.x() = color.y();
1687 color.y() = sampledColor.y();
1688 color.z() = color.w();
1689 color.w() = sampledColor.w();
1690 }
1691
1692 color.x() = deFloatClamp(color.x(), 0.0f, 1.0f);
1693 color.y() = deFloatClamp(color.y(), 0.0f, 1.0f);
1694 color.z() = deFloatClamp(color.z(), 0.0f, 1.0f);
1695 color.w() = deFloatClamp(color.w(), 0.0f, 1.0f);
1696
1697 referenceTextureLevel->getAccess().setPixel(color, x, y, z);
1698 }
1699
1700 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1701 {
1702 // Read back result image
1703 de::MovePtr<tcu::TextureLevel> resultTexture (readColorAttachment(m_context.getDeviceInterface(),
1704 m_context.getDevice(),
1705 m_context.getUniversalQueue(),
1706 m_context.getUniversalQueueFamilyIndex(),
1707 m_context.getDefaultAllocator(),
1708 **m_colorImages[imgNdx],
1709 m_colorFormat,
1710 renderSize,
1711 vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1712 const tcu::ConstPixelBufferAccess result = resultTexture->getAccess();
1713 const bool isIntegerFormat = isUintFormat(m_imageFormat) || isIntFormat(m_imageFormat);
1714
1715 if (!isIntegerFormat)
1716 {
1717 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1718 return tcu::TestStatus::fail("Failed color");
1719 }
1720 else
1721 {
1722 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1723 return tcu::TestStatus::fail("Failed color");
1724 }
1725 }
1726
1727 return tcu::TestStatus::pass("Pass");
1728 }
1729
~AttachmentFeedbackLoopLayoutImageSamplingInstance(void)1730 AttachmentFeedbackLoopLayoutImageSamplingInstance::~AttachmentFeedbackLoopLayoutImageSamplingInstance (void)
1731 {
1732 }
1733
iterate(void)1734 tcu::TestStatus AttachmentFeedbackLoopLayoutImageSamplingInstance::iterate (void)
1735 {
1736 const DeviceInterface& vk = m_context.getDeviceInterface();
1737 const VkDevice vkDevice = m_context.getDevice();
1738 const VkQueue queue = m_context.getUniversalQueue();
1739
1740 setup();
1741 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1742
1743 return verifyImage();
1744 }
1745
1746 class AttachmentFeedbackLoopLayoutSamplerTest : public vkt::TestCase {
1747 public:
1748 AttachmentFeedbackLoopLayoutSamplerTest (tcu::TestContext& testContext,
1749 vk::PipelineConstructionType pipelineConstructionType,
1750 const char* name,
1751 SamplerViewType imageViewType,
1752 VkFormat imageFormat,
1753 int imageSize,
1754 VkDescriptorType imageDescriptorType,
1755 float samplerLod,
1756 TestMode testMode,
1757 ImageAspectTestMode imageAspectTestMode,
1758 bool interleaveReadWriteComponents,
1759 PipelineStateMode pipelineStateMode,
1760 bool useMaintenance5);
~AttachmentFeedbackLoopLayoutSamplerTest(void)1761 virtual ~AttachmentFeedbackLoopLayoutSamplerTest (void) {}
1762
1763 virtual ImageSamplingInstanceParams getImageSamplingInstanceParams (SamplerViewType imageViewType,
1764 VkFormat imageFormat,
1765 int imageSize,
1766 VkDescriptorType imageDescriptorType,
1767 float samplerLod) const;
1768
1769 virtual void initPrograms (SourceCollections& sourceCollections) const;
1770 virtual void checkSupport (Context& context) const;
1771 virtual TestInstance* createInstance (Context& context) const;
1772 virtual tcu::UVec2 getRenderSize (SamplerViewType viewType) const;
1773 virtual std::vector<Vertex4Tex4> createVertices (void) const;
1774 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
1775 virtual VkComponentMapping getComponentMapping (void) const;
1776
1777 static std::string getGlslSamplerType (const tcu::TextureFormat& format, SamplerViewType type);
1778 static tcu::IVec3 getImageSize (SamplerViewType viewType, int size);
1779 static int getArraySize (SamplerViewType viewType);
1780
1781 static std::string getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount);
1782 static std::string getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type);
1783 static std::string getGlslSamplerDecl (int imageCount);
1784 static std::string getGlslTextureDecl (int imageCount);
1785
1786 protected:
1787 vk::PipelineConstructionType m_pipelineConstructionType;
1788 SamplerViewType m_imageViewType;
1789 VkFormat m_imageFormat;
1790 int m_imageSize;
1791 VkDescriptorType m_imageDescriptorType;
1792 float m_samplerLod;
1793 TestMode m_testMode;
1794 ImageAspectTestMode m_imageAspectTestMode;
1795 bool m_interleaveReadWriteComponents;
1796 PipelineStateMode m_pipelineStateMode;
1797 bool m_useMaintenance5;
1798 };
1799
1800 // AttachmentFeedbackLoopLayoutSamplerTest
1801
AttachmentFeedbackLoopLayoutSamplerTest(tcu::TestContext& testContext, vk::PipelineConstructionType pipelineConstructionType, const char* name, SamplerViewType imageViewType, VkFormat imageFormat, int imageSize, VkDescriptorType imageDescriptorType, float samplerLod, TestMode testMode, ImageAspectTestMode imageAspectTestMode, bool interleaveReadWriteComponents, PipelineStateMode pipelineStateMode, bool useMaintenance5)1802 AttachmentFeedbackLoopLayoutSamplerTest::AttachmentFeedbackLoopLayoutSamplerTest (tcu::TestContext& testContext,
1803 vk::PipelineConstructionType pipelineConstructionType,
1804 const char* name,
1805 SamplerViewType imageViewType,
1806 VkFormat imageFormat,
1807 int imageSize,
1808 VkDescriptorType imageDescriptorType,
1809 float samplerLod,
1810 TestMode testMode,
1811 ImageAspectTestMode imageAspectTestMode,
1812 bool interleaveReadWriteComponents,
1813 PipelineStateMode pipelineStateMode,
1814 bool useMaintenance5)
1815 : vkt::TestCase (testContext, name)
1816 , m_pipelineConstructionType (pipelineConstructionType)
1817 , m_imageViewType (imageViewType)
1818 , m_imageFormat (imageFormat)
1819 , m_imageSize (imageSize)
1820 , m_imageDescriptorType (imageDescriptorType)
1821 , m_samplerLod (samplerLod)
1822 , m_testMode (testMode)
1823 , m_imageAspectTestMode (imageAspectTestMode)
1824 , m_interleaveReadWriteComponents (interleaveReadWriteComponents)
1825 , m_pipelineStateMode (pipelineStateMode)
1826 , m_useMaintenance5 (useMaintenance5)
1827 {
1828 }
1829
getImageSamplingInstanceParams(SamplerViewType imageViewType, VkFormat imageFormat, int imageSize, VkDescriptorType imageDescriptorType, float samplerLod) const1830 ImageSamplingInstanceParams AttachmentFeedbackLoopLayoutSamplerTest::getImageSamplingInstanceParams (SamplerViewType imageViewType,
1831 VkFormat imageFormat,
1832 int imageSize,
1833 VkDescriptorType imageDescriptorType,
1834 float samplerLod) const
1835 {
1836 const tcu::UVec2 renderSize = getRenderSize(imageViewType);
1837 const std::vector<Vertex4Tex4> vertices = createVertices();
1838 const VkSamplerCreateInfo samplerParams = getSamplerCreateInfo();
1839 const VkComponentMapping componentMapping = getComponentMapping();
1840
1841 VkImageAspectFlags imageAspect = 0u;
1842 VkPipelineCreateFlags pipelineCreateFlags = 0u;
1843
1844 if (!isCompressedFormat(imageFormat))
1845 {
1846 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR)
1847 {
1848 DE_ASSERT(!tcu::hasDepthComponent(mapVkFormat(imageFormat).order) &&
1849 !tcu::hasStencilComponent(mapVkFormat(imageFormat).order));
1850 }
1851 else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH)
1852 DE_ASSERT(tcu::hasDepthComponent(mapVkFormat(imageFormat).order));
1853 else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL)
1854 DE_ASSERT(tcu::hasStencilComponent(mapVkFormat(imageFormat).order));
1855
1856 imageAspect = testModeToAspectFlags(m_imageAspectTestMode);
1857 pipelineCreateFlags = getStaticPipelineCreateFlags(imageAspect, m_pipelineStateMode);
1858 }
1859 else
1860 {
1861 imageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
1862 }
1863
1864 const VkImageSubresourceRange subresourceRange =
1865 {
1866 imageAspect, // VkImageAspectFlags aspectMask;
1867 0u, // deUint32 baseMipLevel;
1868 1u, // deUint32 mipLevels;
1869 0u, // deUint32 baseArrayLayer;
1870 (deUint32)getArraySize(imageViewType) // deUint32 arraySize;
1871 };
1872
1873 return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat,
1874 getImageSize(imageViewType, imageSize),
1875 getArraySize(imageViewType),
1876 componentMapping, subresourceRange,
1877 samplerParams, samplerLod, vertices, false,
1878 imageDescriptorType, 1u, ALLOCATION_KIND_SUBALLOCATED,
1879 vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT,
1880 pipelineCreateFlags);
1881 }
1882
checkSupport(Context& context) const1883 void AttachmentFeedbackLoopLayoutSamplerTest::checkSupport (Context& context) const
1884 {
1885 const auto& vki = context.getInstanceInterface();
1886 const auto physicalDevice = context.getPhysicalDevice();
1887
1888 checkPipelineConstructionRequirements(vki, physicalDevice, m_pipelineConstructionType);
1889
1890 context.requireDeviceFunctionality("VK_EXT_attachment_feedback_loop_layout");
1891
1892 if (m_useMaintenance5)
1893 context.requireDeviceFunctionality("VK_KHR_maintenance5");
1894
1895 if (m_pipelineStateMode != PipelineStateMode::STATIC || isConstructionTypeShaderObject(m_pipelineConstructionType))
1896 context.requireDeviceFunctionality("VK_EXT_attachment_feedback_loop_dynamic_state");
1897
1898 const auto imgParams = getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod);
1899 checkSupportImageSamplingInstance(context, imgParams);
1900
1901 if (m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL) // Image as color or DS attachment.
1902 {
1903 VkFormatProperties formatProps;
1904 vki.getPhysicalDeviceFormatProperties(physicalDevice, imgParams.imageFormat, &formatProps);
1905
1906 const auto attachmentFormatFeature = isDepthStencilFormat(imgParams.imageFormat)
1907 ? VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT
1908 : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1909 const VkFormatFeatureFlags neededFeatures = attachmentFormatFeature
1910 | VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
1911 | VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
1912 | VK_FORMAT_FEATURE_TRANSFER_DST_BIT
1913 ;
1914
1915 if ((formatProps.optimalTilingFeatures & neededFeatures) != neededFeatures)
1916 {
1917 std::ostringstream msg;
1918 msg << "Format does not support required features: 0x" << std::hex << neededFeatures;
1919 TCU_THROW(NotSupportedError, msg.str());
1920 }
1921
1922 if ((!m_interleaveReadWriteComponents && m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL) ||
1923 (m_interleaveReadWriteComponents && m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH))
1924 context.requireDeviceFunctionality("VK_EXT_shader_stencil_export");
1925 }
1926 }
1927
getGlslTextureType(const tcu::TextureFormat& format, VkImageViewType type)1928 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type)
1929 {
1930 std::ostringstream textureType;
1931
1932 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
1933 textureType << "u";
1934 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
1935 textureType << "i";
1936
1937 switch (type)
1938 {
1939 case VK_IMAGE_VIEW_TYPE_1D:
1940 textureType << "texture1D";
1941 break;
1942
1943 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
1944 textureType << "texture1DArray";
1945 break;
1946
1947 case VK_IMAGE_VIEW_TYPE_2D:
1948 textureType << "texture2D";
1949 break;
1950
1951 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
1952 textureType << "texture2DArray";
1953 break;
1954
1955 case VK_IMAGE_VIEW_TYPE_3D:
1956 textureType << "texture3D";
1957 break;
1958
1959 case VK_IMAGE_VIEW_TYPE_CUBE:
1960 textureType << "textureCube";
1961 break;
1962
1963 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
1964 textureType << "textureCubeArray";
1965 break;
1966
1967 default:
1968 DE_FATAL("Unknown image view type");
1969 }
1970
1971 return textureType.str();
1972 }
1973
getGlslSamplerDecl(int imageCount)1974 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSamplerDecl (int imageCount)
1975 {
1976 std::ostringstream samplerArray;
1977 samplerArray << "texSamplers[" << imageCount << "]";
1978
1979 return imageCount > 1 ? samplerArray.str() : "texSampler";
1980 }
1981
getGlslTextureDecl(int imageCount)1982 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslTextureDecl (int imageCount)
1983 {
1984 std::ostringstream textureArray;
1985 textureArray << "texImages[" << imageCount << "]";
1986
1987 return imageCount > 1 ? textureArray.str() : "texImage";
1988 }
1989
getGlslSampler(const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount)1990 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount)
1991 {
1992 std::string texSampler = imageCount > 1 ? "texSamplers[i]" : "texSampler";
1993 std::string texImage = imageCount > 1 ? "texImages[i]" : "texImage";
1994
1995 switch (samplingType)
1996 {
1997 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1998 return getGlslSamplerType(format, type) + "(" + texImage + ", texSampler)";
1999 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2000 default:
2001 return texSampler;
2002 }
2003 }
2004
initPrograms(SourceCollections& sourceCollections) const2005 void AttachmentFeedbackLoopLayoutSamplerTest::initPrograms (SourceCollections& sourceCollections) const
2006 {
2007 std::ostringstream vertexSrc;
2008 std::ostringstream fragmentSrc;
2009 const char* texCoordSwizzle = DE_NULL;
2010 const VkFormat vkFormat = m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL ? VK_FORMAT_S8_UINT : m_imageFormat;
2011 const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(vkFormat))
2012 : mapVkFormat(vkFormat);
2013 tcu::Vec4 lookupScale;
2014 tcu::Vec4 lookupBias;
2015
2016 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
2017
2018 switch (m_imageViewType)
2019 {
2020 case VK_IMAGE_VIEW_TYPE_1D:
2021 texCoordSwizzle = "x";
2022 break;
2023 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2024 case VK_IMAGE_VIEW_TYPE_2D:
2025 texCoordSwizzle = "xy";
2026 break;
2027 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2028 case VK_IMAGE_VIEW_TYPE_3D:
2029 case VK_IMAGE_VIEW_TYPE_CUBE:
2030 texCoordSwizzle = "xyz";
2031 break;
2032 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2033 texCoordSwizzle = "xyzw";
2034 break;
2035 default:
2036 DE_ASSERT(false);
2037 break;
2038 }
2039
2040 vertexSrc << "#version 440\n"
2041 << "layout(location = 0) in vec4 position;\n"
2042 << "layout(location = 1) in vec4 texCoords;\n"
2043 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
2044 << "out gl_PerVertex {\n"
2045 << " vec4 gl_Position;\n"
2046 << "};\n"
2047 << "void main (void)\n"
2048 << "{\n"
2049 << " gl_Position = position;\n"
2050 << " vtxTexCoords = texCoords;\n"
2051 << "}\n";
2052
2053 fragmentSrc << "#version 440\n";
2054
2055 if ((m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL) ||
2056 (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_interleaveReadWriteComponents))
2057 {
2058 fragmentSrc << "#extension GL_ARB_shader_stencil_export: require\n";
2059 }
2060
2061 switch (m_imageDescriptorType)
2062 {
2063 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
2064 fragmentSrc
2065 << "layout(set = 0, binding = 0) uniform highp sampler texSampler;\n"
2066 << "layout(set = 0, binding = 1) uniform highp " << getGlslTextureType(format, m_imageViewType) << " " << getGlslTextureDecl(1u) << ";\n";
2067 break;
2068 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
2069 default:
2070 fragmentSrc
2071 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " " << getGlslSamplerDecl(1u) << ";\n";
2072 }
2073
2074 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR || m_testMode == TEST_MODE_READ_ONLY)
2075 fragmentSrc << "layout(location = 0) out highp vec4 fragColor;\n";
2076
2077 fragmentSrc << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
2078 << "void main (void)\n"
2079 << "{\n";
2080
2081 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode != TEST_MODE_READ_ONLY)
2082 fragmentSrc << " uvec4 read_data = ";
2083 else
2084 fragmentSrc << " vec4 read_data = ";
2085
2086 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2087 {
2088 fragmentSrc << "vec4(1.0f, 0.0f, 0.0f, 1.0f);\n";
2089
2090 fragmentSrc << " read_data.x = ";
2091 if (m_samplerLod > 0.0f)
2092 {
2093 DE_ASSERT(m_imageViewType.isNormalized());
2094 fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ").x";
2095 }
2096 else
2097 {
2098 if (m_imageViewType.isNormalized())
2099 fragmentSrc << "texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ").x" << std::fixed;
2100 else
2101 fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0).x" << std::fixed;
2102 }
2103
2104 fragmentSrc << " + 0.1f;\n";
2105 }
2106 else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode == TEST_MODE_READ_ONLY)
2107 {
2108 if (m_samplerLod > 0.0f)
2109 {
2110 DE_ASSERT(m_imageViewType.isNormalized());
2111 fragmentSrc << "vec4(textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ").x / 255.0f, 0.0f, 0.0f, 1.0f)";
2112 }
2113 else
2114 {
2115 if (m_imageViewType.isNormalized())
2116 fragmentSrc << "vec4(texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ").x / 255.0f, 0.0f, 0.0f, 1.0f)" << std::fixed;
2117 else
2118 fragmentSrc << "vec4(textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0).x / 255.0f, 0.0f, 0.0f, 1.0f)" << std::fixed;
2119 }
2120
2121 fragmentSrc << ";\n";
2122 }
2123 else
2124 {
2125 if (m_samplerLod > 0.0f)
2126 {
2127 DE_ASSERT(m_imageViewType.isNormalized());
2128 fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ")";
2129 }
2130 else
2131 {
2132 if (m_imageViewType.isNormalized())
2133 fragmentSrc << "texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
2134 else
2135 fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0)" << std::fixed;
2136 }
2137
2138 if (m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2139 {
2140 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL)
2141 fragmentSrc << " + uvec4(1u, 0u, 0u, 0)";
2142 else
2143 fragmentSrc << " + vec4(0.1f)";
2144 }
2145
2146 fragmentSrc << ";\n";
2147 }
2148
2149 if (m_interleaveReadWriteComponents)
2150 {
2151 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR)
2152 {
2153 fragmentSrc << " fragColor = vec4(1.0f);\n"
2154 << " fragColor.x = read_data.y;\n"
2155 << " fragColor.z = read_data.w;\n";
2156 }
2157 else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH)
2158 {
2159 fragmentSrc << " gl_FragStencilRefARB = int(clamp(read_data.x * 255.0f, 0.0f, 255.0f));\n";
2160 }
2161 else
2162 {
2163 fragmentSrc << " gl_FragDepth = clamp(float(read_data.x) / 255.0f, 0.0f, 1.0f);\n";
2164 }
2165 }
2166 else
2167 {
2168 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2169 {
2170 fragmentSrc << " gl_FragDepth = clamp(read_data.x, 0.0f, 1.0f);\n";
2171 }
2172 else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2173 {
2174 fragmentSrc << " gl_FragStencilRefARB = int(clamp(read_data.x, 0u, 255u));\n";
2175 }
2176 else
2177 {
2178 fragmentSrc << " fragColor = read_data;\n";
2179 }
2180 }
2181
2182 fragmentSrc << "}\n";
2183
2184 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
2185 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
2186 }
2187
createInstance(Context& context) const2188 TestInstance* AttachmentFeedbackLoopLayoutSamplerTest::createInstance (Context& context) const
2189 {
2190 const bool useImageAsColorOrDSAttachment = m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL;
2191 const bool useDifferentAreasSampleWrite = m_testMode == TEST_MODE_READ_WRITE_DIFFERENT_AREAS;
2192
2193 if (m_imageAspectTestMode != IMAGE_ASPECT_TEST_COLOR && useImageAsColorOrDSAttachment)
2194 return new AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod), useImageAsColorOrDSAttachment, useDifferentAreasSampleWrite, m_interleaveReadWriteComponents, m_imageAspectTestMode, m_pipelineStateMode, m_useMaintenance5);
2195 return new AttachmentFeedbackLoopLayoutImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod), useImageAsColorOrDSAttachment, useDifferentAreasSampleWrite, m_interleaveReadWriteComponents, m_imageAspectTestMode, m_pipelineStateMode, m_useMaintenance5);
2196 }
2197
getRenderSize(SamplerViewType viewType) const2198 tcu::UVec2 AttachmentFeedbackLoopLayoutSamplerTest::getRenderSize (SamplerViewType viewType) const
2199 {
2200 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
2201 {
2202 return tcu::UVec2(16u, 16u);
2203 }
2204 else
2205 {
2206 return tcu::UVec2(16u * 3u, 16u * 2u);
2207 }
2208 }
2209
createFullscreenQuadArray(vk::VkImageViewType viewType, unsigned arraySize)2210 std::vector<Vertex4Tex4> createFullscreenQuadArray (vk::VkImageViewType viewType, unsigned arraySize)
2211 {
2212 using tcu::Vec4;
2213 std::vector<Vertex4Tex4> verticesArray;
2214
2215 const Vertex4Tex4 lowerLeftVertex =
2216 {
2217 Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
2218 Vec4(0.0f, 0.0f, 0.0f, 0.0f)
2219 };
2220 const Vertex4Tex4 upperLeftVertex =
2221 {
2222 Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
2223 Vec4(0.0f, 1.0f, 0.0f, 0.0f)
2224 };
2225 const Vertex4Tex4 lowerRightVertex =
2226 {
2227 Vec4(1.0f, -1.0f, 0.0f, 1.0f),
2228 Vec4(1.0f, 0.0f, 0.0f, 0.0f)
2229 };
2230 const Vertex4Tex4 upperRightVertex =
2231 {
2232 Vec4(1.0f, 1.0f, 0.0f, 1.0f),
2233 Vec4(1.0f, 1.0f, 0.0f, 0.0f)
2234 };
2235
2236 for (unsigned arrayNdx = 0; arrayNdx < arraySize; arrayNdx++)
2237 {
2238 Vertex4Tex4 vertices[6] =
2239 {
2240 lowerLeftVertex,
2241 upperLeftVertex,
2242 lowerRightVertex,
2243
2244 upperLeftVertex,
2245 lowerRightVertex,
2246 upperRightVertex
2247 };
2248
2249 for (int i = 0; i < 6; i++)
2250 {
2251 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
2252 {
2253 vertices[i].position.y() = (float)arrayNdx;
2254 vertices[i].texCoord.y() = (float)arrayNdx;
2255 }
2256 else
2257 {
2258 vertices[i].position.z() = (float)arrayNdx;
2259 vertices[i].texCoord.z() = (float)arrayNdx;
2260 }
2261 verticesArray.push_back(vertices[i]);
2262 }
2263 }
2264
2265 return verticesArray;
2266 }
2267
createTestQuadAttachmentFeedbackLoopLayout(vk::VkImageViewType viewType)2268 std::vector<Vertex4Tex4> createTestQuadAttachmentFeedbackLoopLayout (vk::VkImageViewType viewType)
2269 {
2270 std::vector<Vertex4Tex4> vertices;
2271
2272 switch (viewType)
2273 {
2274 case vk::VK_IMAGE_VIEW_TYPE_1D:
2275 case vk::VK_IMAGE_VIEW_TYPE_2D:
2276 vertices = createFullscreenQuad();
2277 break;
2278
2279 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2280 vertices = createFullscreenQuadArray(viewType, 6u);
2281 break;
2282
2283 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2284 case vk::VK_IMAGE_VIEW_TYPE_3D:
2285 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
2286 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2287 vertices = createFullscreenQuadArray(viewType, 6u);
2288 break;
2289
2290 default:
2291 DE_ASSERT(false);
2292 break;
2293 }
2294
2295 return vertices;
2296 }
2297
createVertices(void) const2298 std::vector<Vertex4Tex4> AttachmentFeedbackLoopLayoutSamplerTest::createVertices (void) const
2299 {
2300 std::vector<Vertex4Tex4> vertices = m_testMode != TEST_MODE_READ_WRITE_DIFFERENT_AREAS ?
2301 createTestQuadMosaic(m_imageViewType) :
2302 createTestQuadAttachmentFeedbackLoopLayout(m_imageViewType);
2303 for (unsigned int i = 0; i < vertices.size(); ++i) {
2304 if (m_testMode == TEST_MODE_READ_WRITE_DIFFERENT_AREAS)
2305 {
2306 vertices[i].texCoord.x() = std::max(vertices[i].texCoord.x(), 0.5f);
2307 vertices[i].position.x() = std::min(vertices[i].position.x(), 0.0f);
2308 }
2309 if (!m_imageViewType.isNormalized()) {
2310 const float imageSize = static_cast<float>(m_imageSize);
2311 for (int j = 0; j < tcu::Vec4::SIZE; ++j)
2312 vertices[i].texCoord[j] *= imageSize;
2313 }
2314 }
2315 return vertices;
2316 }
2317
getSamplerCreateInfo(void) const2318 VkSamplerCreateInfo AttachmentFeedbackLoopLayoutSamplerTest::getSamplerCreateInfo (void) const
2319 {
2320 const VkSamplerCreateInfo defaultSamplerParams =
2321 {
2322 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
2323 DE_NULL, // const void* pNext;
2324 0u, // VkSamplerCreateFlags flags;
2325 VK_FILTER_NEAREST, // VkFilter magFilter;
2326 VK_FILTER_NEAREST, // VkFilter minFilter;
2327 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
2328 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
2329 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
2330 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
2331 0.0f, // float mipLodBias;
2332 VK_FALSE, // VkBool32 anisotropyEnable;
2333 1.0f, // float maxAnisotropy;
2334 false, // VkBool32 compareEnable;
2335 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
2336 0.0f, // float minLod;
2337 (m_imageViewType.isNormalized() ? 0.25f : 0.0f), // float maxLod;
2338 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat, false), // VkBorderColor borderColor;
2339 !m_imageViewType.isNormalized(), // VkBool32 unnormalizedCoordinates;
2340 };
2341
2342 return defaultSamplerParams;
2343 }
2344
getComponentMapping(void) const2345 VkComponentMapping AttachmentFeedbackLoopLayoutSamplerTest::getComponentMapping (void) const
2346 {
2347 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2348 return componentMapping;
2349 }
2350
getGlslSamplerType(const tcu::TextureFormat& format, SamplerViewType type)2351 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, SamplerViewType type)
2352 {
2353 std::ostringstream samplerType;
2354
2355 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2356 samplerType << "u";
2357 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2358 samplerType << "i";
2359
2360 switch (type)
2361 {
2362 case VK_IMAGE_VIEW_TYPE_1D:
2363 samplerType << "sampler1D";
2364 break;
2365
2366 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2367 samplerType << "sampler1DArray";
2368 break;
2369
2370 case VK_IMAGE_VIEW_TYPE_2D:
2371 samplerType << "sampler2D";
2372 break;
2373
2374 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2375 samplerType << "sampler2DArray";
2376 break;
2377
2378 case VK_IMAGE_VIEW_TYPE_3D:
2379 samplerType << "sampler3D";
2380 break;
2381
2382 case VK_IMAGE_VIEW_TYPE_CUBE:
2383 samplerType << "samplerCube";
2384 break;
2385
2386 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2387 samplerType << "samplerCubeArray";
2388 break;
2389
2390 default:
2391 DE_FATAL("Unknown image view type");
2392 break;
2393 }
2394
2395 return samplerType.str();
2396 }
2397
getImageSize(SamplerViewType viewType, int size)2398 tcu::IVec3 AttachmentFeedbackLoopLayoutSamplerTest::getImageSize (SamplerViewType viewType, int size)
2399 {
2400 switch (viewType)
2401 {
2402 case VK_IMAGE_VIEW_TYPE_1D:
2403 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2404 return tcu::IVec3(size, 1, 1);
2405
2406 case VK_IMAGE_VIEW_TYPE_3D:
2407 return tcu::IVec3(size, size, 4);
2408
2409 default:
2410 break;
2411 }
2412
2413 return tcu::IVec3(size, size, 1);
2414 }
2415
getArraySize(SamplerViewType viewType)2416 int AttachmentFeedbackLoopLayoutSamplerTest::getArraySize (SamplerViewType viewType)
2417 {
2418 switch (viewType)
2419 {
2420 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2421 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2422 case VK_IMAGE_VIEW_TYPE_CUBE:
2423 return 6;
2424
2425 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2426 return 36;
2427
2428 default:
2429 break;
2430 }
2431
2432 return 1;
2433 }
2434 } // anonymous
2435
createAttachmentFeedbackLoopLayoutSamplerTests(tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)2436 tcu::TestCaseGroup* createAttachmentFeedbackLoopLayoutSamplerTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
2437 {
2438 // TODO: implement layer rendering with a geometry shader to render to arrays, 3D and cube images.
2439 const struct
2440 {
2441 SamplerViewType type;
2442 const char* name;
2443 bool readOnly;
2444 }
2445 imageViewTypes[] =
2446 {
2447 { VK_IMAGE_VIEW_TYPE_1D, "1d", false },
2448 { { VK_IMAGE_VIEW_TYPE_1D, false }, "1d_unnormalized", false },
2449 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", true },
2450 { VK_IMAGE_VIEW_TYPE_2D, "2d", false },
2451 { { VK_IMAGE_VIEW_TYPE_2D, false }, "2d_unnormalized", false },
2452 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", true },
2453 { VK_IMAGE_VIEW_TYPE_3D, "3d", true },
2454 { VK_IMAGE_VIEW_TYPE_CUBE, "cube", true },
2455 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", true }
2456 };
2457
2458 const VkFormat formats[] =
2459 {
2460 VK_FORMAT_R8G8B8A8_UNORM,
2461 VK_FORMAT_D16_UNORM,
2462 VK_FORMAT_D32_SFLOAT,
2463 VK_FORMAT_D16_UNORM_S8_UINT,
2464 VK_FORMAT_D24_UNORM_S8_UINT,
2465 VK_FORMAT_D32_SFLOAT_S8_UINT,
2466 VK_FORMAT_S8_UINT
2467 };
2468
2469 de::MovePtr<tcu::TestCaseGroup> samplingTypeTests (new tcu::TestCaseGroup(testCtx, "sampler"));
2470
2471 const struct
2472 {
2473 enum TestMode mode;
2474 const char* name;
2475 }
2476 testModes[] =
2477 {
2478 { TEST_MODE_READ_ONLY, "_read" },
2479 { TEST_MODE_READ_WRITE_SAME_PIXEL, "_read_write_same_pixel" },
2480 { TEST_MODE_READ_WRITE_DIFFERENT_AREAS, "_read_write_different_areas" },
2481 };
2482
2483 const char* imageAspectTestModes[] = { "_color", "_depth", "_stencil" };
2484
2485 const struct
2486 {
2487 VkDescriptorType type;
2488 const char* name;
2489 }
2490 imageDescriptorTypes[] =
2491 {
2492 { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler" },
2493 { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image" },
2494 };
2495
2496 const struct
2497 {
2498 bool interleaveReadWriteComponents;
2499 const char* name;
2500 }
2501 interleaveReadWriteComponentsModes[] =
2502 {
2503 { false, "" },
2504 { true, "_interleave_read_write_components" },
2505 };
2506
2507 const struct
2508 {
2509 const PipelineStateMode pipelineStateMode;
2510 const char* suffix;
2511 } pipelineStateModes[] =
2512 {
2513 { PipelineStateMode::STATIC, "" },
2514 { PipelineStateMode::DYNAMIC_WITH_ZERO_STATIC, "_dynamic_zero_static" },
2515 { PipelineStateMode::DYNAMIC_WITH_CONTRADICTORY_STATIC, "_dynamic_bad_static" },
2516 };
2517
2518 for (int imageDescriptorTypeNdx = 0; imageDescriptorTypeNdx < DE_LENGTH_OF_ARRAY(imageDescriptorTypes); imageDescriptorTypeNdx++)
2519 {
2520 VkDescriptorType imageDescriptorType = imageDescriptorTypes[imageDescriptorTypeNdx].type;
2521 de::MovePtr<tcu::TestCaseGroup> imageDescriptorTypeGroup (new tcu::TestCaseGroup(testCtx, imageDescriptorTypes[imageDescriptorTypeNdx].name));
2522 de::MovePtr<tcu::TestCaseGroup> imageTypeTests (new tcu::TestCaseGroup(testCtx, "image_type"));
2523
2524 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
2525 {
2526 const SamplerViewType viewType = imageViewTypes[viewTypeNdx].type;
2527 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name));
2528 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format"));
2529
2530 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2531 {
2532 const VkFormat format = formats[formatNdx];
2533 const bool isCompressed = isCompressedFormat(format);
2534 const bool isDepthStencil = !isCompressed && tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order);
2535 ImageAspectTestMode imageAspectTestMode = getImageAspectTestMode(format);
2536
2537 if (isCompressed)
2538 {
2539 // Do not use compressed formats with 1D and 1D array textures.
2540 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
2541 break;
2542 }
2543
2544 for (int testModeNdx = 0; testModeNdx < DE_LENGTH_OF_ARRAY(testModes); testModeNdx++)
2545 {
2546 if (imageViewTypes[viewTypeNdx].readOnly && testModes[testModeNdx].mode != TEST_MODE_READ_ONLY)
2547 continue;
2548
2549 for (int restrictColorNdx = 0; restrictColorNdx < DE_LENGTH_OF_ARRAY(interleaveReadWriteComponentsModes); restrictColorNdx++)
2550 {
2551 // Limit the interleaveReadWriteComponents test to the ones sampling and writing to the same pixel, to avoid having more tests that are not really adding coverage.
2552 if (interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents &&
2553 testModes[testModeNdx].mode != TEST_MODE_READ_WRITE_SAME_PIXEL)
2554 continue;
2555
2556 // If the format is depth-only or stencil-only, do not read one component and write it to the other, as it is missing.
2557 if (interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents &&
2558 (tcu::hasDepthComponent(mapVkFormat(format).order) || tcu::hasStencilComponent(mapVkFormat(format).order)) && !isDepthStencil)
2559 continue;
2560
2561 for (const auto& pipelineStateMode : pipelineStateModes)
2562 {
2563 std::string name = getFormatCaseName(format) + imageAspectTestModes[imageAspectTestMode] + testModes[testModeNdx].name + interleaveReadWriteComponentsModes[restrictColorNdx].name + pipelineStateMode.suffix;
2564 formatTests->addChild(new AttachmentFeedbackLoopLayoutSamplerTest(testCtx, pipelineConstructionType, name.c_str(), viewType, format, outputImageSize, imageDescriptorType, 0.0f, testModes[testModeNdx].mode, imageAspectTestMode, interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents, pipelineStateMode.pipelineStateMode, false));
2565
2566 if (!isCompressed && isDepthStencil)
2567 {
2568 // Image is depth-stencil. Add the stencil case as well.
2569 std::string stencilTestName = getFormatCaseName(format) + imageAspectTestModes[IMAGE_ASPECT_TEST_STENCIL] + testModes[testModeNdx].name + interleaveReadWriteComponentsModes[restrictColorNdx].name + pipelineStateMode.suffix;
2570 formatTests->addChild(new AttachmentFeedbackLoopLayoutSamplerTest(testCtx, pipelineConstructionType, stencilTestName.c_str(), viewType, format, outputImageSize, imageDescriptorType, 0.0f, testModes[testModeNdx].mode, IMAGE_ASPECT_TEST_STENCIL, interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents, pipelineStateMode.pipelineStateMode, false));
2571 }
2572 }
2573 }
2574 }
2575 }
2576
2577 viewTypeGroup->addChild(formatTests.release());
2578 imageTypeTests->addChild(viewTypeGroup.release());
2579 }
2580 imageDescriptorTypeGroup->addChild(imageTypeTests.release());
2581 samplingTypeTests->addChild(imageDescriptorTypeGroup.release());
2582 }
2583
2584 if (pipelineConstructionType == PipelineConstructionType::PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC)
2585 {
2586 de::MovePtr<tcu::TestCaseGroup> miscGroup(new tcu::TestCaseGroup(testCtx, "misc", ""));
2587 miscGroup->addChild(new AttachmentFeedbackLoopLayoutSamplerTest(testCtx, pipelineConstructionType, "maintenance5_color_attachment", VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_R8G8B8A8_UNORM, outputImageSize, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0.0f, TEST_MODE_READ_ONLY, IMAGE_ASPECT_TEST_COLOR, false, PipelineStateMode::STATIC, true));
2588 miscGroup->addChild(new AttachmentFeedbackLoopLayoutSamplerTest(testCtx, pipelineConstructionType, "maintenance5_ds_attachment", VK_IMAGE_VIEW_TYPE_2D, VK_FORMAT_D16_UNORM, outputImageSize, VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 0.0f, TEST_MODE_READ_ONLY, IMAGE_ASPECT_TEST_DEPTH, false, PipelineStateMode::STATIC, true));
2589 samplingTypeTests->addChild(miscGroup.release());
2590 }
2591
2592 return samplingTypeTests.release();
2593 }
2594
createAttachmentFeedbackLoopLayoutTests(tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)2595 tcu::TestCaseGroup* createAttachmentFeedbackLoopLayoutTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
2596 {
2597 de::MovePtr<tcu::TestCaseGroup> attachmentFeedbackLoopLayoutTests(new tcu::TestCaseGroup(testCtx, "attachment_feedback_loop_layout"));
2598 {
2599 attachmentFeedbackLoopLayoutTests->addChild(createAttachmentFeedbackLoopLayoutSamplerTests(testCtx, pipelineConstructionType));
2600 }
2601
2602 return attachmentFeedbackLoopLayoutTests.release();
2603 }
2604
2605 } // pipeline
2606 } // vkt
2607