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