1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2023 LunarG, Inc. 6 * Copyright (c) 2023 Nintendo 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); 9 * you may not use this file except in compliance with the License. 10 * You may obtain a copy of the License at 11 * 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * See the License for the specific language governing permissions and 18 * limitations under the License. 19 * 20 *//*! 21 * \file 22 * \brief Shader Object Link Tests 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktShaderObjectRenderingTests.hpp" 26#include "deUniquePtr.hpp" 27#include "tcuTestCase.hpp" 28#include "vktTestCase.hpp" 29#include "vkCmdUtil.hpp" 30#include "vkImageUtil.hpp" 31#include "vktShaderObjectCreateUtil.hpp" 32#include "vkObjUtil.hpp" 33#include "deRandom.hpp" 34#include "vkBuilderUtil.hpp" 35#include "vkBarrierUtil.hpp" 36#include "tcuTextureUtil.hpp" 37#include "tcuImageCompare.hpp" 38#include "tcuVectorUtil.hpp" 39#include <cmath> 40 41namespace vkt 42{ 43namespace ShaderObject 44{ 45 46namespace 47{ 48 49enum ExtraAttachments { 50 NONE = 0, 51 BEFORE, 52 BETWEEN, 53 AFTER, 54}; 55 56enum DummyRenderPass 57{ 58 DUMMY_NONE = 0, 59 DUMMY_DYNAMIC, 60 DUMMY_STATIC, 61}; 62 63struct TestParams { 64 deUint32 colorAttachmentCount; 65 deUint32 extraAttachmentCount; 66 ExtraAttachments extraAttachments; 67 deUint32 extraFragmentOutputCount; 68 ExtraAttachments extraOutputs; 69 bool useDepthAttachment; 70 vk::VkFormat colorFormat; 71 vk::VkFormat depthFormat; 72 bool bindShadersBeforeBeginRendering; 73 DummyRenderPass dummyRenderPass; 74 bool writeGlFragDepth; 75 bool randomColorFormats; 76}; 77 78const vk::VkFormat colorFormats[] = 79{ 80 vk::VK_FORMAT_R4G4_UNORM_PACK8, 81 vk::VK_FORMAT_R4G4B4A4_UNORM_PACK16, 82 vk::VK_FORMAT_B4G4R4A4_UNORM_PACK16, 83 vk::VK_FORMAT_R5G6B5_UNORM_PACK16, 84 vk::VK_FORMAT_B5G6R5_UNORM_PACK16, 85 vk::VK_FORMAT_R5G5B5A1_UNORM_PACK16, 86 vk::VK_FORMAT_B5G5R5A1_UNORM_PACK16, 87 vk::VK_FORMAT_A1R5G5B5_UNORM_PACK16, 88 vk::VK_FORMAT_R8_UNORM, 89 vk::VK_FORMAT_R8_SNORM, 90 vk::VK_FORMAT_R8_USCALED, 91 vk::VK_FORMAT_R8_SSCALED, 92 vk::VK_FORMAT_R8_UINT, 93 vk::VK_FORMAT_R8_SINT, 94 vk::VK_FORMAT_R8_SRGB, 95 vk::VK_FORMAT_R8G8_UNORM, 96 vk::VK_FORMAT_R8G8_SNORM, 97 vk::VK_FORMAT_R8G8_USCALED, 98 vk::VK_FORMAT_R8G8_SSCALED, 99 vk::VK_FORMAT_R8G8_UINT, 100 vk::VK_FORMAT_R8G8_SINT, 101 vk::VK_FORMAT_R8G8_SRGB, 102 vk::VK_FORMAT_R8G8B8_UNORM, 103 vk::VK_FORMAT_R8G8B8_SNORM, 104 vk::VK_FORMAT_R8G8B8_USCALED, 105 vk::VK_FORMAT_R8G8B8_SSCALED, 106 vk::VK_FORMAT_R8G8B8_UINT, 107 vk::VK_FORMAT_R8G8B8_SINT, 108 vk::VK_FORMAT_R8G8B8_SRGB, 109 vk::VK_FORMAT_B8G8R8_UNORM, 110 vk::VK_FORMAT_B8G8R8_SNORM, 111 vk::VK_FORMAT_B8G8R8_USCALED, 112 vk::VK_FORMAT_B8G8R8_SSCALED, 113 vk::VK_FORMAT_B8G8R8_UINT, 114 vk::VK_FORMAT_B8G8R8_SINT, 115 vk::VK_FORMAT_B8G8R8_SRGB, 116 vk::VK_FORMAT_R8G8B8A8_UNORM, 117 vk::VK_FORMAT_R8G8B8A8_SNORM, 118 vk::VK_FORMAT_R8G8B8A8_USCALED, 119 vk::VK_FORMAT_R8G8B8A8_SSCALED, 120 vk::VK_FORMAT_R8G8B8A8_UINT, 121 vk::VK_FORMAT_R8G8B8A8_SINT, 122 vk::VK_FORMAT_R8G8B8A8_SRGB, 123 vk::VK_FORMAT_B8G8R8A8_UNORM, 124 vk::VK_FORMAT_B8G8R8A8_SNORM, 125 vk::VK_FORMAT_B8G8R8A8_USCALED, 126 vk::VK_FORMAT_B8G8R8A8_SSCALED, 127 vk::VK_FORMAT_B8G8R8A8_UINT, 128 vk::VK_FORMAT_B8G8R8A8_SINT, 129 vk::VK_FORMAT_B8G8R8A8_SRGB, 130 vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32, 131 vk::VK_FORMAT_A8B8G8R8_SNORM_PACK32, 132 vk::VK_FORMAT_A8B8G8R8_USCALED_PACK32, 133 vk::VK_FORMAT_A8B8G8R8_SSCALED_PACK32, 134 vk::VK_FORMAT_A8B8G8R8_UINT_PACK32, 135 vk::VK_FORMAT_A8B8G8R8_SINT_PACK32, 136 vk::VK_FORMAT_A8B8G8R8_SRGB_PACK32, 137 vk::VK_FORMAT_A2R10G10B10_UNORM_PACK32, 138 vk::VK_FORMAT_A2R10G10B10_SNORM_PACK32, 139 vk::VK_FORMAT_A2R10G10B10_USCALED_PACK32, 140 vk::VK_FORMAT_A2R10G10B10_SSCALED_PACK32, 141 vk::VK_FORMAT_A2R10G10B10_UINT_PACK32, 142 vk::VK_FORMAT_A2R10G10B10_SINT_PACK32, 143 vk::VK_FORMAT_A2B10G10R10_UNORM_PACK32, 144 vk::VK_FORMAT_A2B10G10R10_SNORM_PACK32, 145 vk::VK_FORMAT_A2B10G10R10_USCALED_PACK32, 146 vk::VK_FORMAT_A2B10G10R10_SSCALED_PACK32, 147 vk::VK_FORMAT_A2B10G10R10_UINT_PACK32, 148 vk::VK_FORMAT_A2B10G10R10_SINT_PACK32, 149 vk::VK_FORMAT_R16_UNORM, 150 vk::VK_FORMAT_R16_SNORM, 151 vk::VK_FORMAT_R16_USCALED, 152 vk::VK_FORMAT_R16_SSCALED, 153 vk::VK_FORMAT_R16_UINT, 154 vk::VK_FORMAT_R16_SINT, 155 vk::VK_FORMAT_R16_SFLOAT, 156 vk::VK_FORMAT_R16G16_UNORM, 157 vk::VK_FORMAT_R16G16_SNORM, 158 vk::VK_FORMAT_R16G16_USCALED, 159 vk::VK_FORMAT_R16G16_SSCALED, 160 vk::VK_FORMAT_R16G16_UINT, 161 vk::VK_FORMAT_R16G16_SINT, 162 vk::VK_FORMAT_R16G16_SFLOAT, 163 vk::VK_FORMAT_R16G16B16_UNORM, 164 vk::VK_FORMAT_R16G16B16_SNORM, 165 vk::VK_FORMAT_R16G16B16_USCALED, 166 vk::VK_FORMAT_R16G16B16_SSCALED, 167 vk::VK_FORMAT_R16G16B16_UINT, 168 vk::VK_FORMAT_R16G16B16_SINT, 169 vk::VK_FORMAT_R16G16B16_SFLOAT, 170 vk::VK_FORMAT_R16G16B16A16_UNORM, 171 vk::VK_FORMAT_R16G16B16A16_SNORM, 172 vk::VK_FORMAT_R16G16B16A16_USCALED, 173 vk::VK_FORMAT_R16G16B16A16_SSCALED, 174 vk::VK_FORMAT_R16G16B16A16_UINT, 175 vk::VK_FORMAT_R16G16B16A16_SINT, 176 vk::VK_FORMAT_R16G16B16A16_SFLOAT, 177 vk::VK_FORMAT_R32_UINT, 178 vk::VK_FORMAT_R32_SINT, 179 vk::VK_FORMAT_R32_SFLOAT, 180 vk::VK_FORMAT_R32G32_UINT, 181 vk::VK_FORMAT_R32G32_SINT, 182 vk::VK_FORMAT_R32G32_SFLOAT, 183 vk::VK_FORMAT_R32G32B32_UINT, 184 vk::VK_FORMAT_R32G32B32_SINT, 185 vk::VK_FORMAT_R32G32B32_SFLOAT, 186 vk::VK_FORMAT_R32G32B32A32_UINT, 187 vk::VK_FORMAT_R32G32B32A32_SINT, 188 vk::VK_FORMAT_R32G32B32A32_SFLOAT, 189}; 190 191const vk::VkFormat randomColorFormats[] = 192{ 193 vk::VK_FORMAT_R8_UNORM, 194 vk::VK_FORMAT_R8_SNORM, 195 vk::VK_FORMAT_R8G8_UNORM, 196 vk::VK_FORMAT_R8G8_SNORM, 197 vk::VK_FORMAT_R8G8B8A8_UNORM, 198 vk::VK_FORMAT_R8G8B8A8_SNORM, 199 vk::VK_FORMAT_A8B8G8R8_UNORM_PACK32, 200 vk::VK_FORMAT_A8B8G8R8_SNORM_PACK32, 201 vk::VK_FORMAT_R16_UNORM, 202 vk::VK_FORMAT_R16_SNORM, 203 vk::VK_FORMAT_R16G16_UNORM, 204 vk::VK_FORMAT_R16G16_SNORM, 205 vk::VK_FORMAT_R16G16_SFLOAT, 206 vk::VK_FORMAT_R16G16B16_UNORM, 207 vk::VK_FORMAT_R16G16B16_SNORM, 208 vk::VK_FORMAT_R16G16B16_SFLOAT, 209 vk::VK_FORMAT_R16G16B16A16_UNORM, 210 vk::VK_FORMAT_R16G16B16A16_SNORM, 211 vk::VK_FORMAT_R16G16B16A16_SFLOAT, 212 vk::VK_FORMAT_R32_SFLOAT, 213 vk::VK_FORMAT_R32G32_SFLOAT, 214 vk::VK_FORMAT_R32G32B32_SFLOAT, 215 vk::VK_FORMAT_R32G32B32A32_SFLOAT, 216}; 217 218de::MovePtr<tcu::TextureLevel> readDepthAttachment (const vk::DeviceInterface& vk, 219 vk::VkDevice device, 220 vk::VkQueue queue, 221 deUint32 queueFamilyIndex, 222 vk::Allocator& allocator, 223 vk::VkImage image, 224 vk::VkFormat format, 225 const tcu::UVec2& renderSize, 226 vk::VkImageLayout currentLayout) 227{ 228 vk::Move<vk::VkBuffer> buffer; 229 de::MovePtr<vk::Allocation> bufferAlloc; 230 vk::Move<vk::VkCommandPool> cmdPool; 231 vk::Move<vk::VkCommandBuffer> cmdBuffer; 232 233 tcu::TextureFormat retFormat (tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST); 234 tcu::TextureFormat bufferFormat (tcu::TextureFormat::D, tcu::TextureFormat::CHANNELTYPE_LAST); 235 const vk::VkImageAspectFlags barrierAspect = vk::VK_IMAGE_ASPECT_DEPTH_BIT | (mapVkFormat(format).order == tcu::TextureFormat::DS ? vk::VK_IMAGE_ASPECT_STENCIL_BIT : (vk::VkImageAspectFlagBits)0); 236 237 switch (format) 238 { 239 case vk::VK_FORMAT_D16_UNORM: 240 case vk::VK_FORMAT_D16_UNORM_S8_UINT: 241 bufferFormat.type = retFormat.type = tcu::TextureFormat::UNORM_INT16; 242 break; 243 case vk::VK_FORMAT_D24_UNORM_S8_UINT: 244 case vk::VK_FORMAT_X8_D24_UNORM_PACK32: 245 retFormat.type = tcu::TextureFormat::UNORM_INT24; 246 // vkCmdCopyBufferToImage copies D24 data to 32-bit pixels. 247 bufferFormat.type = tcu::TextureFormat::UNSIGNED_INT_24_8_REV; 248 break; 249 case vk::VK_FORMAT_D32_SFLOAT: 250 case vk::VK_FORMAT_D32_SFLOAT_S8_UINT: 251 bufferFormat.type = retFormat.type = tcu::TextureFormat::FLOAT; 252 break; 253 default: 254 TCU_FAIL("unrecognized format"); 255 } 256 257 const vk::VkDeviceSize pixelDataSize = renderSize.x() * renderSize.y() * bufferFormat.getPixelSize(); 258 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(retFormat, renderSize.x(), renderSize.y())); 259 260 // Create destination buffer 261 { 262 const vk::VkBufferCreateInfo bufferParams = 263 { 264 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 265 DE_NULL, // const void* pNext; 266 0u, // VkBufferCreateFlags flags; 267 pixelDataSize, // VkDeviceSize size; 268 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // VkBufferUsageFlags usage; 269 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 270 0u, // deUint32 queueFamilyIndexCount; 271 DE_NULL // const deUint32* pQueueFamilyIndices; 272 }; 273 274 buffer = createBuffer(vk, device, &bufferParams); 275 bufferAlloc = allocator.allocate(getBufferMemoryRequirements(vk, device, *buffer), vk::MemoryRequirement::HostVisible); 276 VK_CHECK(vk.bindBufferMemory(device, *buffer, bufferAlloc->getMemory(), bufferAlloc->getOffset())); 277 } 278 279 // Create command pool and buffer 280 cmdPool = createCommandPool(vk, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 281 cmdBuffer = allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY); 282 283 beginCommandBuffer(vk, *cmdBuffer); 284 copyImageToBuffer(vk, *cmdBuffer, image, *buffer, tcu::IVec2(renderSize.x(), renderSize.y()), vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, currentLayout, 1u, barrierAspect, vk::VK_IMAGE_ASPECT_DEPTH_BIT); 285 endCommandBuffer(vk, *cmdBuffer); 286 287 submitCommandsAndWait(vk, device, queue, cmdBuffer.get()); 288 289 // Read buffer data 290 invalidateAlloc(vk, device, *bufferAlloc); 291 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(bufferFormat, resultLevel->getSize(), bufferAlloc->getHostPtr())); 292 293 return resultLevel; 294} 295 296class ShaderObjectRenderingInstance : public vkt::TestInstance 297{ 298public: 299 ShaderObjectRenderingInstance (Context& context, const TestParams& params) 300 : vkt::TestInstance (context) 301 , m_params (params) 302 {} 303 virtual ~ShaderObjectRenderingInstance (void) {} 304 305 tcu::TestStatus iterate (void) override; 306private: 307 void beginRendering (vk::VkCommandBuffer cmdBuffer); 308 void createDummyImage (void); 309 void createDummyRenderPass (void); 310 void setColorFormats (const vk::InstanceDriver& vki); 311 void generateExpectedImage (const tcu::PixelBufferAccess& outputImage, const deUint32 width, const deUint32 height, deUint32 attachmentIndex); 312 313 TestParams m_params; 314 315 const vk::VkRect2D m_renderArea = vk::makeRect2D(0, 0, 32, 32); 316 std::vector<vk::VkFormat> m_colorFormats; 317 std::vector<vk::Move<vk::VkImageView>> m_colorImageViews; 318 vk::Move<vk::VkImageView> m_depthImageView; 319 320 de::MovePtr<vk::ImageWithMemory> m_dummyImage; 321 vk::Move<vk::VkImageView> m_dummyImageView; 322 vk::Move<vk::VkRenderPass> m_dummyRenderPass; 323 vk::Move<vk::VkFramebuffer> m_dummyFramebuffer; 324}; 325 326void ShaderObjectRenderingInstance::createDummyImage (void) 327{ 328 const vk::DeviceInterface& vk = m_context.getDeviceInterface(); 329 const vk::VkDevice device = m_context.getDevice(); 330 auto& alloc = m_context.getDefaultAllocator(); 331 const auto colorSubresourceRange = makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 332 333 vk::VkFormat format = m_params.colorFormat == vk::VK_FORMAT_R8G8B8A8_UNORM ? vk::VK_FORMAT_R32G32B32A32_SFLOAT : vk::VK_FORMAT_R8G8B8A8_UNORM; 334 335 const vk::VkImageCreateInfo createInfo = 336 { 337 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType 338 DE_NULL, // const void* pNext 339 0u, // VkImageCreateFlags flags 340 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType 341 format, // VkFormat format 342 { 32, 32, 1 }, // VkExtent3D extent 343 1u, // uint32_t mipLevels 344 1u, // uint32_t arrayLayers 345 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples 346 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling 347 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage 348 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 349 0, // uint32_t queueFamilyIndexCount 350 DE_NULL, // const uint32_t* pQueueFamilyIndices 351 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout 352 }; 353 354 m_dummyImage = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any)); 355 m_dummyImageView = vk::makeImageView(vk, device, **m_dummyImage, vk::VK_IMAGE_VIEW_TYPE_2D, format, colorSubresourceRange); 356} 357 358void ShaderObjectRenderingInstance::createDummyRenderPass (void) 359{ 360 const vk::DeviceInterface& vk = m_context.getDeviceInterface(); 361 const vk::VkDevice device = m_context.getDevice(); 362 vk::VkFormat format = m_params.colorFormat == vk::VK_FORMAT_R8G8B8A8_UNORM ? vk::VK_FORMAT_R32G32B32A32_SFLOAT : vk::VK_FORMAT_R8G8B8A8_UNORM; 363 m_dummyRenderPass = vk::makeRenderPass(vk, device, format); 364 m_dummyFramebuffer = vk::makeFramebuffer(vk, device, *m_dummyRenderPass, 1u, &*m_dummyImageView, m_renderArea.extent.width, m_renderArea.extent.height); 365} 366 367vk::VkClearValue getClearValue(const tcu::TextureFormat tcuFormat) 368{ 369 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(tcuFormat.type); 370 371 if (channelClass != tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER && channelClass != tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 372 return vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f }); 373 374 const tcu::IVec4 bits = tcu::min(tcu::getTextureFormatBitDepth(tcuFormat), tcu::IVec4(32)); 375 const int signBit = (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER ? 1 : 0); 376 377 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 378 return vk::makeClearValueColorU32(0u, 0u, 0u, deUint32((deUint64(1) << (bits[3] - signBit)) - 1)); 379 380 return vk::makeClearValueColorI32(0u, 0u, 0u, deInt32((deUint64(1) << (bits[3] - signBit)) - 1)); 381} 382 383void ShaderObjectRenderingInstance::beginRendering (vk::VkCommandBuffer cmdBuffer) 384{ 385 const vk::DeviceInterface& vk = m_context.getDeviceInterface(); 386 const vk::VkClearValue floatClearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f }); 387 const vk::VkClearValue clearDepthValue = vk::makeClearValueDepthStencil(1.0f, 0u); 388 389 vk::VkRenderingAttachmentInfo colorAttachment 390 { 391 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; 392 DE_NULL, // const void* pNext; 393 VK_NULL_HANDLE, // VkImageView imageView; 394 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout; 395 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; 396 DE_NULL, // VkImageView resolveImageView; 397 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; 398 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 399 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 400 floatClearValue // VkClearValue clearValue; 401 }; 402 403 deUint32 outputCount = m_params.colorAttachmentCount + m_params.extraFragmentOutputCount + m_params.extraAttachmentCount; 404 std::vector<vk::VkRenderingAttachmentInfo> colorAttachments(outputCount); 405 deUint32 i = 0; 406 if (m_params.extraOutputs == BEFORE || (m_params.extraOutputs == BETWEEN && m_params.colorAttachmentCount + m_params.extraAttachmentCount == 0)) 407 { 408 colorAttachment.imageView = VK_NULL_HANDLE; 409 for (deUint32 j = 0; j < m_params.extraFragmentOutputCount; ++j) 410 colorAttachments[i++] = colorAttachment; 411 } 412 for (deUint32 j = 0; j < m_params.colorAttachmentCount + m_params.extraAttachmentCount; ++j) 413 { 414 if (m_params.extraOutputs == BETWEEN && i == (m_params.colorAttachmentCount + m_params.extraAttachmentCount) / 2 + 1) 415 { 416 colorAttachment.imageView = VK_NULL_HANDLE; 417 for (deUint32 k = 0; k < m_params.extraFragmentOutputCount; ++k) 418 colorAttachments[i++] = colorAttachment; 419 } 420 colorAttachment.imageView = *m_colorImageViews[j]; 421 colorAttachment.clearValue = getClearValue(vk::mapVkFormat(m_colorFormats[j])); 422 423 colorAttachments[i++] = colorAttachment; 424 } 425 if (m_params.extraOutputs == AFTER || (m_params.extraOutputs == BETWEEN && m_params.colorAttachmentCount + m_params.extraAttachmentCount == 1)) 426 { 427 colorAttachment.imageView = VK_NULL_HANDLE; 428 for (deUint32 j = 0; j < m_params.extraFragmentOutputCount; ++j) 429 colorAttachments[i++] = colorAttachment; 430 } 431 432 vk::VkRenderingAttachmentInfo depthAttachment 433 { 434 vk::VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO_KHR, // VkStructureType sType; 435 DE_NULL, // const void* pNext; 436 *m_depthImageView, // VkImageView imageView; 437 vk::VK_IMAGE_LAYOUT_GENERAL, // VkImageLayout imageLayout; 438 vk::VK_RESOLVE_MODE_NONE, // VkResolveModeFlagBits resolveMode; 439 DE_NULL, // VkImageView resolveImageView; 440 vk::VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout resolveImageLayout; 441 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp; 442 vk::VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; 443 clearDepthValue // VkClearValue clearValue; 444 }; 445 446 vk::VkRenderingInfoKHR renderingInfo 447 { 448 vk::VK_STRUCTURE_TYPE_RENDERING_INFO_KHR, 449 DE_NULL, 450 (vk::VkRenderingFlags)0u, // VkRenderingFlagsKHR flags; 451 m_renderArea, // VkRect2D renderArea; 452 1u, // deUint32 layerCount; 453 0x0, // deUint32 viewMask; 454 (deUint32)colorAttachments.size(), // deUint32 colorAttachmentCount; 455 colorAttachments.data(), // const VkRenderingAttachmentInfoKHR* pColorAttachments; 456 m_params.useDepthAttachment ? &depthAttachment : DE_NULL, // const VkRenderingAttachmentInfoKHR* pDepthAttachment; 457 DE_NULL, // const VkRenderingAttachmentInfoKHR* pStencilAttachment; 458 }; 459 460 vk.cmdBeginRendering(cmdBuffer, &renderingInfo); 461} 462 463void ShaderObjectRenderingInstance::setColorFormats (const vk::InstanceDriver& vki) 464{ 465 const auto physicalDevice = m_context.getPhysicalDevice(); 466 467 m_colorFormats.resize(m_params.colorAttachmentCount + m_params.extraAttachmentCount); 468 if (m_params.randomColorFormats) 469 { 470 if (m_colorFormats.size() > 0) 471 { 472 m_colorFormats[0] = m_params.colorFormat; 473 } 474 de::Random random(102030); 475 for (deUint32 i = 1; i < (deUint32)m_colorFormats.size(); ++i) 476 { 477 if (i <= m_params.extraAttachmentCount && m_params.extraAttachments == BEFORE) 478 m_colorFormats[i] = m_params.colorFormat; 479 else 480 { 481 while (true) 482 { 483 // Find random color format, and make sure it is supported 484 vk::VkFormat format = randomColorFormats[random.getUint32() % DE_LENGTH_OF_ARRAY(randomColorFormats)]; 485 vk::VkImageFormatProperties colorImageFormatProperties; 486 const auto colorResult = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, format, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0, &colorImageFormatProperties); 487 if (colorResult == vk::VK_SUCCESS) 488 { 489 m_colorFormats[i] = format; 490 break; 491 } 492 } 493 } 494 } 495 } 496 else 497 { 498 for (auto& colorFormat : m_colorFormats) 499 colorFormat = m_params.colorFormat; 500 } 501} 502 503void ShaderObjectRenderingInstance::generateExpectedImage (const tcu::PixelBufferAccess& outputImage, const deUint32 width, const deUint32 height, deUint32 attachmentIndex) 504{ 505 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(outputImage.getFormat().type); 506 const vk::VkClearValue clearValue = getClearValue(outputImage.getFormat()); 507 508 const deUint32 xOffset = 8; 509 const deUint32 yOffset = 8; 510 511 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 512 tcu::clear(outputImage, tcu::UVec4(clearValue.color.uint32)); 513 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 514 tcu::clear(outputImage, tcu::IVec4(clearValue.color.int32)); 515 else 516 tcu::clear(outputImage, tcu::Vec4(clearValue.color.float32)); 517 518 if ((m_params.extraAttachments == BEFORE && attachmentIndex < m_params.extraAttachmentCount) || (m_params.extraAttachments == BETWEEN && attachmentIndex > m_params.colorAttachmentCount / 2u && attachmentIndex <= m_params.colorAttachmentCount / 2u + m_params.extraAttachmentCount) || (m_params.extraAttachments == AFTER && attachmentIndex >= m_params.colorAttachmentCount)) 519 return; 520 521 tcu::Vec4 setColor = tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f); 522 tcu::IVec4 setColorInt = tcu::IVec4(0, 0, 0, 0); 523 tcu::UVec4 setColorUint = tcu::UVec4(0u, 0u, 0u, 0u); 524 525 for (deInt32 i = 0; i < tcu::getNumUsedChannels(outputImage.getFormat().order); ++i) 526 { 527 setColor[i] = 1.0f; 528 setColorInt[i] = 255; 529 setColorUint[i] = 255u; 530 } 531 532 for (deUint32 j = 0; j < height; ++j) 533 { 534 for (deUint32 i = 0; i < width; ++i) 535 { 536 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset) 537 { 538 if (channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER) 539 outputImage.setPixel(setColorUint, i, j, 0); 540 else if (channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER) 541 outputImage.setPixel(setColorInt, i, j, 0); 542 else 543 outputImage.setPixel(setColor, i, j, 0); 544 } 545 } 546 } 547} 548 549tcu::TestStatus ShaderObjectRenderingInstance::iterate (void) 550{ 551 const vk::VkInstance instance = m_context.getInstance(); 552 const vk::InstanceDriver instanceDriver (m_context.getPlatformInterface(), instance); 553 const vk::DeviceInterface& vk = m_context.getDeviceInterface(); 554 const vk::VkDevice device = m_context.getDevice(); 555 const vk::VkQueue queue = m_context.getUniversalQueue(); 556 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex(); 557 auto& alloc = m_context.getDefaultAllocator(); 558 tcu::TestLog& log = m_context.getTestContext().getLog(); 559 const auto deviceExtensions = vk::removeUnsupportedShaderObjectExtensions(m_context.getInstanceInterface(), m_context.getPhysicalDevice(), m_context.getDeviceExtensions()); 560 const bool tessellationSupported = m_context.getDeviceFeatures().tessellationShader; 561 const bool geometrySupported = m_context.getDeviceFeatures().geometryShader; 562 const bool taskSupported = m_context.getMeshShaderFeatures().taskShader; 563 const bool meshSupported = m_context.getMeshShaderFeatures().meshShader; 564 565 const auto colorSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u); 566 auto depthSubresourceRange = vk::makeImageSubresourceRange(vk::VK_IMAGE_ASPECT_DEPTH_BIT, 0u, 1u, 0u, 1u); 567 if (m_params.useDepthAttachment && tcu::hasStencilComponent(mapVkFormat(m_params.depthFormat).order)) 568 depthSubresourceRange.aspectMask |= vk::VK_IMAGE_ASPECT_STENCIL_BIT; 569 const auto colorSubresourceLayers = vk::makeImageSubresourceLayers(vk::VK_IMAGE_ASPECT_COLOR_BIT, 0u, 0u, 1u); 570 vk::VkExtent3D extent = { m_renderArea.extent.width, m_renderArea.extent.height, 1}; 571 572 setColorFormats(instanceDriver); 573 574 vk::VkImageCreateInfo createInfo = 575 { 576 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType 577 DE_NULL, // const void* pNext 578 0u, // VkImageCreateFlags flags 579 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType 580 vk::VK_FORMAT_UNDEFINED, // VkFormat format 581 { 32, 32, 1 }, // VkExtent3D extent 582 1u, // uint32_t mipLevels 583 1u, // uint32_t arrayLayers 584 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples 585 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling 586 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage 587 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 588 0, // uint32_t queueFamilyIndexCount 589 DE_NULL, // const uint32_t* pQueueFamilyIndices 590 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout 591 }; 592 593 const vk::VkImageCreateInfo depthCreateInfo = 594 { 595 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType 596 DE_NULL, // const void* pNext 597 0u, // VkImageCreateFlags flags 598 vk::VK_IMAGE_TYPE_2D, // VkImageType imageType 599 m_params.depthFormat, // VkFormat format 600 { 32, 32, 1 }, // VkExtent3D extent 601 1u, // uint32_t mipLevels 602 1u, // uint32_t arrayLayers 603 vk::VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples 604 vk::VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling 605 vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage 606 vk::VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode 607 0, // uint32_t queueFamilyIndexCount 608 DE_NULL, // const uint32_t* pQueueFamilyIndices 609 vk::VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout 610 }; 611 612 deUint32 colorAttachmentCount = m_params.colorAttachmentCount + m_params.extraAttachmentCount; 613 std::vector<de::MovePtr<vk::ImageWithMemory>> colorImages (colorAttachmentCount); 614 m_colorImageViews.resize(colorAttachmentCount); 615 for (deUint32 i = 0; i < colorAttachmentCount; ++i) 616 { 617 createInfo.format = m_colorFormats[i]; 618 colorImages[i] = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, createInfo, vk::MemoryRequirement::Any)); 619 m_colorImageViews[i] = vk::makeImageView(vk, device, **colorImages[i], vk::VK_IMAGE_VIEW_TYPE_2D, createInfo.format, colorSubresourceRange); 620 } 621 622 de::MovePtr<vk::ImageWithMemory> depthImage; 623 if (m_params.useDepthAttachment) 624 { 625 depthImage = de::MovePtr<vk::ImageWithMemory>(new vk::ImageWithMemory(vk, device, alloc, depthCreateInfo, vk::MemoryRequirement::Any)); 626 m_depthImageView = vk::makeImageView(vk, device, **depthImage, vk::VK_IMAGE_VIEW_TYPE_2D, m_params.depthFormat, depthSubresourceRange); 627 } 628 629 std::vector<de::MovePtr<vk::BufferWithMemory>> colorOutputBuffers; 630 for (deUint32 i = 0; i < colorAttachmentCount; ++i) 631 { 632 const vk::VkDeviceSize colorOutputBufferSize = m_renderArea.extent.width * m_renderArea.extent.height * tcu::getPixelSize(vk::mapVkFormat(m_colorFormats[i])); 633 colorOutputBuffers.push_back(de::MovePtr<vk::BufferWithMemory>(new vk::BufferWithMemory( 634 vk, device, alloc, makeBufferCreateInfo(colorOutputBufferSize, vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT), vk::MemoryRequirement::HostVisible))); 635 } 636 637 const auto& binaries = m_context.getBinaryCollection(); 638 const auto vertShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_VERTEX_BIT, binaries.get("vertDepth"), tessellationSupported, geometrySupported)); 639 const auto fragShader = vk::createShader(vk, device, vk::makeShaderCreateInfo(vk::VK_SHADER_STAGE_FRAGMENT_BIT, binaries.get("fragMulti"), tessellationSupported, geometrySupported)); 640 641 const vk::Move<vk::VkCommandPool> cmdPool (vk::createCommandPool(vk, device, 0u, queueFamilyIndex)); 642 const vk::Move<vk::VkCommandBuffer> cmdBuffer (vk::allocateCommandBuffer(vk, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY)); 643 644 vk::beginCommandBuffer(vk, *cmdBuffer); 645 646 if (m_params.dummyRenderPass == DUMMY_DYNAMIC) 647 { 648 createDummyImage(); 649 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f }); 650 vk::beginRendering(vk, *cmdBuffer, *m_dummyImageView, m_renderArea, clearValue); 651 } 652 else if (m_params.dummyRenderPass == DUMMY_STATIC) 653 { 654 createDummyImage(); 655 createDummyRenderPass(); 656 const vk::VkClearValue clearValue = vk::makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f }); 657 vk::beginRenderPass(vk, *cmdBuffer, *m_dummyRenderPass, *m_dummyFramebuffer, m_renderArea, clearValue); 658 } 659 660 if (m_params.bindShadersBeforeBeginRendering) 661 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, *fragShader, taskSupported, meshSupported); 662 663 if (m_params.dummyRenderPass == DUMMY_DYNAMIC) 664 { 665 vk::endRendering(vk, *cmdBuffer); 666 } 667 else if (m_params.dummyRenderPass == DUMMY_STATIC) 668 { 669 vk::endRenderPass(vk, *cmdBuffer); 670 } 671 672 for (const auto& colorImage : colorImages) 673 { 674 vk::VkImageMemoryBarrier preImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **colorImage, colorSubresourceRange); 675 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preImageBarrier); 676 } 677 678 if (m_params.useDepthAttachment) 679 { 680 vk::VkImageMemoryBarrier preDepthImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_NONE, vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_IMAGE_LAYOUT_UNDEFINED, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange); 681 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &preDepthImageBarrier); 682 } 683 684 beginRendering(*cmdBuffer); 685 vk::setDefaultShaderObjectDynamicStates(vk, *cmdBuffer, deviceExtensions, vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP); 686 vk::VkBool32 colorBlendEnable = VK_FALSE; 687 vk::VkColorBlendEquationEXT colorBlendEquation = { 688 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor; 689 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor; 690 vk::VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp; 691 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor; 692 vk::VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor; 693 vk::VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp; 694 }; 695 vk::VkColorComponentFlags colorWriteMask = vk::VK_COLOR_COMPONENT_R_BIT | vk::VK_COLOR_COMPONENT_G_BIT | 696 vk::VK_COLOR_COMPONENT_B_BIT | vk::VK_COLOR_COMPONENT_A_BIT; 697 deUint32 count = colorAttachmentCount + m_params.extraFragmentOutputCount; 698 if (count == 0) ++count; 699 std::vector<vk::VkBool32> colorBlendEnables (count, colorBlendEnable); 700 std::vector<vk::VkColorBlendEquationEXT> colorBlendEquations (count, colorBlendEquation); 701 std::vector<vk::VkColorComponentFlags> colorWriteMasks (count, colorWriteMask); 702 vk.cmdSetColorBlendEnableEXT(*cmdBuffer, 0u, count, colorBlendEnables.data()); 703 vk.cmdSetColorBlendEquationEXT(*cmdBuffer, 0u, count, colorBlendEquations.data()); 704 vk.cmdSetColorWriteMaskEXT(*cmdBuffer, 0u, count, colorWriteMasks.data()); 705 std::vector<vk::VkBool32> colorWriteEnables (count, VK_TRUE); 706 vk.cmdSetColorWriteEnableEXT(*cmdBuffer, count, colorWriteEnables.data()); 707 vk.cmdSetDepthWriteEnable(*cmdBuffer, VK_TRUE); 708 vk.cmdSetDepthTestEnable(*cmdBuffer, VK_TRUE); 709 vk.cmdSetDepthCompareOp(*cmdBuffer, vk::VK_COMPARE_OP_LESS); 710 vk::bindNullTaskMeshShaders(vk, *cmdBuffer, m_context.getMeshShaderFeaturesEXT()); 711 if (!m_params.bindShadersBeforeBeginRendering) 712 vk::bindGraphicsShaders(vk, *cmdBuffer, *vertShader, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, *fragShader, taskSupported, meshSupported); 713 vk.cmdDraw(*cmdBuffer, 4, 1, 0, 0); 714 vk::endRendering(vk, *cmdBuffer); 715 716 for (const auto& colorImage : colorImages) 717 { 718 vk::VkImageMemoryBarrier postImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **colorImage, colorSubresourceRange); 719 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postImageBarrier); 720 } 721 722 if (m_params.useDepthAttachment) 723 { 724 vk::VkImageMemoryBarrier postDepthImageBarrier = vk::makeImageMemoryBarrier(vk::VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, vk::VK_ACCESS_TRANSFER_READ_BIT, vk::VK_IMAGE_LAYOUT_GENERAL, vk::VK_IMAGE_LAYOUT_GENERAL, **depthImage, depthSubresourceRange); 725 vk.cmdPipelineBarrier(*cmdBuffer, vk::VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0u, 0u, (const vk::VkMemoryBarrier*)DE_NULL, 0u, (const vk::VkBufferMemoryBarrier*)DE_NULL, 1u, &postDepthImageBarrier); 726 } 727 728 const vk::VkBufferImageCopy colorCopyRegion = vk::makeBufferImageCopy(extent, colorSubresourceLayers); 729 for (deUint32 i = 0; i < colorAttachmentCount; ++i) 730 vk.cmdCopyImageToBuffer(*cmdBuffer, **colorImages[i], vk::VK_IMAGE_LAYOUT_GENERAL, **colorOutputBuffers[i], 1u, &colorCopyRegion); 731 732 vk::endCommandBuffer(vk, *cmdBuffer); 733 734 vk::submitCommandsAndWait(vk, device, queue, *cmdBuffer); 735 736 std::vector<tcu::ConstPixelBufferAccess> colorResultBuffers; 737 for (deUint32 i = 0; i < colorAttachmentCount; ++i) 738 colorResultBuffers.push_back(tcu::ConstPixelBufferAccess(vk::mapVkFormat(m_colorFormats[i]), m_renderArea.extent.width, m_renderArea.extent.height, 1, (const void*)colorOutputBuffers[i]->getAllocation().getHostPtr())); 739 740 const deUint32 width = m_renderArea.extent.width; 741 const deUint32 height = m_renderArea.extent.height; 742 const deUint32 xOffset = 8; 743 const deUint32 yOffset = 8; 744 745 for (deUint32 k = 0; k < (deUint32)colorImages.size(); ++k) 746 { 747 tcu::TextureLevel textureLevel (mapVkFormat(m_colorFormats[k]), width, height); 748 const tcu::PixelBufferAccess expectedImage = textureLevel.getAccess(); 749 generateExpectedImage(expectedImage, width, height, k); 750 751 if (vk::isFloatFormat(m_colorFormats[k])) 752 { 753 if (!tcu::floatThresholdCompare(log, "Image Comparison", "", expectedImage, colorResultBuffers[k], tcu::Vec4(0.02f), tcu::COMPARE_LOG_RESULT)) 754 return tcu::TestStatus::fail("Fail"); 755 } 756 else 757 { 758 if (!tcu::intThresholdCompare(log, "Image Comparison", "", expectedImage, colorResultBuffers[k], tcu::UVec4(2), tcu::COMPARE_LOG_RESULT)) 759 return tcu::TestStatus::fail("Fail"); 760 } 761 } 762 763 if (m_params.useDepthAttachment) 764 { 765 const auto depthBuffer = readDepthAttachment(vk, device, queue, queueFamilyIndex, alloc, **depthImage, m_params.depthFormat, tcu::UVec2(m_renderArea.extent.width, m_renderArea.extent.height), vk::VK_IMAGE_LAYOUT_GENERAL); 766 const auto depthAccess = depthBuffer->getAccess(); 767 768 const float depthEpsilon = 0.02f; 769 for (deUint32 j = 0; j < height; ++j) 770 { 771 for (deUint32 i = 0; i < width; ++i) 772 { 773 const float depth = depthAccess.getPixDepth(i, j); 774 if (i >= xOffset && i < width - xOffset && j >= yOffset && j < height - yOffset) 775 { 776 if (deFloatAbs(depth - 0.5f) > depthEpsilon) 777 { 778 log << tcu::TestLog::Message << "Depth at (" << i << ", " << j << ") is expected to be 0.5, but was (" << depth << ")" << tcu::TestLog::EndMessage; 779 return tcu::TestStatus::fail("Fail"); 780 } 781 } 782 else 783 { 784 if (deFloatAbs(depth - 1.0f) > depthEpsilon) 785 { 786 log << tcu::TestLog::Message << "Color at (" << i << ", " << j << ") is expected to be 0.0, but was (" << depth << ")" << tcu::TestLog::EndMessage; 787 return tcu::TestStatus::fail("Fail"); 788 } 789 } 790 } 791 } 792 } 793 794 return tcu::TestStatus::pass("Pass"); 795} 796 797class ShaderObjectRenderingCase : public vkt::TestCase 798{ 799public: 800 ShaderObjectRenderingCase (tcu::TestContext& testCtx, const std::string& name, const TestParams& params) 801 : vkt::TestCase (testCtx, name) 802 , m_params (params) 803 {} 804 virtual ~ShaderObjectRenderingCase (void) {} 805 806 void checkSupport (vkt::Context& context) const override; 807 virtual void initPrograms (vk::SourceCollections& programCollection) const override; 808 TestInstance* createInstance (Context& context) const override { return new ShaderObjectRenderingInstance(context, m_params); } 809private: 810 TestParams m_params; 811}; 812 813void ShaderObjectRenderingCase::checkSupport (Context& context) const 814{ 815 const auto& vki = context.getInstanceInterface(); 816 const auto physicalDevice = context.getPhysicalDevice(); 817 const vk::VkPhysicalDeviceProperties properties = vk::getPhysicalDeviceProperties(vki, physicalDevice); 818 819 context.requireDeviceFunctionality("VK_EXT_shader_object"); 820 821 if (m_params.colorAttachmentCount + m_params.extraAttachmentCount + m_params.extraFragmentOutputCount > properties.limits.maxColorAttachments) 822 TCU_THROW(NotSupportedError, "Tests uses more color attachments than VkPhysicalDeviceLimits::maxColorAttachments"); 823 824 vk::VkImageFormatProperties colorImageFormatProperties; 825 const auto colorResult = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_params.colorFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, (vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0, &colorImageFormatProperties); 826 if (colorResult != vk::VK_SUCCESS) 827 TCU_THROW(NotSupportedError, "Format unsupported for tiling"); 828 vk::VkImageFormatProperties depthImageFormatProperties; 829 if (m_params.useDepthAttachment) 830 { 831 const auto depthResult = vki.getPhysicalDeviceImageFormatProperties(physicalDevice, m_params.depthFormat, vk::VK_IMAGE_TYPE_2D, vk::VK_IMAGE_TILING_OPTIMAL, (vk::VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT), 0, &depthImageFormatProperties); 832 if (depthResult != vk::VK_SUCCESS) 833 TCU_THROW(NotSupportedError, "Format unsupported for tiling"); 834 } 835} 836 837void ShaderObjectRenderingCase::initPrograms (vk::SourceCollections& programCollection) const 838{ 839 std::stringstream vertDepth; 840 std::stringstream fragMulti; 841 842 vertDepth 843 << "#version 450\n" 844 << "void main() {\n" 845 << " vec2 pos = vec2(float(gl_VertexIndex & 1), float((gl_VertexIndex >> 1) & 1));\n" 846 << " gl_Position = vec4(pos - 0.5f, 0.5f, 1.0f);\n" 847 << "}\n"; 848 849 fragMulti 850 << "#version 450\n"; 851 deUint32 outputCount = m_params.colorAttachmentCount + m_params.extraFragmentOutputCount; 852 for (deUint32 i = 0; i < outputCount; ++i) 853 { 854 deUint32 j = i; 855 if (m_params.extraAttachments == BEFORE || (m_params.extraAttachments == BETWEEN && i > outputCount / 2)) 856 j += m_params.extraAttachmentCount; 857 bool firstWrittenAttachment = (m_params.extraOutputs == BEFORE) ? (i == m_params.extraFragmentOutputCount) : (i == 0); 858 if (vk::isUintFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats)) 859 fragMulti << "layout (location = " << j << ") out uvec4 outColor" << j << ";\n"; 860 else if (vk::isIntFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats)) 861 fragMulti << "layout (location = " << j << ") out ivec4 outColor" << j << ";\n"; 862 else 863 fragMulti << "layout (location = " << j << ") out vec4 outColor" << j << ";\n"; 864 } 865 fragMulti 866 << "void main() {\n"; 867 for (deUint32 i = 0; i < outputCount; ++i) 868 { 869 deUint32 j = i; 870 if (m_params.extraAttachments == BEFORE || (m_params.extraAttachments == BETWEEN && i > outputCount / 2)) 871 j += m_params.extraAttachmentCount; 872 bool firstWrittenAttachment = (m_params.extraOutputs == BEFORE) ? (i == m_params.extraFragmentOutputCount) : (i == 0); 873 if (vk::isUintFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats)) 874 fragMulti << " outColor" << j << " = uvec4(255);\n"; 875 else if (vk::isIntFormat(m_params.colorFormat) && (firstWrittenAttachment || !m_params.randomColorFormats)) 876 fragMulti << " outColor" << j << " = ivec4(255);\n"; 877 else 878 fragMulti << " outColor" << j << " = vec4(1.0f);\n"; 879 } 880 if (m_params.writeGlFragDepth) 881 fragMulti 882 << " gl_FragDepth = 0.5f;\n"; 883 fragMulti 884 << "}\n"; 885 886 programCollection.glslSources.add("vertDepth") << glu::VertexSource(vertDepth.str()); 887 programCollection.glslSources.add("fragMulti") << glu::FragmentSource(fragMulti.str()); 888} 889 890} 891 892std::string getFormatCaseName(vk::VkFormat format) 893{ 894 return de::toLower(de::toString(getFormatStr(format)).substr(10)); 895} 896 897tcu::TestCaseGroup* createShaderObjectRenderingTests (tcu::TestContext& testCtx) 898{ 899 de::MovePtr<tcu::TestCaseGroup> renderingGroup(new tcu::TestCaseGroup(testCtx, "rendering")); 900 901 const struct 902 { 903 deUint32 colorAttachmentCount; 904 const char* name; 905 } colorAttachmentCountTests[] = 906 { 907 { 0u, "color_attachment_count_0", }, 908 { 1u, "color_attachment_count_1", }, 909 { 4u, "color_attachment_count_4", }, 910 { 8u, "color_attachment_count_8", }, 911 }; 912 913 const struct 914 { 915 deUint32 extraAttachmentCount; 916 ExtraAttachments extraAttachment; 917 const char* name; 918 } extraAttachmentTests[] = 919 { 920 { 0u, NONE, "none", }, 921 { 1u, BEFORE, "extra_attachment_before_1", }, 922 { 1u, BETWEEN, "extra_attachment_between_1", }, 923 { 1u, AFTER, "extra_attachment_after_1", }, 924 { 2u, BEFORE, "extra_attachment_before_2", }, 925 { 2u, BETWEEN, "extra_attachment_between_2", }, 926 { 2u, AFTER, "extra_attachment_after_2", }, 927 }; 928 929 const struct 930 { 931 deUint32 extraFragmentOutputCount; 932 ExtraAttachments extraAttachment; 933 const char* name; 934 } extraOutputTests[] = 935 { 936 { 0u, NONE, "none", }, 937 { 1u, BEFORE, "extra_output_before_1", }, 938 { 1u, BETWEEN, "extra_output_between_1", }, 939 { 1u, AFTER, "extra_output_after_1", }, 940 { 2u, BEFORE, "extra_output_before_2", }, 941 { 2u, BETWEEN, "extra_output_between_2", }, 942 { 2u, AFTER, "extra_output_after_2", }, 943 }; 944 945 const vk::VkFormat depthStencilFormats[] = 946 { 947 vk::VK_FORMAT_D16_UNORM, 948 vk::VK_FORMAT_X8_D24_UNORM_PACK32, 949 vk::VK_FORMAT_D32_SFLOAT, 950 vk::VK_FORMAT_D16_UNORM_S8_UINT, 951 vk::VK_FORMAT_D24_UNORM_S8_UINT, 952 vk::VK_FORMAT_D32_SFLOAT_S8_UINT, 953 }; 954 955 const struct 956 { 957 DummyRenderPass dummyRenderPass; 958 const char* name; 959 } dummyRenderPassTests[] = 960 { 961 { DUMMY_NONE, "none", }, 962 { DUMMY_DYNAMIC, "dynamic", }, 963 { DUMMY_STATIC, "static", }, 964 }; 965 966 for (const auto& colorAttachmentCountTest : colorAttachmentCountTests) 967 { 968 de::MovePtr<tcu::TestCaseGroup> colorAttachmentGroup(new tcu::TestCaseGroup(testCtx, colorAttachmentCountTest.name)); 969 for (const auto& extraAttachment : extraAttachmentTests) 970 { 971 de::MovePtr<tcu::TestCaseGroup> extraAttachmentGroup(new tcu::TestCaseGroup(testCtx, extraAttachment.name)); 972 for (const auto& extraOutput : extraOutputTests) 973 { 974 if (extraAttachment.extraAttachment != NONE && extraOutput.extraFragmentOutputCount != NONE) 975 continue; 976 977 de::MovePtr<tcu::TestCaseGroup> extraOutputGroup(new tcu::TestCaseGroup(testCtx, extraOutput.name)); 978 979 for (const auto& dummyRenderPass : dummyRenderPassTests) 980 { 981 de::MovePtr<tcu::TestCaseGroup> dummyRenderPassGroup(new tcu::TestCaseGroup(testCtx, dummyRenderPass.name)); 982 for (deUint32 m = 0; m < 2; ++m) 983 { 984 bool useRandomColorFormats = m == 0; 985 if (useRandomColorFormats && colorAttachmentCountTest.colorAttachmentCount < 2) 986 continue; 987 std::string randomColorFormatsName = useRandomColorFormats ? "random_color_formats" : "same_color_formats"; 988 de::MovePtr<tcu::TestCaseGroup> randomColorFormatsGroup(new tcu::TestCaseGroup(testCtx, randomColorFormatsName.c_str())); 989 for (deUint32 k = 0; k < 2; ++k) 990 { 991 bool bindShadersBeforeBeginRendering = k == 0; 992 std::string bindName = bindShadersBeforeBeginRendering ? "before" : "after"; 993 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, bindName.c_str())); 994 for (deUint32 l = 0; l < 2; ++l) 995 { 996 bool writeGlFragDepth = l == 0; 997 std::string writeGlFragName = writeGlFragDepth ? "gl_frag_write" : "none"; 998 de::MovePtr<tcu::TestCaseGroup> fragWriteGroup(new tcu::TestCaseGroup(testCtx, writeGlFragName.c_str())); 999 for (deUint32 i = 0; i < DE_LENGTH_OF_ARRAY(colorFormats); ++i) 1000 { 1001 if (extraAttachment.extraAttachmentCount > colorAttachmentCountTest.colorAttachmentCount) 1002 continue; 1003 1004 if (!bindShadersBeforeBeginRendering && dummyRenderPass.dummyRenderPass != DUMMY_NONE) 1005 continue; 1006 1007 const auto colorFormat = colorFormats[i]; 1008 1009 TestParams params; 1010 params.colorAttachmentCount = colorAttachmentCountTest.colorAttachmentCount; 1011 params.extraAttachmentCount = extraAttachment.extraAttachmentCount; 1012 params.extraAttachments = extraAttachment.extraAttachment; 1013 params.extraFragmentOutputCount = extraOutput.extraFragmentOutputCount; 1014 params.extraOutputs = extraOutput.extraAttachment; 1015 params.useDepthAttachment = false; 1016 params.colorFormat = colorFormat; 1017 params.depthFormat = vk::VK_FORMAT_UNDEFINED; 1018 params.bindShadersBeforeBeginRendering = bindShadersBeforeBeginRendering; 1019 params.dummyRenderPass = dummyRenderPass.dummyRenderPass; 1020 params.writeGlFragDepth = writeGlFragDepth; 1021 params.randomColorFormats = useRandomColorFormats; 1022 1023 std::string name = getFormatCaseName(colorFormat); 1024 fragWriteGroup->addChild(new ShaderObjectRenderingCase(testCtx, name, params)); 1025 1026 if (writeGlFragDepth) 1027 continue; 1028 1029 for (deUint32 j = 0; j < DE_LENGTH_OF_ARRAY(depthStencilFormats); ++j) 1030 { 1031 const auto depthFormat = depthStencilFormats[j]; 1032 params.useDepthAttachment = true; 1033 params.depthFormat = depthFormat; 1034 1035 std::string depthTestName = name + "_" + getFormatCaseName(depthFormat); 1036 fragWriteGroup->addChild(new ShaderObjectRenderingCase(testCtx, depthTestName, params)); 1037 } 1038 } 1039 bindGroup->addChild(fragWriteGroup.release()); 1040 } 1041 randomColorFormatsGroup->addChild(bindGroup.release()); 1042 } 1043 dummyRenderPassGroup->addChild(randomColorFormatsGroup.release()); 1044 } 1045 extraOutputGroup->addChild(dummyRenderPassGroup.release()); 1046 } 1047 extraAttachmentGroup->addChild(extraOutputGroup.release()); 1048 } 1049 colorAttachmentGroup->addChild(extraAttachmentGroup.release()); 1050 } 1051 renderingGroup->addChild(colorAttachmentGroup.release()); 1052 } 1053 1054 return renderingGroup.release(); 1055} 1056 1057} // ShaderObject 1058} // vkt 1059