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