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 layouts
659 {
660 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
661 {
662 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
663 DE_NULL, // const void* pNext;
664 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, // VkPipelineLayoutCreateFlags flags;
665 0u, // deUint32 setLayoutCount;
666 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
667 0u, // deUint32 pushConstantRangeCount;
668 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
669 };
670
671 m_preRasterizationStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
672 }
673 {
674 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
675 {
676 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
677 DE_NULL, // const void* pNext;
678 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, // VkPipelineLayoutCreateFlags flags;
679 1u, // deUint32 setLayoutCount;
680 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
681 0u, // deUint32 pushConstantRangeCount;
682 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
683 };
684
685 m_fragmentStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
686 }
687
688 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
689 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
690
691 // Create pipeline
692 {
693 const VkVertexInputBindingDescription vertexInputBindingDescription =
694 {
695 0u, // deUint32 binding;
696 sizeof(Vertex4Tex4), // deUint32 strideInBytes;
697 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
698 };
699
700 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
701 {
702 {
703 0u, // deUint32 location;
704 0u, // deUint32 binding;
705 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
706 0u // deUint32 offset;
707 },
708 {
709 1u, // deUint32 location;
710 0u, // deUint32 binding;
711 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
712 DE_OFFSET_OF(Vertex4Tex4, texCoord), // deUint32 offset;
713 }
714 };
715
716 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
717 {
718 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
719 DE_NULL, // const void* pNext;
720 0u, // VkPipelineVertexInputStateCreateFlags flags;
721 1u, // deUint32 vertexBindingDescriptionCount;
722 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
723 2u, // deUint32 vertexAttributeDescriptionCount;
724 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
725 };
726
727 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
728 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
729
730 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(m_imageCount);
731
732 VkColorComponentFlags colorComponents = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
733
734 if (m_interleaveReadWriteComponents)
735 colorComponents = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_B_BIT;
736
737 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
738 {
739 colorBlendAttachmentStates[imgNdx].blendEnable = false; // VkBool32 blendEnable;
740 colorBlendAttachmentStates[imgNdx].srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcColorBlendFactor;
741 colorBlendAttachmentStates[imgNdx].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstColorBlendFactor;
742 colorBlendAttachmentStates[imgNdx].colorBlendOp = VK_BLEND_OP_ADD; // VkBlendOp colorBlendOp;
743 colorBlendAttachmentStates[imgNdx].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcAlphaBlendFactor;
744 colorBlendAttachmentStates[imgNdx].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstAlphaBlendFactor;
745 colorBlendAttachmentStates[imgNdx].alphaBlendOp = VK_BLEND_OP_ADD; // VkBlendOp alphaBlendOp;
746 colorBlendAttachmentStates[imgNdx].colorWriteMask = colorComponents; // VkColorComponentFlags colorWriteMask;
747 }
748
749 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
750 {
751 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
752 DE_NULL, // const void* pNext;
753 0u, // VkPipelineColorBlendStateCreateFlags flags;
754 false, // VkBool32 logicOpEnable;
755 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
756 (deUint32)m_imageCount, // deUint32 attachmentCount;
757 &colorBlendAttachmentStates[0], // const VkPipelineColorBlendAttachmentState* pAttachments;
758 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
759 };
760
761 m_graphicsPipeline.setMonolithicPipelineLayout(*m_fragmentStatePipelineLayout)
762 .setDefaultDepthStencilState()
763 .setDefaultRasterizationState()
764 .setDefaultMultisampleState()
765 .setupVertexInputState(&vertexInputStateParams)
766 .setupPreRasterizationShaderState(viewports,
767 scissors,
768 *m_preRasterizationStatePipelineLayout,
769 *m_renderPass,
770 0u,
771 *m_vertexShaderModule)
772 .setupFragmentShaderState(*m_fragmentStatePipelineLayout, *m_renderPass, 0u, *m_fragmentShaderModule)
773 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateParams)
774 .buildPipeline();
775 }
776
777 // Create vertex buffer
778 {
779 const VkDeviceSize vertexBufferSize = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
780 const VkBufferCreateInfo vertexBufferParams =
781 {
782 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
783 DE_NULL, // const void* pNext;
784 0u, // VkBufferCreateFlags flags;
785 vertexBufferSize, // VkDeviceSize size;
786 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
787 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
788 1u, // deUint32 queueFamilyIndexCount;
789 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
790 };
791
792 DE_ASSERT(vertexBufferSize > 0);
793
794 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
795 m_vertexBufferAlloc = allocateBuffer(vki, vk, physDevice, vkDevice, *m_vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_allocationKind);
796 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
797
798 // Load vertices into vertex buffer
799 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
800 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
801 }
802
803 // Create command buffer
804 {
805 VkFormat clearFormat = m_useImageAsColorOrDSAttachment ? m_imageFormat : m_colorFormat;
806 const std::vector<VkClearValue> attachmentClearValues (m_imageCount, defaultClearValue(clearFormat));
807
808 std::vector<VkImageMemoryBarrier> preAttachmentBarriers(m_imageCount);
809
810 VkAccessFlags dstAccessMask = isDepthStencilFormat(m_imageFormat) ? VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT : VK_ACCESS_SHADER_READ_BIT;
811 VkPipelineStageFlags pipelineStageFlags = isDepthStencilFormat(m_imageFormat) ? VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT : VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
812
813 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
814 {
815 preAttachmentBarriers[imgNdx].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; // VkStructureType sType;
816 preAttachmentBarriers[imgNdx].pNext = DE_NULL; // const void* pNext;
817 preAttachmentBarriers[imgNdx].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; // VkAccessFlags srcAccessMask;
818 preAttachmentBarriers[imgNdx].dstAccessMask = dstAccessMask; // VkAccessFlags dstAccessMask;
819 preAttachmentBarriers[imgNdx].oldLayout = m_imageLayout; // VkImageLayout oldLayout;
820 preAttachmentBarriers[imgNdx].newLayout = m_imageLayout; // VkImageLayout newLayout;
821 preAttachmentBarriers[imgNdx].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 srcQueueFamilyIndex;
822 preAttachmentBarriers[imgNdx].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 dstQueueFamilyIndex;
823 preAttachmentBarriers[imgNdx].image = **m_images[imgNdx]; // VkImage image;
824 preAttachmentBarriers[imgNdx].subresourceRange = m_subresourceRange; // VkImageSubresourceRange subresourceRange;
825 }
826
827 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
828
829 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, pipelineStageFlags, (VkDependencyFlags)0,
830 0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
831
832 if (!m_useImageAsColorOrDSAttachment)
833 {
834 // Pipeline barrier for the color attachment, which is a different image than the sampled one.
835 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
836 {
837 preAttachmentBarriers[imgNdx].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; // VkStructureType sType;
838 preAttachmentBarriers[imgNdx].pNext = DE_NULL; // const void* pNext;
839 preAttachmentBarriers[imgNdx].srcAccessMask = (VkAccessFlagBits)0u; // VkAccessFlags srcAccessMask;
840 preAttachmentBarriers[imgNdx].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // VkAccessFlags dstAccessMask;
841 preAttachmentBarriers[imgNdx].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; // VkImageLayout oldLayout;
842 preAttachmentBarriers[imgNdx].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VkImageLayout newLayout;
843 preAttachmentBarriers[imgNdx].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 srcQueueFamilyIndex;
844 preAttachmentBarriers[imgNdx].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 dstQueueFamilyIndex;
845 preAttachmentBarriers[imgNdx].image = **m_colorImages[imgNdx]; // VkImage image;
846 preAttachmentBarriers[imgNdx].subresourceRange.aspectMask = getAspectFlags(m_colorFormat); // VkImageSubresourceRange subresourceRange;
847 preAttachmentBarriers[imgNdx].subresourceRange.baseMipLevel = 0u;
848 preAttachmentBarriers[imgNdx].subresourceRange.levelCount = 1u;
849 preAttachmentBarriers[imgNdx].subresourceRange.baseArrayLayer = 0u;
850 preAttachmentBarriers[imgNdx].subresourceRange.layerCount = 1u;
851 }
852
853 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
854 0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
855
856 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), (deUint32)attachmentClearValues.size(), &attachmentClearValues[0]);
857 }
858 else
859 {
860 // Do not clear the color attachments as we are using the sampled texture as color attachment as well.
861 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), 0u, DE_NULL);
862 }
863
864 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
865
866 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
867
868 const VkDeviceSize vertexBufferOffset = 0;
869 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
870 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
871
872 endRenderPass(vk, *m_cmdBuffer);
873 endCommandBuffer(vk, *m_cmdBuffer);
874 }
875 }
876
AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(Context & context,ImageSamplingInstanceParams params,bool useImageAsColorOrDSAttachment_,bool useDifferentAreasSampleWrite_,bool interleaveReadWriteComponents_)877 AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance (Context& context,
878 ImageSamplingInstanceParams params,
879 bool useImageAsColorOrDSAttachment_,
880 bool useDifferentAreasSampleWrite_,
881 bool interleaveReadWriteComponents_)
882 : AttachmentFeedbackLoopLayoutImageSamplingInstance (context, params, useImageAsColorOrDSAttachment_, useDifferentAreasSampleWrite_, interleaveReadWriteComponents_)
883 , m_separateStencilUsage (params.separateStencilUsage)
884 {
885 }
886
~AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(void)887 AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::~AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance (void)
888 {
889 }
890
setup(void)891 void AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::setup (void)
892 {
893 const InstanceInterface& vki = m_context.getInstanceInterface();
894 const DeviceInterface& vk = m_context.getDeviceInterface();
895 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
896 const VkDevice vkDevice = m_context.getDevice();
897 const VkQueue queue = m_context.getUniversalQueue();
898 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
899 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
900 tcu::UVec2 renderSize = tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
901
902 DE_ASSERT(m_useImageAsColorOrDSAttachment && isDepthStencilFormat(m_imageFormat));
903 DE_ASSERT(m_samplerParams.pNext == DE_NULL);
904
905 // Create texture images, views
906 {
907 VkImageCreateFlags imageFlags = 0u;
908
909 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
910 imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
911
912 // Initialize texture data
913 if (isCompressedFormat(m_imageFormat))
914 m_texture = createTestTexture(mapVkCompressedFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
915 else
916 m_texture = createTestTexture(mapVkFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
917
918 VkImageUsageFlags imageUsageFlags =
919 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT |
920 VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
921
922 const VkImageCreateInfo imageParams =
923 {
924 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
925 DE_NULL, // const void* pNext;
926 imageFlags, // VkImageCreateFlags flags;
927 getCompatibleImageType(m_imageViewType), // VkImageType imageType;
928 m_imageFormat, // VkFormat format;
929 { // VkExtent3D extent;
930 (deUint32)m_imageSize.x(),
931 (deUint32)m_imageSize.y(),
932 (deUint32)m_imageSize.z()
933 },
934 (deUint32)m_texture->getNumLevels(), // deUint32 mipLevels;
935 (deUint32)m_layerCount, // deUint32 arrayLayers;
936 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
937 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
938 imageUsageFlags, // VkImageUsageFlags usage;
939 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
940 1u, // deUint32 queueFamilyIndexCount;
941 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
942 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
943 };
944
945 checkImageSupport(vki, physDevice, imageParams);
946
947 m_images.resize(m_imageCount);
948 m_imageAllocs.resize(m_imageCount);
949
950 // Create command pool
951 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT | VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex);
952 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
953
954 int numImageViews = m_interleaveReadWriteComponents ? m_imageCount + 1 : m_imageCount;
955 m_imageViews.resize(numImageViews);
956
957 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
958 {
959 m_images[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &imageParams)));
960 m_imageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_images[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
961 VK_CHECK(vk.bindImageMemory(vkDevice, **m_images[imgNdx], (*m_imageAllocs[imgNdx])->getMemory(), (*m_imageAllocs[imgNdx])->getOffset()));
962
963 // Upload texture data
964 uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, **m_images[imgNdx], m_imageLayout);
965
966 }
967
968 for (int imgNdx = 0; imgNdx < numImageViews; ++imgNdx)
969 {
970 VkImage image = (m_interleaveReadWriteComponents && imgNdx == m_imageCount) ? **m_images[imgNdx - 1] : **m_images[imgNdx];
971
972 // Create image view and sampler
973 VkImageViewCreateInfo imageViewParams =
974 {
975 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
976 DE_NULL, // const void* pNext;
977 0u, // VkImageViewCreateFlags flags;
978 image, // VkImage image;
979 m_imageViewType, // VkImageViewType viewType;
980 m_imageFormat, // VkFormat format;
981 m_componentMapping, // VkComponentMapping components;
982 m_subresourceRange, // VkImageSubresourceRange subresourceRange;
983 };
984
985 if (m_interleaveReadWriteComponents && imgNdx == m_imageCount)
986 {
987 imageViewParams.subresourceRange.aspectMask = getImageAspectFlags(mapVkFormat(m_imageFormat));
988 }
989
990 m_imageViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &imageViewParams)));
991 }
992
993 m_sampler = createSampler(vk, vkDevice, &m_samplerParams);
994 }
995
996 // Create descriptor set for image and sampler
997 {
998 DescriptorPoolBuilder descriptorPoolBuilder;
999 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1000 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER, 1u);
1001 descriptorPoolBuilder.addType(m_samplingType, m_imageCount);
1002 m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
1003 m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? m_imageCount + 1u : m_imageCount);
1004
1005 DescriptorSetLayoutBuilder setLayoutBuilder;
1006 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1007 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
1008 setLayoutBuilder.addArrayBinding(m_samplingType, m_imageCount, VK_SHADER_STAGE_FRAGMENT_BIT);
1009 m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
1010
1011 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
1012 {
1013 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
1014 DE_NULL, // const void* pNext;
1015 *m_descriptorPool, // VkDescriptorPool descriptorPool;
1016 1u, // deUint32 setLayoutCount;
1017 &m_descriptorSetLayout.get() // const VkDescriptorSetLayout* pSetLayouts;
1018 };
1019
1020 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
1021
1022 const VkSampler sampler = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? DE_NULL : *m_sampler;
1023 std::vector<VkDescriptorImageInfo> descriptorImageInfo(m_imageCount);
1024 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1025 {
1026 descriptorImageInfo[imgNdx].sampler = sampler; // VkSampler sampler;
1027 descriptorImageInfo[imgNdx].imageView = **m_imageViews[imgNdx]; // VkImageView imageView;
1028 descriptorImageInfo[imgNdx].imageLayout = m_imageLayout; // VkImageLayout imageLayout;
1029 }
1030
1031 DescriptorSetUpdateBuilder setUpdateBuilder;
1032 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
1033 {
1034 const VkDescriptorImageInfo descriptorSamplerInfo =
1035 {
1036 *m_sampler, // VkSampler sampler;
1037 DE_NULL, // VkImageView imageView;
1038 m_imageLayout, // VkImageLayout imageLayout;
1039 };
1040 setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_SAMPLER, &descriptorSamplerInfo);
1041 }
1042
1043 const deUint32 binding = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? 1u : 0u;
1044 setUpdateBuilder.writeArray(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(binding), m_samplingType, m_imageCount, descriptorImageInfo.data());
1045 setUpdateBuilder.update(vk, vkDevice);
1046 }
1047
1048 // Create depth-stencil images and views, no color attachment
1049 {
1050 m_dsImages.resize(m_imageCount);
1051 m_dsImageAllocs.resize(m_imageCount);
1052 m_dsAttachmentViews.resize(m_imageCount);
1053
1054 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1055 {
1056 m_dsImages[imgNdx] = m_images[imgNdx];
1057 m_dsImageAllocs[imgNdx] = m_imageAllocs[imgNdx];
1058 m_dsAttachmentViews[imgNdx] = m_interleaveReadWriteComponents ? m_imageViews[imgNdx + 1] : m_imageViews[imgNdx];
1059 }
1060 }
1061
1062 // Create render pass
1063 {
1064 std::vector<VkAttachmentDescription> attachmentDescriptions(m_imageCount);
1065 std::vector<VkAttachmentReference> attachmentReferences(m_imageCount);
1066
1067 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1068 {
1069 attachmentDescriptions[imgNdx].flags = 0u; // VkAttachmentDescriptionFlags flags;
1070 attachmentDescriptions[imgNdx].format = m_useImageAsColorOrDSAttachment ? m_imageFormat : m_colorFormat; // VkFormat format;
1071 attachmentDescriptions[imgNdx].samples = VK_SAMPLE_COUNT_1_BIT; // VkSampleCountFlagBits samples;
1072 attachmentDescriptions[imgNdx].loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // VkAttachmentLoadOp loadOp;
1073 attachmentDescriptions[imgNdx].storeOp = VK_ATTACHMENT_STORE_OP_STORE; // VkAttachmentStoreOp storeOp;
1074 attachmentDescriptions[imgNdx].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD; // VkAttachmentLoadOp stencilLoadOp;
1075 attachmentDescriptions[imgNdx].stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE; // VkAttachmentStoreOp stencilStoreOp;
1076 attachmentDescriptions[imgNdx].initialLayout = m_imageLayout; // VkImageLayout initialLayout;
1077 attachmentDescriptions[imgNdx].finalLayout = m_imageLayout; // VkImageLayout finalLayout;
1078
1079 attachmentReferences[imgNdx].attachment = (deUint32)imgNdx; // deUint32 attachment;
1080 attachmentReferences[imgNdx].layout = m_imageLayout; // VkImageLayout layout;
1081 }
1082
1083 const VkSubpassDescription subpassDescription =
1084 {
1085 0u, // VkSubpassDescriptionFlags flags;
1086 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
1087 0u, // deUint32 inputAttachmentCount;
1088 DE_NULL, // const VkAttachmentReference* pInputAttachments;
1089 0u, // deUint32 colorAttachmentCount;
1090 DE_NULL, // const VkAttachmentReference* pColorAttachments;
1091 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
1092 &attachmentReferences[0], // const VkAttachmentReference* pDepthStencilAttachment;
1093 0u, // deUint32 preserveAttachmentCount;
1094 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
1095 };
1096
1097 std::vector<VkSubpassDependency> subpassDependencies;
1098
1099 if (m_useImageAsColorOrDSAttachment)
1100 {
1101 const auto srcStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
1102 const auto srcAccessMask = VK_ACCESS_SHADER_READ_BIT;
1103 const auto dstStageMask = (VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT);
1104 const auto dstAccessMask = (VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT);
1105
1106 const VkSubpassDependency spdVal =
1107 {
1108 0u, // uint32_t srcSubpass;
1109 0u, // uint32_t dstSubpass;
1110 srcStageMask, // VkPipelineStageFlags srcStageMask;
1111 dstStageMask, // VkPipelineStageFlags dstStageMask;
1112 srcAccessMask, // VkAccessFlags srcAccessMask;
1113 dstAccessMask, // VkAccessFlags dstAccessMask;
1114 VK_DEPENDENCY_FEEDBACK_LOOP_BIT_EXT | VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags;
1115 };
1116
1117 subpassDependencies.push_back(spdVal);
1118 }
1119
1120 const VkRenderPassCreateInfo renderPassParams =
1121 {
1122 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
1123 DE_NULL, // const void* pNext;
1124 0u, // VkRenderPassCreateFlags flags;
1125 (deUint32)attachmentDescriptions.size(), // deUint32 attachmentCount;
1126 &attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
1127 1u, // deUint32 subpassCount;
1128 &subpassDescription, // const VkSubpassDescription* pSubpasses;
1129 static_cast<uint32_t>(subpassDependencies.size()), // deUint32 dependencyCount;
1130 de::dataOrNull(subpassDependencies), // const VkSubpassDependency* pDependencies;
1131 };
1132
1133 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
1134 }
1135
1136 // Create framebuffer
1137 {
1138 std::vector<VkImageView> pAttachments(m_imageCount);
1139 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1140 {
1141 pAttachments[imgNdx] = m_dsAttachmentViews[imgNdx]->get();
1142 }
1143
1144 const VkFramebufferCreateInfo framebufferParams =
1145 {
1146 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
1147 DE_NULL, // const void* pNext;
1148 0u, // VkFramebufferCreateFlags flags;
1149 *m_renderPass, // VkRenderPass renderPass;
1150 (deUint32)m_imageCount, // deUint32 attachmentCount;
1151 &pAttachments[0], // const VkImageView* pAttachments;
1152 (deUint32)renderSize.x(), // deUint32 width;
1153 (deUint32)renderSize.y(), // deUint32 height;
1154 1u // deUint32 layers;
1155 };
1156
1157 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
1158 }
1159
1160 // Create pipeline layout
1161 {
1162 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1163 {
1164 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1165 DE_NULL, // const void* pNext;
1166 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, // VkPipelineLayoutCreateFlags flags;
1167 0u, // deUint32 setLayoutCount;
1168 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
1169 0u, // deUint32 pushConstantRangeCount;
1170 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1171 };
1172
1173 m_preRasterizationStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1174 }
1175 {
1176 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
1177 {
1178 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
1179 DE_NULL, // const void* pNext;
1180 VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT, // VkPipelineLayoutCreateFlags flags;
1181 1u, // deUint32 setLayoutCount;
1182 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
1183 0u, // deUint32 pushConstantRangeCount;
1184 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
1185 };
1186
1187 m_fragmentStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
1188 }
1189
1190 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
1191 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
1192
1193 // Create pipeline
1194 {
1195 const VkVertexInputBindingDescription vertexInputBindingDescription =
1196 {
1197 0u, // deUint32 binding;
1198 sizeof(Vertex4Tex4), // deUint32 strideInBytes;
1199 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
1200 };
1201
1202 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
1203 {
1204 {
1205 0u, // deUint32 location;
1206 0u, // deUint32 binding;
1207 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1208 0u // deUint32 offset;
1209 },
1210 {
1211 1u, // deUint32 location;
1212 0u, // deUint32 binding;
1213 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
1214 DE_OFFSET_OF(Vertex4Tex4, texCoord), // deUint32 offset;
1215 }
1216 };
1217
1218 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
1219 {
1220 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
1221 DE_NULL, // const void* pNext;
1222 0u, // VkPipelineVertexInputStateCreateFlags flags;
1223 1u, // deUint32 vertexBindingDescriptionCount;
1224 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
1225 2u, // deUint32 vertexAttributeDescriptionCount;
1226 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
1227 };
1228
1229 const std::vector<VkViewport> viewports (1, makeViewport(renderSize));
1230 const std::vector<VkRect2D> scissors (1, makeRect2D(renderSize));
1231
1232 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(m_imageCount);
1233
1234 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1235 {
1236 colorBlendAttachmentStates[imgNdx].blendEnable = false; // VkBool32 blendEnable;
1237 colorBlendAttachmentStates[imgNdx].srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcColorBlendFactor;
1238 colorBlendAttachmentStates[imgNdx].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstColorBlendFactor;
1239 colorBlendAttachmentStates[imgNdx].colorBlendOp = VK_BLEND_OP_ADD; // VkBlendOp colorBlendOp;
1240 colorBlendAttachmentStates[imgNdx].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcAlphaBlendFactor;
1241 colorBlendAttachmentStates[imgNdx].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstAlphaBlendFactor;
1242 colorBlendAttachmentStates[imgNdx].alphaBlendOp = VK_BLEND_OP_ADD; // VkBlendOp alphaBlendOp;
1243 colorBlendAttachmentStates[imgNdx].colorWriteMask = 0u; // VkColorComponentFlags colorWriteMask;
1244 }
1245
1246 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
1247 {
1248 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
1249 DE_NULL, // const void* pNext;
1250 0u, // VkPipelineColorBlendStateCreateFlags flags;
1251 false, // VkBool32 logicOpEnable;
1252 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
1253 0u, // deUint32 attachmentCount;
1254 DE_NULL, // const VkPipelineColorBlendAttachmentState* pAttachments;
1255 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
1256 };
1257
1258 VkBool32 depthTestEnable =
1259 ((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && !m_interleaveReadWriteComponents) ||
1260 ((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && m_interleaveReadWriteComponents);
1261
1262 VkBool32 stencilTestEnable =
1263 ((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) && !m_interleaveReadWriteComponents) ||
1264 ((m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT) && m_interleaveReadWriteComponents);
1265
1266 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);
1267 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);
1268
1269 const VkPipelineDepthStencilStateCreateInfo depthStencilStateCreateInfo =
1270 {
1271 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType
1272 DE_NULL, // const void* pNext
1273 0u, // VkPipelineDepthStencilStateCreateFlags flags
1274 depthTestEnable, // VkBool32 depthTestEnable
1275 depthTestEnable, // VkBool32 depthWriteEnable
1276 VK_COMPARE_OP_ALWAYS, // VkCompareOp depthCompareOp
1277 DE_FALSE, // VkBool32 depthBoundsTestEnable
1278 stencilTestEnable, // VkBool32 stencilTestEnable
1279 stencilFrontOpState, // VkStencilOpState front
1280 stencilBackOpState, // VkStencilOpState back
1281 0.0f, // float minDepthBounds
1282 1.0f, // float maxDepthBounds;
1283 };
1284
1285 m_graphicsPipeline.setMonolithicPipelineLayout(*m_fragmentStatePipelineLayout)
1286 .setDefaultDepthStencilState()
1287 .setDefaultRasterizationState()
1288 .setDefaultMultisampleState()
1289 .setupVertexInputState(&vertexInputStateParams)
1290 .setupPreRasterizationShaderState(viewports,
1291 scissors,
1292 *m_preRasterizationStatePipelineLayout,
1293 *m_renderPass,
1294 0u,
1295 *m_vertexShaderModule)
1296 .setupFragmentShaderState(*m_fragmentStatePipelineLayout, *m_renderPass, 0u, *m_fragmentShaderModule, &depthStencilStateCreateInfo)
1297 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateParams)
1298 .buildPipeline();
1299
1300 }
1301
1302 // Create vertex buffer
1303 {
1304 const VkDeviceSize vertexBufferSize = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
1305 const VkBufferCreateInfo vertexBufferParams =
1306 {
1307 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
1308 DE_NULL, // const void* pNext;
1309 0u, // VkBufferCreateFlags flags;
1310 vertexBufferSize, // VkDeviceSize size;
1311 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
1312 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
1313 1u, // deUint32 queueFamilyIndexCount;
1314 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
1315 };
1316
1317 DE_ASSERT(vertexBufferSize > 0);
1318
1319 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
1320 m_vertexBufferAlloc = allocateBuffer(vki, vk, physDevice, vkDevice, *m_vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_allocationKind);
1321 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
1322
1323 // Load vertices into vertex buffer
1324 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
1325 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
1326 }
1327
1328 // Create command buffer
1329 {
1330 std::vector<VkImageMemoryBarrier> preAttachmentBarriers(m_imageCount);
1331
1332 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1333 {
1334 preAttachmentBarriers[imgNdx].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; // VkStructureType sType;
1335 preAttachmentBarriers[imgNdx].pNext = DE_NULL; // const void* pNext;
1336 preAttachmentBarriers[imgNdx].srcAccessMask = VK_ACCESS_TRANSFER_WRITE_BIT; // VkAccessFlags srcAccessMask;
1337 preAttachmentBarriers[imgNdx].dstAccessMask = VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; // VkAccessFlags dstAccessMask;
1338 preAttachmentBarriers[imgNdx].oldLayout = m_imageLayout; // VkImageLayout oldLayout;
1339 preAttachmentBarriers[imgNdx].newLayout = m_imageLayout; // VkImageLayout newLayout;
1340 preAttachmentBarriers[imgNdx].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 srcQueueFamilyIndex;
1341 preAttachmentBarriers[imgNdx].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 dstQueueFamilyIndex;
1342 preAttachmentBarriers[imgNdx].image = **m_dsImages[imgNdx]; // VkImage image;
1343 preAttachmentBarriers[imgNdx].subresourceRange.aspectMask = getAspectFlags(m_imageFormat); // VkImageSubresourceRange subresourceRange;
1344 preAttachmentBarriers[imgNdx].subresourceRange.baseMipLevel = 0u;
1345 preAttachmentBarriers[imgNdx].subresourceRange.levelCount = 1u;
1346 preAttachmentBarriers[imgNdx].subresourceRange.baseArrayLayer = 0u;
1347 preAttachmentBarriers[imgNdx].subresourceRange.layerCount = 1u;
1348 }
1349
1350 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
1351
1352 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (VkDependencyFlags)0,
1353 0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
1354
1355 // Do not clear the color attachments as we are using the texture as color attachment.
1356 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, renderSize.x(), renderSize.y()), 0u, DE_NULL);
1357
1358 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
1359
1360 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
1361
1362 const VkDeviceSize vertexBufferOffset = 0;
1363 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
1364 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
1365
1366 endRenderPass(vk, *m_cmdBuffer);
1367 endCommandBuffer(vk, *m_cmdBuffer);
1368 }
1369 }
1370
verifyImage(void)1371 tcu::TestStatus AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::verifyImage(void)
1372 {
1373 const tcu::TextureFormat tcuFormat = getSizeCompatibleTcuTextureFormat(m_imageFormat);
1374 const bool isDepth = (!m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT)) ||
1375 (m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT));
1376 const bool isStencil = (!m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)) ||
1377 (m_interleaveReadWriteComponents && (m_subresourceRange.aspectMask & VK_IMAGE_ASPECT_DEPTH_BIT));
1378 // ImageSamplingInstance::verifyImage() doesn't support stencil sampling.
1379 if (!m_useImageAsColorOrDSAttachment && !isStencil)
1380 return ImageSamplingInstance::verifyImage();
1381
1382 const tcu::Vec4 fThreshold (0.005f);
1383 const tcu::UVec4 uThreshold (0u); // Due to unsigned normalized fixed-point integers conversion to floats and viceversa.
1384 tcu::UVec2 renderSize = tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
1385
1386 de::MovePtr<tcu::TextureLevel> referenceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(tcuFormat,
1387 m_imageSize.x(),
1388 m_imageSize.y(),
1389 m_imageSize.z()));
1390
1391 for (int z = 0; z < m_imageSize.z(); z++)
1392 for (int y = 0; y < m_imageSize.y(); y++)
1393 for (int x = 0; x < m_imageSize.x(); x++)
1394 {
1395 if (isDepth)
1396 {
1397 float depth = 0.0f;
1398 if (m_interleaveReadWriteComponents)
1399 {
1400 int stencil = 1 + m_texture->getLevel(0, 0).getPixStencil(x, y, z);
1401 depth = static_cast<float>(stencil) / 255.0f;
1402 }
1403 else
1404 {
1405 if (m_useDifferentAreasSampleWrite && x < m_imageSize.x() / 2)
1406 depth = m_texture->getLevel(0, 0).getPixDepth(x + (m_imageSize.x() / 2), y, z) + 0.1f;
1407 else
1408 depth = m_texture->getLevel(0, 0).getPixDepth(x, y, z);
1409
1410 if (!m_useDifferentAreasSampleWrite)
1411 depth += 0.1f;
1412 }
1413
1414 depth = deFloatClamp(depth, 0.0f, 1.0f);
1415 referenceTextureLevel->getAccess().setPixDepth(depth, x, y, z);
1416 }
1417 if (isStencil)
1418 {
1419 int stencil = 0;
1420 if (m_interleaveReadWriteComponents)
1421 {
1422 float depth = m_texture->getLevel(0, 0).getPixDepth(x, y, z) + 0.1f;
1423 stencil = static_cast<int>(depth * 255.0f);
1424 }
1425 else
1426 {
1427 if (m_useDifferentAreasSampleWrite && x < m_imageSize.x() / 2)
1428 stencil = 1 + m_texture->getLevel(0, 0).getPixStencil(x + (m_imageSize.x() / 2), y, z);
1429 else
1430 stencil = m_texture->getLevel(0, 0).getPixStencil(x, y, z);
1431
1432 if (!m_useDifferentAreasSampleWrite)
1433 stencil += 1;
1434
1435 stencil = deClamp32(stencil, 0, 255);
1436 }
1437
1438 referenceTextureLevel->getAccess().setPixStencil(stencil, x, y, z);
1439 }
1440 }
1441
1442 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1443 {
1444 if (isDepth)
1445 {
1446 // Read back result image
1447 de::MovePtr<tcu::TextureLevel> resultTexture (readDepthAttachment(m_context.getDeviceInterface(),
1448 m_context.getDevice(),
1449 m_context.getUniversalQueue(),
1450 m_context.getUniversalQueueFamilyIndex(),
1451 m_context.getDefaultAllocator(),
1452 **m_dsImages[imgNdx],
1453 m_imageFormat,
1454 renderSize,
1455 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1456
1457 const tcu::ConstPixelBufferAccess result = resultTexture->getAccess();
1458 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_DEPTH;
1459 const tcu::ConstPixelBufferAccess depthResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1460 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(referenceTextureLevel->getAccess(), mode);
1461 bool isIntegerFormat = isUintFormat(mapTextureFormat(depthResult.getFormat())) || isIntFormat(mapTextureFormat(depthResult.getFormat()));
1462
1463 if (!isIntegerFormat)
1464 {
1465 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1466 return tcu::TestStatus::fail("Failed depth");
1467 }
1468 else
1469 {
1470 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, depthResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1471 return tcu::TestStatus::fail("Failed depth");
1472 }
1473 }
1474
1475 if (isStencil)
1476 {
1477 // Read back result image
1478 de::MovePtr<tcu::TextureLevel> resultTexture (readStencilAttachment(m_context.getDeviceInterface(),
1479 m_context.getDevice(),
1480 m_context.getUniversalQueue(),
1481 m_context.getUniversalQueueFamilyIndex(),
1482 m_context.getDefaultAllocator(),
1483 **m_dsImages[imgNdx],
1484 m_imageFormat,
1485 renderSize,
1486 VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1487
1488 const tcu::ConstPixelBufferAccess result = resultTexture->getAccess();
1489 const tcu::Sampler::DepthStencilMode mode = tcu::Sampler::MODE_STENCIL;
1490 const tcu::ConstPixelBufferAccess stencilResult = tcu::getEffectiveDepthStencilAccess(result, mode);
1491 const tcu::ConstPixelBufferAccess expectedResult = tcu::getEffectiveDepthStencilAccess(referenceTextureLevel->getAccess(), mode);
1492 bool isIntegerFormat = isUintFormat(mapTextureFormat(stencilResult.getFormat())) || isIntFormat(mapTextureFormat(stencilResult.getFormat()));
1493
1494 if (!isIntegerFormat)
1495 {
1496 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, fThreshold, tcu::COMPARE_LOG_RESULT))
1497 return tcu::TestStatus::fail("Failed stencil");
1498 }
1499 else
1500 {
1501 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", expectedResult, stencilResult, uThreshold, tcu::COMPARE_LOG_RESULT))
1502 return tcu::TestStatus::fail("Failed stencil");
1503 }
1504 }
1505 }
1506
1507 return tcu::TestStatus::pass("Pass");
1508 }
1509
iterate(void)1510 tcu::TestStatus AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance::iterate (void)
1511 {
1512 const DeviceInterface& vk = m_context.getDeviceInterface();
1513 const VkDevice vkDevice = m_context.getDevice();
1514 const VkQueue queue = m_context.getUniversalQueue();
1515
1516 setup();
1517 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1518
1519 return verifyImage();
1520 }
1521
verifyImage(void)1522 tcu::TestStatus AttachmentFeedbackLoopLayoutImageSamplingInstance::verifyImage(void)
1523 {
1524 if (!m_useImageAsColorOrDSAttachment)
1525 return ImageSamplingInstance::verifyImage();
1526
1527 const tcu::Vec4 fThreshold (0.01f);
1528 const tcu::UVec4 uThreshold (1u);
1529 tcu::UVec2 renderSize = tcu::UVec2({ (unsigned)m_imageSize.x(), (unsigned)m_imageSize.y() });
1530
1531 const tcu::TextureFormat tcuFormat = getSizeCompatibleTcuTextureFormat(m_imageFormat);
1532 de::MovePtr<tcu::TextureLevel> referenceTextureLevel = de::MovePtr<tcu::TextureLevel>(new tcu::TextureLevel(tcuFormat,
1533 m_imageSize.x(),
1534 m_imageSize.y(),
1535 m_imageSize.z()));
1536
1537 for (int z = 0; z < m_imageSize.z(); z++)
1538 for (int y = 0; y < m_imageSize.y(); y++)
1539 for (int x = 0; x < m_imageSize.x(); x++)
1540 {
1541 tcu::Vec4 color = tcu::Vec4(1.0f);
1542
1543 if (m_useDifferentAreasSampleWrite && (x < m_imageSize.x() / 2))
1544 color = m_texture->getLevel(0, 0).getPixel(x + (m_imageSize.x() / 2), y, z) + tcu::Vec4(0.1f);
1545 else
1546 color = m_texture->getLevel(0, 0).getPixel(x, y, z);
1547
1548 if (!m_useDifferentAreasSampleWrite)
1549 color += tcu::Vec4(0.1f);
1550
1551 if (m_interleaveReadWriteComponents)
1552 {
1553 tcu::Vec4 sampledColor = m_texture->getLevel(0, 0).getPixel(x, y, z);
1554 color.x() = color.y();
1555 color.y() = sampledColor.y();
1556 color.z() = color.w();
1557 color.w() = sampledColor.w();
1558 }
1559
1560 color.x() = deFloatClamp(color.x(), 0.0f, 1.0f);
1561 color.y() = deFloatClamp(color.y(), 0.0f, 1.0f);
1562 color.z() = deFloatClamp(color.z(), 0.0f, 1.0f);
1563 color.w() = deFloatClamp(color.w(), 0.0f, 1.0f);
1564
1565 referenceTextureLevel->getAccess().setPixel(color, x, y, z);
1566 }
1567
1568 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1569 {
1570 // Read back result image
1571 de::MovePtr<tcu::TextureLevel> resultTexture (readColorAttachment(m_context.getDeviceInterface(),
1572 m_context.getDevice(),
1573 m_context.getUniversalQueue(),
1574 m_context.getUniversalQueueFamilyIndex(),
1575 m_context.getDefaultAllocator(),
1576 **m_colorImages[imgNdx],
1577 m_colorFormat,
1578 renderSize,
1579 vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT));
1580 const tcu::ConstPixelBufferAccess result = resultTexture->getAccess();
1581 const bool isIntegerFormat = isUintFormat(m_imageFormat) || isIntFormat(m_imageFormat);
1582
1583 if (!isIntegerFormat)
1584 {
1585 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceTextureLevel->getAccess(), result, fThreshold, tcu::COMPARE_LOG_RESULT))
1586 return tcu::TestStatus::fail("Failed color");
1587 }
1588 else
1589 {
1590 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", referenceTextureLevel->getAccess(), result, uThreshold, tcu::COMPARE_LOG_RESULT))
1591 return tcu::TestStatus::fail("Failed color");
1592 }
1593 }
1594
1595 return tcu::TestStatus::pass("Pass");
1596 }
1597
~AttachmentFeedbackLoopLayoutImageSamplingInstance(void)1598 AttachmentFeedbackLoopLayoutImageSamplingInstance::~AttachmentFeedbackLoopLayoutImageSamplingInstance (void)
1599 {
1600 }
1601
iterate(void)1602 tcu::TestStatus AttachmentFeedbackLoopLayoutImageSamplingInstance::iterate (void)
1603 {
1604 const DeviceInterface& vk = m_context.getDeviceInterface();
1605 const VkDevice vkDevice = m_context.getDevice();
1606 const VkQueue queue = m_context.getUniversalQueue();
1607
1608 setup();
1609 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
1610
1611 return verifyImage();
1612 }
1613
1614 class AttachmentFeedbackLoopLayoutSamplerTest : public vkt::TestCase {
1615 public:
1616 AttachmentFeedbackLoopLayoutSamplerTest (tcu::TestContext& testContext,
1617 vk::PipelineConstructionType pipelineConstructionType,
1618 const char* name,
1619 const char* description,
1620 SamplerViewType imageViewType,
1621 VkFormat imageFormat,
1622 int imageSize,
1623 VkDescriptorType imageDescriptorType,
1624 float samplerLod,
1625 TestMode testMode,
1626 ImageAspectTestMode imageAspectTestMode,
1627 bool interleaveReadWriteComponents);
~AttachmentFeedbackLoopLayoutSamplerTest(void)1628 virtual ~AttachmentFeedbackLoopLayoutSamplerTest (void) {}
1629
1630 virtual ImageSamplingInstanceParams getImageSamplingInstanceParams (SamplerViewType imageViewType,
1631 VkFormat imageFormat,
1632 int imageSize,
1633 VkDescriptorType imageDescriptorType,
1634 float samplerLod) const;
1635
1636 virtual void initPrograms (SourceCollections& sourceCollections) const;
1637 virtual void checkSupport (Context& context) const;
1638 virtual TestInstance* createInstance (Context& context) const;
1639 virtual tcu::UVec2 getRenderSize (SamplerViewType viewType) const;
1640 virtual std::vector<Vertex4Tex4> createVertices (void) const;
1641 virtual VkSamplerCreateInfo getSamplerCreateInfo (void) const;
1642 virtual VkComponentMapping getComponentMapping (void) const;
1643
1644 static std::string getGlslSamplerType (const tcu::TextureFormat& format, SamplerViewType type);
1645 static tcu::IVec3 getImageSize (SamplerViewType viewType, int size);
1646 static int getArraySize (SamplerViewType viewType);
1647
1648 static std::string getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount);
1649 static std::string getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type);
1650 static std::string getGlslSamplerDecl (int imageCount);
1651 static std::string getGlslTextureDecl (int imageCount);
1652
1653 protected:
1654 vk::PipelineConstructionType m_pipelineConstructionType;
1655 SamplerViewType m_imageViewType;
1656 VkFormat m_imageFormat;
1657 int m_imageSize;
1658 VkDescriptorType m_imageDescriptorType;
1659 float m_samplerLod;
1660 TestMode m_testMode;
1661 ImageAspectTestMode m_imageAspectTestMode;
1662 bool m_interleaveReadWriteComponents;
1663 };
1664
1665 // AttachmentFeedbackLoopLayoutSamplerTest
1666
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)1667 AttachmentFeedbackLoopLayoutSamplerTest::AttachmentFeedbackLoopLayoutSamplerTest (tcu::TestContext& testContext,
1668 vk::PipelineConstructionType pipelineConstructionType,
1669 const char* name,
1670 const char* description,
1671 SamplerViewType imageViewType,
1672 VkFormat imageFormat,
1673 int imageSize,
1674 VkDescriptorType imageDescriptorType,
1675 float samplerLod,
1676 TestMode testMode,
1677 ImageAspectTestMode imageAspectTestMode,
1678 bool interleaveReadWriteComponents = false)
1679 : vkt::TestCase (testContext, name, description)
1680 , m_pipelineConstructionType (pipelineConstructionType)
1681 , m_imageViewType (imageViewType)
1682 , m_imageFormat (imageFormat)
1683 , m_imageSize (imageSize)
1684 , m_imageDescriptorType (imageDescriptorType)
1685 , m_samplerLod (samplerLod)
1686 , m_testMode (testMode)
1687 , m_imageAspectTestMode (imageAspectTestMode)
1688 , m_interleaveReadWriteComponents (interleaveReadWriteComponents)
1689 {
1690 }
1691
getImageSamplingInstanceParams(SamplerViewType imageViewType,VkFormat imageFormat,int imageSize,VkDescriptorType imageDescriptorType,float samplerLod) const1692 ImageSamplingInstanceParams AttachmentFeedbackLoopLayoutSamplerTest::getImageSamplingInstanceParams (SamplerViewType imageViewType,
1693 VkFormat imageFormat,
1694 int imageSize,
1695 VkDescriptorType imageDescriptorType,
1696 float samplerLod) const
1697 {
1698 const tcu::UVec2 renderSize = getRenderSize(imageViewType);
1699 const std::vector<Vertex4Tex4> vertices = createVertices();
1700 const VkSamplerCreateInfo samplerParams = getSamplerCreateInfo();
1701 const VkComponentMapping componentMapping = getComponentMapping();
1702
1703 VkImageAspectFlags imageAspect = 0u;
1704 VkPipelineCreateFlags pipelineCreateFlags = 0u;
1705 if (!isCompressedFormat(imageFormat))
1706 {
1707 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR)
1708 {
1709 DE_ASSERT(!tcu::hasDepthComponent(mapVkFormat(imageFormat).order) &&
1710 !tcu::hasStencilComponent(mapVkFormat(imageFormat).order));
1711 imageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
1712 pipelineCreateFlags = VK_PIPELINE_CREATE_COLOR_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
1713 }
1714 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH)
1715 {
1716 DE_ASSERT(tcu::hasDepthComponent(mapVkFormat(imageFormat).order));
1717 imageAspect |= VK_IMAGE_ASPECT_DEPTH_BIT;
1718 pipelineCreateFlags = VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
1719 }
1720 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL)
1721 {
1722 DE_ASSERT(tcu::hasStencilComponent(mapVkFormat(imageFormat).order));
1723 imageAspect |= VK_IMAGE_ASPECT_STENCIL_BIT;
1724 pipelineCreateFlags = VK_PIPELINE_CREATE_DEPTH_STENCIL_ATTACHMENT_FEEDBACK_LOOP_BIT_EXT;
1725 }
1726 }
1727 else
1728 {
1729 imageAspect = VK_IMAGE_ASPECT_COLOR_BIT;
1730 }
1731
1732 const VkImageSubresourceRange subresourceRange =
1733 {
1734 imageAspect, // VkImageAspectFlags aspectMask;
1735 0u, // deUint32 baseMipLevel;
1736 1u, // deUint32 mipLevels;
1737 0u, // deUint32 baseArrayLayer;
1738 (deUint32)getArraySize(imageViewType) // deUint32 arraySize;
1739 };
1740
1741 return ImageSamplingInstanceParams(m_pipelineConstructionType, renderSize, imageViewType, imageFormat,
1742 getImageSize(imageViewType, imageSize),
1743 getArraySize(imageViewType),
1744 componentMapping, subresourceRange,
1745 samplerParams, samplerLod, vertices, false,
1746 imageDescriptorType, 1u, ALLOCATION_KIND_SUBALLOCATED,
1747 vk::VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT,
1748 pipelineCreateFlags);
1749 }
1750
checkSupport(Context & context) const1751 void AttachmentFeedbackLoopLayoutSamplerTest::checkSupport (Context& context) const
1752 {
1753 context.requireDeviceFunctionality("VK_EXT_attachment_feedback_loop_layout");
1754
1755 checkPipelineLibraryRequirements(context.getInstanceInterface(), context.getPhysicalDevice(), m_pipelineConstructionType);
1756
1757 vk::VkPhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT attachmentFeedbackLoopLayoutFeatures =
1758 {
1759 vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ATTACHMENT_FEEDBACK_LOOP_LAYOUT_FEATURES_EXT, // VkStructureType sType;
1760 DE_NULL, // void* pNext;
1761 DE_FALSE, // VkBool32 attachmentFeedbackLoopLayout;
1762 };
1763
1764 vk::VkPhysicalDeviceFeatures2 features2;
1765 deMemset(&features2, 0, sizeof(features2));
1766 features2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
1767 features2.pNext = &attachmentFeedbackLoopLayoutFeatures;
1768
1769 context.getInstanceInterface().getPhysicalDeviceFeatures2(context.getPhysicalDevice(), &features2);
1770
1771 if (attachmentFeedbackLoopLayoutFeatures.attachmentFeedbackLoopLayout == DE_FALSE)
1772 {
1773 throw tcu::NotSupportedError("attachmentFeedbackLoopLayout not supported");
1774 }
1775
1776 checkSupportImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod));
1777
1778 ImageSamplingInstanceParams params = getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod);
1779
1780 bool useImageAsColorOrDSAttachment = m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL;
1781 if (useImageAsColorOrDSAttachment)
1782 {
1783 VkFormatProperties formatProps;
1784 const InstanceInterface& instanceInterface = context.getInstanceInterface();
1785 VkFormatFeatureFlags attachmentFormatFeature = isDepthStencilFormat(params.imageFormat) ?
1786 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT : VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT;
1787
1788 instanceInterface.getPhysicalDeviceFormatProperties(context.getPhysicalDevice(), params.imageFormat, &formatProps);
1789 bool error =
1790 (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT ) == 0u ||
1791 (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_SRC_BIT ) == 0u ||
1792 (formatProps.optimalTilingFeatures & VK_FORMAT_FEATURE_TRANSFER_DST_BIT ) == 0u ||
1793 (formatProps.optimalTilingFeatures & attachmentFormatFeature ) == 0u;
1794
1795 if (error)
1796 {
1797 throw tcu::NotSupportedError("format doesn't support some required features");
1798 }
1799
1800 if ((!m_interleaveReadWriteComponents && m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL) ||
1801 (m_interleaveReadWriteComponents && m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH))
1802 context.requireDeviceFunctionality("VK_EXT_shader_stencil_export");
1803 }
1804 }
1805
getGlslTextureType(const tcu::TextureFormat & format,VkImageViewType type)1806 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslTextureType (const tcu::TextureFormat& format, VkImageViewType type)
1807 {
1808 std::ostringstream textureType;
1809
1810 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
1811 textureType << "u";
1812 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
1813 textureType << "i";
1814
1815 switch (type)
1816 {
1817 case VK_IMAGE_VIEW_TYPE_1D:
1818 textureType << "texture1D";
1819 break;
1820
1821 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
1822 textureType << "texture1DArray";
1823 break;
1824
1825 case VK_IMAGE_VIEW_TYPE_2D:
1826 textureType << "texture2D";
1827 break;
1828
1829 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
1830 textureType << "texture2DArray";
1831 break;
1832
1833 case VK_IMAGE_VIEW_TYPE_3D:
1834 textureType << "texture3D";
1835 break;
1836
1837 case VK_IMAGE_VIEW_TYPE_CUBE:
1838 textureType << "textureCube";
1839 break;
1840
1841 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
1842 textureType << "textureCubeArray";
1843 break;
1844
1845 default:
1846 DE_FATAL("Unknown image view type");
1847 }
1848
1849 return textureType.str();
1850 }
1851
getGlslSamplerDecl(int imageCount)1852 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSamplerDecl (int imageCount)
1853 {
1854 std::ostringstream samplerArray;
1855 samplerArray << "texSamplers[" << imageCount << "]";
1856
1857 return imageCount > 1 ? samplerArray.str() : "texSampler";
1858 }
1859
getGlslTextureDecl(int imageCount)1860 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslTextureDecl (int imageCount)
1861 {
1862 std::ostringstream textureArray;
1863 textureArray << "texImages[" << imageCount << "]";
1864
1865 return imageCount > 1 ? textureArray.str() : "texImage";
1866 }
1867
getGlslSampler(const tcu::TextureFormat & format,VkImageViewType type,VkDescriptorType samplingType,int imageCount)1868 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSampler (const tcu::TextureFormat& format, VkImageViewType type, VkDescriptorType samplingType, int imageCount)
1869 {
1870 std::string texSampler = imageCount > 1 ? "texSamplers[i]" : "texSampler";
1871 std::string texImage = imageCount > 1 ? "texImages[i]" : "texImage";
1872
1873 switch (samplingType)
1874 {
1875 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1876 return getGlslSamplerType(format, type) + "(" + texImage + ", texSampler)";
1877 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1878 default:
1879 return texSampler;
1880 }
1881 }
1882
initPrograms(SourceCollections & sourceCollections) const1883 void AttachmentFeedbackLoopLayoutSamplerTest::initPrograms (SourceCollections& sourceCollections) const
1884 {
1885 std::ostringstream vertexSrc;
1886 std::ostringstream fragmentSrc;
1887 const char* texCoordSwizzle = DE_NULL;
1888 const VkFormat vkFormat = m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL ? VK_FORMAT_S8_UINT : m_imageFormat;
1889 const tcu::TextureFormat format = (isCompressedFormat(m_imageFormat)) ? tcu::getUncompressedFormat(mapVkCompressedFormat(vkFormat))
1890 : mapVkFormat(vkFormat);
1891 tcu::Vec4 lookupScale;
1892 tcu::Vec4 lookupBias;
1893
1894 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias);
1895
1896 switch (m_imageViewType)
1897 {
1898 case VK_IMAGE_VIEW_TYPE_1D:
1899 texCoordSwizzle = "x";
1900 break;
1901 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
1902 case VK_IMAGE_VIEW_TYPE_2D:
1903 texCoordSwizzle = "xy";
1904 break;
1905 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
1906 case VK_IMAGE_VIEW_TYPE_3D:
1907 case VK_IMAGE_VIEW_TYPE_CUBE:
1908 texCoordSwizzle = "xyz";
1909 break;
1910 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
1911 texCoordSwizzle = "xyzw";
1912 break;
1913 default:
1914 DE_ASSERT(false);
1915 break;
1916 }
1917
1918 vertexSrc << "#version 440\n"
1919 << "layout(location = 0) in vec4 position;\n"
1920 << "layout(location = 1) in vec4 texCoords;\n"
1921 << "layout(location = 0) out highp vec4 vtxTexCoords;\n"
1922 << "out gl_PerVertex {\n"
1923 << " vec4 gl_Position;\n"
1924 << "};\n"
1925 << "void main (void)\n"
1926 << "{\n"
1927 << " gl_Position = position;\n"
1928 << " vtxTexCoords = texCoords;\n"
1929 << "}\n";
1930
1931 fragmentSrc << "#version 440\n";
1932
1933 if ((m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL) ||
1934 (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_interleaveReadWriteComponents))
1935 {
1936 fragmentSrc << "#extension GL_ARB_shader_stencil_export: require\n";
1937 }
1938
1939 switch (m_imageDescriptorType)
1940 {
1941 case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
1942 fragmentSrc
1943 << "layout(set = 0, binding = 0) uniform highp sampler texSampler;\n"
1944 << "layout(set = 0, binding = 1) uniform highp " << getGlslTextureType(format, m_imageViewType) << " " << getGlslTextureDecl(1u) << ";\n";
1945 break;
1946 case VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
1947 default:
1948 fragmentSrc
1949 << "layout(set = 0, binding = 0) uniform highp " << getGlslSamplerType(format, m_imageViewType) << " " << getGlslSamplerDecl(1u) << ";\n";
1950 }
1951
1952 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR || m_testMode == TEST_MODE_READ_ONLY)
1953 fragmentSrc << "layout(location = 0) out highp vec4 fragColor;\n";
1954
1955 fragmentSrc << "layout(location = 0) in highp vec4 vtxTexCoords;\n"
1956 << "void main (void)\n"
1957 << "{\n";
1958
1959 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode != TEST_MODE_READ_ONLY)
1960 fragmentSrc << " uvec4 read_data = ";
1961 else
1962 fragmentSrc << " vec4 read_data = ";
1963
1964 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
1965 {
1966 fragmentSrc << "vec4(1.0f, 0.0f, 0.0f, 1.0f);\n";
1967
1968 fragmentSrc << " read_data.x = ";
1969 if (m_samplerLod > 0.0f)
1970 {
1971 DE_ASSERT(m_imageViewType.isNormalized());
1972 fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ").x";
1973 }
1974 else
1975 {
1976 if (m_imageViewType.isNormalized())
1977 fragmentSrc << "texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ").x" << std::fixed;
1978 else
1979 fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0).x" << std::fixed;
1980 }
1981
1982 fragmentSrc << " + 0.1f;\n";
1983 }
1984 else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode == TEST_MODE_READ_ONLY)
1985 {
1986 if (m_samplerLod > 0.0f)
1987 {
1988 DE_ASSERT(m_imageViewType.isNormalized());
1989 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)";
1990 }
1991 else
1992 {
1993 if (m_imageViewType.isNormalized())
1994 fragmentSrc << "vec4(texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ").x / 255.0f, 0.0f, 0.0f, 1.0f)" << std::fixed;
1995 else
1996 fragmentSrc << "vec4(textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0).x / 255.0f, 0.0f, 0.0f, 1.0f)" << std::fixed;
1997 }
1998
1999 fragmentSrc << ";\n";
2000 }
2001 else
2002 {
2003 if (m_samplerLod > 0.0f)
2004 {
2005 DE_ASSERT(m_imageViewType.isNormalized());
2006 fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", " << std::fixed << m_samplerLod << ")";
2007 }
2008 else
2009 {
2010 if (m_imageViewType.isNormalized())
2011 fragmentSrc << "texture(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ")" << std::fixed;
2012 else
2013 fragmentSrc << "textureLod(" << getGlslSampler(format, m_imageViewType, m_imageDescriptorType, 1u) << ", vtxTexCoords." << texCoordSwizzle << ", 0)" << std::fixed;
2014 }
2015
2016 if (m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2017 {
2018 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL)
2019 fragmentSrc << " + uvec4(1u, 0u, 0u, 0)";
2020 else
2021 fragmentSrc << " + vec4(0.1f)";
2022 }
2023
2024 fragmentSrc << ";\n";
2025 }
2026
2027 if (m_interleaveReadWriteComponents)
2028 {
2029 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_COLOR)
2030 {
2031 fragmentSrc << " fragColor = vec4(1.0f);\n"
2032 << " fragColor.x = read_data.y;\n"
2033 << " fragColor.z = read_data.w;\n";
2034 }
2035 else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH)
2036 {
2037 fragmentSrc << " gl_FragStencilRefARB = int(clamp(read_data.x * 255.0f, 0.0f, 255.0f));\n";
2038 }
2039 else
2040 {
2041 fragmentSrc << " gl_FragDepth = clamp(float(read_data.x) / 255.0f, 0.0f, 1.0f);\n";
2042 }
2043 }
2044 else
2045 {
2046 if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_DEPTH && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2047 {
2048 fragmentSrc << " gl_FragDepth = clamp(read_data.x, 0.0f, 1.0f);\n";
2049 }
2050 else if (m_imageAspectTestMode == IMAGE_ASPECT_TEST_STENCIL && m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL)
2051 {
2052 fragmentSrc << " gl_FragStencilRefARB = int(clamp(read_data.x, 0u, 255u));\n";
2053 }
2054 else
2055 {
2056 fragmentSrc << " fragColor = read_data;\n";
2057 }
2058 }
2059
2060 fragmentSrc << "}\n";
2061
2062 sourceCollections.glslSources.add("tex_vert") << glu::VertexSource(vertexSrc.str());
2063 sourceCollections.glslSources.add("tex_frag") << glu::FragmentSource(fragmentSrc.str());
2064 }
2065
createInstance(Context & context) const2066 TestInstance* AttachmentFeedbackLoopLayoutSamplerTest::createInstance (Context& context) const
2067 {
2068 const bool useImageAsColorOrDSAttachment = m_testMode >= TEST_MODE_READ_WRITE_SAME_PIXEL;
2069 const bool useDifferentAreasSampleWrite = m_testMode == TEST_MODE_READ_WRITE_DIFFERENT_AREAS;
2070
2071 if (m_imageAspectTestMode != IMAGE_ASPECT_TEST_COLOR && useImageAsColorOrDSAttachment)
2072 return new AttachmentFeedbackLoopLayoutDepthStencilImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod), useImageAsColorOrDSAttachment, useDifferentAreasSampleWrite, m_interleaveReadWriteComponents);
2073 return new AttachmentFeedbackLoopLayoutImageSamplingInstance(context, getImageSamplingInstanceParams(m_imageViewType, m_imageFormat, m_imageSize, m_imageDescriptorType, m_samplerLod), useImageAsColorOrDSAttachment, useDifferentAreasSampleWrite, m_interleaveReadWriteComponents);
2074 }
2075
getRenderSize(SamplerViewType viewType) const2076 tcu::UVec2 AttachmentFeedbackLoopLayoutSamplerTest::getRenderSize (SamplerViewType viewType) const
2077 {
2078 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_2D)
2079 {
2080 return tcu::UVec2(16u, 16u);
2081 }
2082 else
2083 {
2084 return tcu::UVec2(16u * 3u, 16u * 2u);
2085 }
2086 }
2087
createFullscreenQuadArray(vk::VkImageViewType viewType,unsigned arraySize)2088 std::vector<Vertex4Tex4> createFullscreenQuadArray (vk::VkImageViewType viewType, unsigned arraySize)
2089 {
2090 using tcu::Vec4;
2091 std::vector<Vertex4Tex4> verticesArray;
2092
2093 const Vertex4Tex4 lowerLeftVertex =
2094 {
2095 Vec4(-1.0f, -1.0f, 0.0f, 1.0f),
2096 Vec4(0.0f, 0.0f, 0.0f, 0.0f)
2097 };
2098 const Vertex4Tex4 upperLeftVertex =
2099 {
2100 Vec4(-1.0f, 1.0f, 0.0f, 1.0f),
2101 Vec4(0.0f, 1.0f, 0.0f, 0.0f)
2102 };
2103 const Vertex4Tex4 lowerRightVertex =
2104 {
2105 Vec4(1.0f, -1.0f, 0.0f, 1.0f),
2106 Vec4(1.0f, 0.0f, 0.0f, 0.0f)
2107 };
2108 const Vertex4Tex4 upperRightVertex =
2109 {
2110 Vec4(1.0f, 1.0f, 0.0f, 1.0f),
2111 Vec4(1.0f, 1.0f, 0.0f, 0.0f)
2112 };
2113
2114 for (unsigned arrayNdx = 0; arrayNdx < arraySize; arrayNdx++)
2115 {
2116 Vertex4Tex4 vertices[6] =
2117 {
2118 lowerLeftVertex,
2119 upperLeftVertex,
2120 lowerRightVertex,
2121
2122 upperLeftVertex,
2123 lowerRightVertex,
2124 upperRightVertex
2125 };
2126
2127 for (int i = 0; i < 6; i++)
2128 {
2129 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
2130 {
2131 vertices[i].position.y() = (float)arrayNdx;
2132 vertices[i].texCoord.y() = (float)arrayNdx;
2133 }
2134 else
2135 {
2136 vertices[i].position.z() = (float)arrayNdx;
2137 vertices[i].texCoord.z() = (float)arrayNdx;
2138 }
2139 verticesArray.push_back(vertices[i]);
2140 }
2141 }
2142
2143 return verticesArray;
2144 }
2145
createTestQuadAttachmentFeedbackLoopLayout(vk::VkImageViewType viewType)2146 std::vector<Vertex4Tex4> createTestQuadAttachmentFeedbackLoopLayout (vk::VkImageViewType viewType)
2147 {
2148 std::vector<Vertex4Tex4> vertices;
2149
2150 switch (viewType)
2151 {
2152 case vk::VK_IMAGE_VIEW_TYPE_1D:
2153 case vk::VK_IMAGE_VIEW_TYPE_2D:
2154 vertices = createFullscreenQuad();
2155 break;
2156
2157 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2158 vertices = createFullscreenQuadArray(viewType, 6u);
2159 break;
2160
2161 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2162 case vk::VK_IMAGE_VIEW_TYPE_3D:
2163 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
2164 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2165 vertices = createFullscreenQuadArray(viewType, 6u);
2166 break;
2167
2168 default:
2169 DE_ASSERT(false);
2170 break;
2171 }
2172
2173 return vertices;
2174 }
2175
createVertices(void) const2176 std::vector<Vertex4Tex4> AttachmentFeedbackLoopLayoutSamplerTest::createVertices (void) const
2177 {
2178 std::vector<Vertex4Tex4> vertices = m_testMode != TEST_MODE_READ_WRITE_DIFFERENT_AREAS ?
2179 createTestQuadMosaic(m_imageViewType) :
2180 createTestQuadAttachmentFeedbackLoopLayout(m_imageViewType);
2181 for (unsigned int i = 0; i < vertices.size(); ++i) {
2182 if (m_testMode == TEST_MODE_READ_WRITE_DIFFERENT_AREAS)
2183 {
2184 vertices[i].texCoord.x() = std::max(vertices[i].texCoord.x(), 0.5f);
2185 vertices[i].position.x() = std::min(vertices[i].position.x(), 0.0f);
2186 }
2187 if (!m_imageViewType.isNormalized()) {
2188 const float imageSize = static_cast<float>(m_imageSize);
2189 for (int j = 0; j < tcu::Vec4::SIZE; ++j)
2190 vertices[i].texCoord[j] *= imageSize;
2191 }
2192 }
2193 return vertices;
2194 }
2195
getSamplerCreateInfo(void) const2196 VkSamplerCreateInfo AttachmentFeedbackLoopLayoutSamplerTest::getSamplerCreateInfo (void) const
2197 {
2198 const VkSamplerCreateInfo defaultSamplerParams =
2199 {
2200 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, // VkStructureType sType;
2201 DE_NULL, // const void* pNext;
2202 0u, // VkSamplerCreateFlags flags;
2203 VK_FILTER_NEAREST, // VkFilter magFilter;
2204 VK_FILTER_NEAREST, // VkFilter minFilter;
2205 VK_SAMPLER_MIPMAP_MODE_NEAREST, // VkSamplerMipmapMode mipmapMode;
2206 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeU;
2207 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeV;
2208 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // VkSamplerAddressMode addressModeW;
2209 0.0f, // float mipLodBias;
2210 VK_FALSE, // VkBool32 anisotropyEnable;
2211 1.0f, // float maxAnisotropy;
2212 false, // VkBool32 compareEnable;
2213 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
2214 0.0f, // float minLod;
2215 (m_imageViewType.isNormalized() ? 0.25f : 0.0f), // float maxLod;
2216 getFormatBorderColor(BORDER_COLOR_TRANSPARENT_BLACK, m_imageFormat, false), // VkBorderColor borderColor;
2217 !m_imageViewType.isNormalized(), // VkBool32 unnormalizedCoordinates;
2218 };
2219
2220 return defaultSamplerParams;
2221 }
2222
getComponentMapping(void) const2223 VkComponentMapping AttachmentFeedbackLoopLayoutSamplerTest::getComponentMapping (void) const
2224 {
2225 const VkComponentMapping componentMapping = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
2226 return componentMapping;
2227 }
2228
getGlslSamplerType(const tcu::TextureFormat & format,SamplerViewType type)2229 std::string AttachmentFeedbackLoopLayoutSamplerTest::getGlslSamplerType (const tcu::TextureFormat& format, SamplerViewType type)
2230 {
2231 std::ostringstream samplerType;
2232
2233 if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
2234 samplerType << "u";
2235 else if (tcu::getTextureChannelClass(format.type) == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
2236 samplerType << "i";
2237
2238 switch (type)
2239 {
2240 case VK_IMAGE_VIEW_TYPE_1D:
2241 samplerType << "sampler1D";
2242 break;
2243
2244 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2245 samplerType << "sampler1DArray";
2246 break;
2247
2248 case VK_IMAGE_VIEW_TYPE_2D:
2249 samplerType << "sampler2D";
2250 break;
2251
2252 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2253 samplerType << "sampler2DArray";
2254 break;
2255
2256 case VK_IMAGE_VIEW_TYPE_3D:
2257 samplerType << "sampler3D";
2258 break;
2259
2260 case VK_IMAGE_VIEW_TYPE_CUBE:
2261 samplerType << "samplerCube";
2262 break;
2263
2264 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2265 samplerType << "samplerCubeArray";
2266 break;
2267
2268 default:
2269 DE_FATAL("Unknown image view type");
2270 break;
2271 }
2272
2273 return samplerType.str();
2274 }
2275
getImageSize(SamplerViewType viewType,int size)2276 tcu::IVec3 AttachmentFeedbackLoopLayoutSamplerTest::getImageSize (SamplerViewType viewType, int size)
2277 {
2278 switch (viewType)
2279 {
2280 case VK_IMAGE_VIEW_TYPE_1D:
2281 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2282 return tcu::IVec3(size, 1, 1);
2283
2284 case VK_IMAGE_VIEW_TYPE_3D:
2285 return tcu::IVec3(size, size, 4);
2286
2287 default:
2288 break;
2289 }
2290
2291 return tcu::IVec3(size, size, 1);
2292 }
2293
getArraySize(SamplerViewType viewType)2294 int AttachmentFeedbackLoopLayoutSamplerTest::getArraySize (SamplerViewType viewType)
2295 {
2296 switch (viewType)
2297 {
2298 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
2299 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
2300 case VK_IMAGE_VIEW_TYPE_CUBE:
2301 return 6;
2302
2303 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
2304 return 36;
2305
2306 default:
2307 break;
2308 }
2309
2310 return 1;
2311 }
2312 } // anonymous
2313
createAttachmentFeedbackLoopLayoutSamplerTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)2314 tcu::TestCaseGroup* createAttachmentFeedbackLoopLayoutSamplerTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
2315 {
2316 // TODO: implement layer rendering with a geometry shader to render to arrays, 3D and cube images.
2317 const struct
2318 {
2319 SamplerViewType type;
2320 const char* name;
2321 bool readOnly;
2322 }
2323 imageViewTypes[] =
2324 {
2325 { VK_IMAGE_VIEW_TYPE_1D, "1d", false },
2326 { { VK_IMAGE_VIEW_TYPE_1D, false }, "1d_unnormalized", false },
2327 { VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", true },
2328 { VK_IMAGE_VIEW_TYPE_2D, "2d", false },
2329 { { VK_IMAGE_VIEW_TYPE_2D, false }, "2d_unnormalized", false },
2330 { VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", true },
2331 { VK_IMAGE_VIEW_TYPE_3D, "3d", true },
2332 { VK_IMAGE_VIEW_TYPE_CUBE, "cube", true },
2333 { VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", true }
2334 };
2335
2336 const VkFormat formats[] =
2337 {
2338 VK_FORMAT_R8G8B8A8_UNORM,
2339 VK_FORMAT_D16_UNORM,
2340 VK_FORMAT_D32_SFLOAT,
2341 VK_FORMAT_D16_UNORM_S8_UINT,
2342 VK_FORMAT_D24_UNORM_S8_UINT,
2343 VK_FORMAT_D32_SFLOAT_S8_UINT,
2344 VK_FORMAT_S8_UINT
2345 };
2346
2347 de::MovePtr<tcu::TestCaseGroup> samplingTypeTests (new tcu::TestCaseGroup(testCtx, "sampler", ""));
2348
2349 const struct
2350 {
2351 enum TestMode mode;
2352 const char* name;
2353 }
2354 testModes[] =
2355 {
2356 { TEST_MODE_READ_ONLY, "_read" },
2357 { TEST_MODE_READ_WRITE_SAME_PIXEL, "_read_write_same_pixel" },
2358 { TEST_MODE_READ_WRITE_DIFFERENT_AREAS, "_read_write_different_areas" },
2359 };
2360
2361 const char* imageAspectTestModes[] = { "_color", "_depth", "_stencil" };
2362
2363 const struct
2364 {
2365 VkDescriptorType type;
2366 const char* name;
2367 }
2368 imageDescriptorTypes[] =
2369 {
2370 { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler" },
2371 { VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image" },
2372 };
2373
2374 const struct
2375 {
2376 bool interleaveReadWriteComponents;
2377 const char* name;
2378 }
2379 interleaveReadWriteComponentsModes[] =
2380 {
2381 { false, "" },
2382 { true, "_interleave_read_write_components" },
2383 };
2384
2385
2386 for (int imageDescriptorTypeNdx = 0; imageDescriptorTypeNdx < DE_LENGTH_OF_ARRAY(imageDescriptorTypes); imageDescriptorTypeNdx++)
2387 {
2388 VkDescriptorType imageDescriptorType = imageDescriptorTypes[imageDescriptorTypeNdx].type;
2389 de::MovePtr<tcu::TestCaseGroup> imageDescriptorTypeGroup (new tcu::TestCaseGroup(testCtx, imageDescriptorTypes[imageDescriptorTypeNdx].name, (std::string("Uses a ") + imageDescriptorTypes[imageDescriptorTypeNdx].name + " sampler").c_str()));
2390 de::MovePtr<tcu::TestCaseGroup> imageTypeTests (new tcu::TestCaseGroup(testCtx, "image_type", ""));
2391
2392 for (int viewTypeNdx = 0; viewTypeNdx < DE_LENGTH_OF_ARRAY(imageViewTypes); viewTypeNdx++)
2393 {
2394 const SamplerViewType viewType = imageViewTypes[viewTypeNdx].type;
2395 de::MovePtr<tcu::TestCaseGroup> viewTypeGroup (new tcu::TestCaseGroup(testCtx, imageViewTypes[viewTypeNdx].name, (std::string("Uses a ") + imageViewTypes[viewTypeNdx].name + " view").c_str()));
2396 de::MovePtr<tcu::TestCaseGroup> formatTests (new tcu::TestCaseGroup(testCtx, "format", "Tests samplable formats"));
2397
2398 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
2399 {
2400 const VkFormat format = formats[formatNdx];
2401 const bool isCompressed = isCompressedFormat(format);
2402 const bool isDepthStencil = !isCompressed && tcu::hasDepthComponent(mapVkFormat(format).order) && tcu::hasStencilComponent(mapVkFormat(format).order);
2403 ImageAspectTestMode imageAspectTestMode = getImageAspectTestMode(format);
2404
2405 if (isCompressed)
2406 {
2407 // Do not use compressed formats with 1D and 1D array textures.
2408 if (viewType == VK_IMAGE_VIEW_TYPE_1D || viewType == VK_IMAGE_VIEW_TYPE_1D_ARRAY)
2409 break;
2410 }
2411
2412 for (int testModeNdx = 0; testModeNdx < DE_LENGTH_OF_ARRAY(testModes); testModeNdx++)
2413 {
2414 if (imageViewTypes[viewTypeNdx].readOnly && testModes[testModeNdx].mode != TEST_MODE_READ_ONLY)
2415 continue;
2416
2417 for (int restrictColorNdx = 0; restrictColorNdx < DE_LENGTH_OF_ARRAY(interleaveReadWriteComponentsModes); restrictColorNdx++)
2418 {
2419 // 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.
2420 if (interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents &&
2421 testModes[testModeNdx].mode != TEST_MODE_READ_WRITE_SAME_PIXEL)
2422 continue;
2423
2424 // If the format is depth-only or stencil-only, do not read one component and write it to the other, as it is missing.
2425 if (interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents &&
2426 (tcu::hasDepthComponent(mapVkFormat(format).order) || tcu::hasStencilComponent(mapVkFormat(format).order)) && !isDepthStencil)
2427 continue;
2428
2429 std::string name = getFormatCaseName(format) + imageAspectTestModes[imageAspectTestMode] + testModes[testModeNdx].name + interleaveReadWriteComponentsModes[restrictColorNdx].name;
2430 formatTests->addChild(new AttachmentFeedbackLoopLayoutSamplerTest(testCtx, pipelineConstructionType, name.c_str(), "", viewType, format, outputImageSize, imageDescriptorType, 0.0f, testModes[testModeNdx].mode, imageAspectTestMode, interleaveReadWriteComponentsModes[restrictColorNdx].interleaveReadWriteComponents));
2431
2432 if (!isCompressed && isDepthStencil)
2433 {
2434 // Image is depth-stencil. Add the stencil case as well.
2435 std::string stencilTestName = getFormatCaseName(format) + imageAspectTestModes[IMAGE_ASPECT_TEST_STENCIL] + testModes[testModeNdx].name + interleaveReadWriteComponentsModes[restrictColorNdx].name;
2436 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));
2437 }
2438 }
2439 }
2440 }
2441
2442 viewTypeGroup->addChild(formatTests.release());
2443 imageTypeTests->addChild(viewTypeGroup.release());
2444 }
2445 imageDescriptorTypeGroup->addChild(imageTypeTests.release());
2446 samplingTypeTests->addChild(imageDescriptorTypeGroup.release());
2447 }
2448
2449 return samplingTypeTests.release();
2450 }
2451
createAttachmentFeedbackLoopLayoutTests(tcu::TestContext & testCtx,vk::PipelineConstructionType pipelineConstructionType)2452 tcu::TestCaseGroup* createAttachmentFeedbackLoopLayoutTests (tcu::TestContext& testCtx, vk::PipelineConstructionType pipelineConstructionType)
2453 {
2454 de::MovePtr<tcu::TestCaseGroup> attachmentFeedbackLoopLayoutTests(new tcu::TestCaseGroup(testCtx, "attachment_feedback_loop_layout", "VK_EXT_attachment_feedback_loop_layout tests"));
2455 {
2456 attachmentFeedbackLoopLayoutTests->addChild(createAttachmentFeedbackLoopLayoutSamplerTests(testCtx, pipelineConstructionType));
2457 }
2458
2459 return attachmentFeedbackLoopLayoutTests.release();
2460 }
2461
2462 } // pipeline
2463 } // vkt
2464