1/*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2015 The Khronos Group Inc. 6 * Copyright (c) 2015 Samsung Electronics Co., Ltd. 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 Vulkan Buffer View Memory Tests 23 *//*--------------------------------------------------------------------*/ 24 25#include "vktApiBufferViewAccessTests.hpp" 26#include "vktApiBufferAndImageAllocationUtil.hpp" 27 28#include "deStringUtil.hpp" 29#include "deUniquePtr.hpp" 30#include "vktTestCase.hpp" 31#include "vktTestCaseUtil.hpp" 32#include "vkImageUtil.hpp" 33#include "vkMemUtil.hpp" 34#include "vkPrograms.hpp" 35#include "vkQueryUtil.hpp" 36#include "vkRef.hpp" 37#include "vkRefUtil.hpp" 38#include "vkTypeUtil.hpp" 39#include "vkCmdUtil.hpp" 40#include "vkObjUtil.hpp" 41#include "tcuImageCompare.hpp" 42#include "tcuTexture.hpp" 43#include "tcuTextureUtil.hpp" 44#include "deSharedPtr.hpp" 45#include "deArrayUtil.hpp" 46#include "tcuVectorUtil.hpp" 47#include "../image/vktImageTestsUtil.hpp" 48 49namespace vkt 50{ 51 52namespace api 53{ 54 55using namespace vk; 56 57namespace 58{ 59 60enum AllocationKind 61{ 62 ALLOCATION_KIND_SUBALLOCATION = 0, 63 ALLOCATION_KIND_DEDICATED = 1, 64 ALLOCATION_KIND_LAST 65}; 66 67struct BufferViewCaseParams 68{ 69 deUint32 bufferSize; 70 deUint32 bufferViewSize; 71 deUint32 elementOffset; 72 AllocationKind bufferAllocationKind; 73 AllocationKind imageAllocationKind; 74 75 VkFormat format; 76 VkBufferUsageFlags createUsage; 77 VkBufferUsageFlags bindUsage; 78 VkFormatFeatureFlags feature; 79 VkDescriptorType descType; 80 81 BufferViewCaseParams (deUint32 bufferSize_, 82 deUint32 bufferViewSize_, 83 deUint32 elementOffset_, 84 AllocationKind bufferAllocKind_, 85 AllocationKind imageAllocKind_, 86 VkFormat format_ = VK_FORMAT_R32_UINT, 87 VkBufferUsageFlags createUsage_ = VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, 88 VkBufferUsageFlags bindUsage_ = VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM, 89 VkFormatFeatureFlags featureFlags_ = VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, 90 VkDescriptorType descType_ = VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER) 91 : bufferSize(bufferSize_) 92 , bufferViewSize(bufferViewSize_) 93 , elementOffset(elementOffset_) 94 , bufferAllocationKind(bufferAllocKind_) 95 , imageAllocationKind(imageAllocKind_) 96 , format(format_) 97 , createUsage(createUsage_) 98 , bindUsage(bindUsage_) 99 , feature(featureFlags_) 100 , descType(descType_) 101 { 102 } 103}; 104 105class BufferViewTestInstance : public vkt::TestInstance 106{ 107public: 108 BufferViewTestInstance (Context& context, 109 BufferViewCaseParams testCase); 110 virtual ~BufferViewTestInstance (void); 111 virtual tcu::TestStatus iterate (void); 112 113private: 114 void createQuad (void); 115 tcu::TestStatus checkResult (deInt8 factor); 116 117private: 118 BufferViewCaseParams m_testCase; 119 120 const tcu::IVec2 m_renderSize; 121 const VkFormat m_colorFormat; 122 123 const VkDeviceSize m_pixelDataSize; 124 125 Move<VkImage> m_colorImage; 126 de::MovePtr<Allocation> m_colorImageAlloc; 127 Move<VkImageView> m_colorAttachmentView; 128 Move<VkRenderPass> m_renderPass; 129 Move<VkFramebuffer> m_framebuffer; 130 131 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 132 Move<VkDescriptorPool> m_descriptorPool; 133 Move<VkDescriptorSet> m_descriptorSet; 134 135 Move<VkBuffer> m_uniformBuffer; 136 de::MovePtr<vk::Allocation> m_uniformBufferAlloc; 137 Move<VkBufferView> m_uniformBufferView; 138 139 Move<VkShaderModule> m_vertexShaderModule; 140 Move<VkShaderModule> m_fragmentShaderModule; 141 142 Move<VkBuffer> m_vertexBuffer; 143 std::vector<tcu::Vec4> m_vertices; 144 de::MovePtr<Allocation> m_vertexBufferAlloc; 145 146 Move<VkPipelineLayout> m_pipelineLayout; 147 Move<VkPipeline> m_graphicsPipelines; 148 149 Move<VkCommandPool> m_cmdPool; 150 Move<VkCommandBuffer> m_cmdBuffer; 151 152 Move<VkBuffer> m_resultBuffer; 153 de::MovePtr<Allocation> m_resultBufferAlloc; 154}; 155 156static void generateBuffer (std::vector<deUint32>& uniformData, 157 deUint32 bufferSize, 158 deInt8 factor) 159{ 160 for (deUint32 i = 0; i < bufferSize; ++i) 161 uniformData.push_back(factor * i); 162} 163 164void BufferViewTestInstance::createQuad (void) 165{ 166 tcu::Vec4 a(-1.0, -1.0, 0.0, 1.0); 167 tcu::Vec4 b(1.0, -1.0, 0.0, 1.0); 168 tcu::Vec4 c(1.0, 1.0, 0.0, 1.0); 169 tcu::Vec4 d(-1.0, 1.0, 0.0, 1.0); 170 171 // Triangle 1 172 m_vertices.push_back(a); 173 m_vertices.push_back(c); 174 m_vertices.push_back(b); 175 176 // Triangle 2 177 m_vertices.push_back(c); 178 m_vertices.push_back(a); 179 m_vertices.push_back(d); 180} 181 182BufferViewTestInstance::~BufferViewTestInstance (void) 183{ 184} 185 186BufferViewTestInstance::BufferViewTestInstance (Context& context, 187 BufferViewCaseParams testCase) 188 : vkt::TestInstance (context) 189 , m_testCase (testCase) 190 , m_renderSize (testCase.bufferViewSize, testCase.bufferViewSize) 191 , m_colorFormat (VK_FORMAT_R32_UINT) 192 , m_pixelDataSize (m_renderSize.x() * m_renderSize.y() * mapVkFormat(m_colorFormat).getPixelSize()) 193{ 194 const DeviceInterface& vk = context.getDeviceInterface(); 195 const VkDevice vkDevice = context.getDevice(); 196 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 197 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 198 const VkComponentMapping channelMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A }; 199 200 // Create color image 201 if (m_testCase.imageAllocationKind == ALLOCATION_KIND_DEDICATED) 202 { 203 ImageDedicatedAllocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage, MemoryRequirement::Any, m_colorImageAlloc); 204 } 205 else 206 { 207 ImageSuballocation().createTestImage(m_renderSize, m_colorFormat, context, memAlloc, m_colorImage, MemoryRequirement::Any, m_colorImageAlloc); 208 } 209 210 // Create destination buffer 211 if (m_testCase.bufferAllocationKind == ALLOCATION_KIND_DEDICATED) 212 { 213 BufferDedicatedAllocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc); 214 } 215 else 216 { 217 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, m_pixelDataSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc); 218 } 219 220 // Create color attachment view 221 { 222 const VkImageViewCreateInfo colorAttachmentViewParams = 223 { 224 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 225 DE_NULL, // const void* pNext; 226 0u, // VkImageViewCreateFlags flags; 227 *m_colorImage, // VkImage image; 228 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType; 229 m_colorFormat, // VkFormat format; 230 channelMappingRGBA, // VkChannelMapping channels; 231 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }, // VkImageSubresourceRange subresourceRange; 232 }; 233 234 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams); 235 } 236 237 // Create render pass 238 m_renderPass = makeRenderPass(vk, vkDevice, m_colorFormat); 239 240 // Create framebuffer 241 { 242 const VkImageView attachmentBindInfos[1] = 243 { 244 *m_colorAttachmentView, 245 }; 246 247 const VkFramebufferCreateInfo framebufferParams = 248 { 249 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 250 DE_NULL, // const void* pNext; 251 (VkFramebufferCreateFlags)0, 252 *m_renderPass, // VkRenderPass renderPass; 253 1u, // deUint32 attachmentCount; 254 attachmentBindInfos, // const VkImageView* pAttachments; 255 (deUint32)m_renderSize.x(), // deUint32 width; 256 (deUint32)m_renderSize.y(), // deUint32 height; 257 1u // deUint32 layers; 258 }; 259 260 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams); 261 } 262 263 // Create descriptors 264 { 265 const VkDescriptorSetLayoutBinding 266 layoutBindings[1] = 267 { 268 { 269 0u, // deUint32 binding; 270 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType descriptorType; 271 1u, // deUint32 arraySize; 272 VK_SHADER_STAGE_ALL, // VkShaderStageFlags stageFlags; 273 DE_NULL // const VkSampler* pImmutableSamplers; 274 }, 275 }; 276 277 const VkDescriptorSetLayoutCreateInfo 278 descriptorLayoutParams = 279 { 280 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType; 281 DE_NULL, // const void* pNext; 282 (VkDescriptorSetLayoutCreateFlags)0, 283 DE_LENGTH_OF_ARRAY(layoutBindings), // deUint32 count; 284 layoutBindings // const VkDescriptorSetLayoutBinding pBinding; 285 }; 286 287 m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams); 288 289 // Generate buffer 290 std::vector<deUint32> uniformData; 291 generateBuffer(uniformData, testCase.bufferSize, 1); 292 293 const VkDeviceSize uniformSize = testCase.bufferSize * sizeof(deUint32); 294 295 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, uniformSize, testCase.createUsage, m_context, memAlloc, m_uniformBuffer, MemoryRequirement::HostVisible, m_uniformBufferAlloc); 296 deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize); 297 flushAlloc(vk, vkDevice, *m_uniformBufferAlloc); 298 299 const VkBufferViewCreateInfo viewInfo = 300 { 301 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType; 302 DE_NULL, // void* pNext; 303 (VkBufferViewCreateFlags)0, 304 *m_uniformBuffer, // VkBuffer buffer; 305 m_colorFormat, // VkFormat format; 306 m_testCase.elementOffset * sizeof(deUint32), // VkDeviceSize offset; 307 m_testCase.bufferViewSize * sizeof(deUint32) // VkDeviceSize range; 308 }; 309 310 m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo); 311 312 const VkDescriptorPoolSize descriptorTypes[1] = 313 { 314 { 315 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType type; 316 1 // deUint32 count; 317 } 318 }; 319 320 const VkDescriptorPoolCreateInfo 321 descriptorPoolParams = 322 { 323 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType; 324 DE_NULL, // void* pNext; 325 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags; 326 1u, // uint32_t maxSets; 327 DE_LENGTH_OF_ARRAY(descriptorTypes), // deUint32 count; 328 descriptorTypes // const VkDescriptorTypeCount* pTypeCount 329 }; 330 331 m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams); 332 333 const VkDescriptorSetAllocateInfo 334 descriptorSetParams = 335 { 336 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 337 DE_NULL, 338 *m_descriptorPool, 339 1u, 340 &m_descriptorSetLayout.get(), 341 }; 342 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams); 343 344 const VkWriteDescriptorSet writeDescritporSets[] = 345 { 346 { 347 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType; 348 DE_NULL, // const void* pNext; 349 *m_descriptorSet, // VkDescriptorSet destSet; 350 0, // deUint32 destBinding; 351 0, // deUint32 destArrayElement; 352 1u, // deUint32 count; 353 VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, // VkDescriptorType descriptorType; 354 (const VkDescriptorImageInfo*)DE_NULL, 355 (const VkDescriptorBufferInfo*)DE_NULL, 356 &m_uniformBufferView.get(), 357 } 358 }; 359 360 vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL); 361 } 362 363 // Create pipeline layout 364 { 365 const VkPipelineLayoutCreateInfo 366 pipelineLayoutParams = 367 { 368 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 369 DE_NULL, // const void* pNext; 370 (VkPipelineLayoutCreateFlags)0, 371 1u, // deUint32 descriptorSetCount; 372 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 373 0u, // deUint32 pushConstantRangeCount; 374 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 375 }; 376 377 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 378 } 379 380 // Create shaders 381 { 382 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("vert"), 0); 383 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("frag"), 0); 384 } 385 386 // Create pipeline 387 { 388 const std::vector<VkViewport> viewports (1, makeViewport(m_renderSize)); 389 const std::vector<VkRect2D> scissors (1, makeRect2D(m_renderSize)); 390 391 m_graphicsPipelines = makeGraphicsPipeline(vk, // const DeviceInterface& vk 392 vkDevice, // const VkDevice device 393 *m_pipelineLayout, // const VkPipelineLayout pipelineLayout 394 *m_vertexShaderModule, // const VkShaderModule vertexShaderModule 395 DE_NULL, // const VkShaderModule tessellationControlModule 396 DE_NULL, // const VkShaderModule tessellationEvalModule 397 DE_NULL, // const VkShaderModule geometryShaderModule 398 *m_fragmentShaderModule, // const VkShaderModule fragmentShaderModule 399 *m_renderPass, // const VkRenderPass renderPass 400 viewports, // const std::vector<VkViewport>& viewports 401 scissors); // const std::vector<VkRect2D>& scissors 402 } 403 404 // Create vertex buffer 405 { 406 createQuad(); 407 const VkDeviceSize vertexDataSize = m_vertices.size() * sizeof(tcu::Vec4); 408 409 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, vertexDataSize, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, m_context, memAlloc, m_vertexBuffer, MemoryRequirement::HostVisible, m_vertexBufferAlloc); 410 411 // Load vertices into vertex buffer 412 deMemcpy(m_vertexBufferAlloc->getHostPtr(), m_vertices.data(), (size_t)vertexDataSize); 413 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc); 414 } 415 416 // Create command pool 417 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 418 419 // Create command buffer 420 { 421 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 422 423 beginCommandBuffer(vk, *m_cmdBuffer, 0u); 424 425 const VkImageMemoryBarrier initialImageBarrier = 426 { 427 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 428 DE_NULL, // const void* pNext; 429 0, // VkAccessFlags srcAccessMask; 430 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // VkAccessFlags dstAccessMask; 431 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout oldLayout; 432 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout newLayout; 433 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 434 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 435 *m_colorImage, // VkImage image; 436 { // VkImageSubresourceRange subresourceRange; 437 VK_IMAGE_ASPECT_COLOR_BIT, // VkImageAspectFlags aspectMask; 438 0u, // deUint32 baseMipLevel; 439 1u, // deUint32 mipLevels; 440 0u, // deUint32 baseArraySlice; 441 1u // deUint32 arraySize; 442 } 443 }; 444 445 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0, 0, (const VkMemoryBarrier*)DE_NULL, 0, (const VkBufferMemoryBarrier*)DE_NULL, 1, &initialImageBarrier); 446 447 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), tcu::Vec4(0.0f)); 448 449 const VkDeviceSize vertexBufferOffset[1] = { 0 }; 450 451 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipelines); 452 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0u, 1, &*m_descriptorSet, 0u, DE_NULL); 453 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), vertexBufferOffset); 454 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0); 455 endRenderPass(vk, *m_cmdBuffer); 456 copyImageToBuffer(vk, *m_cmdBuffer, *m_colorImage, *m_resultBuffer, m_renderSize); 457 endCommandBuffer(vk, *m_cmdBuffer); 458 } 459} 460 461tcu::TestStatus BufferViewTestInstance::checkResult (deInt8 factor) 462{ 463 const DeviceInterface& vk = m_context.getDeviceInterface(); 464 const VkDevice vkDevice = m_context.getDevice(); 465 const tcu::TextureFormat tcuFormat = mapVkFormat(m_colorFormat); 466 de::MovePtr<tcu::TextureLevel> resultLevel (new tcu::TextureLevel(tcuFormat, m_renderSize.x(), m_renderSize.y())); 467 468 invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc); 469 tcu::copy(*resultLevel, tcu::ConstPixelBufferAccess(resultLevel->getFormat(), resultLevel->getSize(), m_resultBufferAlloc->getHostPtr())); 470 471 tcu::ConstPixelBufferAccess pixelBuffer = resultLevel->getAccess(); 472 for (deInt32 i = 0; i < (deInt32) m_renderSize.x(); ++i) 473 { 474 tcu::IVec4 pixel = pixelBuffer.getPixelInt(i, i); 475 deInt32 expected = factor * (m_testCase.elementOffset + i); 476 deInt32 actual = pixel[0]; 477 if (expected != actual) 478 { 479 std::ostringstream errorMessage; 480 errorMessage << "BufferView test failed. expected: " << expected << " actual: " << actual; 481 return tcu::TestStatus::fail(errorMessage.str()); 482 } 483 } 484 485 return tcu::TestStatus::pass("BufferView test"); 486} 487 488tcu::TestStatus BufferViewTestInstance::iterate (void) 489{ 490 const DeviceInterface& vk = m_context.getDeviceInterface(); 491 const VkDevice vkDevice = m_context.getDevice(); 492 const VkQueue queue = m_context.getUniversalQueue(); 493 494 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get()); 495 496 tcu::TestStatus testStatus = checkResult(1); 497 if (testStatus.getCode() != QP_TEST_RESULT_PASS) 498 return testStatus; 499 500 // Generate and bind another buffer 501 std::vector<deUint32> uniformData; 502 const VkDeviceSize uniformSize = m_testCase.bufferSize * sizeof(deUint32); 503 const deInt8 factor = 2; 504 505 generateBuffer(uniformData, m_testCase.bufferSize, factor); 506 deMemcpy(m_uniformBufferAlloc->getHostPtr(), uniformData.data(), (size_t)uniformSize); 507 flushAlloc(vk, vkDevice, *m_uniformBufferAlloc); 508 509 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get()); 510 511 return checkResult(factor); 512} 513 514class BufferViewTestCase : public vkt::TestCase 515{ 516public: 517 BufferViewTestCase (tcu::TestContext& testCtx, 518 const std::string& name, 519 BufferViewCaseParams bufferViewTestInfo) 520 : vkt::TestCase (testCtx, name) 521 , m_bufferViewTestInfo (bufferViewTestInfo) 522 {} 523 524 virtual ~BufferViewTestCase (void) 525 {} 526 virtual void initPrograms (SourceCollections& programCollection) const; 527 528 virtual TestInstance* createInstance (Context& context) const 529 { 530 return new BufferViewTestInstance(context, m_bufferViewTestInfo); 531 } 532private: 533 BufferViewCaseParams m_bufferViewTestInfo; 534}; 535 536void BufferViewTestCase::initPrograms (SourceCollections& programCollection) const 537{ 538 programCollection.glslSources.add("vert") << glu::VertexSource( 539 "#version 310 es\n" 540 "layout (location = 0) in highp vec4 a_position;\n" 541 "void main()\n" 542 "{\n" 543 " gl_Position = a_position;\n" 544 "}\n"); 545 546 547 programCollection.glslSources.add("frag") << glu::FragmentSource( 548 "#version 310 es\n" 549 "#extension GL_EXT_texture_buffer : enable\n" 550 "layout (set=0, binding=0) uniform highp utextureBuffer u_buffer;\n" 551 "layout (location = 0) out highp uint o_color;\n" 552 "void main()\n" 553 "{\n" 554 " o_color = texelFetch(u_buffer, int(gl_FragCoord.x)).x;\n" 555 "}\n"); 556} 557 558class BufferViewAllFormatsTestInstance : public vkt::TestInstance 559{ 560public: 561 BufferViewAllFormatsTestInstance (Context& context, 562 BufferViewCaseParams testCase); 563 virtual ~BufferViewAllFormatsTestInstance (void); 564 virtual tcu::TestStatus iterate (void); 565 566private: 567 void checkTexelBufferSupport (Context& context, 568 VkFormat format, 569 BufferViewCaseParams testCase); 570 int getFetchPos (int fetchPosNdx); 571 tcu::TestStatus checkResult (); 572 tcu::TestStatus checkResultFloat (); 573 void populateSourceBuffer (const tcu::PixelBufferAccess& access, deUint32 bufferNdx); 574 575private: 576 enum 577 { 578 // some arbitrary points 579 SAMPLE_POINT_0 = 6, 580 SAMPLE_POINT_1 = 51, 581 SAMPLE_POINT_2 = 42, 582 SAMPLE_POINT_3 = 25, 583 }; 584 585 BufferViewCaseParams m_testCase; 586 const VkFormat m_bufferFormat; 587 588 Move<VkDescriptorSetLayout> m_descriptorSetLayout; 589 Move<VkDescriptorPool> m_descriptorPool; 590 Move<VkDescriptorSet> m_descriptorSet; 591 592 Move<VkBuffer> m_uniformBuffer; 593 de::MovePtr<vk::Allocation> m_uniformBufferAlloc; 594 Move<VkBufferView> m_uniformBufferView; 595 Move<VkShaderModule> m_computeShaderModule; 596 Move<VkPipelineLayout> m_pipelineLayout; 597 Move<VkPipeline> m_computePipeline; 598 599 Move<VkCommandPool> m_cmdPool; 600 Move<VkCommandBuffer> m_cmdBuffer; 601 602 Move<VkBuffer> m_resultBuffer; 603 de::MovePtr<Allocation> m_resultBufferAlloc; 604 605 de::ArrayBuffer<deUint8> m_sourceBuffer; 606 tcu::ConstPixelBufferAccess m_sourceView; 607}; 608 609void BufferViewAllFormatsTestInstance::checkTexelBufferSupport (Context& context, VkFormat format, BufferViewCaseParams testCase) 610{ 611 const InstanceInterface& vki = context.getInstanceInterface(); 612 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 613 614 VkFormatProperties properties; 615 properties = getPhysicalDeviceFormatProperties(vki, physicalDevice, format); 616 617 if (!(properties.bufferFeatures & testCase.feature)) 618 TCU_THROW(NotSupportedError, "Format not supported"); 619 620#ifndef CTS_USES_VULKANSC 621 if(testCase.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM) 622 { 623 if (!context.isDeviceFunctionalitySupported("VK_KHR_maintenance5")) 624 TCU_THROW(NotSupportedError, "Extension VK_KHR_maintenance5 not supported"); 625 } 626#endif 627} 628 629BufferViewAllFormatsTestInstance::~BufferViewAllFormatsTestInstance (void) 630{ 631} 632 633/* Taken from BindingShaderAccessTests.cpp */ 634void BufferViewAllFormatsTestInstance::populateSourceBuffer (const tcu::PixelBufferAccess& access, deUint32 bufferNdx) 635{ 636 DE_ASSERT(access.getHeight() == 1); 637 DE_ASSERT(access.getDepth() == 1); 638 639 const deInt32 width = access.getWidth(); 640 641 for (int x = 0; x < width; ++x) 642 { 643 int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors) 644 int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors) 645 int blue = 16 * (x % 16); //!< 16-long triangle wave 646 647 DE_ASSERT(de::inRange(red, 0, 255)); 648 DE_ASSERT(de::inRange(green, 0, 255)); 649 DE_ASSERT(de::inRange(blue, 0, 255)); 650 651 if (bufferNdx % 2 == 0) red = 255 - red; 652 if (bufferNdx % 3 == 0) green = 255 - green; 653 if (bufferNdx % 4 == 0) blue = 255 - blue; 654 655 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0); 656 } 657} 658 659BufferViewAllFormatsTestInstance::BufferViewAllFormatsTestInstance (Context& context, 660 BufferViewCaseParams testCase) 661 : vkt::TestInstance (context) 662 , m_testCase (testCase) 663 , m_bufferFormat (testCase.format) 664{ 665 const DeviceInterface& vk = context.getDeviceInterface(); 666 const VkDevice vkDevice = context.getDevice(); 667 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex(); 668 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice())); 669 670 checkTexelBufferSupport(context, m_bufferFormat, testCase); 671 672 // Create a result buffer 673 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, sizeof(tcu::Vec4[4]), VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, m_context, memAlloc, m_resultBuffer, MemoryRequirement::HostVisible, m_resultBufferAlloc); 674 675 // Create descriptors 676 { 677 const VkDescriptorSetLayoutBinding layoutBindings[2] = 678 { 679 { 680 0u, // deUint32 binding; 681 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType; 682 1u, // deUint32 arraySize; 683 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags; 684 DE_NULL // const VkSampler* pImmutableSamplers; 685 }, 686 { 687 1u, // deUint32 binding; 688 testCase.descType, // VkDescriptorType descriptorType; 689 1u, // deUint32 arraySize; 690 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlags stageFlags; 691 DE_NULL // const VkSampler* pImmutableSamplers; 692 }, 693 }; 694 695 const VkDescriptorSetLayoutCreateInfo descriptorLayoutParams = 696 { 697 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, // VkStructureType sType; 698 DE_NULL, // const void* pNext; 699 (VkDescriptorSetLayoutCreateFlags)0, 700 DE_LENGTH_OF_ARRAY(layoutBindings), // deUint32 count; 701 layoutBindings // const VkDescriptorSetLayoutBinding pBinding; 702 }; 703 704 m_descriptorSetLayout = createDescriptorSetLayout(vk, vkDevice, &descriptorLayoutParams); 705 706 707 // Generate buffer 708 const tcu::TextureFormat tcuFormat = mapVkFormat(m_bufferFormat); 709 710 de::ArrayBuffer<deUint8> sourceBuffer(testCase.bufferSize); 711 populateSourceBuffer(tcu::PixelBufferAccess(tcuFormat, tcu::IVec3(testCase.bufferSize / tcuFormat.getPixelSize(), 1, 1), sourceBuffer.getPtr()), 0); 712 713 m_sourceBuffer = sourceBuffer; 714 m_sourceView = tcu::ConstPixelBufferAccess(tcuFormat, tcu::IVec3(64, 1, 1), m_sourceBuffer.getPtr()); 715 716 BufferSuballocation().createTestBuffer(vk, vkDevice, queueFamilyIndex, sourceBuffer.size(), testCase.createUsage, m_context, memAlloc, m_uniformBuffer, MemoryRequirement::HostVisible, m_uniformBufferAlloc); 717 deMemcpy(m_uniformBufferAlloc->getHostPtr(), sourceBuffer.getPtr(), sourceBuffer.size()); 718 flushAlloc(vk, vkDevice, *m_uniformBufferAlloc); 719 720 VkBufferViewCreateInfo viewInfo = 721 { 722 VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO, // VkStructureType sType; 723 DE_NULL, // void* pNext; 724 (VkBufferViewCreateFlags)0, 725 *m_uniformBuffer, // VkBuffer buffer; 726 m_bufferFormat, // VkFormat format; 727 m_testCase.elementOffset, // VkDeviceSize offset; 728 VK_WHOLE_SIZE // VkDeviceSize range; 729 }; 730 731#ifndef CTS_USES_VULKANSC 732 VkBufferUsageFlags2CreateInfoKHR bindUsageInfo; 733 if (testCase.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM) 734 { 735 bindUsageInfo.sType = VK_STRUCTURE_TYPE_BUFFER_USAGE_FLAGS_2_CREATE_INFO_KHR; // VkStructureType sType; 736 bindUsageInfo.pNext = DE_NULL; // const void* pNext; 737 bindUsageInfo.usage = testCase.bindUsage; // VkBufferUsageFlags2KHR usage; 738 739 viewInfo.pNext = &bindUsageInfo; 740 } 741#endif 742 743 m_uniformBufferView = createBufferView(vk, vkDevice, &viewInfo); 744 745 const VkDescriptorPoolSize descriptorTypes[2] = 746 { 747 { 748 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType type; 749 1 // deUint32 count; 750 }, 751 { 752 testCase.descType, // VkDescriptorType type; 753 1 // deUint32 count; 754 } 755 }; 756 757 const VkDescriptorPoolCreateInfo 758 descriptorPoolParams = 759 { 760 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, // VkStructureType sType; 761 DE_NULL, // void* pNext; 762 VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, // VkDescriptorPoolCreateFlags flags; 763 1u, // uint32_t maxSets; 764 DE_LENGTH_OF_ARRAY(descriptorTypes), // deUint32 count; 765 descriptorTypes // const VkDescriptorTypeCount* pTypeCount 766 }; 767 768 m_descriptorPool = createDescriptorPool(vk, vkDevice, &descriptorPoolParams); 769 770 const VkDescriptorSetAllocateInfo 771 descriptorSetParams = 772 { 773 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, 774 DE_NULL, 775 *m_descriptorPool, 776 1u, 777 &m_descriptorSetLayout.get(), 778 }; 779 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetParams); 780 781 const VkDescriptorBufferInfo outBufferInfo = 782 { 783 m_resultBuffer.get(), 784 0, 785 sizeof(tcu::Vec4[4]) 786 }; 787 788 const VkWriteDescriptorSet writeDescritporSets[] = 789 { 790 { 791 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType; 792 DE_NULL, // const void* pNext; 793 *m_descriptorSet, // VkDescriptorSet destSet; 794 0, // deUint32 destBinding; 795 0, // deUint32 destArrayElement; 796 1u, // deUint32 count; 797 VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, // VkDescriptorType descriptorType; 798 (const VkDescriptorImageInfo*)DE_NULL, 799 &outBufferInfo, 800 (const VkBufferView*)DE_NULL, 801 }, 802 { 803 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // VkStructureType sType; 804 DE_NULL, // const void* pNext; 805 *m_descriptorSet, // VkDescriptorSet destSet; 806 1, // deUint32 destBinding; 807 0, // deUint32 destArrayElement; 808 1u, // deUint32 count; 809 testCase.descType, // VkDescriptorType descriptorType; 810 (const VkDescriptorImageInfo*)DE_NULL, 811 (const VkDescriptorBufferInfo*)DE_NULL, 812 &m_uniformBufferView.get(), 813 } 814 }; 815 816 vk.updateDescriptorSets(vkDevice, DE_LENGTH_OF_ARRAY(writeDescritporSets), writeDescritporSets, 0u, DE_NULL); 817 } 818 819 // Create pipeline layout 820 { 821 const VkPipelineLayoutCreateInfo pipelineLayoutParams = 822 { 823 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 824 DE_NULL, // const void* pNext; 825 (VkPipelineLayoutCreateFlags)0, 826 1u, // deUint32 descriptorSetCount; 827 &*m_descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 828 0u, // deUint32 pushConstantRangeCount; 829 DE_NULL // const VkPushConstantRange* pPushConstantRanges; 830 }; 831 832 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams); 833 } 834 835 // Create shaders 836 { 837 m_computeShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("comp"), 0); 838 } 839 840 // Create pipeline 841 { 842 m_computePipeline = makeComputePipeline(vk, vkDevice, m_pipelineLayout.get(), m_computeShaderModule.get()); 843 } 844 845 // Create command pool 846 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex); 847 848 // Create and record a command buffer 849 { 850 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 851 852 beginCommandBuffer(vk, *m_cmdBuffer, 0u); 853 854 vk.cmdBindPipeline(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *m_computePipeline); 855 vk.cmdBindDescriptorSets(*m_cmdBuffer, vk::VK_PIPELINE_BIND_POINT_COMPUTE, *m_pipelineLayout, 0u, 1u, &*m_descriptorSet, 0u, nullptr); 856 857 const vk::VkBufferMemoryBarrier barrier = 858 { 859 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 860 DE_NULL, 861 vk::VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask 862 vk::VK_ACCESS_UNIFORM_READ_BIT, // dstAccessMask 863 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex 864 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex 865 *m_resultBuffer, // buffer 866 0u, // offset 867 sizeof(tcu::Vec4[4]), // size 868 }; 869 const vk::VkBufferMemoryBarrier bufferBarrier = 870 { 871 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, 872 DE_NULL, 873 vk::VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask 874 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask 875 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex 876 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex 877 *m_resultBuffer, // buffer 878 (vk::VkDeviceSize)0u, // offset 879 sizeof(tcu::Vec4[4]), // size 880 }; 881 882 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_HOST_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0u, 0u, nullptr, 0u, &barrier, 0u, nullptr); 883 //vk.cmdDispatch(*m_cmdBuffer, 1u, 1u, 1u); 884 vk.cmdDispatch(*m_cmdBuffer, 4u, 1u, 1u); 885 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_PIPELINE_STAGE_HOST_BIT, 0u, 0u, nullptr, 0u, &bufferBarrier, 0u, nullptr); 886 endCommandBuffer(vk, *m_cmdBuffer); 887 } 888} 889 890int BufferViewAllFormatsTestInstance::getFetchPos (int fetchPosNdx) 891{ 892 static const int fetchPositions[4] = 893 { 894 SAMPLE_POINT_0, 895 SAMPLE_POINT_1, 896 SAMPLE_POINT_2, 897 SAMPLE_POINT_3, 898 }; 899 900 return fetchPositions[fetchPosNdx]; 901} 902 903tcu::TestStatus BufferViewAllFormatsTestInstance::checkResult () 904{ 905 const DeviceInterface& vk = m_context.getDeviceInterface(); 906 const VkDevice vkDevice = m_context.getDevice(); 907 bool allResultsOk = true; 908 909 tcu::UVec4 results[4]; 910 invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc); 911 deMemcpy(results, m_resultBufferAlloc->getHostPtr(), sizeof(tcu::UVec4[4])); 912 913 // verify 914 for (int resultNdx = 0; resultNdx < 4; ++resultNdx) 915 { 916 const tcu::UVec4 result = results[resultNdx]; 917 const tcu::UVec4 conversionThreshold = tcu::UVec4(0); 918 tcu::UVec4 reference = tcu::UVec4(0); 919 920 reference += m_sourceView.getPixelUint(getFetchPos(resultNdx), 0, 0); 921 922 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold))) 923 { 924 allResultsOk = false; 925 926 m_context.getTestContext().getLog() 927 << tcu::TestLog::Message 928 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result 929 << tcu::TestLog::EndMessage; 930 } 931 } 932 933 if (allResultsOk) 934 return tcu::TestStatus::pass("Pass"); 935 else 936 return tcu::TestStatus::fail("Invalid result values"); 937} 938 939tcu::TestStatus BufferViewAllFormatsTestInstance::checkResultFloat () 940{ 941 const DeviceInterface& vk = m_context.getDeviceInterface(); 942 const VkDevice vkDevice = m_context.getDevice(); 943 bool allResultsOk = true; 944 945 tcu::Vec4 results[4]; 946 invalidateAlloc(vk, vkDevice, *m_resultBufferAlloc); 947 deMemcpy(results, m_resultBufferAlloc->getHostPtr(), sizeof(tcu::Vec4[4])); 948 949 // verify 950 for (int resultNdx = 0; resultNdx < 4; ++resultNdx) 951 { 952 const tcu::Vec4 result = results[resultNdx]; 953 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f); 954 tcu::Vec4 reference = tcu::Vec4(0.0f); 955 956 reference += m_sourceView.getPixel(getFetchPos(resultNdx), 0, 0); 957 958 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold))) 959 { 960 allResultsOk = false; 961 962 m_context.getTestContext().getLog() 963 << tcu::TestLog::Message 964 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result 965 << tcu::TestLog::EndMessage; 966 } 967 } 968 969 if (allResultsOk) 970 return tcu::TestStatus::pass("Pass"); 971 else 972 return tcu::TestStatus::fail("Invalid result values"); 973} 974 975tcu::TestStatus BufferViewAllFormatsTestInstance::iterate (void) 976{ 977 const DeviceInterface& vk = m_context.getDeviceInterface(); 978 const VkDevice vkDevice = m_context.getDevice(); 979 const VkQueue queue = m_context.getUniversalQueue(); 980 981 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get()); 982 983 if (isIntFormat(m_bufferFormat) || isUintFormat(m_bufferFormat)) 984 return checkResult(); 985 else 986 return checkResultFloat(); 987} 988 989 990class BufferViewAllFormatsTestCase : public vkt::TestCase 991{ 992public: 993 BufferViewAllFormatsTestCase (tcu::TestContext& testCtx, 994 const std::string& name, 995 BufferViewCaseParams bufferViewTestInfo) 996 : vkt::TestCase (testCtx, name) 997 , m_bufferViewTestInfo (bufferViewTestInfo) 998 {} 999 1000 virtual ~BufferViewAllFormatsTestCase (void) 1001 {} 1002 virtual void initPrograms (SourceCollections& programCollection) const; 1003 virtual void checkSupport (Context& context) const 1004 { 1005 const InstanceInterface& vki = context.getInstanceInterface(); 1006 const VkPhysicalDevice physicalDevice = context.getPhysicalDevice(); 1007 1008#ifndef CTS_USES_VULKANSC 1009 if ((m_bufferViewTestInfo.format == VK_FORMAT_A8_UNORM_KHR) || 1010 (m_bufferViewTestInfo.format == VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR)) 1011 context.requireDeviceFunctionality("VK_KHR_maintenance5"); 1012#endif // CTS_USES_VULKANSC 1013 1014 if ((m_bufferViewTestInfo.createUsage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) != 0) 1015 { 1016 VkFormatProperties properties; 1017 properties = getPhysicalDeviceFormatProperties(vki, physicalDevice, m_bufferViewTestInfo.format); 1018 if ((properties.bufferFeatures & VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT) == 0) 1019 { 1020 TCU_THROW(NotSupportedError, "VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT not supported for format"); 1021 } 1022 } 1023 } 1024 1025 virtual TestInstance* createInstance (Context& context) const 1026 { 1027 return new BufferViewAllFormatsTestInstance(context, m_bufferViewTestInfo); 1028 } 1029 1030private: 1031 BufferViewCaseParams m_bufferViewTestInfo; 1032}; 1033 1034const std::string strLayoutFormat (VkFormat format) 1035{ 1036 std::ostringstream buf; 1037 1038 buf << ", " << image::getShaderImageFormatQualifier(mapVkFormat(format)).c_str(); 1039 1040 return buf.str(); 1041} 1042 1043void BufferViewAllFormatsTestCase::initPrograms (SourceCollections& programCollection) const 1044{ 1045 std::ostringstream buf; 1046 1047 const bool isIntFmt = isIntFormat(m_bufferViewTestInfo.format); 1048 const bool isUintFmt = isUintFormat(m_bufferViewTestInfo.format); 1049 1050 bool isUniform; 1051 if (m_bufferViewTestInfo.bindUsage != VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM) 1052 { 1053 isUniform = m_bufferViewTestInfo.bindUsage == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ? true : false; 1054 } 1055 else 1056 { 1057 isUniform = m_bufferViewTestInfo.createUsage == VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT ? true : false; 1058 } 1059 const char* const storageType = isUniform ? "textureBuffer " : "imageBuffer "; 1060 const char* const extraOption = isUniform ? "" : "readonly "; 1061 const std::string stringFmtLayout = isUniform ? "" : strLayoutFormat(m_bufferViewTestInfo.format); 1062 const char* const fmtLayout = isUniform ? "" : stringFmtLayout.c_str(); 1063 const char* const opName = isUniform ? "texelFetch" : "imageLoad"; 1064 const char* const outFormat = isIntFmt ? "i" : isUintFmt ? "u" : ""; 1065 const char* const inFormat = vk::isScaledFormat(m_bufferViewTestInfo.format)? "" : outFormat; 1066 1067 buf << "#version 440\n" 1068 << "#extension GL_EXT_texture_buffer : require\n" 1069 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n" 1070 << "layout(set = 0, binding = 1" << fmtLayout << ") uniform highp " << extraOption << inFormat << storageType << " texelBuffer;\n" 1071 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n" 1072 << "{\n" 1073 << " highp " << outFormat << "vec4 read_colors[4];\n" 1074 << "} b_out;\n" 1075 << "void main (void)\n" 1076 << "{\n" 1077 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n" 1078 << " highp " << outFormat << "vec4 result_color;\n" 1079 << " result_color = " << outFormat << "vec4(0);\n" 1080 << " if (quadrant_id == 0)\n" 1081 << " result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 6));\n" 1082 << " else if (quadrant_id == 1)\n" 1083 << " result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 51));\n" 1084 << " else if (quadrant_id == 2)\n" 1085 << " result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 42));\n" 1086 << " else\n" 1087 << " result_color += " << outFormat << "vec4(" << opName << "(texelBuffer, 25));\n" 1088 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n" 1089 << "}\n"; 1090 1091 programCollection.glslSources.add("comp") << glu::ComputeSource(buf.str()); 1092} 1093 1094} // anonymous 1095 1096bool isSupportedImageLoadStore (const tcu::TextureFormat& format) 1097{ 1098 if (!image::isPackedType(mapTextureFormat(format))) 1099 { 1100 switch (format.order) 1101 { 1102 case tcu::TextureFormat::RGBA: 1103 break; 1104 default: 1105 return false; 1106 } 1107 1108 switch (format.type) 1109 { 1110 case tcu::TextureFormat::FLOAT: 1111 case tcu::TextureFormat::HALF_FLOAT: 1112 1113 case tcu::TextureFormat::UNSIGNED_INT32: 1114 case tcu::TextureFormat::UNSIGNED_INT16: 1115 case tcu::TextureFormat::UNSIGNED_INT8: 1116 1117 case tcu::TextureFormat::SIGNED_INT32: 1118 case tcu::TextureFormat::SIGNED_INT16: 1119 case tcu::TextureFormat::SIGNED_INT8: 1120 1121 case tcu::TextureFormat::UNORM_INT16: 1122 case tcu::TextureFormat::UNORM_INT8: 1123 1124 case tcu::TextureFormat::SNORM_INT16: 1125 case tcu::TextureFormat::SNORM_INT8: 1126 break; 1127 1128 default: 1129 return false; 1130 } 1131 } 1132 else 1133 { 1134 switch (mapTextureFormat(format)) 1135 { 1136 case VK_FORMAT_A2B10G10R10_UNORM_PACK32: 1137 case VK_FORMAT_A2B10G10R10_UINT_PACK32: 1138 break; 1139 1140 default: 1141 return false; 1142 } 1143 } 1144 1145 return true; 1146} 1147 1148tcu::TestCaseGroup* createBufferViewAccessTests (tcu::TestContext& testCtx) 1149{ 1150 const char* const bufferTexts[ALLOCATION_KIND_LAST] = 1151 { 1152 "buffer_suballocated", 1153 "buffer_dedicated_alloc" 1154 }; 1155 1156 const char* const imageTexts[ALLOCATION_KIND_LAST] = 1157 { 1158 "image_suballocated", 1159 "image_dedicated_alloc" 1160 }; 1161 1162 de::MovePtr<tcu::TestCaseGroup> bufferViewTests (new tcu::TestCaseGroup(testCtx, "access")); 1163 de::MovePtr<tcu::TestCaseGroup> bufferViewAllocationGroupTests[] = 1164 { 1165 // BufferView Access Tests for Suballocated Objects 1166 de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "suballocation")), 1167 de::MovePtr<tcu::TestCaseGroup>(new tcu::TestCaseGroup(testCtx, "dedicated_alloc", "BufferView Access Tests for Dedicatedly Allocated Objects")) 1168 }; 1169 1170 for (deUint32 buffersAllocationNdx = 0u; buffersAllocationNdx < ALLOCATION_KIND_LAST; ++buffersAllocationNdx) 1171 for (deUint32 imageAllocationNdx = 0u; imageAllocationNdx < ALLOCATION_KIND_LAST; ++imageAllocationNdx) 1172 { 1173 const deUint32 testCaseGroupNdx = (buffersAllocationNdx == 0u && imageAllocationNdx == 0u) ? 0u : 1u; 1174 de::MovePtr<tcu::TestCaseGroup>& 1175 currentTestsGroup = bufferViewAllocationGroupTests[testCaseGroupNdx]; 1176 { 1177 const BufferViewCaseParams info = 1178 { 1179 512, // deUint32 bufferSize 1180 512, // deUint32 bufferViewSize 1181 0, // deUint32 elementOffset 1182 static_cast<AllocationKind>(buffersAllocationNdx), 1183 static_cast<AllocationKind>(imageAllocationNdx) 1184 }; 1185 std::ostringstream name; 1186 name << "buffer_view_memory_test_complete"; 1187 if (testCaseGroupNdx != 0) 1188 name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx]; 1189 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info)); 1190 } 1191 1192 { 1193 const BufferViewCaseParams info = 1194 { 1195 4096, // deUint32 bufferSize 1196 512, // deUint32 bufferViewSize 1197 0, // deUint32 elementOffset 1198 static_cast<AllocationKind>(buffersAllocationNdx), 1199 static_cast<AllocationKind>(imageAllocationNdx) 1200 }; 1201 std::ostringstream name; 1202 name << "buffer_view_memory_test_partial_offset0"; 1203 if (testCaseGroupNdx != 0) 1204 name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx]; 1205 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info)); 1206 } 1207 1208 { 1209 const BufferViewCaseParams info = 1210 { 1211 4096, // deUint32 bufferSize 1212 512, // deUint32 bufferViewSize 1213 128, // deUint32 elementOffset 1214 static_cast<AllocationKind>(buffersAllocationNdx), 1215 static_cast<AllocationKind>(imageAllocationNdx) 1216 }; 1217 std::ostringstream name; 1218 name << "buffer_view_memory_test_partial_offset1"; 1219 if (testCaseGroupNdx != 0) 1220 name << "_with_" << bufferTexts[buffersAllocationNdx] << "_" << imageTexts[imageAllocationNdx]; 1221 currentTestsGroup->addChild(new BufferViewTestCase(testCtx, name.str(), info)); 1222 } 1223 } 1224 1225 for (deUint32 subgroupNdx = 0u; subgroupNdx < DE_LENGTH_OF_ARRAY(bufferViewAllocationGroupTests); ++subgroupNdx) 1226 { 1227 bufferViewTests->addChild(bufferViewAllocationGroupTests[subgroupNdx].release()); 1228 } 1229 1230 VkFormat testFormats[] = 1231 { 1232 VK_FORMAT_R4G4_UNORM_PACK8, 1233 VK_FORMAT_R4G4B4A4_UNORM_PACK16, 1234 VK_FORMAT_B4G4R4A4_UNORM_PACK16, 1235 VK_FORMAT_R5G6B5_UNORM_PACK16, 1236 VK_FORMAT_B5G6R5_UNORM_PACK16, 1237 VK_FORMAT_R5G5B5A1_UNORM_PACK16, 1238 VK_FORMAT_B5G5R5A1_UNORM_PACK16, 1239 VK_FORMAT_A1R5G5B5_UNORM_PACK16, 1240#ifndef CTS_USES_VULKANSC 1241 VK_FORMAT_A1B5G5R5_UNORM_PACK16_KHR, 1242#endif // CTS_USES_VULKANSC 1243 VK_FORMAT_R8_UNORM, 1244 VK_FORMAT_R8_SNORM, 1245 VK_FORMAT_R8_USCALED, 1246 VK_FORMAT_R8_SSCALED, 1247 VK_FORMAT_R8_UINT, 1248 VK_FORMAT_R8_SINT, 1249#ifndef CTS_USES_VULKANSC 1250 VK_FORMAT_A8_UNORM_KHR, 1251#endif // CTS_USES_VULKANSC 1252 VK_FORMAT_R8G8_UNORM, 1253 VK_FORMAT_R8G8_SNORM, 1254 VK_FORMAT_R8G8_USCALED, 1255 VK_FORMAT_R8G8_SSCALED, 1256 VK_FORMAT_R8G8_UINT, 1257 VK_FORMAT_R8G8_SINT, 1258 VK_FORMAT_R8G8B8_UNORM, 1259 VK_FORMAT_R8G8B8_SNORM, 1260 VK_FORMAT_R8G8B8_USCALED, 1261 VK_FORMAT_R8G8B8_SSCALED, 1262 VK_FORMAT_R8G8B8_UINT, 1263 VK_FORMAT_R8G8B8_SINT, 1264 VK_FORMAT_B8G8R8_UNORM, 1265 VK_FORMAT_B8G8R8_SNORM, 1266 VK_FORMAT_B8G8R8_USCALED, 1267 VK_FORMAT_B8G8R8_SSCALED, 1268 VK_FORMAT_B8G8R8_UINT, 1269 VK_FORMAT_B8G8R8_SINT, 1270 VK_FORMAT_R8G8B8A8_UNORM, 1271 VK_FORMAT_R8G8B8A8_SNORM, 1272 VK_FORMAT_R8G8B8A8_USCALED, 1273 VK_FORMAT_R8G8B8A8_SSCALED, 1274 VK_FORMAT_R8G8B8A8_UINT, 1275 VK_FORMAT_R8G8B8A8_SINT, 1276 VK_FORMAT_B8G8R8A8_UNORM, 1277 VK_FORMAT_B8G8R8A8_SNORM, 1278 VK_FORMAT_B8G8R8A8_USCALED, 1279 VK_FORMAT_B8G8R8A8_SSCALED, 1280 VK_FORMAT_B8G8R8A8_UINT, 1281 VK_FORMAT_B8G8R8A8_SINT, 1282 VK_FORMAT_A8B8G8R8_UNORM_PACK32, 1283 VK_FORMAT_A8B8G8R8_SNORM_PACK32, 1284 VK_FORMAT_A8B8G8R8_USCALED_PACK32, 1285 VK_FORMAT_A8B8G8R8_SSCALED_PACK32, 1286 VK_FORMAT_A8B8G8R8_UINT_PACK32, 1287 VK_FORMAT_A8B8G8R8_SINT_PACK32, 1288 VK_FORMAT_A2R10G10B10_UNORM_PACK32, 1289 VK_FORMAT_A2R10G10B10_SNORM_PACK32, 1290 VK_FORMAT_A2R10G10B10_USCALED_PACK32, 1291 VK_FORMAT_A2R10G10B10_SSCALED_PACK32, 1292 VK_FORMAT_A2R10G10B10_UINT_PACK32, 1293 VK_FORMAT_A2R10G10B10_SINT_PACK32, 1294 VK_FORMAT_A2B10G10R10_UNORM_PACK32, 1295 VK_FORMAT_A2B10G10R10_SNORM_PACK32, 1296 VK_FORMAT_A2B10G10R10_USCALED_PACK32, 1297 VK_FORMAT_A2B10G10R10_SSCALED_PACK32, 1298 VK_FORMAT_A2B10G10R10_UINT_PACK32, 1299 VK_FORMAT_A2B10G10R10_SINT_PACK32, 1300 VK_FORMAT_R16_UNORM, 1301 VK_FORMAT_R16_SNORM, 1302 VK_FORMAT_R16_USCALED, 1303 VK_FORMAT_R16_SSCALED, 1304 VK_FORMAT_R16_UINT, 1305 VK_FORMAT_R16_SINT, 1306 VK_FORMAT_R16_SFLOAT, 1307 VK_FORMAT_R16G16_UNORM, 1308 VK_FORMAT_R16G16_SNORM, 1309 VK_FORMAT_R16G16_USCALED, 1310 VK_FORMAT_R16G16_SSCALED, 1311 VK_FORMAT_R16G16_UINT, 1312 VK_FORMAT_R16G16_SINT, 1313 VK_FORMAT_R16G16_SFLOAT, 1314 VK_FORMAT_R16G16B16_UNORM, 1315 VK_FORMAT_R16G16B16_SNORM, 1316 VK_FORMAT_R16G16B16_USCALED, 1317 VK_FORMAT_R16G16B16_SSCALED, 1318 VK_FORMAT_R16G16B16_UINT, 1319 VK_FORMAT_R16G16B16_SINT, 1320 VK_FORMAT_R16G16B16_SFLOAT, 1321 VK_FORMAT_R16G16B16A16_UNORM, 1322 VK_FORMAT_R16G16B16A16_SNORM, 1323 VK_FORMAT_R16G16B16A16_USCALED, 1324 VK_FORMAT_R16G16B16A16_SSCALED, 1325 VK_FORMAT_R16G16B16A16_UINT, 1326 VK_FORMAT_R16G16B16A16_SINT, 1327 VK_FORMAT_R16G16B16A16_SFLOAT, 1328 VK_FORMAT_R32_UINT, 1329 VK_FORMAT_R32_SINT, 1330 VK_FORMAT_R32_SFLOAT, 1331 VK_FORMAT_R32G32_UINT, 1332 VK_FORMAT_R32G32_SINT, 1333 VK_FORMAT_R32G32_SFLOAT, 1334 }; 1335 1336 { 1337 const char* const usageName[] = { "uniform_texel_buffer", "storage_texel_buffer"}; 1338 const vk::VkBufferUsageFlags createUsage[] = { vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT }; 1339 const vk::VkBufferUsageFlags bindUsage[] = { vk::VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM, vk::VK_BUFFER_USAGE_FLAG_BITS_MAX_ENUM }; 1340 const vk::VkFormatFeatureFlags feature[] = { vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT }; 1341 const vk::VkDescriptorType descType[] = { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER }; 1342 1343 for (deUint32 usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(createUsage); ++usageNdx) 1344 { 1345 de::MovePtr<tcu::TestCaseGroup> usageGroup (new tcu::TestCaseGroup(testCtx, usageName[usageNdx], "")); 1346 1347 for (deUint32 formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); formatIdx++) 1348 { 1349 const auto skip = strlen("VK_FORMAT_"); 1350 const std::string fmtName = de::toLower(std::string(getFormatName(testFormats[formatIdx])).substr(skip)); 1351 1352 de::MovePtr<tcu::TestCaseGroup> formatGroup (new tcu::TestCaseGroup(testCtx, fmtName.c_str(), "")); 1353 1354 if (createUsage[usageNdx] == VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT && !isSupportedImageLoadStore(mapVkFormat(testFormats[formatIdx]))) 1355 continue; 1356 1357 const BufferViewCaseParams info = 1358 { 1359 512, // deUint32 bufferSize 1360 128, // deUint32 bufferViewSize 1361 0, // deUint32 elementOffset 1362 ALLOCATION_KIND_SUBALLOCATION, // AllocationKind bufferAllocationKind 1363 ALLOCATION_KIND_SUBALLOCATION, // AllocationKind imageAllocationKind 1364 1365 testFormats[formatIdx], // VkFormat format 1366 createUsage[usageNdx], // VkBufferUsageFlags createUsage 1367 bindUsage[usageNdx], // VkBufferUsageFlags bindUsage 1368 feature[usageNdx], // VkFormatFeatureFlags2KHR feature 1369 descType[usageNdx], // VkDescriptorType descType 1370 }; 1371 1372 usageGroup->addChild(new BufferViewAllFormatsTestCase(testCtx, fmtName.c_str(), info)); 1373 } 1374 1375 bufferViewTests->addChild(usageGroup.release()); 1376 } 1377 } 1378 1379#ifndef CTS_USES_VULKANSC 1380 de::MovePtr<tcu::TestCaseGroup> uniformStorageGroup (new tcu::TestCaseGroup(testCtx, "uniform_storage_texel_buffer", "")); 1381 { 1382 1383 const char* const usageName[] = { "bind_as_uniform", "bind_as_storage" }; 1384 const vk::VkBufferUsageFlags createUsage = vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT | vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT; 1385 const vk::VkBufferUsageFlags bindUsage[] = { vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT }; 1386 const vk::VkFormatFeatureFlags feature[] = { vk::VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT, vk::VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT }; 1387 const vk::VkDescriptorType descType[] = { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER }; 1388 1389 for (deUint32 usageNdx = 0; usageNdx < DE_LENGTH_OF_ARRAY(usageName); ++usageNdx) 1390 { 1391 de::MovePtr<tcu::TestCaseGroup> usageGroup (new tcu::TestCaseGroup(testCtx, usageName[usageNdx], "")); 1392 1393 for (deUint32 formatIdx = 0; formatIdx < DE_LENGTH_OF_ARRAY(testFormats); formatIdx++) 1394 { 1395 const auto skip = strlen("VK_FORMAT_"); 1396 const std::string fmtName = de::toLower(std::string(getFormatName(testFormats[formatIdx])).substr(skip)); 1397 1398 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, fmtName.c_str(), "")); 1399 1400 if (bindUsage[usageNdx] == VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT && !isSupportedImageLoadStore(mapVkFormat(testFormats[formatIdx]))) 1401 continue; 1402 1403 const BufferViewCaseParams info = 1404 { 1405 512, // deUint32 bufferSize 1406 128, // deUint32 bufferViewSize 1407 0, // deUint32 elementOffset 1408 ALLOCATION_KIND_SUBALLOCATION, // AllocationKind bufferAllocationKind 1409 ALLOCATION_KIND_SUBALLOCATION, // AllocationKind imageAllocationKind 1410 1411 testFormats[formatIdx], // VkFormat format 1412 createUsage, // VkBufferUsageFlags createUsage 1413 bindUsage[usageNdx], // VkBufferUsageFlags bindUsage 1414 feature[usageNdx], // VkFormatFeatureFlags2KHR feature 1415 descType[usageNdx], // VkDescriptorType descType 1416 }; 1417 1418 usageGroup->addChild(new BufferViewAllFormatsTestCase(testCtx, fmtName.c_str(), info)); 1419 } 1420 1421 uniformStorageGroup->addChild(usageGroup.release()); 1422 } 1423 } 1424 1425 bufferViewTests->addChild(uniformStorageGroup.release()); 1426#endif 1427 1428 return bufferViewTests.release(); 1429} 1430 1431} // api 1432} // vkt 1433