1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and/or associated documentation files (the
9 * "Materials"), to deal in the Materials without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Materials, and to
12 * permit persons to whom the Materials are furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice(s) and this permission notice shall be
16 * included in all copies or substantial portions of the Materials.
18 * The Materials are Confidential Information as defined by the
19 * Khronos Membership Agreement until designated non-confidential by
20 * Khronos, at which point this condition clause shall be removed.
22 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
32 * \brief Binding shader access tests
33 *//*--------------------------------------------------------------------*/
35 #include "vktBindingShaderAccessTests.hpp"
37 #include "vktTestCase.hpp"
41 #include "vkRefUtil.hpp"
42 #include "vkPlatform.hpp"
43 #include "vkPrograms.hpp"
44 #include "vkMemUtil.hpp"
45 #include "vkBuilderUtil.hpp"
46 #include "vkQueryUtil.hpp"
47 #include "vkImageUtil.hpp"
48 #include "vkTypeUtil.hpp"
50 #include "tcuVector.hpp"
51 #include "tcuVectorUtil.hpp"
52 #include "tcuTexture.hpp"
53 #include "tcuTextureUtil.hpp"
54 #include "tcuResultCollector.hpp"
55 #include "tcuTestLog.hpp"
56 #include "tcuRGBA.hpp"
57 #include "tcuSurface.hpp"
58 #include "tcuImageCompare.hpp"
60 #include "deUniquePtr.hpp"
61 #include "deSharedPtr.hpp"
62 #include "deStringUtil.hpp"
63 #include "deArrayUtil.hpp"
69 namespace BindingModel
76 RESOURCE_FLAG_IMMUTABLE_SAMPLER = (1u << 0u),
78 RESOURCE_FLAG_LAST = (1u << 1u)
81 static const char* const s_quadrantGenVertexPosSource = " highp int quadPhase = gl_VertexID % 6;\n"
82 " highp int quadXcoord = int(quadPhase == 1 || quadPhase == 4 || quadPhase == 5);\n"
83 " highp int quadYcoord = int(quadPhase == 2 || quadPhase == 3 || quadPhase == 5);\n"
84 " highp int quadOriginX = (gl_VertexID / 6) % 2;\n"
85 " highp int quadOriginY = (gl_VertexID / 6) / 2;\n"
86 " quadrant_id = gl_VertexID / 6;\n"
87 " result_position = vec4(float(quadOriginX + quadXcoord - 1), float(quadOriginY + quadYcoord - 1), 0.0, 1.0);\n";
89 bool isUniformDescriptorType (vk::VkDescriptorType type)
91 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
92 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
93 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
96 bool isDynamicDescriptorType (vk::VkDescriptorType type)
98 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || type == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
101 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type)
105 case vk::VK_IMAGE_VIEW_TYPE_1D:
106 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return vk::VK_IMAGE_TYPE_1D;
107 case vk::VK_IMAGE_VIEW_TYPE_2D:
108 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return vk::VK_IMAGE_TYPE_2D;
109 case vk::VK_IMAGE_VIEW_TYPE_3D: return vk::VK_IMAGE_TYPE_3D;
110 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
111 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return vk::VK_IMAGE_TYPE_2D;
114 DE_FATAL("Impossible");
115 return (vk::VkImageType)0;
119 deUint32 getTextureLevelPyramidDataSize (const tcu::TextureLevelPyramid& srcImage)
121 deUint32 dataSize = 0;
122 for (int level = 0; level < srcImage.getNumLevels(); ++level)
124 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
127 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
129 dataSize += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
134 void writeTextureLevelPyramidData (void* dst, deUint32 dstLen, const tcu::TextureLevelPyramid& srcImage, vk::VkImageViewType viewType, std::vector<vk::VkBufferImageCopy>* copySlices)
136 // \note cube is copied face-by-face
137 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (srcImage.getLevel(0).getHeight()) :
138 (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
139 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
140 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
142 deUint32 levelOffset = 0;
144 DE_ASSERT(arraySize != 0);
146 for (int level = 0; level < srcImage.getNumLevels(); ++level)
148 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
149 const tcu::PixelBufferAccess dstAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), (deUint8*)dst + levelOffset);
150 const deUint32 dataSize = srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
151 const deUint32 sliceDataSize = dataSize / arraySize;
152 const deInt32 sliceHeight = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (srcAccess.getHeight());
153 const deInt32 sliceDepth = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (srcAccess.getDepth()) : (1);
154 const tcu::IVec3 sliceSize (srcAccess.getWidth(), sliceHeight, sliceDepth);
157 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
159 for (int sliceNdx = 0; sliceNdx < (int)arraySize; ++sliceNdx)
161 const vk::VkBufferImageCopy copySlice =
163 (vk::VkDeviceSize)levelOffset + sliceNdx * sliceDataSize, // bufferOffset
164 (deUint32)sliceSize.x(), // bufferRowLength
165 (deUint32)sliceSize.y(), // bufferImageHeight
167 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
168 (deUint32)level, // mipLevel
169 (deUint32)sliceNdx, // arrayLayer
171 }, // imageSubresource
183 copySlices->push_back(copySlice);
186 DE_ASSERT(arraySize * sliceDataSize == dataSize);
188 tcu::copy(dstAccess, srcAccess);
189 levelOffset += dataSize;
192 DE_ASSERT(dstLen == levelOffset);
196 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement)
198 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer);
199 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
201 VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
205 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkImage image, vk::MemoryRequirement requirement)
207 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vki, device, image);
208 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
210 VK_CHECK(vki.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
214 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkSampler sampler)
216 return vk::makeDescriptorImageInfo(sampler, (vk::VkImageView)0, (vk::VkImageLayout)0);
219 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkImageView imageView, vk::VkImageLayout layout)
221 return vk::makeDescriptorImageInfo((vk::VkSampler)0, imageView, layout);
224 void drawQuadrantReferenceResult (const tcu::PixelBufferAccess& dst, const tcu::Vec4& c1, const tcu::Vec4& c2, const tcu::Vec4& c3, const tcu::Vec4& c4)
226 tcu::clear(tcu::getSubregion(dst, 0, 0, dst.getWidth() / 2, dst.getHeight() / 2), c1);
227 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, 0, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() / 2), c2);
228 tcu::clear(tcu::getSubregion(dst, 0, dst.getHeight() / 2, dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c3);
229 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, dst.getHeight() / 2, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c4);
232 class SingleTargetRenderInstance : public vkt::TestInstance
235 SingleTargetRenderInstance (Context& context,
236 const tcu::UVec2& size);
239 static vk::Move<vk::VkImage> createColorAttachment (const vk::DeviceInterface& vki,
241 vk::Allocator& allocator,
242 const tcu::TextureFormat& format,
243 const tcu::UVec2& size,
244 de::MovePtr<vk::Allocation>* outAllocation);
246 static vk::Move<vk::VkImageView> createColorAttachmentView (const vk::DeviceInterface& vki,
248 const tcu::TextureFormat& format,
251 static vk::Move<vk::VkRenderPass> createRenderPass (const vk::DeviceInterface& vki,
253 const tcu::TextureFormat& format);
255 static vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vki,
257 vk::VkRenderPass renderpass,
258 vk::VkImageView colorAttachmentView,
259 const tcu::UVec2& size);
261 static vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vki,
263 deUint32 queueFamilyIndex);
265 virtual void logTestPlan (void) const = 0;
266 virtual void renderToTarget (void) = 0;
267 virtual tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const = 0;
269 void readRenderTarget (tcu::TextureLevel& dst);
270 tcu::TestStatus iterate (void);
273 const tcu::TextureFormat m_targetFormat;
274 const tcu::UVec2 m_targetSize;
276 const vk::DeviceInterface& m_vki;
277 const vk::VkDevice m_device;
278 const vk::VkQueue m_queue;
279 const deUint32 m_queueFamilyIndex;
280 vk::Allocator& m_allocator;
281 de::MovePtr<vk::Allocation> m_colorAttachmentMemory;
282 const vk::Unique<vk::VkImage> m_colorAttachmentImage;
283 const vk::Unique<vk::VkImageView> m_colorAttachmentView;
284 const vk::Unique<vk::VkRenderPass> m_renderPass;
285 const vk::Unique<vk::VkFramebuffer> m_framebuffer;
286 const vk::Unique<vk::VkCommandPool> m_cmdPool;
288 bool m_firstIteration;
291 SingleTargetRenderInstance::SingleTargetRenderInstance (Context& context,
292 const tcu::UVec2& size)
293 : vkt::TestInstance (context)
294 , m_targetFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
295 , m_targetSize (size)
296 , m_vki (context.getDeviceInterface())
297 , m_device (context.getDevice())
298 , m_queue (context.getUniversalQueue())
299 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
300 , m_allocator (context.getDefaultAllocator())
301 , m_colorAttachmentMemory (DE_NULL)
302 , m_colorAttachmentImage (createColorAttachment(m_vki, m_device, m_allocator, m_targetFormat, m_targetSize, &m_colorAttachmentMemory))
303 , m_colorAttachmentView (createColorAttachmentView(m_vki, m_device, m_targetFormat, *m_colorAttachmentImage))
304 , m_renderPass (createRenderPass(m_vki, m_device, m_targetFormat))
305 , m_framebuffer (createFramebuffer(m_vki, m_device, *m_renderPass, *m_colorAttachmentView, m_targetSize))
306 , m_cmdPool (createCommandPool(m_vki, m_device, context.getUniversalQueueFamilyIndex()))
307 , m_firstIteration (true)
311 vk::Move<vk::VkImage> SingleTargetRenderInstance::createColorAttachment (const vk::DeviceInterface& vki,
313 vk::Allocator& allocator,
314 const tcu::TextureFormat& format,
315 const tcu::UVec2& size,
316 de::MovePtr<vk::Allocation>* outAllocation)
318 const vk::VkImageCreateInfo imageInfo =
320 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
322 (vk::VkImageCreateFlags)0,
323 vk::VK_IMAGE_TYPE_2D, // imageType
324 vk::mapTextureFormat(format), // format
325 { (deInt32)size.x(), (deInt32)size.y(), 1 }, // extent
328 vk::VK_SAMPLE_COUNT_1_BIT, // samples
329 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
330 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
331 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
332 0u, // queueFamilyCount
333 DE_NULL, // pQueueFamilyIndices
334 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
337 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &imageInfo));
338 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any));
340 *outAllocation = allocation;
344 vk::Move<vk::VkImageView> SingleTargetRenderInstance::createColorAttachmentView (const vk::DeviceInterface& vki,
346 const tcu::TextureFormat& format,
349 const vk::VkImageViewCreateInfo createInfo =
351 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
353 (vk::VkImageViewCreateFlags)0,
355 vk::VK_IMAGE_VIEW_TYPE_2D, // viewType
356 vk::mapTextureFormat(format), // format
357 vk::makeComponentMappingRGBA(),
359 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
362 0u, // baseArrayLayer
367 return vk::createImageView(vki, device, &createInfo);
370 vk::Move<vk::VkRenderPass> SingleTargetRenderInstance::createRenderPass (const vk::DeviceInterface& vki,
372 const tcu::TextureFormat& format)
374 const vk::VkAttachmentDescription attachmentDescription =
376 (vk::VkAttachmentDescriptionFlags)0,
377 vk::mapTextureFormat(format), // format
378 vk::VK_SAMPLE_COUNT_1_BIT, // samples
379 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp
380 vk::VK_ATTACHMENT_STORE_OP_STORE, // storeOp
381 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
382 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
383 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
384 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout
386 const vk::VkAttachmentReference colorAttachment =
389 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
391 const vk::VkAttachmentReference depthStencilAttachment =
393 vk::VK_NO_ATTACHMENT, // attachment
394 vk::VK_IMAGE_LAYOUT_UNDEFINED // layout
396 const vk::VkSubpassDescription subpass =
398 (vk::VkSubpassDescriptionFlags)0,
399 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
400 0u, // inputAttachmentCount
401 DE_NULL, // pInputAttachments
402 1u, // colorAttachmentCount
403 &colorAttachment, // pColorAttachments
404 DE_NULL, // pResolveAttachments
405 &depthStencilAttachment, // pDepthStencilAttachment
406 0u, // preserveAttachmentCount
407 DE_NULL // pPreserveAttachments
409 const vk::VkRenderPassCreateInfo renderPassCreateInfo =
411 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
413 (vk::VkRenderPassCreateFlags)0,
414 1u, // attachmentCount
415 &attachmentDescription, // pAttachments
417 &subpass, // pSubpasses
418 0u, // dependencyCount
419 DE_NULL, // pDependencies
422 return vk::createRenderPass(vki, device, &renderPassCreateInfo);
425 vk::Move<vk::VkFramebuffer> SingleTargetRenderInstance::createFramebuffer (const vk::DeviceInterface& vki,
427 vk::VkRenderPass renderpass,
428 vk::VkImageView colorAttachmentView,
429 const tcu::UVec2& size)
431 const vk::VkFramebufferCreateInfo framebufferCreateInfo =
433 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
435 (vk::VkFramebufferCreateFlags)0,
436 renderpass, // renderPass
437 1u, // attachmentCount
438 &colorAttachmentView, // pAttachments
444 return vk::createFramebuffer(vki, device, &framebufferCreateInfo);
447 vk::Move<vk::VkCommandPool> SingleTargetRenderInstance::createCommandPool (const vk::DeviceInterface& vki,
449 deUint32 queueFamilyIndex)
451 const vk::VkCommandPoolCreateInfo createInfo =
453 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
455 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
456 queueFamilyIndex, // queueFamilyIndex
458 return vk::createCommandPool(vki, device, &createInfo);
461 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
463 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
464 const vk::VkBufferCreateInfo bufferCreateInfo =
466 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
469 pixelDataSize, // size
470 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
471 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
472 0u, // queueFamilyCount
473 DE_NULL, // pQueueFamilyIndices
475 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
476 const vk::VkImageSubresourceRange fullSubrange =
478 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
481 0u, // baseArraySlice
484 const vk::VkImageMemoryBarrier imageBarrier =
486 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
488 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
489 vk::VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
490 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
491 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
492 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
493 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
494 *m_colorAttachmentImage, // image
495 fullSubrange, // subresourceRange
497 const vk::VkBufferMemoryBarrier memoryBarrier =
499 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
501 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
502 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
503 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
504 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
507 (vk::VkDeviceSize)pixelDataSize // size
509 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
511 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
513 *m_cmdPool, // cmdPool
514 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
517 const vk::VkFenceCreateInfo fenceCreateInfo =
519 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
523 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
525 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
527 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
528 (vk::VkRenderPass)0u, // renderPass
530 (vk::VkFramebuffer)0u, // framebuffer
531 vk::VK_FALSE, // occlusionQueryEnable
532 (vk::VkQueryControlFlags)0,
533 (vk::VkQueryPipelineStatisticFlags)0,
535 const vk::VkImageSubresourceLayers firstSlice =
537 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspect
542 const vk::VkBufferImageCopy copyRegion =
545 m_targetSize.x(), // bufferRowLength
546 m_targetSize.y(), // bufferImageHeight
547 firstSlice, // imageSubresource
548 { 0, 0, 0 }, // imageOffset
549 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y(), 1 } // imageExtent
552 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
554 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
555 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
556 const void* const imageBarrierPtr = &imageBarrier;
557 const void* const bufferBarrierPtr = &memoryBarrier;
558 const deUint64 infiniteTimeout = ~(deUint64)0u;
560 // copy content to buffer
561 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
562 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_FALSE, 1, &imageBarrierPtr);
563 m_vki.cmdCopyImageToBuffer(*cmd, *m_colorAttachmentImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
564 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, 1, &bufferBarrierPtr);
565 VK_CHECK(m_vki.endCommandBuffer(*cmd));
567 // wait for transfer to complete
569 const vk::VkSubmitInfo submitInfo =
571 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
574 (const vk::VkSemaphore*)0,
578 (const vk::VkSemaphore*)0,
581 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *cmdCompleteFence));
583 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
585 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
588 invalidateMappedMemoryRange(m_vki, m_device, bufferMemory->getMemory(), bufferMemory->getOffset(), pixelDataSize);
589 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
592 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
594 tcu::TextureLevel resultImage;
597 if (m_firstIteration)
600 m_firstIteration = false;
605 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
606 const vk::VkImageSubresourceRange fullSubrange =
608 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
611 0u, // baseArraySlice
614 const vk::VkImageMemoryBarrier imageBarrier =
616 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
619 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
620 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
621 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
622 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
623 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
624 *m_colorAttachmentImage, // image
625 fullSubrange, // subresourceRange
627 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
629 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
631 *m_cmdPool, // cmdPool
632 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
635 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
637 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
639 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
640 (vk::VkRenderPass)0u, // renderPass
642 (vk::VkFramebuffer)0u, // framebuffer
643 vk::VK_FALSE, // occlusionQueryEnable
644 (vk::VkQueryControlFlags)0,
645 (vk::VkQueryPipelineStatisticFlags)0,
648 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
649 const void* const imageBarrierPtr = &imageBarrier;
651 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
652 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, 1, &imageBarrierPtr);
653 VK_CHECK(m_vki.endCommandBuffer(*cmd));
656 const vk::VkSubmitInfo submitInfo =
658 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
661 (const vk::VkSemaphore*)0,
665 (const vk::VkSemaphore*)0,
668 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, (vk::VkFence)0));
671 // and then render to
676 readRenderTarget(resultImage);
677 return verifyResultImage(resultImage.getAccess());
680 class RenderInstanceShaders
683 RenderInstanceShaders (const vk::DeviceInterface& vki,
685 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
686 const vk::BinaryCollection& programCollection);
688 inline bool hasTessellationStage (void) const { return *m_tessCtrlShaderModule != 0 || *m_tessEvalShaderModule != 0; }
689 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
690 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
693 void addStage (const vk::DeviceInterface& vki,
695 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
696 const vk::BinaryCollection& programCollection,
698 vk::VkShaderStageFlagBits stage,
699 vk::Move<vk::VkShaderModule>* outModule);
701 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const;
703 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
704 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
705 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
706 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
707 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
708 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
711 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
713 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
714 const vk::BinaryCollection& programCollection)
716 addStage(vki, device, deviceFeatures, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX_BIT, &m_vertexShaderModule);
717 addStage(vki, device, deviceFeatures, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessCtrlShaderModule);
718 addStage(vki, device, deviceFeatures, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvalShaderModule);
719 addStage(vki, device, deviceFeatures, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule);
720 addStage(vki, device, deviceFeatures, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule);
722 DE_ASSERT(!m_stageInfos.empty());
725 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
727 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
728 const vk::BinaryCollection& programCollection,
730 vk::VkShaderStageFlagBits stage,
731 vk::Move<vk::VkShaderModule>* outModule)
733 if (programCollection.contains(name))
735 if (vk::isShaderStageSupported(deviceFeatures, stage))
737 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
739 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *module));
743 TCU_THROW(NotSupportedError, (de::toString(stage) + " is not supported").c_str());
747 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const
749 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
751 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
753 (vk::VkPipelineShaderStageCreateFlags)0,
757 DE_NULL, // pSpecializationInfo
759 return stageCreateInfo;
762 class SingleCmdRenderInstance : public SingleTargetRenderInstance
765 SingleCmdRenderInstance (Context& context,
766 bool isPrimaryCmdBuf,
767 const tcu::UVec2& renderSize);
770 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
772 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
773 virtual void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const = 0;
775 void renderToTarget (void);
777 const bool m_isPrimaryCmdBuf;
780 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
781 bool isPrimaryCmdBuf,
782 const tcu::UVec2& renderSize)
783 : SingleTargetRenderInstance (context, renderSize)
784 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
788 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
790 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getDeviceFeatures(), m_context.getBinaryCollection());
791 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
792 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
794 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
796 (vk::VkPipelineVertexInputStateCreateFlags)0,
798 DE_NULL, // pVertexBindingDescriptions
799 0u, // attributeCount
800 DE_NULL, // pVertexAttributeDescriptions
802 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
804 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
806 (vk::VkPipelineInputAssemblyStateCreateFlags)0,
807 topology, // topology
808 vk::VK_FALSE, // primitiveRestartEnable
810 const vk::VkPipelineTessellationStateCreateInfo tessState =
812 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
814 (vk::VkPipelineTesselationStateCreateFlags)0,
815 3u, // patchControlPoints
817 const vk::VkViewport viewport =
821 float(m_targetSize.x()), // width
822 float(m_targetSize.y()), // height
826 const vk::VkRect2D renderArea =
829 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y() }, // extent
831 const vk::VkPipelineViewportStateCreateInfo vpState =
833 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
835 (vk::VkPipelineViewportStateCreateFlags)0,
841 const vk::VkPipelineRasterizationStateCreateInfo rsState =
843 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
845 (vk::VkPipelineRasterizationStateCreateFlags)0,
846 vk::VK_TRUE, // depthClipEnable
847 vk::VK_FALSE, // rasterizerDiscardEnable
848 vk::VK_POLYGON_MODE_FILL, // fillMode
849 vk::VK_CULL_MODE_NONE, // cullMode
850 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
851 vk::VK_FALSE, // depthBiasEnable
853 0.0f, // depthBiasClamp
854 0.0f, // slopeScaledDepthBias
857 const vk::VkSampleMask sampleMask = 0x01u;
858 const vk::VkPipelineMultisampleStateCreateInfo msState =
860 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
862 (vk::VkPipelineMultisampleStateCreateFlags)0,
863 vk::VK_SAMPLE_COUNT_1_BIT, // rasterSamples
864 vk::VK_FALSE, // sampleShadingEnable
865 0.0f, // minSampleShading
866 &sampleMask, // sampleMask
867 vk::VK_FALSE, // alphaToCoverageEnable
868 vk::VK_FALSE, // alphaToOneEnable
870 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
872 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
874 (vk::VkPipelineDepthStencilStateCreateFlags)0,
875 vk::VK_FALSE, // depthTestEnable
876 vk::VK_FALSE, // depthWriteEnable
877 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
878 vk::VK_FALSE, // depthBoundsTestEnable
879 vk::VK_FALSE, // stencilTestEnable
880 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
881 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
882 -1.0f, // minDepthBounds
883 +1.0f, // maxDepthBounds
885 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
887 vk::VK_FALSE, // blendEnable
888 vk::VK_BLEND_FACTOR_ZERO, // srcBlendColor
889 vk::VK_BLEND_FACTOR_ZERO, // destBlendColor
890 vk::VK_BLEND_OP_ADD, // blendOpColor
891 vk::VK_BLEND_FACTOR_ZERO, // srcBlendAlpha
892 vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha
893 vk::VK_BLEND_OP_ADD, // blendOpAlpha
894 (vk::VK_COLOR_COMPONENT_R_BIT |
895 vk::VK_COLOR_COMPONENT_G_BIT |
896 vk::VK_COLOR_COMPONENT_B_BIT |
897 vk::VK_COLOR_COMPONENT_A_BIT), // channelWriteMask
899 const vk::VkPipelineColorBlendStateCreateInfo cbState =
901 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
903 (vk::VkPipelineColorBlendStateCreateFlags)0,
904 vk::VK_FALSE, // logicOpEnable
905 vk::VK_LOGIC_OP_CLEAR, // logicOp
906 1u, // attachmentCount
907 &cbAttachment, // pAttachments
908 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
910 const vk::VkPipelineDynamicStateCreateInfo dynState =
912 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
914 (vk::VkPipelineDynamicStateCreateFlags)0,
915 0u, // dynamicStateCount
916 DE_NULL, // pDynamicStates
918 const vk::VkGraphicsPipelineCreateInfo createInfo =
920 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
922 (vk::VkPipelineCreateFlags)0,
923 shaderStages.getNumStages(), // stageCount
924 shaderStages.getStages(), // pStages
925 &vertexInputState, // pVertexInputState
926 &iaState, // pInputAssemblyState
927 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
928 &vpState, // pViewportState
929 &rsState, // pRasterState
930 &msState, // pMultisampleState
931 &dsState, // pDepthStencilState
932 &cbState, // pColorBlendState
933 &dynState, // pDynamicState
934 pipelineLayout, // layout
935 *m_renderPass, // renderPass
937 (vk::VkPipeline)0, // basePipelineHandle
938 0u, // basePipelineIndex
940 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
943 void SingleCmdRenderInstance::renderToTarget (void)
945 const vk::VkRect2D renderArea =
948 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y() }, // extent
950 const vk::VkCommandBufferAllocateInfo mainCmdBufCreateInfo =
952 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
954 *m_cmdPool, // cmdPool
955 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
958 const vk::VkCommandBufferBeginInfo mainCmdBufBeginInfo =
960 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
962 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
963 (vk::VkRenderPass)0u, // renderPass
965 (vk::VkFramebuffer)0u, // framebuffer
966 vk::VK_FALSE, // occlusionQueryEnable
967 (vk::VkQueryControlFlags)0,
968 (vk::VkQueryPipelineStatisticFlags)0,
970 const vk::VkCommandBufferAllocateInfo passCmdBufCreateInfo =
972 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
974 *m_cmdPool, // cmdPool
975 vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level
978 const vk::VkCommandBufferBeginInfo passCmdBufBeginInfo =
980 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
982 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
983 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // flags
984 (vk::VkRenderPass)*m_renderPass, // renderPass
986 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
987 vk::VK_FALSE, // occlusionQueryEnable
988 (vk::VkQueryControlFlags)0,
989 (vk::VkQueryPipelineStatisticFlags)0,
991 const vk::VkFenceCreateInfo fenceCreateInfo =
993 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
997 const vk::VkClearValue clearValue = vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
998 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1000 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1002 *m_renderPass, // renderPass
1003 *m_framebuffer, // framebuffer
1004 renderArea, // renderArea
1005 1u, // clearValueCount
1006 &clearValue, // pClearValues
1009 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1010 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1011 const vk::Unique<vk::VkCommandBuffer> mainCmd (vk::allocateCommandBuffer(m_vki, m_device, &mainCmdBufCreateInfo));
1012 const vk::Unique<vk::VkCommandBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCommandBuffer>()) : (vk::allocateCommandBuffer(m_vki, m_device, &passCmdBufCreateInfo)));
1013 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1014 const deUint64 infiniteTimeout = ~(deUint64)0u;
1015 const vk::VkSubpassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_SUBPASS_CONTENTS_INLINE) : (vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1017 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1018 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1020 if (m_isPrimaryCmdBuf)
1022 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1023 writeDrawCmdBuffer(*mainCmd);
1027 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1028 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1029 writeDrawCmdBuffer(*passCmd);
1030 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1032 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1035 m_vki.cmdEndRenderPass(*mainCmd);
1036 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1038 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1040 const vk::VkSubmitInfo submitInfo =
1042 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1045 (const vk::VkSemaphore*)0,
1049 (const vk::VkSemaphore*)0,
1051 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *fence));
1053 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1056 enum ShaderInputInterface
1058 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1059 SHADER_INPUT_MULTIPLE_DESCRIPTORS, //!< multiple descriptors
1060 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1065 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1067 switch (shaderInterface)
1069 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1070 case SHADER_INPUT_MULTIPLE_DESCRIPTORS: return 2u;
1071 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1074 DE_FATAL("Impossible");
1079 class BufferRenderInstance : public SingleCmdRenderInstance
1082 BufferRenderInstance (Context& context,
1083 bool isPrimaryCmdBuf,
1084 vk::VkDescriptorType descriptorType,
1085 vk::VkShaderStageFlags stageFlags,
1086 ShaderInputInterface shaderInterface,
1089 bool dynamicOffsetNonZero);
1091 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1092 vk::VkDevice device,
1093 vk::Allocator& allocator,
1094 vk::VkDescriptorType descriptorType,
1096 deUint32 bufferSize,
1097 de::MovePtr<vk::Allocation>* outMemory);
1099 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1100 vk::VkDevice device,
1101 vk::VkDescriptorType descriptorType,
1102 ShaderInputInterface shaderInterface);
1104 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1105 vk::VkDevice device,
1106 vk::VkDescriptorType descriptorType,
1107 ShaderInputInterface shaderInterface,
1108 vk::VkShaderStageFlags stageFlags);
1110 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1111 vk::VkDevice device,
1112 vk::VkDescriptorSetLayout descriptorSetLayout,
1113 vk::VkDescriptorPool descriptorPool,
1114 vk::VkDescriptorType descriptorType,
1115 ShaderInputInterface shaderInterface,
1116 vk::VkBuffer sourceBufferA,
1117 const deUint32 viewOffsetA,
1118 vk::VkBuffer sourceBufferB,
1119 const deUint32 viewOffsetB);
1121 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1122 vk::VkDevice device,
1123 vk::VkDescriptorSetLayout descriptorSetLayout);
1125 void logTestPlan (void) const;
1126 vk::VkPipelineLayout getPipelineLayout (void) const;
1127 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1128 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1133 BUFFER_DATA_SIZE = 8 * sizeof(float),
1134 BUFFER_SIZE_A = 2048, //!< a lot more than required
1135 BUFFER_SIZE_B = 2560, //!< a lot more than required
1137 STATIC_OFFSET_VALUE_A = 256,
1138 DYNAMIC_OFFSET_VALUE_A = 512,
1139 STATIC_OFFSET_VALUE_B = 1024,
1140 DYNAMIC_OFFSET_VALUE_B = 768,
1143 const vk::VkDescriptorType m_descriptorType;
1144 const ShaderInputInterface m_shaderInterface;
1145 const bool m_setViewOffset;
1146 const bool m_setDynamicOffset;
1147 const bool m_dynamicOffsetNonZero;
1148 const vk::VkShaderStageFlags m_stageFlags;
1150 const deUint32 m_viewOffsetA;
1151 const deUint32 m_viewOffsetB;
1152 const deUint32 m_dynamicOffsetA;
1153 const deUint32 m_dynamicOffsetB;
1154 const deUint32 m_effectiveOffsetA;
1155 const deUint32 m_effectiveOffsetB;
1156 const deUint32 m_bufferSizeA;
1157 const deUint32 m_bufferSizeB;
1159 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1160 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1161 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1162 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1163 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1164 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1165 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1166 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1169 BufferRenderInstance::BufferRenderInstance (Context& context,
1170 bool isPrimaryCmdBuf,
1171 vk::VkDescriptorType descriptorType,
1172 vk::VkShaderStageFlags stageFlags,
1173 ShaderInputInterface shaderInterface,
1176 bool dynamicOffsetNonZero)
1177 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1178 , m_descriptorType (descriptorType)
1179 , m_shaderInterface (shaderInterface)
1180 , m_setViewOffset (viewOffset)
1181 , m_setDynamicOffset (dynamicOffset)
1182 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1183 , m_stageFlags (stageFlags)
1184 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1185 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1186 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1187 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1188 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetA + m_dynamicOffsetA) : (m_viewOffsetA))
1189 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetB + m_dynamicOffsetB) : (m_viewOffsetB))
1190 , m_bufferSizeA (BUFFER_SIZE_A)
1191 , m_bufferSizeB (BUFFER_SIZE_B)
1192 , m_bufferMemoryA (DE_NULL)
1193 , m_bufferMemoryB (DE_NULL)
1194 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1195 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1196 ? vk::Move<vk::VkBuffer>()
1197 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1198 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1199 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
1200 , m_descriptorSet (createDescriptorSet(m_vki, m_device, *m_descriptorSetLayout, *m_descriptorPool, m_descriptorType, m_shaderInterface, *m_sourceBufferA, m_viewOffsetA, *m_sourceBufferB, m_viewOffsetB))
1201 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1203 if (m_setDynamicOffset)
1204 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1205 if (m_dynamicOffsetNonZero)
1206 DE_ASSERT(m_setDynamicOffset);
1209 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1210 vk::VkDevice device,
1211 vk::Allocator& allocator,
1212 vk::VkDescriptorType descriptorType,
1214 deUint32 bufferSize,
1215 de::MovePtr<vk::Allocation>* outMemory)
1217 static const float s_colors[] =
1219 0.0f, 1.0f, 0.0f, 1.0f, // green
1220 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1222 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1223 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1224 DE_ASSERT(offset % sizeof(float) == 0);
1225 DE_ASSERT(bufferSize % sizeof(float) == 0);
1227 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1228 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1229 const float preGuardValue = 0.5f;
1230 const float postGuardValue = 0.75f;
1231 const vk::VkBufferCreateInfo bufferCreateInfo =
1233 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1237 usageFlags, // usage
1238 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1239 0u, // queueFamilyCount
1240 DE_NULL, // pQueueFamilyIndices
1242 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1243 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1244 void* const mapPtr = bufferMemory->getHostPtr();
1246 // guard with interesting values
1247 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1248 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1250 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1251 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1252 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1253 deMemset((deUint8*)mapPtr + offset + sizeof(s_colors), 0x5A, (size_t)bufferSize - (size_t)offset - sizeof(s_colors)); // fill with interesting pattern that produces valid floats
1255 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1257 *outMemory = bufferMemory;
1261 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1262 vk::VkDevice device,
1263 vk::VkDescriptorType descriptorType,
1264 ShaderInputInterface shaderInterface)
1266 return vk::DescriptorPoolBuilder()
1267 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1268 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1271 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1272 vk::VkDevice device,
1273 vk::VkDescriptorType descriptorType,
1274 ShaderInputInterface shaderInterface,
1275 vk::VkShaderStageFlags stageFlags)
1277 vk::DescriptorSetLayoutBuilder builder;
1279 switch (shaderInterface)
1281 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1282 builder.addSingleBinding(descriptorType, stageFlags);
1285 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1286 builder.addSingleBinding(descriptorType, stageFlags);
1287 builder.addSingleBinding(descriptorType, stageFlags);
1290 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1291 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1295 DE_FATAL("Impossible");
1298 return builder.build(vki, device);
1301 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1302 vk::VkDevice device,
1303 vk::VkDescriptorSetLayout descriptorSetLayout,
1304 vk::VkDescriptorPool descriptorPool,
1305 vk::VkDescriptorType descriptorType,
1306 ShaderInputInterface shaderInterface,
1307 vk::VkBuffer bufferA,
1309 vk::VkBuffer bufferB,
1312 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1314 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1315 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1317 const vk::VkDescriptorSetAllocateInfo allocInfo =
1319 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1323 &descriptorSetLayout
1326 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1327 vk::DescriptorSetUpdateBuilder builder;
1329 switch (shaderInterface)
1331 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1332 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1335 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1336 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1337 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1340 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1341 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1345 DE_FATAL("Impossible");
1348 builder.update(vki, device);
1349 return descriptorSet;
1352 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1353 vk::VkDevice device,
1354 vk::VkDescriptorSetLayout descriptorSetLayout)
1356 const vk::VkPipelineLayoutCreateInfo createInfo =
1358 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1360 (vk::VkPipelineLayoutCreateFlags)0,
1361 1, // descriptorSetCount
1362 &descriptorSetLayout, // pSetLayouts
1363 0u, // pushConstantRangeCount
1364 DE_NULL, // pPushConstantRanges
1367 return vk::createPipelineLayout(vki, device, &createInfo);
1370 void BufferRenderInstance::logTestPlan (void) const
1372 std::ostringstream msg;
1374 msg << "Rendering 2x2 yellow-green grid.\n"
1375 << "Single descriptor set. Descriptor set contains "
1376 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1377 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
1378 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1379 (const char*)DE_NULL)
1380 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1381 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1383 if (isDynamicDescriptorType(m_descriptorType))
1385 if (m_setDynamicOffset)
1387 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1388 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1392 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1396 if (m_stageFlags == 0u)
1398 msg << "Descriptors are not accessed in any shader stage.\n";
1402 msg << "Descriptors are accessed in {"
1403 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1404 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1405 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1406 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1407 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1411 m_context.getTestContext().getLog()
1412 << tcu::TestLog::Message
1414 << tcu::TestLog::EndMessage;
1417 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1419 return *m_pipelineLayout;
1422 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1424 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1426 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1427 const deUint32 dynamicOffsets[] =
1432 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1433 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1435 // make host writes device-visible
1436 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
1437 const vk::VkBufferMemoryBarrier memoryBarrierA =
1439 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1441 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
1442 inputBit, // inputMask
1443 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1444 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1445 *m_sourceBufferA, // buffer
1447 (vk::VkDeviceSize)m_bufferSizeA, // size
1449 const vk::VkBufferMemoryBarrier memoryBarrierB =
1451 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1453 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
1454 inputBit, // inputMask
1455 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1456 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1457 *m_sourceBufferB, // buffer
1459 (vk::VkDeviceSize)m_bufferSizeB, // size
1461 const void* const memoryBarriers[2] =
1466 const deUint32 numMemoryBarriers = getInterfaceNumResources(m_shaderInterface);
1468 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1469 m_vki.cmdPipelineBarrier(cmd, 0u, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_FALSE, numMemoryBarriers, memoryBarriers);
1470 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1473 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1475 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1476 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1477 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1479 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1481 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1482 return tcu::TestStatus::fail("Image verification failed");
1484 return tcu::TestStatus::pass("Pass");
1487 class ComputeInstanceResultBuffer
1492 DATA_SIZE = sizeof(tcu::Vec4[4])
1495 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1496 vk::VkDevice device,
1497 vk::Allocator& allocator);
1499 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1501 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1502 inline const void* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1505 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1506 vk::VkDevice device,
1507 vk::Allocator& allocator,
1508 de::MovePtr<vk::Allocation>* outAllocation);
1510 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1512 const vk::DeviceInterface& m_vki;
1513 const vk::VkDevice m_device;
1515 de::MovePtr<vk::Allocation> m_bufferMem;
1516 const vk::Unique<vk::VkBuffer> m_buffer;
1517 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1520 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1521 vk::VkDevice device,
1522 vk::Allocator& allocator)
1525 , m_bufferMem (DE_NULL)
1526 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1527 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1531 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1533 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1534 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1537 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1538 vk::VkDevice device,
1539 vk::Allocator& allocator,
1540 de::MovePtr<vk::Allocation>* outAllocation)
1542 const vk::VkBufferCreateInfo createInfo =
1544 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1547 (vk::VkDeviceSize)DATA_SIZE, // size
1548 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1549 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1550 0u, // queueFamilyCount
1551 DE_NULL, // pQueueFamilyIndices
1553 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1554 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1555 const float clearValue = -1.0f;
1556 void* mapPtr = allocation->getHostPtr();
1558 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1559 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1561 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1563 *outAllocation = allocation;
1567 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1569 const vk::VkBufferMemoryBarrier bufferBarrier =
1571 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1573 vk::VK_ACCESS_SHADER_WRITE_BIT, // outputMask
1574 vk::VK_ACCESS_HOST_READ_BIT, // inputMask
1575 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1576 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1578 (vk::VkDeviceSize)0u, // offset
1581 return bufferBarrier;
1584 class ComputePipeline
1587 ComputePipeline (const vk::DeviceInterface& vki,
1588 vk::VkDevice device,
1589 const vk::BinaryCollection& programCollection,
1590 deUint32 numDescriptorSets,
1591 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1593 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1594 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1597 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1598 vk::VkDevice device,
1599 deUint32 numDescriptorSets,
1600 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1602 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1603 vk::VkDevice device,
1604 const vk::BinaryCollection& programCollection,
1605 vk::VkPipelineLayout layout);
1607 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1608 const vk::Unique<vk::VkPipeline> m_pipeline;
1611 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1612 vk::VkDevice device,
1613 const vk::BinaryCollection& programCollection,
1614 deUint32 numDescriptorSets,
1615 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1616 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
1617 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
1621 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
1622 vk::VkDevice device,
1623 deUint32 numDescriptorSets,
1624 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1626 const vk::VkPipelineLayoutCreateInfo createInfo =
1628 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1630 (vk::VkPipelineLayoutCreateFlags)0,
1631 numDescriptorSets, // descriptorSetCount
1632 descriptorSetLayouts, // pSetLayouts
1633 0u, // pushConstantRangeCount
1634 DE_NULL, // pPushConstantRanges
1636 return vk::createPipelineLayout(vki, device, &createInfo);
1639 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
1640 vk::VkDevice device,
1641 const vk::BinaryCollection& programCollection,
1642 vk::VkPipelineLayout layout)
1644 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
1645 const vk::VkPipelineShaderStageCreateInfo cs =
1647 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1649 (vk::VkPipelineShaderStageCreateFlags)0,
1650 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
1651 *computeModule, // shader
1653 DE_NULL, // pSpecializationInfo
1655 const vk::VkComputePipelineCreateInfo createInfo =
1657 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1662 (vk::VkPipeline)0, // basePipelineHandle
1663 0u, // basePipelineIndex
1665 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
1668 class ComputeCommand
1671 ComputeCommand (const vk::DeviceInterface& vki,
1672 vk::VkDevice device,
1673 vk::VkPipeline pipeline,
1674 vk::VkPipelineLayout pipelineLayout,
1675 const tcu::UVec3& numWorkGroups,
1676 int numDescriptorSets,
1677 const vk::VkDescriptorSet* descriptorSets,
1678 int numDynamicOffsets,
1679 const deUint32* dynamicOffsets,
1681 const void* const* preBarriers,
1682 int numPostBarriers,
1683 const void* const* postBarriers);
1685 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const;
1688 const vk::DeviceInterface& m_vki;
1689 const vk::VkDevice m_device;
1690 const vk::VkPipeline m_pipeline;
1691 const vk::VkPipelineLayout m_pipelineLayout;
1692 const tcu::UVec3& m_numWorkGroups;
1693 const int m_numDescriptorSets;
1694 const vk::VkDescriptorSet* const m_descriptorSets;
1695 const int m_numDynamicOffsets;
1696 const deUint32* const m_dynamicOffsets;
1697 const int m_numPreBarriers;
1698 const void* const* const m_preBarriers;
1699 const int m_numPostBarriers;
1700 const void* const* const m_postBarriers;
1703 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
1704 vk::VkDevice device,
1705 vk::VkPipeline pipeline,
1706 vk::VkPipelineLayout pipelineLayout,
1707 const tcu::UVec3& numWorkGroups,
1708 int numDescriptorSets,
1709 const vk::VkDescriptorSet* descriptorSets,
1710 int numDynamicOffsets,
1711 const deUint32* dynamicOffsets,
1713 const void* const* preBarriers,
1714 int numPostBarriers,
1715 const void* const* postBarriers)
1718 , m_pipeline (pipeline)
1719 , m_pipelineLayout (pipelineLayout)
1720 , m_numWorkGroups (numWorkGroups)
1721 , m_numDescriptorSets (numDescriptorSets)
1722 , m_descriptorSets (descriptorSets)
1723 , m_numDynamicOffsets (numDynamicOffsets)
1724 , m_dynamicOffsets (dynamicOffsets)
1725 , m_numPreBarriers (numPreBarriers)
1726 , m_preBarriers (preBarriers)
1727 , m_numPostBarriers (numPostBarriers)
1728 , m_postBarriers (postBarriers)
1732 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const
1734 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
1736 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1738 queueFamilyIndex, // queueFamilyIndex
1739 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
1741 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
1743 const vk::VkFenceCreateInfo fenceCreateInfo =
1745 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1750 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
1752 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1754 *cmdPool, // cmdPool
1755 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1758 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
1760 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1762 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1763 (vk::VkRenderPass)0u, // renderPass
1765 (vk::VkFramebuffer)0u, // framebuffer
1766 vk::VK_FALSE, // occlusionQueryEnable
1767 (vk::VkQueryControlFlags)0,
1768 (vk::VkQueryPipelineStatisticFlags)0,
1771 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1772 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
1773 const deUint64 infiniteTimeout = ~(deUint64)0u;
1775 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
1777 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
1778 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
1780 if (m_numPreBarriers)
1781 m_vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_FALSE, m_numPreBarriers, m_preBarriers);
1783 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
1784 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, m_numPostBarriers, m_postBarriers);
1785 VK_CHECK(m_vki.endCommandBuffer(*cmd));
1789 const vk::VkSubmitInfo submitInfo =
1791 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1794 (const vk::VkSemaphore*)0,
1798 (const vk::VkSemaphore*)0,
1800 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
1802 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1805 class BufferComputeInstance : public vkt::TestInstance
1808 BufferComputeInstance (Context& context,
1809 vk::VkDescriptorType descriptorType,
1810 ShaderInputInterface shaderInterface,
1813 bool dynamicOffsetNonZero);
1816 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
1817 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
1818 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
1819 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
1820 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf) const;
1822 tcu::TestStatus iterate (void);
1823 void logTestPlan (void) const;
1824 tcu::TestStatus testResourceAccess (void);
1828 STATIC_OFFSET_VALUE_A = 256,
1829 DYNAMIC_OFFSET_VALUE_A = 512,
1830 STATIC_OFFSET_VALUE_B = 1024,
1831 DYNAMIC_OFFSET_VALUE_B = 768,
1834 const vk::VkDescriptorType m_descriptorType;
1835 const ShaderInputInterface m_shaderInterface;
1836 const bool m_setViewOffset;
1837 const bool m_setDynamicOffset;
1838 const bool m_dynamicOffsetNonZero;
1840 const vk::DeviceInterface& m_vki;
1841 const vk::VkDevice m_device;
1842 const vk::VkQueue m_queue;
1843 const deUint32 m_queueFamilyIndex;
1844 vk::Allocator& m_allocator;
1846 const ComputeInstanceResultBuffer m_result;
1849 BufferComputeInstance::BufferComputeInstance (Context& context,
1850 vk::VkDescriptorType descriptorType,
1851 ShaderInputInterface shaderInterface,
1854 bool dynamicOffsetNonZero)
1855 : vkt::TestInstance (context)
1856 , m_descriptorType (descriptorType)
1857 , m_shaderInterface (shaderInterface)
1858 , m_setViewOffset (viewOffset)
1859 , m_setDynamicOffset (dynamicOffset)
1860 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1861 , m_vki (context.getDeviceInterface())
1862 , m_device (context.getDevice())
1863 , m_queue (context.getUniversalQueue())
1864 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
1865 , m_allocator (context.getDefaultAllocator())
1866 , m_result (m_vki, m_device, m_allocator)
1868 if (m_dynamicOffsetNonZero)
1869 DE_ASSERT(m_setDynamicOffset);
1872 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
1874 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
1876 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1877 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1878 const vk::VkBufferCreateInfo createInfo =
1880 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1883 (vk::VkDeviceSize)bufferSize, // size
1884 usageFlags, // usage
1885 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1886 0u, // queueFamilyCount
1887 DE_NULL, // pQueueFamilyIndices
1889 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
1890 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
1891 void* mapPtr = allocation->getHostPtr();
1894 deMemset(mapPtr, 0x5A, (size_t)offset);
1895 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
1896 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
1897 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
1899 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
1901 *outAllocation = allocation;
1905 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
1907 vk::DescriptorSetLayoutBuilder builder;
1909 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1911 switch (m_shaderInterface)
1913 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1914 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1917 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1918 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1919 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1922 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1923 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1927 DE_FATAL("Impossible");
1930 return builder.build(m_vki, m_device);
1933 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
1935 return vk::DescriptorPoolBuilder()
1936 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1937 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
1938 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1941 vk::Move<vk::VkDescriptorSet> BufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf) const
1943 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
1944 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1946 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1947 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1949 const vk::VkDescriptorSetAllocateInfo allocInfo =
1951 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1958 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
1959 vk::DescriptorSetUpdateBuilder builder;
1962 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
1965 switch (m_shaderInterface)
1967 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1968 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
1971 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1972 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
1973 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
1976 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1977 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
1981 DE_FATAL("Impossible");
1984 builder.update(m_vki, m_device);
1985 return descriptorSet;
1988 tcu::TestStatus BufferComputeInstance::iterate (void)
1991 return testResourceAccess();
1994 void BufferComputeInstance::logTestPlan (void) const
1996 std::ostringstream msg;
1998 msg << "Accessing resource in a compute program.\n"
1999 << "Single descriptor set. Descriptor set contains "
2000 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2001 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
2002 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2003 (const char*)DE_NULL)
2004 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2005 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2006 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2008 if (isDynamicDescriptorType(m_descriptorType))
2010 if (m_setDynamicOffset)
2012 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2013 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2017 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2021 msg << "Destination buffer is pre-initialized to -1.\n";
2023 m_context.getTestContext().getLog()
2024 << tcu::TestLog::Message
2026 << tcu::TestLog::EndMessage;
2029 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2033 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2036 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2037 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2038 const deUint32 bindTimeOffsets[] =
2040 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2041 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2044 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2045 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2046 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2047 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2049 const deUint32 dataOffsetA = (isDynamicCase) ? (bindTimeOffsets[0]) : (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2050 const deUint32 dataOffsetB = (isDynamicCase) ? (bindTimeOffsets[1]) : (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2051 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2052 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2053 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2054 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2056 de::MovePtr<vk::Allocation> bufferMemA;
2057 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2059 de::MovePtr<vk::Allocation> bufferMemB;
2060 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2061 ? (vk::Move<vk::VkBuffer>())
2062 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2064 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2065 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2066 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer()));
2067 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2069 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2070 const vk::VkBufferMemoryBarrier bufferBarrierA =
2072 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2074 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2075 inputBit, // inputMask
2076 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2077 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2079 (vk::VkDeviceSize)0u, // offset
2080 (vk::VkDeviceSize)bufferSizeA, // size
2082 const vk::VkBufferMemoryBarrier bufferBarrierB =
2084 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2086 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2087 inputBit, // inputMask
2088 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2089 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2091 (vk::VkDeviceSize)0u, // offset
2092 (vk::VkDeviceSize)bufferSizeB, // size
2095 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2097 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2098 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2099 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2100 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2101 const void* const preBarriers[] = { &bufferBarrierA, &bufferBarrierB };
2102 const int numPreBarriers = numSrcBuffers;
2103 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
2104 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
2106 const ComputeCommand compute (m_vki,
2108 pipeline.getPipeline(),
2109 pipeline.getPipelineLayout(),
2110 tcu::UVec3(4, 1, 1),
2111 numDescriptorSets, descriptorSets,
2112 numDynamicOffsets, dynamicOffsets,
2113 numPreBarriers, preBarriers,
2114 numPostBarriers, postBarriers);
2116 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2117 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorB2) :
2118 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2120 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2121 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorA1) :
2122 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2124 const tcu::Vec4 references[4] =
2131 tcu::Vec4 results[4];
2133 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2134 m_result.readResultContentsTo(&results);
2137 if (results[0] == references[0] &&
2138 results[1] == references[1] &&
2139 results[2] == references[2] &&
2140 results[3] == references[3])
2142 return tcu::TestStatus::pass("Pass");
2144 else if (results[0] == tcu::Vec4(-1.0f) &&
2145 results[1] == tcu::Vec4(-1.0f) &&
2146 results[2] == tcu::Vec4(-1.0f) &&
2147 results[3] == tcu::Vec4(-1.0f))
2149 m_context.getTestContext().getLog()
2150 << tcu::TestLog::Message
2151 << "Result buffer was not written to."
2152 << tcu::TestLog::EndMessage;
2153 return tcu::TestStatus::fail("Result buffer was not written to");
2157 m_context.getTestContext().getLog()
2158 << tcu::TestLog::Message
2159 << "Error expected ["
2160 << references[0] << ", "
2161 << references[1] << ", "
2162 << references[2] << ", "
2163 << references[3] << "], got ["
2164 << results[0] << ", "
2165 << results[1] << ", "
2166 << results[2] << ", "
2167 << results[3] << "]"
2168 << tcu::TestLog::EndMessage;
2169 return tcu::TestStatus::fail("Invalid result values");
2173 class QuadrantRendederCase : public vkt::TestCase
2176 QuadrantRendederCase (tcu::TestContext& testCtx,
2178 const char* description,
2179 glu::GLSLVersion glslVersion,
2180 vk::VkShaderStageFlags exitingStages,
2181 vk::VkShaderStageFlags activeStages);
2183 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
2184 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
2185 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
2186 virtual std::string genNoAccessSource (void) const = 0;
2188 std::string genVertexSource (void) const;
2189 std::string genTessCtrlSource (void) const;
2190 std::string genTessEvalSource (void) const;
2191 std::string genGeometrySource (void) const;
2192 std::string genFragmentSource (void) const;
2193 std::string genComputeSource (void) const;
2195 void initPrograms (vk::SourceCollections& programCollection) const;
2198 const glu::GLSLVersion m_glslVersion;
2199 const vk::VkShaderStageFlags m_exitingStages;
2200 const vk::VkShaderStageFlags m_activeStages;
2203 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2205 const char* description,
2206 glu::GLSLVersion glslVersion,
2207 vk::VkShaderStageFlags exitingStages,
2208 vk::VkShaderStageFlags activeStages)
2209 : vkt::TestCase (testCtx, name, description)
2210 , m_glslVersion (glslVersion)
2211 , m_exitingStages (exitingStages)
2212 , m_activeStages (activeStages)
2214 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2217 std::string QuadrantRendederCase::genVertexSource (void) const
2219 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
2220 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2221 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2223 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2224 std::ostringstream buf;
2226 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2228 // active vertex shader
2229 buf << versionDecl << "\n"
2230 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2231 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0)
2232 << "layout(location = 0) out highp vec4 " << nextStageName << "_color;\n"
2233 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2234 << "void main (void)\n"
2236 << " highp vec4 result_position;\n"
2237 << " highp int quadrant_id;\n"
2238 << s_quadrantGenVertexPosSource
2239 << " gl_Position = result_position;\n"
2240 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2242 << " highp vec4 result_color;\n"
2243 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
2244 << " " << nextStageName << "_color = result_color;\n"
2250 buf << versionDecl << "\n"
2251 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2252 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2253 << "void main (void)\n"
2255 << " highp vec4 result_position;\n"
2256 << " highp int quadrant_id;\n"
2257 << s_quadrantGenVertexPosSource
2258 << " gl_Position = result_position;\n"
2259 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2266 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2268 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2269 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2270 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2271 std::ostringstream buf;
2273 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2275 // contributing not implemented
2276 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2279 buf << versionDecl << "\n"
2281 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2282 << "layout(vertices=3) out;\n"
2283 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
2284 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2285 << "layout(location = 0) out highp vec4 tes_color[];\n"
2286 << "void main (void)\n"
2288 << " highp vec4 result_color;\n"
2289 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2290 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2292 << " tes_color[gl_InvocationID] = result_color;\n"
2294 << " // no dynamic input block indexing\n"
2295 << " highp vec4 position;\n"
2296 << " if (gl_InvocationID == 0)\n"
2297 << " position = gl_in[0].gl_Position;\n"
2298 << " else if (gl_InvocationID == 1)\n"
2299 << " position = gl_in[1].gl_Position;\n"
2301 << " position = gl_in[2].gl_Position;\n"
2302 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2303 << " gl_TessLevelInner[0] = 2.8;\n"
2304 << " gl_TessLevelInner[1] = 2.8;\n"
2305 << " gl_TessLevelOuter[0] = 2.8;\n"
2306 << " gl_TessLevelOuter[1] = 2.8;\n"
2307 << " gl_TessLevelOuter[2] = 2.8;\n"
2308 << " gl_TessLevelOuter[3] = 2.8;\n"
2311 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2313 // active te shader, tc passthru
2314 buf << versionDecl << "\n"
2316 << "layout(vertices=3) out;\n"
2317 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2318 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2319 << "void main (void)\n"
2321 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2323 << " // no dynamic input block indexing\n"
2324 << " highp vec4 position;\n"
2325 << " if (gl_InvocationID == 0)\n"
2326 << " position = gl_in[0].gl_Position;\n"
2327 << " else if (gl_InvocationID == 1)\n"
2328 << " position = gl_in[1].gl_Position;\n"
2330 << " position = gl_in[2].gl_Position;\n"
2331 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2332 << " gl_TessLevelInner[0] = 2.8;\n"
2333 << " gl_TessLevelInner[1] = 2.8;\n"
2334 << " gl_TessLevelOuter[0] = 2.8;\n"
2335 << " gl_TessLevelOuter[1] = 2.8;\n"
2336 << " gl_TessLevelOuter[2] = 2.8;\n"
2337 << " gl_TessLevelOuter[3] = 2.8;\n"
2342 // passthrough not implemented
2343 DE_FATAL("not implemented");
2349 std::string QuadrantRendederCase::genTessEvalSource (void) const
2351 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2352 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2353 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2354 std::ostringstream buf;
2356 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2358 // contributing not implemented
2359 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
2362 buf << versionDecl << "\n"
2364 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2365 << "layout(triangles) in;\n"
2366 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
2367 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2368 << "layout(location = 0) out highp vec4 frag_color;\n"
2369 << "void main (void)\n"
2371 << " highp vec4 result_color;\n"
2372 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2373 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2375 << " frag_color = result_color;\n"
2376 << " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n"
2379 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2381 // contributing not implemented
2382 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2384 // active tc shader, te is passthru
2385 buf << versionDecl << "\n"
2387 << "layout(triangles) in;\n"
2388 << "layout(location = 0) in highp vec4 tes_color[];\n"
2389 << "layout(location = 0) out highp vec4 frag_color;\n"
2390 << "void main (void)\n"
2392 << " frag_color = tes_color[0];\n"
2393 << " gl_Position = gl_TessCoord.x * gl_in[0].gl_Position + gl_TessCoord.y * gl_in[1].gl_Position + gl_TessCoord.z * gl_in[2].gl_Position;\n"
2398 // passthrough not implemented
2399 DE_FATAL("not implemented");
2405 std::string QuadrantRendederCase::genGeometrySource (void) const
2407 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2408 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2409 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
2410 std::ostringstream buf;
2412 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2414 // contributing not implemented
2415 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
2417 // active geometry shader
2418 buf << versionDecl << "\n"
2420 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2421 << "layout(triangles) in;\n"
2422 << "layout(triangle_strip, max_vertices=4) out;\n"
2423 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
2424 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
2425 << "layout(location = 0) out highp vec4 frag_color;\n"
2426 << "void main (void)\n"
2428 << " highp int quadrant_id;\n"
2429 << " highp vec4 result_color;\n"
2431 << " quadrant_id = geo_quadrant_id[0];\n"
2432 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2433 << " frag_color = result_color;\n"
2434 << " gl_Position = gl_in[0].gl_Position;\n"
2435 << " EmitVertex();\n"
2437 << " quadrant_id = geo_quadrant_id[1];\n"
2438 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2439 << " frag_color = result_color;\n"
2440 << " gl_Position = gl_in[1].gl_Position;\n"
2441 << " EmitVertex();\n"
2443 << " quadrant_id = geo_quadrant_id[2];\n"
2444 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2445 << " frag_color = result_color;\n"
2446 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
2447 << " EmitVertex();\n"
2449 << " quadrant_id = geo_quadrant_id[0];\n"
2450 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2451 << " frag_color = result_color;\n"
2452 << " gl_Position = gl_in[2].gl_Position;\n"
2453 << " EmitVertex();\n"
2458 // passthrough not implemented
2459 DE_FATAL("not implemented");
2465 std::string QuadrantRendederCase::genFragmentSource (void) const
2467 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2468 std::ostringstream buf;
2470 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2472 buf << versionDecl << "\n"
2473 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2474 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
2476 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2478 // there are other stages, this is just a contributor
2479 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
2482 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2483 << "layout(location = 0) out mediump vec4 o_color;\n"
2484 << "void main (void)\n"
2486 << " highp int quadrant_id = frag_quadrant_id;\n"
2487 << " highp vec4 result_color;\n"
2488 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
2490 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2493 buf << " if (frag_quadrant_id < 2)\n"
2494 << " o_color = result_color;\n"
2496 << " o_color = frag_color;\n";
2499 buf << " o_color = result_color;\n";
2503 else if (m_activeStages == 0u)
2505 // special case, no active stages
2506 buf << versionDecl << "\n"
2507 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2508 << "layout(location = 0) out mediump vec4 o_color;\n"
2509 << "void main (void)\n"
2511 << " highp int quadrant_id = frag_quadrant_id;\n"
2512 << " highp vec4 result_color;\n"
2513 << genNoAccessSource()
2514 << " o_color = result_color;\n"
2520 buf << versionDecl << "\n"
2521 << "layout(location = 0) in mediump vec4 frag_color;\n"
2522 "layout(location = 0) out mediump vec4 o_color;\n"
2523 "void main (void)\n"
2525 " o_color = frag_color;\n"
2532 std::string QuadrantRendederCase::genComputeSource (void) const
2534 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2535 std::ostringstream buf;
2537 buf << versionDecl << "\n"
2538 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2539 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2540 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
2541 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
2543 << " highp vec4 read_colors[4];\n"
2545 << "void main(void)\n"
2547 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
2548 << " highp vec4 result_color;\n"
2549 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2550 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
2556 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
2558 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2559 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
2561 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2562 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
2564 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2565 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
2567 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2568 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
2570 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2571 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
2573 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
2574 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
2577 class BufferDescriptorCase : public QuadrantRendederCase
2582 FLAG_VIEW_OFFSET = (1u << 1u),
2583 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
2584 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
2586 // enum continues where resource flags ends
2587 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
2589 BufferDescriptorCase (tcu::TestContext& testCtx,
2591 const char* description,
2592 bool isPrimaryCmdBuf,
2593 vk::VkDescriptorType descriptorType,
2594 vk::VkShaderStageFlags exitingStages,
2595 vk::VkShaderStageFlags activeStages,
2596 ShaderInputInterface shaderInterface,
2600 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
2601 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
2602 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
2603 std::string genNoAccessSource (void) const;
2605 vkt::TestInstance* createInstance (vkt::Context& context) const;
2607 const bool m_viewOffset;
2608 const bool m_dynamicOffsetSet;
2609 const bool m_dynamicOffsetNonZero;
2610 const bool m_isPrimaryCmdBuf;
2611 const vk::VkDescriptorType m_descriptorType;
2612 const ShaderInputInterface m_shaderInterface;
2615 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
2617 const char* description,
2618 bool isPrimaryCmdBuf,
2619 vk::VkDescriptorType descriptorType,
2620 vk::VkShaderStageFlags exitingStages,
2621 vk::VkShaderStageFlags activeStages,
2622 ShaderInputInterface shaderInterface,
2624 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
2625 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
2626 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
2627 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
2628 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
2629 , m_descriptorType (descriptorType)
2630 , m_shaderInterface (shaderInterface)
2634 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
2640 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
2644 const bool isUniform = isUniformDescriptorType(m_descriptorType);
2645 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
2646 std::ostringstream buf;
2648 switch (m_shaderInterface)
2650 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2651 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2653 << " highp vec4 colorA;\n"
2654 << " highp vec4 colorB;\n"
2655 << "} b_instance;\n";
2658 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2659 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
2661 << " highp vec4 colorA;\n"
2662 << " highp vec4 colorB;\n"
2663 << "} b_instanceA;\n"
2664 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
2666 << " highp vec4 colorA;\n"
2667 << " highp vec4 colorB;\n"
2668 << "} b_instanceB;\n";
2671 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2672 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2674 << " highp vec4 colorA;\n"
2675 << " highp vec4 colorB;\n"
2676 << "} b_instances[2];\n";
2680 DE_FATAL("Impossible");
2686 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
2690 std::ostringstream buf;
2692 switch (m_shaderInterface)
2694 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2695 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2696 << " result_color = b_instance.colorA;\n"
2698 << " result_color = b_instance.colorB;\n";
2701 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2702 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2703 << " result_color = b_instanceA.colorA;\n"
2705 << " result_color = b_instanceB.colorB;\n";
2708 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2709 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2710 << " result_color = b_instances[0].colorA;\n"
2712 << " result_color = b_instances[1].colorB;\n";
2716 DE_FATAL("Impossible");
2722 std::string BufferDescriptorCase::genNoAccessSource (void) const
2724 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
2725 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2727 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
2730 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
2732 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
2734 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
2735 return new BufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2738 return new BufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2741 class ImageInstanceImages
2744 ImageInstanceImages (const vk::DeviceInterface& vki,
2745 vk::VkDevice device,
2746 deUint32 queueFamilyIndex,
2748 vk::Allocator& allocator,
2749 vk::VkDescriptorType descriptorType,
2750 vk::VkImageViewType viewType,
2752 deUint32 baseMipLevel,
2753 deUint32 baseArraySlice);
2756 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
2757 vk::VkDevice device,
2758 vk::Allocator& allocator,
2759 vk::VkDescriptorType descriptorType,
2760 vk::VkImageViewType viewType,
2761 const tcu::TextureLevelPyramid& sourceImage,
2762 de::MovePtr<vk::Allocation>* outAllocation);
2764 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
2765 vk::VkDevice device,
2766 vk::VkImageViewType viewType,
2767 const tcu::TextureLevelPyramid& sourceImage,
2769 deUint32 baseMipLevel,
2770 deUint32 baseArraySlice);
2772 void populateSourceImage (tcu::TextureLevelPyramid* dst,
2773 bool isFirst) const;
2775 void uploadImage (const vk::DeviceInterface& vki,
2776 vk::VkDevice device,
2777 deUint32 queueFamilyIndex,
2779 vk::Allocator& allocator,
2781 const tcu::TextureLevelPyramid& data);
2791 const vk::VkImageViewType m_viewType;
2792 const deUint32 m_baseMipLevel;
2793 const deUint32 m_baseArraySlice;
2795 const tcu::TextureFormat m_imageFormat;
2796 tcu::TextureLevelPyramid m_sourceImageA;
2797 tcu::TextureLevelPyramid m_sourceImageB;
2799 de::MovePtr<vk::Allocation> m_imageMemoryA;
2800 de::MovePtr<vk::Allocation> m_imageMemoryB;
2801 vk::Move<vk::VkImage> m_imageA;
2802 vk::Move<vk::VkImage> m_imageB;
2803 vk::Move<vk::VkImageView> m_imageViewA;
2804 vk::Move<vk::VkImageView> m_imageViewB;
2807 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
2808 vk::VkDevice device,
2809 deUint32 queueFamilyIndex,
2811 vk::Allocator& allocator,
2812 vk::VkDescriptorType descriptorType,
2813 vk::VkImageViewType viewType,
2815 deUint32 baseMipLevel,
2816 deUint32 baseArraySlice)
2817 : m_viewType (viewType)
2818 , m_baseMipLevel (baseMipLevel)
2819 , m_baseArraySlice (baseArraySlice)
2820 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
2821 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
2822 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
2823 , m_imageMemoryA (DE_NULL)
2824 , m_imageMemoryB (DE_NULL)
2825 , m_imageA (vk::Move<vk::VkImage>())
2826 , m_imageB (vk::Move<vk::VkImage>())
2827 , m_imageViewA (vk::Move<vk::VkImageView>())
2828 , m_imageViewB (vk::Move<vk::VkImageView>())
2830 DE_ASSERT(numImages == 1 || numImages == 2);
2832 populateSourceImage(&m_sourceImageA, true);
2833 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
2834 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
2835 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, m_sourceImageA);
2839 populateSourceImage(&m_sourceImageB, false);
2840 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
2841 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
2842 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, m_sourceImageB);
2846 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
2847 vk::VkDevice device,
2848 vk::Allocator& allocator,
2849 vk::VkDescriptorType descriptorType,
2850 vk::VkImageViewType viewType,
2851 const tcu::TextureLevelPyramid& sourceImage,
2852 de::MovePtr<vk::Allocation>* outAllocation)
2854 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2855 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
2856 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
2857 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
2858 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
2859 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
2860 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2861 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
2863 const vk::VkExtent3D extent =
2866 (deInt32)baseLevel.getWidth(),
2869 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (deInt32)baseLevel.getHeight(),
2872 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deInt32)baseLevel.getDepth()) : (1),
2874 const vk::VkImageCreateInfo createInfo =
2876 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2878 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
2879 viewTypeToImageType(viewType), // imageType
2880 vk::mapTextureFormat(baseLevel.getFormat()), // format
2882 (deUint32)sourceImage.getNumLevels(), // mipLevels
2883 arraySize, // arraySize
2884 vk::VK_SAMPLE_COUNT_1_BIT, // samples
2885 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
2886 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
2887 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2888 0u, // queueFamilyCount
2889 DE_NULL, // pQueueFamilyIndices
2890 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2892 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
2894 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
2898 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
2899 vk::VkDevice device,
2900 vk::VkImageViewType viewType,
2901 const tcu::TextureLevelPyramid& sourceImage,
2903 deUint32 baseMipLevel,
2904 deUint32 baseArraySlice)
2906 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2907 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
2908 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
2909 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
2910 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
2911 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
2912 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2913 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
2914 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
2917 DE_ASSERT(viewArraySize > 0);
2919 const vk::VkImageSubresourceRange resourceRange =
2921 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
2922 baseMipLevel, // baseMipLevel
2923 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
2924 viewTypeBaseSlice, // baseArraySlice
2925 viewArraySize, // arraySize
2927 const vk::VkImageViewCreateInfo createInfo =
2929 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
2931 (vk::VkImageViewCreateFlags)0,
2933 viewType, // viewType
2934 vk::mapTextureFormat(baseLevel.getFormat()), // format
2936 vk::VK_COMPONENT_SWIZZLE_R,
2937 vk::VK_COMPONENT_SWIZZLE_G,
2938 vk::VK_COMPONENT_SWIZZLE_B,
2939 vk::VK_COMPONENT_SWIZZLE_A
2941 resourceRange, // subresourceRange
2943 return vk::createImageView(vki, device, &createInfo);
2946 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
2948 const int numLevels = dst->getNumLevels();
2950 for (int level = 0; level < numLevels; ++level)
2952 const int width = IMAGE_SIZE >> level;
2953 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
2954 : (IMAGE_SIZE >> level);
2955 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
2956 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
2957 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
2958 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
2961 dst->allocLevel(level, width, height, depth);
2964 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
2966 for (int z = 0; z < depth; ++z)
2967 for (int y = 0; y < height; ++y)
2968 for (int x = 0; x < width; ++x)
2970 const int gradPos = x + y + z;
2971 const int gradMax = width + height + depth - 3;
2973 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
2974 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
2975 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
2977 DE_ASSERT(de::inRange(red, 0, 255));
2978 DE_ASSERT(de::inRange(green, 0, 255));
2979 DE_ASSERT(de::inRange(blue, 0, 255));
2981 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
2987 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
2988 vk::VkDevice device,
2989 deUint32 queueFamilyIndex,
2991 vk::Allocator& allocator,
2993 const tcu::TextureLevelPyramid& data)
2995 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
2996 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
2997 ((deUint32)ARRAY_SIZE);
2998 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
2999 const vk::VkBufferCreateInfo bufferCreateInfo =
3001 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3004 dataBufferSize, // size
3005 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
3006 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3007 0u, // queueFamilyCount
3008 DE_NULL, // pQueueFamilyIndices
3010 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3011 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3012 const vk::VkFenceCreateInfo fenceCreateInfo =
3014 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3018 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3020 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3022 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
3023 vk::VK_ACCESS_TRANSFER_READ_BIT, // inputMask
3024 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3025 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3026 *dataBuffer, // buffer
3028 dataBufferSize, // size
3030 const vk::VkImageSubresourceRange fullSubrange =
3032 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3034 (deUint32)data.getNumLevels(), // mipLevels
3035 0u, // baseArraySlice
3036 arraySize, // arraySize
3038 const vk::VkImageMemoryBarrier preImageBarrier =
3040 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3044 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3045 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout
3046 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3047 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3049 fullSubrange // subresourceRange
3051 const vk::VkImageMemoryBarrier postImageBarrier =
3053 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3055 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask
3056 vk::VK_ACCESS_SHADER_READ_BIT, // inputMask
3057 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout
3058 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
3059 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3060 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3062 fullSubrange // subresourceRange
3064 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
3066 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
3068 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
3069 queueFamilyIndex, // queueFamilyIndex
3071 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3072 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
3074 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
3076 *cmdPool, // cmdPool
3077 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
3080 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
3082 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3084 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
3085 (vk::VkRenderPass)0u, // renderPass
3087 (vk::VkFramebuffer)0u, // framebuffer
3088 vk::VK_FALSE, // occlusionQueryEnable
3089 (vk::VkQueryControlFlags)0,
3090 (vk::VkQueryPipelineStatisticFlags)0,
3093 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(vki, device, &cmdBufCreateInfo));
3094 const void* const preBarriers[2] = { &preMemoryBarrier, &preImageBarrier };
3095 const void* const postBarriers[1] = { &postImageBarrier };
3096 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device, &fenceCreateInfo));
3097 const deUint64 infiniteTimeout = ~(deUint64)0u;
3098 std::vector<vk::VkBufferImageCopy> copySlices;
3100 // copy data to buffer
3101 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3102 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3104 // record command buffer
3105 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3106 vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_FALSE, DE_LENGTH_OF_ARRAY(preBarriers), preBarriers);
3107 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3108 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, DE_LENGTH_OF_ARRAY(postBarriers), postBarriers);
3109 VK_CHECK(vki.endCommandBuffer(*cmd));
3111 // submit and wait for command buffer to complete before killing it
3113 const vk::VkSubmitInfo submitInfo =
3115 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
3118 (const vk::VkSemaphore*)0,
3122 (const vk::VkSemaphore*)0,
3124 VK_CHECK(vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
3126 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3129 class ImageFetchInstanceImages : private ImageInstanceImages
3132 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3133 vk::VkDevice device,
3134 deUint32 queueFamilyIndex,
3136 vk::Allocator& allocator,
3137 vk::VkDescriptorType descriptorType,
3138 ShaderInputInterface shaderInterface,
3139 vk::VkImageViewType viewType,
3140 deUint32 baseMipLevel,
3141 deUint32 baseArraySlice);
3143 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3144 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3146 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3147 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3152 // some arbitrary sample points for all four quadrants
3153 SAMPLE_POINT_0_X = 6,
3154 SAMPLE_POINT_0_Y = 13,
3155 SAMPLE_POINT_0_Z = 49,
3157 SAMPLE_POINT_1_X = 51,
3158 SAMPLE_POINT_1_Y = 40,
3159 SAMPLE_POINT_1_Z = 44,
3161 SAMPLE_POINT_2_X = 42,
3162 SAMPLE_POINT_2_Y = 26,
3163 SAMPLE_POINT_2_Z = 19,
3165 SAMPLE_POINT_3_X = 25,
3166 SAMPLE_POINT_3_Y = 25,
3167 SAMPLE_POINT_3_Z = 18,
3170 const ShaderInputInterface m_shaderInterface;
3173 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3174 vk::VkDevice device,
3175 deUint32 queueFamilyIndex,
3177 vk::Allocator& allocator,
3178 vk::VkDescriptorType descriptorType,
3179 ShaderInputInterface shaderInterface,
3180 vk::VkImageViewType viewType,
3181 deUint32 baseMipLevel,
3182 deUint32 baseArraySlice)
3183 : ImageInstanceImages (vki,
3190 getInterfaceNumResources(shaderInterface), // numImages
3193 , m_shaderInterface (shaderInterface)
3197 bool isImageViewTypeArray (vk::VkImageViewType type)
3199 return type == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || type == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY || type == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY;
3202 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3204 const tcu::IVec3 fetchPositions[4] =
3206 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3207 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3208 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3209 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3211 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3212 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3213 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3217 case vk::VK_IMAGE_VIEW_TYPE_1D:
3218 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3219 case vk::VK_IMAGE_VIEW_TYPE_2D:
3220 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3221 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3222 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3223 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3225 DE_FATAL("Impossible");
3226 return tcu::IVec3();
3230 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3232 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3234 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3235 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3236 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3237 const tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3239 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3242 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3245 ImageFetchRenderInstance (vkt::Context& context,
3246 bool isPrimaryCmdBuf,
3247 vk::VkDescriptorType descriptorType,
3248 vk::VkShaderStageFlags stageFlags,
3249 ShaderInputInterface shaderInterface,
3250 vk::VkImageViewType viewType,
3251 deUint32 baseMipLevel,
3252 deUint32 baseArraySlice);
3255 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3256 vk::VkDevice device,
3257 vk::VkDescriptorType descriptorType,
3258 ShaderInputInterface shaderInterface,
3259 vk::VkShaderStageFlags stageFlags);
3261 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3262 vk::VkDevice device,
3263 vk::VkDescriptorSetLayout descriptorSetLayout);
3265 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3266 vk::VkDevice device,
3267 vk::VkDescriptorType descriptorType,
3268 ShaderInputInterface shaderInterface);
3270 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3271 vk::VkDevice device,
3272 vk::VkDescriptorType descriptorType,
3273 ShaderInputInterface shaderInterface,
3274 vk::VkDescriptorSetLayout layout,
3275 vk::VkDescriptorPool pool,
3276 vk::VkImageView viewA,
3277 vk::VkImageView viewB);
3279 void logTestPlan (void) const;
3280 vk::VkPipelineLayout getPipelineLayout (void) const;
3281 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
3282 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3289 const vk::VkDescriptorType m_descriptorType;
3290 const vk::VkShaderStageFlags m_stageFlags;
3291 const ShaderInputInterface m_shaderInterface;
3292 const vk::VkImageViewType m_viewType;
3293 const deUint32 m_baseMipLevel;
3294 const deUint32 m_baseArraySlice;
3296 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3297 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3298 const ImageFetchInstanceImages m_images;
3299 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3300 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3303 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3304 bool isPrimaryCmdBuf,
3305 vk::VkDescriptorType descriptorType,
3306 vk::VkShaderStageFlags stageFlags,
3307 ShaderInputInterface shaderInterface,
3308 vk::VkImageViewType viewType,
3309 deUint32 baseMipLevel,
3310 deUint32 baseArraySlice)
3311 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3312 , m_descriptorType (descriptorType)
3313 , m_stageFlags (stageFlags)
3314 , m_shaderInterface (shaderInterface)
3315 , m_viewType (viewType)
3316 , m_baseMipLevel (baseMipLevel)
3317 , m_baseArraySlice (baseArraySlice)
3318 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
3319 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3320 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3321 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3322 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_images.getImageViewA(), m_images.getImageViewB()))
3326 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3327 vk::VkDevice device,
3328 vk::VkDescriptorType descriptorType,
3329 ShaderInputInterface shaderInterface,
3330 vk::VkShaderStageFlags stageFlags)
3332 vk::DescriptorSetLayoutBuilder builder;
3334 switch (shaderInterface)
3336 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3337 builder.addSingleBinding(descriptorType, stageFlags);
3340 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3341 builder.addSingleBinding(descriptorType, stageFlags);
3342 builder.addSingleBinding(descriptorType, stageFlags);
3345 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3346 builder.addArrayBinding(descriptorType, 2u, stageFlags);
3350 DE_FATAL("Impossible");
3353 return builder.build(vki, device);
3356 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
3357 vk::VkDevice device,
3358 vk::VkDescriptorSetLayout descriptorSetLayout)
3360 const vk::VkPipelineLayoutCreateInfo createInfo =
3362 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3364 (vk::VkPipelineLayoutCreateFlags)0,
3365 1, // descriptorSetCount
3366 &descriptorSetLayout, // pSetLayouts
3367 0u, // pushConstantRangeCount
3368 DE_NULL, // pPushConstantRanges
3370 return vk::createPipelineLayout(vki, device, &createInfo);
3373 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
3374 vk::VkDevice device,
3375 vk::VkDescriptorType descriptorType,
3376 ShaderInputInterface shaderInterface)
3378 return vk::DescriptorPoolBuilder()
3379 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
3380 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3383 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
3384 vk::VkDevice device,
3385 vk::VkDescriptorType descriptorType,
3386 ShaderInputInterface shaderInterface,
3387 vk::VkDescriptorSetLayout layout,
3388 vk::VkDescriptorPool pool,
3389 vk::VkImageView viewA,
3390 vk::VkImageView viewB)
3392 const vk::VkDescriptorImageInfo imageInfos[2] =
3394 makeDescriptorImageInfo(viewA, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3395 makeDescriptorImageInfo(viewB, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3397 const vk::VkDescriptorSetAllocateInfo allocInfo =
3399 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3406 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
3407 vk::DescriptorSetUpdateBuilder builder;
3409 switch (shaderInterface)
3411 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3412 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3415 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3416 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3417 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
3420 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3421 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
3425 DE_FATAL("Impossible");
3428 builder.update(vki, device);
3429 return descriptorSet;
3432 void ImageFetchRenderInstance::logTestPlan (void) const
3434 std::ostringstream msg;
3436 msg << "Rendering 2x2 grid.\n"
3437 << "Single descriptor set. Descriptor set contains "
3438 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3439 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3440 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3441 (const char*)DE_NULL)
3442 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3443 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3446 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3447 if (m_baseArraySlice)
3448 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3450 if (m_stageFlags == 0u)
3452 msg << "Descriptors are not accessed in any shader stage.\n";
3456 msg << "Color in each cell is fetched using the descriptor(s):\n";
3458 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3460 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3462 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3464 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3465 msg << " from descriptor " << srcResourceNdx;
3471 msg << "Descriptors are accessed in {"
3472 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
3473 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
3474 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
3475 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
3476 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
3480 m_context.getTestContext().getLog()
3481 << tcu::TestLog::Message
3483 << tcu::TestLog::EndMessage;
3486 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
3488 return *m_pipelineLayout;
3491 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
3493 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
3494 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
3497 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
3499 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3500 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
3501 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
3502 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
3503 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
3504 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
3505 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
3506 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
3508 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
3510 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
3511 return tcu::TestStatus::fail("Image verification failed");
3513 return tcu::TestStatus::pass("Pass");
3516 class ImageFetchComputeInstance : public vkt::TestInstance
3519 ImageFetchComputeInstance (vkt::Context& context,
3520 vk::VkDescriptorType descriptorType,
3521 ShaderInputInterface shaderInterface,
3522 vk::VkImageViewType viewType,
3523 deUint32 baseMipLevel,
3524 deUint32 baseArraySlice);
3527 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
3528 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
3529 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
3531 tcu::TestStatus iterate (void);
3532 void logTestPlan (void) const;
3533 tcu::TestStatus testResourceAccess (void);
3535 const vk::VkDescriptorType m_descriptorType;
3536 const ShaderInputInterface m_shaderInterface;
3537 const vk::VkImageViewType m_viewType;
3538 const deUint32 m_baseMipLevel;
3539 const deUint32 m_baseArraySlice;
3541 const vk::DeviceInterface& m_vki;
3542 const vk::VkDevice m_device;
3543 const vk::VkQueue m_queue;
3544 const deUint32 m_queueFamilyIndex;
3545 vk::Allocator& m_allocator;
3547 const ComputeInstanceResultBuffer m_result;
3548 const ImageFetchInstanceImages m_images;
3551 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
3552 vk::VkDescriptorType descriptorType,
3553 ShaderInputInterface shaderInterface,
3554 vk::VkImageViewType viewType,
3555 deUint32 baseMipLevel,
3556 deUint32 baseArraySlice)
3557 : vkt::TestInstance (context)
3558 , m_descriptorType (descriptorType)
3559 , m_shaderInterface (shaderInterface)
3560 , m_viewType (viewType)
3561 , m_baseMipLevel (baseMipLevel)
3562 , m_baseArraySlice (baseArraySlice)
3563 , m_vki (context.getDeviceInterface())
3564 , m_device (context.getDevice())
3565 , m_queue (context.getUniversalQueue())
3566 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
3567 , m_allocator (context.getDefaultAllocator())
3568 , m_result (m_vki, m_device, m_allocator)
3569 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3573 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
3575 vk::DescriptorSetLayoutBuilder builder;
3577 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3579 switch (m_shaderInterface)
3581 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3582 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3585 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3586 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3587 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3590 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3591 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3595 DE_FATAL("Impossible");
3598 return builder.build(m_vki, m_device);
3601 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
3603 return vk::DescriptorPoolBuilder()
3604 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3605 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
3606 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3609 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
3611 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
3612 const vk::VkDescriptorImageInfo imageInfos[2] =
3614 makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3615 makeDescriptorImageInfo(m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3617 const vk::VkDescriptorSetAllocateInfo allocInfo =
3619 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3626 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
3627 vk::DescriptorSetUpdateBuilder builder;
3630 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
3633 switch (m_shaderInterface)
3635 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3636 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3639 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3640 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3641 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
3644 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3645 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
3649 DE_FATAL("Impossible");
3652 builder.update(m_vki, m_device);
3653 return descriptorSet;
3656 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
3659 return testResourceAccess();
3662 void ImageFetchComputeInstance::logTestPlan (void) const
3664 std::ostringstream msg;
3666 msg << "Fetching 4 values from image in compute shader.\n"
3667 << "Single descriptor set. Descriptor set contains "
3668 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3669 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3670 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3671 (const char*)DE_NULL)
3672 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3673 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3676 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3677 if (m_baseArraySlice)
3678 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3680 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3682 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3684 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3686 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3687 msg << " from descriptor " << srcResourceNdx;
3693 m_context.getTestContext().getLog()
3694 << tcu::TestLog::Message
3696 << tcu::TestLog::EndMessage;
3699 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
3701 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
3702 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
3703 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
3704 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
3706 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
3707 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
3708 const deUint32* const dynamicOffsets = DE_NULL;
3709 const int numDynamicOffsets = 0;
3710 const void* const* preBarriers = DE_NULL;
3711 const int numPreBarriers = 0;
3712 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
3713 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
3715 const ComputeCommand compute (m_vki,
3717 pipeline.getPipeline(),
3718 pipeline.getPipelineLayout(),
3719 tcu::UVec3(4, 1, 1),
3720 numDescriptorSets, descriptorSets,
3721 numDynamicOffsets, dynamicOffsets,
3722 numPreBarriers, preBarriers,
3723 numPostBarriers, postBarriers);
3725 tcu::Vec4 results[4];
3726 bool anyResultSet = false;
3727 bool allResultsOk = true;
3729 compute.submitAndWait(m_queueFamilyIndex, m_queue);
3730 m_result.readResultContentsTo(&results);
3733 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3735 const tcu::Vec4 result = results[resultNdx];
3736 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
3737 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
3739 if (result != tcu::Vec4(-1.0f))
3740 anyResultSet = true;
3742 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
3744 allResultsOk = false;
3746 m_context.getTestContext().getLog()
3747 << tcu::TestLog::Message
3748 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
3749 << tcu::TestLog::EndMessage;
3753 // read back and verify
3755 return tcu::TestStatus::pass("Pass");
3756 else if (anyResultSet)
3757 return tcu::TestStatus::fail("Invalid result values");
3760 m_context.getTestContext().getLog()
3761 << tcu::TestLog::Message
3762 << "Result buffer was not written to."
3763 << tcu::TestLog::EndMessage;
3764 return tcu::TestStatus::fail("Result buffer was not written to");
3768 class ImageSampleInstanceImages : private ImageInstanceImages
3771 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3772 vk::VkDevice device,
3773 deUint32 queueFamilyIndex,
3775 vk::Allocator& allocator,
3776 vk::VkDescriptorType descriptorType,
3777 ShaderInputInterface shaderInterface,
3778 vk::VkImageViewType viewType,
3779 deUint32 baseMipLevel,
3780 deUint32 baseArraySlice,
3783 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
3784 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
3786 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3787 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3788 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
3789 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
3790 inline bool isImmutable (void) const { return m_isImmutable; }
3793 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
3794 static tcu::Sampler createRefSampler (bool isFirst);
3795 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
3797 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3798 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3799 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3800 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3802 const vk::VkDescriptorType m_descriptorType;
3803 const ShaderInputInterface m_shaderInterface;
3804 const bool m_isImmutable;
3806 const tcu::Sampler m_refSamplerA;
3807 const tcu::Sampler m_refSamplerB;
3808 const vk::Unique<vk::VkSampler> m_samplerA;
3809 const vk::Unique<vk::VkSampler> m_samplerB;
3812 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3813 vk::VkDevice device,
3814 deUint32 queueFamilyIndex,
3816 vk::Allocator& allocator,
3817 vk::VkDescriptorType descriptorType,
3818 ShaderInputInterface shaderInterface,
3819 vk::VkImageViewType viewType,
3820 deUint32 baseMipLevel,
3821 deUint32 baseArraySlice,
3823 : ImageInstanceImages (vki,
3830 getNumImages(descriptorType, shaderInterface),
3833 , m_descriptorType (descriptorType)
3834 , m_shaderInterface (shaderInterface)
3835 , m_isImmutable (immutable)
3836 , m_refSamplerA (createRefSampler(true))
3837 , m_refSamplerB (createRefSampler(false))
3838 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
3839 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
3840 ? vk::Move<vk::VkSampler>()
3841 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
3845 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
3847 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3849 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3850 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3852 // choose arbitrary values that are not ambiguous with NEAREST filtering
3856 case vk::VK_IMAGE_VIEW_TYPE_1D:
3857 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
3858 case vk::VK_IMAGE_VIEW_TYPE_2D:
3859 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
3860 case vk::VK_IMAGE_VIEW_TYPE_3D:
3862 const tcu::Vec3 coords[4] =
3866 (float)(12u % imageSize) + 0.25f),
3868 tcu::Vec3((float)(23u % imageSize) + 0.25f,
3869 (float)(73u % imageSize) + 0.5f,
3870 (float)(16u % imageSize) + 0.5f + (float)imageSize),
3872 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
3873 (float)(84u % imageSize) + 0.5f + (float)imageSize,
3874 (float)(117u % imageSize) + 0.75f),
3876 tcu::Vec3((float)imageSize + 0.5f,
3877 (float)(75u % imageSize) + 0.25f,
3878 (float)(83u % imageSize) + 0.25f + (float)imageSize),
3880 const deUint32 slices[4] =
3888 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3889 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3890 (float)slices[samplePosNdx],
3893 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
3894 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3895 coords[samplePosNdx].y() / (float)imageSize,
3896 (float)slices[samplePosNdx],
3898 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
3899 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3900 coords[samplePosNdx].y() / (float)imageSize,
3901 coords[samplePosNdx].z() / (float)imageSize,
3905 DE_FATAL("Impossible");
3910 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3911 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
3913 // \note these values are in [0, texSize]*3 space for convenience
3914 const tcu::Vec3 coords[4] =
3920 tcu::Vec3((float)(13u % imageSize) + 0.25f,
3922 (float)(16u % imageSize) + 0.5f),
3925 (float)(84u % imageSize) + 0.5f,
3926 (float)(10u % imageSize) + 0.75f),
3928 tcu::Vec3((float)imageSize,
3929 (float)(75u % imageSize) + 0.25f,
3930 (float)(83u % imageSize) + 0.75f),
3932 const deUint32 slices[4] =
3940 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
3941 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
3942 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
3944 // map to [-1, 1]*3 space
3945 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
3946 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
3947 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
3948 (float)slices[samplePosNdx]);
3952 DE_FATAL("Impossible");
3957 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
3959 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3961 // texture order is ABAB
3962 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
3963 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
3964 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3965 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
3967 // sampler order is ABAB
3968 const tcu::Sampler& samplerA = m_refSamplerA;
3969 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
3970 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
3972 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
3973 const float lod = 0.0f;
3974 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
3978 case vk::VK_IMAGE_VIEW_TYPE_1D:
3979 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
3980 case vk::VK_IMAGE_VIEW_TYPE_2D:
3981 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return getRef2DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
3982 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
3983 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3984 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return getRefCubeView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), samplePos.w(), lod);
3988 DE_FATAL("Impossible");
3994 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
3996 // If we are testing separate samplers, just one image is enough
3997 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
3999 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4001 // combined: numImages == numSamplers
4002 return getInterfaceNumResources(shaderInterface);
4006 DE_FATAL("Impossible");
4011 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4016 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4020 // nearest, clamping
4021 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4025 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4027 const bool compareEnabled = (sampler.compare != tcu::Sampler::COMPAREMODE_NONE);
4028 const vk::VkCompareOp compareOp = (compareEnabled) ? (vk::mapCompareMode(sampler.compare)) : (vk::VK_COMPARE_OP_ALWAYS);
4029 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4030 const bool isIntTexture = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4031 const vk::VkBorderColor borderColor = (isIntTexture) ? (vk::VK_BORDER_COLOR_INT_OPAQUE_WHITE) : (vk::VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE);
4032 const vk::VkSamplerCreateInfo createInfo =
4034 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
4036 (vk::VkSamplerCreateFlags)0,
4037 vk::mapFilterMode(sampler.magFilter), // magFilter
4038 vk::mapFilterMode(sampler.minFilter), // minFilter
4039 vk::mapMipmapMode(sampler.minFilter), // mipMode
4040 vk::mapWrapMode(sampler.wrapS), // addressU
4041 vk::mapWrapMode(sampler.wrapT), // addressV
4042 vk::mapWrapMode(sampler.wrapR), // addressW
4045 (compareEnabled ? vk::VK_TRUE : vk::VK_FALSE), // compareEnable
4046 compareOp, // compareOp
4049 borderColor, // borderColor
4050 vk::VK_FALSE, // unnormalizedCoords
4052 return vk::createSampler(vki, device, &createInfo);
4055 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4057 DE_ASSERT(levelStorage->empty());
4059 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4060 const deUint32 numLevels = (deUint32)source.getNumLevels();
4062 // cut pyramid from baseMipLevel
4063 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4065 // cut levels from baseArraySlice
4066 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4067 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4068 levelStorage->push_back(cutLevel);
4071 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4074 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4076 DE_ASSERT(levelStorage->empty());
4078 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4079 const deUint32 numLevels = (deUint32)source.getNumLevels();
4081 // cut pyramid from baseMipLevel
4082 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4084 // cut levels from baseArraySlice
4085 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4086 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4087 levelStorage->push_back(cutLevel);
4090 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4093 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4095 DE_ASSERT(levelStorage->empty());
4096 DE_ASSERT(baseArraySlice == 0);
4097 DE_UNREF(baseArraySlice);
4099 const deUint32 numLevels = (deUint32)source.getNumLevels();
4101 // cut pyramid from baseMipLevel
4102 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4103 levelStorage->push_back(source.getLevel(level));
4105 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
4108 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4110 DE_ASSERT(levelStorage->empty());
4112 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
4113 const deUint32 numLevels = (deUint32)source.getNumLevels();
4115 // cut pyramid from baseMipLevel
4116 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4118 // cut levels from baseArraySlice
4119 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4120 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
4121 levelStorage->push_back(cutLevel);
4124 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
4127 class ImageSampleRenderInstance : public SingleCmdRenderInstance
4130 ImageSampleRenderInstance (vkt::Context& context,
4131 bool isPrimaryCmdBuf,
4132 vk::VkDescriptorType descriptorType,
4133 vk::VkShaderStageFlags stageFlags,
4134 ShaderInputInterface shaderInterface,
4135 vk::VkImageViewType viewType,
4136 deUint32 baseMipLevel,
4137 deUint32 baseArraySlice,
4141 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
4142 vk::VkDevice device,
4143 vk::VkDescriptorType descriptorType,
4144 ShaderInputInterface shaderInterface,
4145 vk::VkShaderStageFlags stageFlags,
4146 const ImageSampleInstanceImages& images);
4148 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4149 vk::VkDevice device,
4150 vk::VkDescriptorSetLayout descriptorSetLayout);
4152 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4153 vk::VkDevice device,
4154 vk::VkDescriptorType descriptorType,
4155 ShaderInputInterface shaderInterface,
4158 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
4159 vk::VkDevice device,
4160 vk::VkDescriptorType descriptorType,
4161 ShaderInputInterface shaderInterface,
4162 vk::VkDescriptorSetLayout layout,
4163 vk::VkDescriptorPool pool,
4165 const ImageSampleInstanceImages& images);
4167 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4168 vk::VkDevice device,
4169 ShaderInputInterface shaderInterface,
4171 const ImageSampleInstanceImages& images,
4172 vk::VkDescriptorSet descriptorSet);
4174 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4175 vk::VkDevice device,
4176 ShaderInputInterface shaderInterface,
4178 const ImageSampleInstanceImages& images,
4179 vk::VkDescriptorSet descriptorSet);
4181 void logTestPlan (void) const;
4182 vk::VkPipelineLayout getPipelineLayout (void) const;
4183 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
4184 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4191 const vk::VkDescriptorType m_descriptorType;
4192 const vk::VkShaderStageFlags m_stageFlags;
4193 const ShaderInputInterface m_shaderInterface;
4194 const vk::VkImageViewType m_viewType;
4195 const deUint32 m_baseMipLevel;
4196 const deUint32 m_baseArraySlice;
4198 const ImageSampleInstanceImages m_images;
4199 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
4200 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4201 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4202 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
4205 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
4206 bool isPrimaryCmdBuf,
4207 vk::VkDescriptorType descriptorType,
4208 vk::VkShaderStageFlags stageFlags,
4209 ShaderInputInterface shaderInterface,
4210 vk::VkImageViewType viewType,
4211 deUint32 baseMipLevel,
4212 deUint32 baseArraySlice,
4214 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4215 , m_descriptorType (descriptorType)
4216 , m_stageFlags (stageFlags)
4217 , m_shaderInterface (shaderInterface)
4218 , m_viewType (viewType)
4219 , m_baseMipLevel (baseMipLevel)
4220 , m_baseArraySlice (baseArraySlice)
4221 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
4222 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images))
4223 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
4224 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface, isImmutable))
4225 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, isImmutable, m_images))
4229 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
4230 vk::VkDevice device,
4231 vk::VkDescriptorType descriptorType,
4232 ShaderInputInterface shaderInterface,
4233 vk::VkShaderStageFlags stageFlags,
4234 const ImageSampleInstanceImages& images)
4236 const vk::VkSampler samplers[2] =
4238 images.getSamplerA(),
4239 images.getSamplerB(),
4242 vk::DescriptorSetLayoutBuilder builder;
4244 // with samplers, separate texture at binding 0
4245 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4246 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4248 // (combined)samplers follow
4249 switch (shaderInterface)
4251 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4252 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4255 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4256 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4257 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4260 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4261 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
4265 DE_FATAL("Impossible");
4268 return builder.build(vki, device);
4271 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4272 vk::VkDevice device,
4273 vk::VkDescriptorSetLayout descriptorSetLayout)
4275 const vk::VkPipelineLayoutCreateInfo createInfo =
4277 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4279 (vk::VkPipelineLayoutCreateFlags)0,
4280 1, // descriptorSetCount
4281 &descriptorSetLayout, // pSetLayouts
4282 0u, // pushConstantRangeCount
4283 DE_NULL, // pPushConstantRanges
4285 return vk::createPipelineLayout(vki, device, &createInfo);
4288 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4289 vk::VkDevice device,
4290 vk::VkDescriptorType descriptorType,
4291 ShaderInputInterface shaderInterface,
4294 vk::DescriptorPoolBuilder builder;
4296 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4298 // separate samplers need image to sample
4299 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4301 // samplers needed only if they are specified in the descriptor set
4303 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
4305 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4307 // combined image samplers
4308 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
4311 DE_FATAL("Impossible");
4313 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4316 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
4317 vk::VkDevice device,
4318 vk::VkDescriptorType descriptorType,
4319 ShaderInputInterface shaderInterface,
4320 vk::VkDescriptorSetLayout layout,
4321 vk::VkDescriptorPool pool,
4323 const ImageSampleInstanceImages& images)
4325 const vk::VkDescriptorSetAllocateInfo allocInfo =
4327 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4334 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4336 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4337 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4338 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4339 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4341 DE_FATAL("Impossible");
4343 return descriptorSet;
4346 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4347 vk::VkDevice device,
4348 ShaderInputInterface shaderInterface,
4350 const ImageSampleInstanceImages& images,
4351 vk::VkDescriptorSet descriptorSet)
4353 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4354 const vk::VkDescriptorImageInfo samplersInfos[2] =
4356 makeDescriptorImageInfo(images.getSamplerA()),
4357 makeDescriptorImageInfo(images.getSamplerB()),
4360 vk::DescriptorSetUpdateBuilder builder;
4362 // stand alone texture
4363 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4368 switch (shaderInterface)
4370 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4371 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4374 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4375 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4376 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4379 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4380 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4384 DE_FATAL("Impossible");
4388 builder.update(vki, device);
4391 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4392 vk::VkDevice device,
4393 ShaderInputInterface shaderInterface,
4395 const ImageSampleInstanceImages& images,
4396 vk::VkDescriptorSet descriptorSet)
4398 const vk::VkSampler samplers[2] =
4400 (isImmutable) ? (0) : (images.getSamplerA()),
4401 (isImmutable) ? (0) : (images.getSamplerB()),
4403 const vk::VkDescriptorImageInfo imageSamplers[2] =
4405 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4406 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4409 vk::DescriptorSetUpdateBuilder builder;
4411 // combined image samplers
4412 switch (shaderInterface)
4414 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4415 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4418 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4419 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4420 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4423 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4424 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4428 DE_FATAL("Impossible");
4431 builder.update(vki, device);
4434 void ImageSampleRenderInstance::logTestPlan (void) const
4436 std::ostringstream msg;
4438 msg << "Rendering 2x2 grid.\n";
4440 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4442 msg << "Single descriptor set. Descriptor set contains "
4443 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4444 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4445 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4446 (const char*)DE_NULL)
4447 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4449 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4451 msg << "Single descriptor set. Descriptor set contains "
4452 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4453 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4454 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4455 (const char*)DE_NULL)
4456 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4459 DE_FATAL("Impossible");
4461 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4464 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4465 if (m_baseArraySlice)
4466 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4468 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4469 msg << "Sampler mode is LINEAR, with WRAP\n";
4471 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4473 if (m_stageFlags == 0u)
4475 msg << "Descriptors are not accessed in any shader stage.\n";
4479 msg << "Color in each cell is fetched using the descriptor(s):\n";
4481 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4483 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4485 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4487 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4489 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4490 msg << " using sampler " << srcResourceNdx;
4491 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4492 msg << " from combined image sampler " << srcResourceNdx;
4494 DE_FATAL("Impossible");
4499 msg << "Descriptors are accessed in {"
4500 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4501 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4502 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4503 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4504 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4508 m_context.getTestContext().getLog()
4509 << tcu::TestLog::Message
4511 << tcu::TestLog::EndMessage;
4514 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
4516 return *m_pipelineLayout;
4519 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4521 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4522 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
4525 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4527 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4528 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4529 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4530 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
4531 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
4532 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
4533 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
4534 const tcu::RGBA threshold = tcu::RGBA(8, 8, 8, 8); // source image is high-frequency so the threshold is quite large to tolerate sampling errors
4535 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4537 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4539 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
4540 return tcu::TestStatus::fail("Image verification failed");
4542 return tcu::TestStatus::pass("Pass");
4545 class ImageSampleComputeInstance : public vkt::TestInstance
4548 ImageSampleComputeInstance (vkt::Context& context,
4549 vk::VkDescriptorType descriptorType,
4550 ShaderInputInterface shaderInterface,
4551 vk::VkImageViewType viewType,
4552 deUint32 baseMipLevel,
4553 deUint32 baseArraySlice,
4554 bool isImmutableSampler);
4557 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4558 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4559 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
4560 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4561 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4563 tcu::TestStatus iterate (void);
4564 void logTestPlan (void) const;
4565 tcu::TestStatus testResourceAccess (void);
4567 const vk::VkDescriptorType m_descriptorType;
4568 const ShaderInputInterface m_shaderInterface;
4569 const vk::VkImageViewType m_viewType;
4570 const deUint32 m_baseMipLevel;
4571 const deUint32 m_baseArraySlice;
4572 const bool m_isImmutableSampler;
4574 const vk::DeviceInterface& m_vki;
4575 const vk::VkDevice m_device;
4576 const vk::VkQueue m_queue;
4577 const deUint32 m_queueFamilyIndex;
4578 vk::Allocator& m_allocator;
4580 const ComputeInstanceResultBuffer m_result;
4581 const ImageSampleInstanceImages m_images;
4584 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
4585 vk::VkDescriptorType descriptorType,
4586 ShaderInputInterface shaderInterface,
4587 vk::VkImageViewType viewType,
4588 deUint32 baseMipLevel,
4589 deUint32 baseArraySlice,
4590 bool isImmutableSampler)
4591 : vkt::TestInstance (context)
4592 , m_descriptorType (descriptorType)
4593 , m_shaderInterface (shaderInterface)
4594 , m_viewType (viewType)
4595 , m_baseMipLevel (baseMipLevel)
4596 , m_baseArraySlice (baseArraySlice)
4597 , m_isImmutableSampler (isImmutableSampler)
4598 , m_vki (context.getDeviceInterface())
4599 , m_device (context.getDevice())
4600 , m_queue (context.getUniversalQueue())
4601 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4602 , m_allocator (context.getDefaultAllocator())
4603 , m_result (m_vki, m_device, m_allocator)
4604 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
4608 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
4610 const vk::VkSampler samplers[2] =
4612 m_images.getSamplerA(),
4613 m_images.getSamplerB(),
4616 vk::DescriptorSetLayoutBuilder builder;
4619 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4621 // with samplers, separate texture at binding 0
4622 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4623 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4625 // (combined)samplers follow
4626 switch (m_shaderInterface)
4628 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4629 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4632 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4633 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4634 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4637 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4638 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
4642 DE_FATAL("Impossible");
4645 return builder.build(m_vki, m_device);
4648 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
4650 vk::DescriptorPoolBuilder builder;
4652 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
4653 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
4655 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4656 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4658 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4661 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
4663 const vk::VkDescriptorSetAllocateInfo allocInfo =
4665 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4672 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4674 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4675 writeSamplerDescriptorSet(*descriptorSet);
4676 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4677 writeImageSamplerDescriptorSet(*descriptorSet);
4679 DE_FATAL("Impossible");
4681 return descriptorSet;
4684 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4686 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4687 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4688 const vk::VkDescriptorImageInfo samplersInfos[2] =
4690 makeDescriptorImageInfo(m_images.getSamplerA()),
4691 makeDescriptorImageInfo(m_images.getSamplerB()),
4694 vk::DescriptorSetUpdateBuilder builder;
4697 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4699 // stand alone texture
4700 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4703 if (!m_isImmutableSampler)
4705 switch (m_shaderInterface)
4707 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4708 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4711 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4712 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4713 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4716 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4717 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4721 DE_FATAL("Impossible");
4725 builder.update(m_vki, m_device);
4728 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4730 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4731 const vk::VkSampler samplers[2] =
4733 (m_isImmutableSampler) ? (0) : (m_images.getSamplerA()),
4734 (m_isImmutableSampler) ? (0) : (m_images.getSamplerB()),
4736 const vk::VkDescriptorImageInfo imageSamplers[2] =
4738 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4739 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4742 vk::DescriptorSetUpdateBuilder builder;
4745 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4747 // combined image samplers
4748 switch (m_shaderInterface)
4750 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4751 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4754 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4755 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4756 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4759 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4760 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4764 DE_FATAL("Impossible");
4767 builder.update(m_vki, m_device);
4770 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
4773 return testResourceAccess();
4776 void ImageSampleComputeInstance::logTestPlan (void) const
4778 std::ostringstream msg;
4780 msg << "Accessing resource in a compute program.\n";
4782 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4784 msg << "Single descriptor set. Descriptor set contains "
4785 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4786 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4787 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4788 (const char*)DE_NULL)
4789 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4791 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4793 msg << "Single descriptor set. Descriptor set contains "
4794 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4795 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4796 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4797 (const char*)DE_NULL)
4798 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4801 DE_FATAL("Impossible");
4803 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4806 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4807 if (m_baseArraySlice)
4808 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4810 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4811 msg << "Sampler mode is LINEAR, with WRAP\n";
4813 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4815 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4817 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4819 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4821 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4823 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4824 msg << " using sampler " << srcResourceNdx;
4825 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4826 msg << " from combined image sampler " << srcResourceNdx;
4828 DE_FATAL("Impossible");
4833 m_context.getTestContext().getLog()
4834 << tcu::TestLog::Message
4836 << tcu::TestLog::EndMessage;
4839 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
4841 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4842 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4843 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4844 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4846 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4847 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
4848 const deUint32* const dynamicOffsets = DE_NULL;
4849 const int numDynamicOffsets = 0;
4850 const void* const* preBarriers = DE_NULL;
4851 const int numPreBarriers = 0;
4852 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
4853 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
4855 const ComputeCommand compute (m_vki,
4857 pipeline.getPipeline(),
4858 pipeline.getPipelineLayout(),
4859 tcu::UVec3(4, 1, 1),
4860 numDescriptorSets, descriptorSets,
4861 numDynamicOffsets, dynamicOffsets,
4862 numPreBarriers, preBarriers,
4863 numPostBarriers, postBarriers);
4865 tcu::Vec4 results[4];
4866 bool anyResultSet = false;
4867 bool allResultsOk = true;
4869 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4870 m_result.readResultContentsTo(&results);
4873 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4875 const tcu::Vec4 result = results[resultNdx];
4876 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
4878 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
4879 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
4881 if (result != tcu::Vec4(-1.0f))
4882 anyResultSet = true;
4884 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
4886 allResultsOk = false;
4888 m_context.getTestContext().getLog()
4889 << tcu::TestLog::Message
4890 << "Test sample " << resultNdx << ":\n"
4891 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
4892 << "\tError expected " << reference << ", got " << result
4893 << tcu::TestLog::EndMessage;
4897 // read back and verify
4899 return tcu::TestStatus::pass("Pass");
4900 else if (anyResultSet)
4901 return tcu::TestStatus::fail("Invalid result values");
4904 m_context.getTestContext().getLog()
4905 << tcu::TestLog::Message
4906 << "Result buffer was not written to."
4907 << tcu::TestLog::EndMessage;
4908 return tcu::TestStatus::fail("Result buffer was not written to");
4912 class ImageDescriptorCase : public QuadrantRendederCase
4917 FLAG_BASE_MIP = (1u << 1u),
4918 FLAG_BASE_SLICE = (1u << 2u),
4920 // enum continues where resource flags ends
4921 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
4923 ImageDescriptorCase (tcu::TestContext& testCtx,
4925 const char* description,
4926 bool isPrimaryCmdBuf,
4927 vk::VkDescriptorType descriptorType,
4928 vk::VkShaderStageFlags exitingStages,
4929 vk::VkShaderStageFlags activeStages,
4930 ShaderInputInterface shaderInterface,
4931 vk::VkImageViewType viewType,
4935 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
4936 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
4937 std::string genFetchCoordStr (int fetchPosNdx) const;
4938 std::string genSampleCoordStr (int samplePosNdx) const;
4939 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
4940 std::string genNoAccessSource (void) const;
4942 vkt::TestInstance* createInstance (vkt::Context& context) const;
4945 const bool m_isPrimaryCmdBuf;
4946 const vk::VkDescriptorType m_descriptorType;
4947 const ShaderInputInterface m_shaderInterface;
4948 const vk::VkImageViewType m_viewType;
4949 const deUint32 m_baseMipLevel;
4950 const deUint32 m_baseArraySlice;
4951 const bool m_isImmutableSampler;
4954 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
4956 const char* description,
4957 bool isPrimaryCmdBuf,
4958 vk::VkDescriptorType descriptorType,
4959 vk::VkShaderStageFlags exitingStages,
4960 vk::VkShaderStageFlags activeStages,
4961 ShaderInputInterface shaderInterface,
4962 vk::VkImageViewType viewType,
4964 : QuadrantRendederCase (testCtx, name, description,
4965 // \note 1D textures are not supported in ES
4966 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
4967 exitingStages, activeStages)
4968 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
4969 , m_descriptorType (descriptorType)
4970 , m_shaderInterface (shaderInterface)
4971 , m_viewType (viewType)
4972 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
4973 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
4974 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
4978 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
4982 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
4983 return "#extension GL_OES_texture_cube_map_array : require\n";
4988 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
4992 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
4993 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
4994 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
4995 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
4996 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
4998 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
4999 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5000 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5001 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5003 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
5005 switch (m_shaderInterface)
5007 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5009 switch (m_descriptorType)
5011 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5012 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5013 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
5014 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5015 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
5016 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5017 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
5018 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5019 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
5021 DE_FATAL("invalid descriptor");
5026 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5027 switch (m_descriptorType)
5029 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5030 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5031 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
5032 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5033 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5034 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
5035 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
5036 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5037 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
5038 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
5039 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5040 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
5041 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
5043 DE_FATAL("invalid descriptor");
5047 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5048 switch (m_descriptorType)
5050 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5051 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5052 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler[2];\n";
5053 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5054 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
5055 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5056 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
5057 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5058 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
5060 DE_FATAL("invalid descriptor");
5065 DE_FATAL("Impossible");
5070 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
5072 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
5073 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
5075 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5077 return de::toString(fetchPos.x());
5079 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5081 std::ostringstream buf;
5082 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
5087 std::ostringstream buf;
5088 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
5093 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
5095 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
5096 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5098 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5100 std::ostringstream buf;
5101 buf << "float(" << fetchPos.x() << ")";
5104 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5106 std::ostringstream buf;
5107 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
5110 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5112 std::ostringstream buf;
5113 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
5118 std::ostringstream buf;
5119 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
5124 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
5128 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
5129 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5130 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
5131 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5132 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5133 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
5134 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5136 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5137 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
5138 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
5140 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5141 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
5142 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
5145 switch (m_descriptorType)
5147 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5148 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5150 const std::string coodStr[4] =
5152 genSampleCoordStr(0),
5153 genSampleCoordStr(1),
5154 genSampleCoordStr(2),
5155 genSampleCoordStr(3),
5157 std::ostringstream buf;
5159 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5161 buf << " if (quadrant_id == 0)\n"
5162 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
5163 << " else if (quadrant_id == 1)\n"
5164 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
5165 << " else if (quadrant_id == 2)\n"
5166 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
5168 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
5172 buf << " if (quadrant_id == 0)\n"
5173 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
5174 << " else if (quadrant_id == 1)\n"
5175 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
5176 << " else if (quadrant_id == 2)\n"
5177 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
5179 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
5185 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5187 const std::string coodStr[4] =
5189 genFetchCoordStr(0),
5190 genFetchCoordStr(1),
5191 genFetchCoordStr(2),
5192 genFetchCoordStr(3),
5194 std::ostringstream buf;
5196 buf << " if (quadrant_id == 0)\n"
5197 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
5198 << " else if (quadrant_id == 1)\n"
5199 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
5200 << " else if (quadrant_id == 2)\n"
5201 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
5203 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
5209 DE_FATAL("invalid descriptor");
5214 std::string ImageDescriptorCase::genNoAccessSource (void) const
5216 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
5217 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5219 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
5222 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
5224 switch (m_descriptorType)
5226 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5227 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5228 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5230 DE_ASSERT(m_isPrimaryCmdBuf);
5231 return new ImageSampleComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5234 return new ImageSampleRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5236 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5237 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5238 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5240 DE_ASSERT(m_isPrimaryCmdBuf);
5241 return new ImageFetchComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5244 return new ImageFetchRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5247 DE_FATAL("Impossible");
5252 class TexelBufferInstanceBuffers
5255 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5256 vk::VkDevice device,
5257 vk::Allocator& allocator,
5258 vk::VkDescriptorType descriptorType,
5259 int numTexelBuffers,
5260 bool hasViewOffset);
5263 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
5264 vk::VkDevice device,
5265 vk::Allocator& allocator,
5266 vk::VkDescriptorType descriptorType,
5267 de::MovePtr<vk::Allocation> *outAllocation);
5269 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
5270 vk::VkDevice device,
5271 const tcu::TextureFormat& textureFormat,
5273 vk::VkBuffer buffer);
5275 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
5277 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
5278 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
5281 static int getFetchPos (int fetchPosNdx);
5282 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
5284 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
5285 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
5286 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
5287 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
5288 inline const void* getBufferInitBarrierA (void) const { return &m_bufferBarrierA; }
5289 inline const void* getBufferInitBarrierB (void) const { return &m_bufferBarrierB; }
5295 VIEW_OFFSET_VALUE = 256,
5296 VIEW_DATA_SIZE = 256, //!< size in bytes
5297 VIEW_WIDTH = 64, //!< size in pixels
5301 // some arbitrary points
5303 SAMPLE_POINT_1 = 51,
5304 SAMPLE_POINT_2 = 42,
5305 SAMPLE_POINT_3 = 25,
5308 const deUint32 m_numTexelBuffers;
5309 const tcu::TextureFormat m_imageFormat;
5310 const deUint32 m_viewOffset;
5312 de::ArrayBuffer<deUint8> m_sourceBufferA;
5313 de::ArrayBuffer<deUint8> m_sourceBufferB;
5314 const tcu::ConstPixelBufferAccess m_sourceViewA;
5315 const tcu::ConstPixelBufferAccess m_sourceViewB;
5317 de::MovePtr<vk::Allocation> m_bufferMemoryA;
5318 de::MovePtr<vk::Allocation> m_bufferMemoryB;
5319 const vk::Unique<vk::VkBuffer> m_bufferA;
5320 const vk::Unique<vk::VkBuffer> m_bufferB;
5321 const vk::Unique<vk::VkBufferView> m_bufferViewA;
5322 const vk::Unique<vk::VkBufferView> m_bufferViewB;
5323 const vk::VkBufferMemoryBarrier m_bufferBarrierA;
5324 const vk::VkBufferMemoryBarrier m_bufferBarrierB;
5327 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5328 vk::VkDevice device,
5329 vk::Allocator& allocator,
5330 vk::VkDescriptorType descriptorType,
5331 int numTexelBuffers,
5333 : m_numTexelBuffers (numTexelBuffers)
5334 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
5335 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
5336 , m_sourceBufferA (BUFFER_SIZE)
5337 , m_sourceBufferB ((numTexelBuffers == 1)
5339 : ((size_t)BUFFER_SIZE))
5340 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
5341 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
5342 , m_bufferMemoryA (DE_NULL)
5343 , m_bufferMemoryB (DE_NULL)
5344 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
5345 , m_bufferB ((numTexelBuffers == 1)
5346 ? vk::Move<vk::VkBuffer>()
5347 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
5348 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
5349 , m_bufferViewB ((numTexelBuffers == 1)
5350 ? vk::Move<vk::VkBufferView>()
5351 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
5352 , m_bufferBarrierA (createBarrier(descriptorType, *m_bufferA))
5353 , m_bufferBarrierB (createBarrier(descriptorType, *m_bufferB))
5355 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
5356 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
5357 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
5359 // specify and upload
5361 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
5362 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
5364 if (numTexelBuffers == 2)
5366 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
5367 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
5371 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
5372 vk::VkDevice device,
5373 vk::Allocator& allocator,
5374 vk::VkDescriptorType descriptorType,
5375 de::MovePtr<vk::Allocation> *outAllocation)
5377 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
5378 const vk::VkBufferCreateInfo createInfo =
5380 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
5383 (vk::VkDeviceSize)BUFFER_SIZE, // size
5385 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
5386 0u, // queueFamilyCount
5387 DE_NULL, // pQueueFamilyIndices
5389 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
5390 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
5392 *outAllocation = allocation;
5396 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
5397 vk::VkDevice device,
5398 const tcu::TextureFormat& textureFormat,
5400 vk::VkBuffer buffer)
5402 const vk::VkBufferViewCreateInfo createInfo =
5404 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
5406 (vk::VkBufferViewCreateFlags)0,
5408 vk::mapTextureFormat(textureFormat), // format
5409 (vk::VkDeviceSize)offset, // offset
5410 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
5412 return vk::createBufferView(vki, device, &createInfo);
5415 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
5417 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
5418 const vk::VkBufferMemoryBarrier barrier =
5420 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
5422 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
5423 inputBit, // inputMask
5424 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
5425 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
5428 (vk::VkDeviceSize)BUFFER_SIZE // size
5433 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
5435 DE_ASSERT(access.getHeight() == 1);
5436 DE_ASSERT(access.getDepth() == 1);
5438 const deInt32 width = access.getWidth();
5440 for (int x = 0; x < width; ++x)
5442 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
5443 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
5444 const int blue = 16 * (x % 16); //!< 16-long triangle wave
5446 DE_ASSERT(de::inRange(red, 0, 255));
5447 DE_ASSERT(de::inRange(green, 0, 255));
5448 DE_ASSERT(de::inRange(blue, 0, 255));
5450 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
5454 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
5456 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
5457 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
5460 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
5462 static const int fetchPositions[4] =
5469 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
5472 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
5474 // source order is ABAB
5475 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
5476 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
5477 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
5479 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
5482 class TexelBufferRenderInstance : public SingleCmdRenderInstance
5485 TexelBufferRenderInstance (vkt::Context& context,
5486 bool isPrimaryCmdBuf,
5487 vk::VkDescriptorType descriptorType,
5488 vk::VkShaderStageFlags stageFlags,
5489 ShaderInputInterface shaderInterface,
5490 bool nonzeroViewOffset);
5493 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
5494 vk::VkDevice device,
5495 vk::VkDescriptorType descriptorType,
5496 ShaderInputInterface shaderInterface,
5497 vk::VkShaderStageFlags stageFlags);
5499 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5500 vk::VkDevice device,
5501 vk::VkDescriptorSetLayout descriptorSetLayout);
5503 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5504 vk::VkDevice device,
5505 vk::VkDescriptorType descriptorType,
5506 ShaderInputInterface shaderInterface);
5508 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
5509 vk::VkDevice device,
5510 vk::VkDescriptorType descriptorType,
5511 ShaderInputInterface shaderInterface,
5512 vk::VkDescriptorSetLayout layout,
5513 vk::VkDescriptorPool pool,
5514 vk::VkBufferView viewA,
5515 vk::VkBufferView viewB);
5517 void logTestPlan (void) const;
5518 vk::VkPipelineLayout getPipelineLayout (void) const;
5519 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5520 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5527 const vk::VkDescriptorType m_descriptorType;
5528 const vk::VkShaderStageFlags m_stageFlags;
5529 const ShaderInputInterface m_shaderInterface;
5530 const bool m_nonzeroViewOffset;
5532 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5533 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5534 const TexelBufferInstanceBuffers m_texelBuffers;
5535 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5536 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5539 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
5540 bool isPrimaryCmdBuf,
5541 vk::VkDescriptorType descriptorType,
5542 vk::VkShaderStageFlags stageFlags,
5543 ShaderInputInterface shaderInterface,
5544 bool nonzeroViewOffset)
5545 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5546 , m_descriptorType (descriptorType)
5547 , m_stageFlags (stageFlags)
5548 , m_shaderInterface (shaderInterface)
5549 , m_nonzeroViewOffset (nonzeroViewOffset)
5550 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
5551 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5552 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5553 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5554 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_texelBuffers.getBufferViewA(), m_texelBuffers.getBufferViewB()))
5558 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5559 vk::VkDevice device,
5560 vk::VkDescriptorType descriptorType,
5561 ShaderInputInterface shaderInterface,
5562 vk::VkShaderStageFlags stageFlags)
5564 vk::DescriptorSetLayoutBuilder builder;
5566 switch (shaderInterface)
5568 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5569 builder.addSingleBinding(descriptorType, stageFlags);
5572 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5573 builder.addSingleBinding(descriptorType, stageFlags);
5574 builder.addSingleBinding(descriptorType, stageFlags);
5577 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5578 builder.addArrayBinding(descriptorType, 2u, stageFlags);
5582 DE_FATAL("Impossible");
5585 return builder.build(vki, device);
5588 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5589 vk::VkDevice device,
5590 vk::VkDescriptorSetLayout descriptorSetLayout)
5592 const vk::VkPipelineLayoutCreateInfo createInfo =
5594 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5596 (vk::VkPipelineLayoutCreateFlags)0,
5597 1, // descriptorSetCount
5598 &descriptorSetLayout, // pSetLayouts
5599 0u, // pushConstantRangeCount
5600 DE_NULL, // pPushConstantRanges
5602 return vk::createPipelineLayout(vki, device, &createInfo);
5605 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5606 vk::VkDevice device,
5607 vk::VkDescriptorType descriptorType,
5608 ShaderInputInterface shaderInterface)
5610 return vk::DescriptorPoolBuilder()
5611 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
5612 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5615 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5616 vk::VkDevice device,
5617 vk::VkDescriptorType descriptorType,
5618 ShaderInputInterface shaderInterface,
5619 vk::VkDescriptorSetLayout layout,
5620 vk::VkDescriptorPool pool,
5621 vk::VkBufferView viewA,
5622 vk::VkBufferView viewB)
5624 const vk::VkBufferView texelBufferInfos[2] =
5629 const vk::VkDescriptorSetAllocateInfo allocInfo =
5631 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5638 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5639 vk::DescriptorSetUpdateBuilder builder;
5641 switch (shaderInterface)
5643 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5644 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5647 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5648 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5649 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
5652 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5653 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
5657 DE_FATAL("Impossible");
5660 builder.update(vki, device);
5661 return descriptorSet;
5664 void TexelBufferRenderInstance::logTestPlan (void) const
5666 std::ostringstream msg;
5668 msg << "Rendering 2x2 grid.\n"
5669 << "Single descriptor set. Descriptor set contains "
5670 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5671 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5672 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5673 (const char*)DE_NULL)
5674 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5675 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5676 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5678 if (m_stageFlags == 0u)
5680 msg << "Descriptors are not accessed in any shader stage.\n";
5684 msg << "Color in each cell is fetched using the descriptor(s):\n";
5686 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5688 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5690 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5692 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5693 msg << " from texelBuffer " << srcResourceNdx;
5699 msg << "Descriptors are accessed in {"
5700 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5701 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5702 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5703 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5704 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5708 m_context.getTestContext().getLog()
5709 << tcu::TestLog::Message
5711 << tcu::TestLog::EndMessage;
5714 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
5716 return *m_pipelineLayout;
5719 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
5721 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
5722 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
5725 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5727 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5728 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5729 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5730 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
5731 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
5732 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
5733 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
5734 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5736 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5738 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
5739 return tcu::TestStatus::fail("Image verification failed");
5741 return tcu::TestStatus::pass("Pass");
5744 class TexelBufferComputeInstance : public vkt::TestInstance
5747 TexelBufferComputeInstance (vkt::Context& context,
5748 vk::VkDescriptorType descriptorType,
5749 ShaderInputInterface shaderInterface,
5750 bool nonzeroViewOffset);
5753 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5754 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5755 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
5757 tcu::TestStatus iterate (void);
5758 void logTestPlan (void) const;
5759 tcu::TestStatus testResourceAccess (void);
5761 const vk::VkDescriptorType m_descriptorType;
5762 const ShaderInputInterface m_shaderInterface;
5763 const bool m_nonzeroViewOffset;
5765 const vk::DeviceInterface& m_vki;
5766 const vk::VkDevice m_device;
5767 const vk::VkQueue m_queue;
5768 const deUint32 m_queueFamilyIndex;
5769 vk::Allocator& m_allocator;
5771 const ComputeInstanceResultBuffer m_result;
5772 const TexelBufferInstanceBuffers m_texelBuffers;
5775 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
5776 vk::VkDescriptorType descriptorType,
5777 ShaderInputInterface shaderInterface,
5778 bool nonzeroViewOffset)
5779 : vkt::TestInstance (context)
5780 , m_descriptorType (descriptorType)
5781 , m_shaderInterface (shaderInterface)
5782 , m_nonzeroViewOffset (nonzeroViewOffset)
5783 , m_vki (context.getDeviceInterface())
5784 , m_device (context.getDevice())
5785 , m_queue (context.getUniversalQueue())
5786 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5787 , m_allocator (context.getDefaultAllocator())
5788 , m_result (m_vki, m_device, m_allocator)
5789 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5793 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
5795 vk::DescriptorSetLayoutBuilder builder;
5797 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5799 switch (m_shaderInterface)
5801 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5802 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5805 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5806 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5807 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5810 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5811 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5815 DE_FATAL("Impossible");
5818 return builder.build(m_vki, m_device);
5821 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
5823 return vk::DescriptorPoolBuilder()
5824 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
5825 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
5826 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5829 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
5831 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5832 const vk::VkBufferView texelBufferInfos[2] =
5834 m_texelBuffers.getBufferViewA(),
5835 m_texelBuffers.getBufferViewB(),
5837 const vk::VkDescriptorSetAllocateInfo allocInfo =
5839 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5846 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
5847 vk::DescriptorSetUpdateBuilder builder;
5850 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5853 switch (m_shaderInterface)
5855 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5856 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5859 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5860 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5861 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
5864 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5865 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
5869 DE_FATAL("Impossible");
5872 builder.update(m_vki, m_device);
5873 return descriptorSet;
5876 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
5879 return testResourceAccess();
5882 void TexelBufferComputeInstance::logTestPlan (void) const
5884 std::ostringstream msg;
5886 msg << "Fetching 4 values from image in compute shader.\n"
5887 << "Single descriptor set. Descriptor set contains "
5888 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5889 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5890 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5891 (const char*)DE_NULL)
5892 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5893 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5894 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5896 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5898 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5900 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5902 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5903 msg << " from texelBuffer " << srcResourceNdx;
5909 m_context.getTestContext().getLog()
5910 << tcu::TestLog::Message
5912 << tcu::TestLog::EndMessage;
5915 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
5917 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
5918 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5919 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
5920 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
5922 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
5923 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
5924 const deUint32* const dynamicOffsets = DE_NULL;
5925 const int numDynamicOffsets = 0;
5926 const void* const preBarriers[] = { m_texelBuffers.getBufferInitBarrierA(), m_texelBuffers.getBufferInitBarrierB() };
5927 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
5928 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
5929 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
5931 const ComputeCommand compute (m_vki,
5933 pipeline.getPipeline(),
5934 pipeline.getPipelineLayout(),
5935 tcu::UVec3(4, 1, 1),
5936 numDescriptorSets, descriptorSets,
5937 numDynamicOffsets, dynamicOffsets,
5938 numPreBarriers, preBarriers,
5939 numPostBarriers, postBarriers);
5941 tcu::Vec4 results[4];
5942 bool anyResultSet = false;
5943 bool allResultsOk = true;
5945 compute.submitAndWait(m_queueFamilyIndex, m_queue);
5946 m_result.readResultContentsTo(&results);
5949 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5951 const tcu::Vec4 result = results[resultNdx];
5952 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
5953 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
5955 if (result != tcu::Vec4(-1.0f))
5956 anyResultSet = true;
5958 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
5960 allResultsOk = false;
5962 m_context.getTestContext().getLog()
5963 << tcu::TestLog::Message
5964 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
5965 << tcu::TestLog::EndMessage;
5969 // read back and verify
5971 return tcu::TestStatus::pass("Pass");
5972 else if (anyResultSet)
5973 return tcu::TestStatus::fail("Invalid result values");
5976 m_context.getTestContext().getLog()
5977 << tcu::TestLog::Message
5978 << "Result buffer was not written to."
5979 << tcu::TestLog::EndMessage;
5980 return tcu::TestStatus::fail("Result buffer was not written to");
5984 class TexelBufferDescriptorCase : public QuadrantRendederCase
5989 FLAG_VIEW_OFFSET = (1u << 1u),
5991 // enum continues where resource flags ends
5992 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
5994 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
5996 const char* description,
5997 bool isPrimaryCmdBuf,
5998 vk::VkDescriptorType descriptorType,
5999 vk::VkShaderStageFlags exitingStages,
6000 vk::VkShaderStageFlags activeStages,
6001 ShaderInputInterface shaderInterface,
6005 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
6006 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
6007 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
6008 std::string genNoAccessSource (void) const;
6010 vkt::TestInstance* createInstance (vkt::Context& context) const;
6012 const bool m_isPrimaryCmdBuf;
6013 const vk::VkDescriptorType m_descriptorType;
6014 const ShaderInputInterface m_shaderInterface;
6015 const bool m_nonzeroViewOffset;
6018 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6020 const char* description,
6021 bool isPrimaryCmdBuf,
6022 vk::VkDescriptorType descriptorType,
6023 vk::VkShaderStageFlags exitingStages,
6024 vk::VkShaderStageFlags activeStages,
6025 ShaderInputInterface shaderInterface,
6027 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
6028 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6029 , m_descriptorType (descriptorType)
6030 , m_shaderInterface (shaderInterface)
6031 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
6035 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
6038 return "#extension GL_EXT_texture_buffer : require\n";
6041 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
6045 const bool isUniform = isUniformDescriptorType(m_descriptorType);
6046 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
6047 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
6049 switch (m_shaderInterface)
6051 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6052 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
6054 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
6055 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
6056 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
6058 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6059 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
6062 DE_FATAL("Impossible");
6067 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
6071 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6072 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
6073 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6075 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6076 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
6077 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6079 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
6080 std::ostringstream buf;
6082 buf << " if (quadrant_id == 0)\n"
6083 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
6084 << " else if (quadrant_id == 1)\n"
6085 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
6086 << " else if (quadrant_id == 2)\n"
6087 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
6089 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
6094 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
6096 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6097 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6099 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6102 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
6104 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6106 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
6107 return new TexelBufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
6110 return new TexelBufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
6113 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
6114 bool isPrimaryCmdBuf,
6115 vk::VkDescriptorType descriptorType,
6116 vk::VkShaderStageFlags exitingStages,
6117 vk::VkShaderStageFlags activeStages,
6118 ShaderInputInterface dimension,
6119 deUint32 resourceFlags)
6123 vk::VkImageViewType viewType;
6125 const char* description;
6129 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
6130 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6131 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6133 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
6134 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6135 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6137 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
6138 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6139 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6141 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
6142 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6143 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6145 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
6146 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6147 // no 3d array textures
6149 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
6150 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6151 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6153 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
6154 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6155 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6158 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
6161 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
6163 group->addChild(new ImageDescriptorCase(group->getTestContext(),
6164 s_imageTypes[ndx].name,
6165 s_imageTypes[ndx].description,
6171 s_imageTypes[ndx].viewType,
6172 s_imageTypes[ndx].flags | resourceFlags));
6176 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
6177 bool isPrimaryCmdBuf,
6178 vk::VkDescriptorType descriptorType,
6179 vk::VkShaderStageFlags exitingStages,
6180 vk::VkShaderStageFlags activeStages,
6181 ShaderInputInterface dimension,
6182 deUint32 resourceFlags)
6184 DE_ASSERT(resourceFlags == 0);
6185 DE_UNREF(resourceFlags);
6190 const char* description;
6192 } s_texelBufferTypes[] =
6194 { "offset_zero", "View offset is zero", 0u },
6195 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
6198 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
6200 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
6201 s_texelBufferTypes[ndx].name,
6202 s_texelBufferTypes[ndx].description,
6208 s_texelBufferTypes[ndx].flags));
6212 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
6213 bool isPrimaryCmdBuf,
6214 vk::VkDescriptorType descriptorType,
6215 vk::VkShaderStageFlags exitingStages,
6216 vk::VkShaderStageFlags activeStages,
6217 ShaderInputInterface dimension,
6218 deUint32 resourceFlags)
6220 DE_ASSERT(resourceFlags == 0u);
6221 DE_UNREF(resourceFlags);
6226 const char* description;
6227 bool isForDynamicCases;
6231 { "offset_view_zero", "View offset is zero", false, 0u },
6232 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6234 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6235 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
6236 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6237 { "offset_view_nonzero_dynamic_nonzero", "View offset is non-zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
6240 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
6242 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
6244 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
6245 group->addChild(new BufferDescriptorCase(group->getTestContext(),
6246 s_bufferTypes[ndx].name,
6247 s_bufferTypes[ndx].description,
6253 s_bufferTypes[ndx].flags));
6259 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
6263 const bool isPrimary;
6265 const char* description;
6268 { true, "primary_cmd_buf", "Bind in primary command buffer" },
6269 { false, "seconday_cmd_buf", "Bind in secondary command buffer" },
6273 const vk::VkDescriptorType descriptorType;
6275 const char* description;
6277 } s_descriptorTypes[] =
6279 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
6280 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6281 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
6282 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6283 // \note No way to access SAMPLED_IMAGE without a sampler
6284 // { vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
6285 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
6286 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
6287 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
6288 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
6289 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
6290 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
6291 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
6296 const char* description;
6297 vk::VkShaderStageFlags existingStages; //!< stages that exists
6298 vk::VkShaderStageFlags activeStages; //!< stages that access resource
6299 bool supportsSecondaryCmdBufs;
6300 } s_shaderStages[] =
6304 "No accessing stages",
6305 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6312 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6313 vk::VK_SHADER_STAGE_VERTEX_BIT,
6318 "Tessellation control stage",
6319 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6320 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
6325 "Tessellation evaluation stage",
6326 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6327 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
6333 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6334 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
6340 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6341 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6347 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6348 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6353 "Vertex and fragment stages",
6354 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6355 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6361 ShaderInputInterface dimension;
6363 const char* description;
6364 } s_variableDimensions[] =
6366 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
6367 { SHADER_INPUT_MULTIPLE_DESCRIPTORS, "multiple_descriptors", "Multiple descriptors" },
6368 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
6371 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
6373 // .primary_cmd_buf...
6374 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
6376 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
6378 // .sampler, .combined_image_sampler, other resource types ...
6379 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
6381 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
6383 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
6385 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
6387 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
6389 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
6391 de::MovePtr<tcu::TestCaseGroup> dimensionGroup(new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
6392 void (*createTestsFunc)(tcu::TestCaseGroup* group,
6393 bool isPrimaryCmdBuf,
6394 vk::VkDescriptorType descriptorType,
6395 vk::VkShaderStageFlags existingStages,
6396 vk::VkShaderStageFlags activeStages,
6397 ShaderInputInterface dimension,
6398 deUint32 resourceFlags);
6400 switch (s_descriptorTypes[descriptorNdx].descriptorType)
6402 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6403 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6404 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6405 createTestsFunc = createShaderAccessImageTests;
6408 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
6409 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
6410 createTestsFunc = createShaderAccessTexelBufferTests;
6413 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
6414 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
6415 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
6416 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
6417 createTestsFunc = createShaderAccessBufferTests;
6421 createTestsFunc = DE_NULL;
6422 DE_FATAL("Impossible");
6425 if (createTestsFunc)
6427 createTestsFunc(dimensionGroup.get(),
6428 s_bindTypes[bindTypeNdx].isPrimary,
6429 s_descriptorTypes[descriptorNdx].descriptorType,
6430 s_shaderStages[stageNdx].existingStages,
6431 s_shaderStages[stageNdx].activeStages,
6432 s_variableDimensions[dimensionNdx].dimension,
6433 s_descriptorTypes[descriptorNdx].flags);
6436 DE_FATAL("Impossible");
6438 stageGroup->addChild(dimensionGroup.release());
6441 typeGroup->addChild(stageGroup.release());
6445 bindGroup->addChild(typeGroup.release());
6448 group->addChild(bindGroup.release());
6451 return group.release();