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));
744 // Wait for the GPU to idle so that throwing the exception
745 // below doesn't free in-use GPU resource.
746 vki.deviceWaitIdle(device);
747 TCU_THROW(NotSupportedError, (de::toString(stage) + " is not supported").c_str());
752 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const
754 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
756 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
758 (vk::VkPipelineShaderStageCreateFlags)0,
762 DE_NULL, // pSpecializationInfo
764 return stageCreateInfo;
767 class SingleCmdRenderInstance : public SingleTargetRenderInstance
770 SingleCmdRenderInstance (Context& context,
771 bool isPrimaryCmdBuf,
772 const tcu::UVec2& renderSize);
775 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
777 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
778 virtual void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const = 0;
780 void renderToTarget (void);
782 const bool m_isPrimaryCmdBuf;
785 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
786 bool isPrimaryCmdBuf,
787 const tcu::UVec2& renderSize)
788 : SingleTargetRenderInstance (context, renderSize)
789 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
793 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
795 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getDeviceFeatures(), m_context.getBinaryCollection());
796 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
797 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
799 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
801 (vk::VkPipelineVertexInputStateCreateFlags)0,
803 DE_NULL, // pVertexBindingDescriptions
804 0u, // attributeCount
805 DE_NULL, // pVertexAttributeDescriptions
807 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
809 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
811 (vk::VkPipelineInputAssemblyStateCreateFlags)0,
812 topology, // topology
813 vk::VK_FALSE, // primitiveRestartEnable
815 const vk::VkPipelineTessellationStateCreateInfo tessState =
817 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
819 (vk::VkPipelineTesselationStateCreateFlags)0,
820 3u, // patchControlPoints
822 const vk::VkViewport viewport =
826 float(m_targetSize.x()), // width
827 float(m_targetSize.y()), // height
831 const vk::VkRect2D renderArea =
834 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y() }, // extent
836 const vk::VkPipelineViewportStateCreateInfo vpState =
838 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
840 (vk::VkPipelineViewportStateCreateFlags)0,
846 const vk::VkPipelineRasterizationStateCreateInfo rsState =
848 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
850 (vk::VkPipelineRasterizationStateCreateFlags)0,
851 vk::VK_TRUE, // depthClipEnable
852 vk::VK_FALSE, // rasterizerDiscardEnable
853 vk::VK_POLYGON_MODE_FILL, // fillMode
854 vk::VK_CULL_MODE_NONE, // cullMode
855 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
856 vk::VK_FALSE, // depthBiasEnable
858 0.0f, // depthBiasClamp
859 0.0f, // slopeScaledDepthBias
862 const vk::VkSampleMask sampleMask = 0x01u;
863 const vk::VkPipelineMultisampleStateCreateInfo msState =
865 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
867 (vk::VkPipelineMultisampleStateCreateFlags)0,
868 vk::VK_SAMPLE_COUNT_1_BIT, // rasterSamples
869 vk::VK_FALSE, // sampleShadingEnable
870 0.0f, // minSampleShading
871 &sampleMask, // sampleMask
872 vk::VK_FALSE, // alphaToCoverageEnable
873 vk::VK_FALSE, // alphaToOneEnable
875 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
877 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
879 (vk::VkPipelineDepthStencilStateCreateFlags)0,
880 vk::VK_FALSE, // depthTestEnable
881 vk::VK_FALSE, // depthWriteEnable
882 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
883 vk::VK_FALSE, // depthBoundsTestEnable
884 vk::VK_FALSE, // stencilTestEnable
885 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
886 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
887 -1.0f, // minDepthBounds
888 +1.0f, // maxDepthBounds
890 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
892 vk::VK_FALSE, // blendEnable
893 vk::VK_BLEND_FACTOR_ZERO, // srcBlendColor
894 vk::VK_BLEND_FACTOR_ZERO, // destBlendColor
895 vk::VK_BLEND_OP_ADD, // blendOpColor
896 vk::VK_BLEND_FACTOR_ZERO, // srcBlendAlpha
897 vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha
898 vk::VK_BLEND_OP_ADD, // blendOpAlpha
899 (vk::VK_COLOR_COMPONENT_R_BIT |
900 vk::VK_COLOR_COMPONENT_G_BIT |
901 vk::VK_COLOR_COMPONENT_B_BIT |
902 vk::VK_COLOR_COMPONENT_A_BIT), // channelWriteMask
904 const vk::VkPipelineColorBlendStateCreateInfo cbState =
906 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
908 (vk::VkPipelineColorBlendStateCreateFlags)0,
909 vk::VK_FALSE, // logicOpEnable
910 vk::VK_LOGIC_OP_CLEAR, // logicOp
911 1u, // attachmentCount
912 &cbAttachment, // pAttachments
913 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
915 const vk::VkPipelineDynamicStateCreateInfo dynState =
917 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
919 (vk::VkPipelineDynamicStateCreateFlags)0,
920 0u, // dynamicStateCount
921 DE_NULL, // pDynamicStates
923 const vk::VkGraphicsPipelineCreateInfo createInfo =
925 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
927 (vk::VkPipelineCreateFlags)0,
928 shaderStages.getNumStages(), // stageCount
929 shaderStages.getStages(), // pStages
930 &vertexInputState, // pVertexInputState
931 &iaState, // pInputAssemblyState
932 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
933 &vpState, // pViewportState
934 &rsState, // pRasterState
935 &msState, // pMultisampleState
936 &dsState, // pDepthStencilState
937 &cbState, // pColorBlendState
938 &dynState, // pDynamicState
939 pipelineLayout, // layout
940 *m_renderPass, // renderPass
942 (vk::VkPipeline)0, // basePipelineHandle
943 0u, // basePipelineIndex
945 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
948 void SingleCmdRenderInstance::renderToTarget (void)
950 const vk::VkRect2D renderArea =
953 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y() }, // extent
955 const vk::VkCommandBufferAllocateInfo mainCmdBufCreateInfo =
957 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
959 *m_cmdPool, // cmdPool
960 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
963 const vk::VkCommandBufferBeginInfo mainCmdBufBeginInfo =
965 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
967 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
968 (vk::VkRenderPass)0u, // renderPass
970 (vk::VkFramebuffer)0u, // framebuffer
971 vk::VK_FALSE, // occlusionQueryEnable
972 (vk::VkQueryControlFlags)0,
973 (vk::VkQueryPipelineStatisticFlags)0,
975 const vk::VkCommandBufferAllocateInfo passCmdBufCreateInfo =
977 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
979 *m_cmdPool, // cmdPool
980 vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level
983 const vk::VkCommandBufferBeginInfo passCmdBufBeginInfo =
985 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
987 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
988 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // flags
989 (vk::VkRenderPass)*m_renderPass, // renderPass
991 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
992 vk::VK_FALSE, // occlusionQueryEnable
993 (vk::VkQueryControlFlags)0,
994 (vk::VkQueryPipelineStatisticFlags)0,
996 const vk::VkFenceCreateInfo fenceCreateInfo =
998 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1002 const vk::VkClearValue clearValue = vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
1003 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1005 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1007 *m_renderPass, // renderPass
1008 *m_framebuffer, // framebuffer
1009 renderArea, // renderArea
1010 1u, // clearValueCount
1011 &clearValue, // pClearValues
1014 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1015 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1016 const vk::Unique<vk::VkCommandBuffer> mainCmd (vk::allocateCommandBuffer(m_vki, m_device, &mainCmdBufCreateInfo));
1017 const vk::Unique<vk::VkCommandBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCommandBuffer>()) : (vk::allocateCommandBuffer(m_vki, m_device, &passCmdBufCreateInfo)));
1018 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1019 const deUint64 infiniteTimeout = ~(deUint64)0u;
1020 const vk::VkSubpassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_SUBPASS_CONTENTS_INLINE) : (vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1022 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1023 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1025 if (m_isPrimaryCmdBuf)
1027 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1028 writeDrawCmdBuffer(*mainCmd);
1032 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1033 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1034 writeDrawCmdBuffer(*passCmd);
1035 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1037 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1040 m_vki.cmdEndRenderPass(*mainCmd);
1041 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1043 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1045 const vk::VkSubmitInfo submitInfo =
1047 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1050 (const vk::VkSemaphore*)0,
1054 (const vk::VkSemaphore*)0,
1056 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *fence));
1058 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1061 enum ShaderInputInterface
1063 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1064 SHADER_INPUT_MULTIPLE_DESCRIPTORS, //!< multiple descriptors
1065 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1070 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1072 switch (shaderInterface)
1074 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1075 case SHADER_INPUT_MULTIPLE_DESCRIPTORS: return 2u;
1076 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1079 DE_FATAL("Impossible");
1084 class BufferRenderInstance : public SingleCmdRenderInstance
1087 BufferRenderInstance (Context& context,
1088 bool isPrimaryCmdBuf,
1089 vk::VkDescriptorType descriptorType,
1090 vk::VkShaderStageFlags stageFlags,
1091 ShaderInputInterface shaderInterface,
1094 bool dynamicOffsetNonZero);
1096 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1097 vk::VkDevice device,
1098 vk::Allocator& allocator,
1099 vk::VkDescriptorType descriptorType,
1101 deUint32 bufferSize,
1102 de::MovePtr<vk::Allocation>* outMemory);
1104 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1105 vk::VkDevice device,
1106 vk::VkDescriptorType descriptorType,
1107 ShaderInputInterface shaderInterface);
1109 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1110 vk::VkDevice device,
1111 vk::VkDescriptorType descriptorType,
1112 ShaderInputInterface shaderInterface,
1113 vk::VkShaderStageFlags stageFlags);
1115 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1116 vk::VkDevice device,
1117 vk::VkDescriptorSetLayout descriptorSetLayout,
1118 vk::VkDescriptorPool descriptorPool,
1119 vk::VkDescriptorType descriptorType,
1120 ShaderInputInterface shaderInterface,
1121 vk::VkBuffer sourceBufferA,
1122 const deUint32 viewOffsetA,
1123 vk::VkBuffer sourceBufferB,
1124 const deUint32 viewOffsetB);
1126 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1127 vk::VkDevice device,
1128 vk::VkDescriptorSetLayout descriptorSetLayout);
1130 void logTestPlan (void) const;
1131 vk::VkPipelineLayout getPipelineLayout (void) const;
1132 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1133 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1138 BUFFER_DATA_SIZE = 8 * sizeof(float),
1139 BUFFER_SIZE_A = 2048, //!< a lot more than required
1140 BUFFER_SIZE_B = 2560, //!< a lot more than required
1142 STATIC_OFFSET_VALUE_A = 256,
1143 DYNAMIC_OFFSET_VALUE_A = 512,
1144 STATIC_OFFSET_VALUE_B = 1024,
1145 DYNAMIC_OFFSET_VALUE_B = 768,
1148 const vk::VkDescriptorType m_descriptorType;
1149 const ShaderInputInterface m_shaderInterface;
1150 const bool m_setViewOffset;
1151 const bool m_setDynamicOffset;
1152 const bool m_dynamicOffsetNonZero;
1153 const vk::VkShaderStageFlags m_stageFlags;
1155 const deUint32 m_viewOffsetA;
1156 const deUint32 m_viewOffsetB;
1157 const deUint32 m_dynamicOffsetA;
1158 const deUint32 m_dynamicOffsetB;
1159 const deUint32 m_effectiveOffsetA;
1160 const deUint32 m_effectiveOffsetB;
1161 const deUint32 m_bufferSizeA;
1162 const deUint32 m_bufferSizeB;
1164 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1165 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1166 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1167 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1168 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1169 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1170 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1171 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1174 BufferRenderInstance::BufferRenderInstance (Context& context,
1175 bool isPrimaryCmdBuf,
1176 vk::VkDescriptorType descriptorType,
1177 vk::VkShaderStageFlags stageFlags,
1178 ShaderInputInterface shaderInterface,
1181 bool dynamicOffsetNonZero)
1182 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1183 , m_descriptorType (descriptorType)
1184 , m_shaderInterface (shaderInterface)
1185 , m_setViewOffset (viewOffset)
1186 , m_setDynamicOffset (dynamicOffset)
1187 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1188 , m_stageFlags (stageFlags)
1189 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1190 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1191 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1192 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1193 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetA + m_dynamicOffsetA) : (m_viewOffsetA))
1194 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetB + m_dynamicOffsetB) : (m_viewOffsetB))
1195 , m_bufferSizeA (BUFFER_SIZE_A)
1196 , m_bufferSizeB (BUFFER_SIZE_B)
1197 , m_bufferMemoryA (DE_NULL)
1198 , m_bufferMemoryB (DE_NULL)
1199 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1200 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1201 ? vk::Move<vk::VkBuffer>()
1202 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1203 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1204 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
1205 , m_descriptorSet (createDescriptorSet(m_vki, m_device, *m_descriptorSetLayout, *m_descriptorPool, m_descriptorType, m_shaderInterface, *m_sourceBufferA, m_viewOffsetA, *m_sourceBufferB, m_viewOffsetB))
1206 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1208 if (m_setDynamicOffset)
1209 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1210 if (m_dynamicOffsetNonZero)
1211 DE_ASSERT(m_setDynamicOffset);
1214 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1215 vk::VkDevice device,
1216 vk::Allocator& allocator,
1217 vk::VkDescriptorType descriptorType,
1219 deUint32 bufferSize,
1220 de::MovePtr<vk::Allocation>* outMemory)
1222 static const float s_colors[] =
1224 0.0f, 1.0f, 0.0f, 1.0f, // green
1225 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1227 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1228 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1229 DE_ASSERT(offset % sizeof(float) == 0);
1230 DE_ASSERT(bufferSize % sizeof(float) == 0);
1232 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1233 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1234 const float preGuardValue = 0.5f;
1235 const float postGuardValue = 0.75f;
1236 const vk::VkBufferCreateInfo bufferCreateInfo =
1238 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1242 usageFlags, // usage
1243 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1244 0u, // queueFamilyCount
1245 DE_NULL, // pQueueFamilyIndices
1247 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1248 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1249 void* const mapPtr = bufferMemory->getHostPtr();
1251 // guard with interesting values
1252 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1253 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1255 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1256 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1257 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1258 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
1260 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1262 *outMemory = bufferMemory;
1266 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1267 vk::VkDevice device,
1268 vk::VkDescriptorType descriptorType,
1269 ShaderInputInterface shaderInterface)
1271 return vk::DescriptorPoolBuilder()
1272 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1273 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1276 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1277 vk::VkDevice device,
1278 vk::VkDescriptorType descriptorType,
1279 ShaderInputInterface shaderInterface,
1280 vk::VkShaderStageFlags stageFlags)
1282 vk::DescriptorSetLayoutBuilder builder;
1284 switch (shaderInterface)
1286 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1287 builder.addSingleBinding(descriptorType, stageFlags);
1290 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1291 builder.addSingleBinding(descriptorType, stageFlags);
1292 builder.addSingleBinding(descriptorType, stageFlags);
1295 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1296 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1300 DE_FATAL("Impossible");
1303 return builder.build(vki, device);
1306 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1307 vk::VkDevice device,
1308 vk::VkDescriptorSetLayout descriptorSetLayout,
1309 vk::VkDescriptorPool descriptorPool,
1310 vk::VkDescriptorType descriptorType,
1311 ShaderInputInterface shaderInterface,
1312 vk::VkBuffer bufferA,
1314 vk::VkBuffer bufferB,
1317 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1319 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1320 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1322 const vk::VkDescriptorSetAllocateInfo allocInfo =
1324 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1328 &descriptorSetLayout
1331 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1332 vk::DescriptorSetUpdateBuilder builder;
1334 switch (shaderInterface)
1336 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1337 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1340 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1341 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1342 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1345 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1346 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1350 DE_FATAL("Impossible");
1353 builder.update(vki, device);
1354 return descriptorSet;
1357 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1358 vk::VkDevice device,
1359 vk::VkDescriptorSetLayout descriptorSetLayout)
1361 const vk::VkPipelineLayoutCreateInfo createInfo =
1363 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1365 (vk::VkPipelineLayoutCreateFlags)0,
1366 1, // descriptorSetCount
1367 &descriptorSetLayout, // pSetLayouts
1368 0u, // pushConstantRangeCount
1369 DE_NULL, // pPushConstantRanges
1372 return vk::createPipelineLayout(vki, device, &createInfo);
1375 void BufferRenderInstance::logTestPlan (void) const
1377 std::ostringstream msg;
1379 msg << "Rendering 2x2 yellow-green grid.\n"
1380 << "Single descriptor set. Descriptor set contains "
1381 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1382 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
1383 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1384 (const char*)DE_NULL)
1385 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1386 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1388 if (isDynamicDescriptorType(m_descriptorType))
1390 if (m_setDynamicOffset)
1392 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1393 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1397 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1401 if (m_stageFlags == 0u)
1403 msg << "Descriptors are not accessed in any shader stage.\n";
1407 msg << "Descriptors are accessed in {"
1408 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1409 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1410 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1411 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1412 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1416 m_context.getTestContext().getLog()
1417 << tcu::TestLog::Message
1419 << tcu::TestLog::EndMessage;
1422 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1424 return *m_pipelineLayout;
1427 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1429 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1431 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1432 const deUint32 dynamicOffsets[] =
1437 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1438 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1440 // make host writes device-visible
1441 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
1442 const vk::VkBufferMemoryBarrier memoryBarrierA =
1444 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1446 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
1447 inputBit, // inputMask
1448 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1449 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1450 *m_sourceBufferA, // buffer
1452 (vk::VkDeviceSize)m_bufferSizeA, // size
1454 const vk::VkBufferMemoryBarrier memoryBarrierB =
1456 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1458 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
1459 inputBit, // inputMask
1460 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1461 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1462 *m_sourceBufferB, // buffer
1464 (vk::VkDeviceSize)m_bufferSizeB, // size
1466 const void* const memoryBarriers[2] =
1471 const deUint32 numMemoryBarriers = getInterfaceNumResources(m_shaderInterface);
1473 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1474 m_vki.cmdPipelineBarrier(cmd, 0u, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, vk::VK_FALSE, numMemoryBarriers, memoryBarriers);
1475 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1478 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1480 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1481 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1482 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1484 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1486 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1487 return tcu::TestStatus::fail("Image verification failed");
1489 return tcu::TestStatus::pass("Pass");
1492 class ComputeInstanceResultBuffer
1497 DATA_SIZE = sizeof(tcu::Vec4[4])
1500 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1501 vk::VkDevice device,
1502 vk::Allocator& allocator);
1504 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1506 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1507 inline const void* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1510 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1511 vk::VkDevice device,
1512 vk::Allocator& allocator,
1513 de::MovePtr<vk::Allocation>* outAllocation);
1515 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1517 const vk::DeviceInterface& m_vki;
1518 const vk::VkDevice m_device;
1520 de::MovePtr<vk::Allocation> m_bufferMem;
1521 const vk::Unique<vk::VkBuffer> m_buffer;
1522 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1525 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1526 vk::VkDevice device,
1527 vk::Allocator& allocator)
1530 , m_bufferMem (DE_NULL)
1531 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1532 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1536 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1538 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1539 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1542 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1543 vk::VkDevice device,
1544 vk::Allocator& allocator,
1545 de::MovePtr<vk::Allocation>* outAllocation)
1547 const vk::VkBufferCreateInfo createInfo =
1549 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1552 (vk::VkDeviceSize)DATA_SIZE, // size
1553 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1554 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1555 0u, // queueFamilyCount
1556 DE_NULL, // pQueueFamilyIndices
1558 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1559 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1560 const float clearValue = -1.0f;
1561 void* mapPtr = allocation->getHostPtr();
1563 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1564 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1566 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1568 *outAllocation = allocation;
1572 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1574 const vk::VkBufferMemoryBarrier bufferBarrier =
1576 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1578 vk::VK_ACCESS_SHADER_WRITE_BIT, // outputMask
1579 vk::VK_ACCESS_HOST_READ_BIT, // inputMask
1580 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1581 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1583 (vk::VkDeviceSize)0u, // offset
1586 return bufferBarrier;
1589 class ComputePipeline
1592 ComputePipeline (const vk::DeviceInterface& vki,
1593 vk::VkDevice device,
1594 const vk::BinaryCollection& programCollection,
1595 deUint32 numDescriptorSets,
1596 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1598 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1599 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1602 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1603 vk::VkDevice device,
1604 deUint32 numDescriptorSets,
1605 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1607 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1608 vk::VkDevice device,
1609 const vk::BinaryCollection& programCollection,
1610 vk::VkPipelineLayout layout);
1612 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1613 const vk::Unique<vk::VkPipeline> m_pipeline;
1616 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1617 vk::VkDevice device,
1618 const vk::BinaryCollection& programCollection,
1619 deUint32 numDescriptorSets,
1620 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1621 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
1622 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
1626 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
1627 vk::VkDevice device,
1628 deUint32 numDescriptorSets,
1629 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1631 const vk::VkPipelineLayoutCreateInfo createInfo =
1633 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1635 (vk::VkPipelineLayoutCreateFlags)0,
1636 numDescriptorSets, // descriptorSetCount
1637 descriptorSetLayouts, // pSetLayouts
1638 0u, // pushConstantRangeCount
1639 DE_NULL, // pPushConstantRanges
1641 return vk::createPipelineLayout(vki, device, &createInfo);
1644 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
1645 vk::VkDevice device,
1646 const vk::BinaryCollection& programCollection,
1647 vk::VkPipelineLayout layout)
1649 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
1650 const vk::VkPipelineShaderStageCreateInfo cs =
1652 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1654 (vk::VkPipelineShaderStageCreateFlags)0,
1655 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
1656 *computeModule, // shader
1658 DE_NULL, // pSpecializationInfo
1660 const vk::VkComputePipelineCreateInfo createInfo =
1662 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1667 (vk::VkPipeline)0, // basePipelineHandle
1668 0u, // basePipelineIndex
1670 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
1673 class ComputeCommand
1676 ComputeCommand (const vk::DeviceInterface& vki,
1677 vk::VkDevice device,
1678 vk::VkPipeline pipeline,
1679 vk::VkPipelineLayout pipelineLayout,
1680 const tcu::UVec3& numWorkGroups,
1681 int numDescriptorSets,
1682 const vk::VkDescriptorSet* descriptorSets,
1683 int numDynamicOffsets,
1684 const deUint32* dynamicOffsets,
1686 const void* const* preBarriers,
1687 int numPostBarriers,
1688 const void* const* postBarriers);
1690 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const;
1693 const vk::DeviceInterface& m_vki;
1694 const vk::VkDevice m_device;
1695 const vk::VkPipeline m_pipeline;
1696 const vk::VkPipelineLayout m_pipelineLayout;
1697 const tcu::UVec3 m_numWorkGroups;
1698 const int m_numDescriptorSets;
1699 const vk::VkDescriptorSet* const m_descriptorSets;
1700 const int m_numDynamicOffsets;
1701 const deUint32* const m_dynamicOffsets;
1702 const int m_numPreBarriers;
1703 const void* const* const m_preBarriers;
1704 const int m_numPostBarriers;
1705 const void* const* const m_postBarriers;
1708 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
1709 vk::VkDevice device,
1710 vk::VkPipeline pipeline,
1711 vk::VkPipelineLayout pipelineLayout,
1712 const tcu::UVec3& numWorkGroups,
1713 int numDescriptorSets,
1714 const vk::VkDescriptorSet* descriptorSets,
1715 int numDynamicOffsets,
1716 const deUint32* dynamicOffsets,
1718 const void* const* preBarriers,
1719 int numPostBarriers,
1720 const void* const* postBarriers)
1723 , m_pipeline (pipeline)
1724 , m_pipelineLayout (pipelineLayout)
1725 , m_numWorkGroups (numWorkGroups)
1726 , m_numDescriptorSets (numDescriptorSets)
1727 , m_descriptorSets (descriptorSets)
1728 , m_numDynamicOffsets (numDynamicOffsets)
1729 , m_dynamicOffsets (dynamicOffsets)
1730 , m_numPreBarriers (numPreBarriers)
1731 , m_preBarriers (preBarriers)
1732 , m_numPostBarriers (numPostBarriers)
1733 , m_postBarriers (postBarriers)
1737 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const
1739 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
1741 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1743 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
1744 queueFamilyIndex, // queueFamilyIndex
1746 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
1748 const vk::VkFenceCreateInfo fenceCreateInfo =
1750 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1755 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
1757 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1759 *cmdPool, // cmdPool
1760 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1763 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
1765 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1767 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1768 (vk::VkRenderPass)0u, // renderPass
1770 (vk::VkFramebuffer)0u, // framebuffer
1771 vk::VK_FALSE, // occlusionQueryEnable
1772 (vk::VkQueryControlFlags)0,
1773 (vk::VkQueryPipelineStatisticFlags)0,
1776 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1777 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
1778 const deUint64 infiniteTimeout = ~(deUint64)0u;
1780 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
1782 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
1783 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
1785 if (m_numPreBarriers)
1786 m_vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_FALSE, m_numPreBarriers, m_preBarriers);
1788 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
1789 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);
1790 VK_CHECK(m_vki.endCommandBuffer(*cmd));
1794 const vk::VkSubmitInfo submitInfo =
1796 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1799 (const vk::VkSemaphore*)0,
1803 (const vk::VkSemaphore*)0,
1805 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
1807 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1810 class BufferComputeInstance : public vkt::TestInstance
1813 BufferComputeInstance (Context& context,
1814 vk::VkDescriptorType descriptorType,
1815 ShaderInputInterface shaderInterface,
1818 bool dynamicOffsetNonZero);
1821 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
1822 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
1823 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
1824 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
1825 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;
1827 tcu::TestStatus iterate (void);
1828 void logTestPlan (void) const;
1829 tcu::TestStatus testResourceAccess (void);
1833 STATIC_OFFSET_VALUE_A = 256,
1834 DYNAMIC_OFFSET_VALUE_A = 512,
1835 STATIC_OFFSET_VALUE_B = 1024,
1836 DYNAMIC_OFFSET_VALUE_B = 768,
1839 const vk::VkDescriptorType m_descriptorType;
1840 const ShaderInputInterface m_shaderInterface;
1841 const bool m_setViewOffset;
1842 const bool m_setDynamicOffset;
1843 const bool m_dynamicOffsetNonZero;
1845 const vk::DeviceInterface& m_vki;
1846 const vk::VkDevice m_device;
1847 const vk::VkQueue m_queue;
1848 const deUint32 m_queueFamilyIndex;
1849 vk::Allocator& m_allocator;
1851 const ComputeInstanceResultBuffer m_result;
1854 BufferComputeInstance::BufferComputeInstance (Context& context,
1855 vk::VkDescriptorType descriptorType,
1856 ShaderInputInterface shaderInterface,
1859 bool dynamicOffsetNonZero)
1860 : vkt::TestInstance (context)
1861 , m_descriptorType (descriptorType)
1862 , m_shaderInterface (shaderInterface)
1863 , m_setViewOffset (viewOffset)
1864 , m_setDynamicOffset (dynamicOffset)
1865 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1866 , m_vki (context.getDeviceInterface())
1867 , m_device (context.getDevice())
1868 , m_queue (context.getUniversalQueue())
1869 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
1870 , m_allocator (context.getDefaultAllocator())
1871 , m_result (m_vki, m_device, m_allocator)
1873 if (m_dynamicOffsetNonZero)
1874 DE_ASSERT(m_setDynamicOffset);
1877 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
1879 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
1881 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1882 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1883 const vk::VkBufferCreateInfo createInfo =
1885 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1888 (vk::VkDeviceSize)bufferSize, // size
1889 usageFlags, // usage
1890 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1891 0u, // queueFamilyCount
1892 DE_NULL, // pQueueFamilyIndices
1894 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
1895 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
1896 void* mapPtr = allocation->getHostPtr();
1899 deMemset(mapPtr, 0x5A, (size_t)offset);
1900 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
1901 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
1902 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
1904 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
1906 *outAllocation = allocation;
1910 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
1912 vk::DescriptorSetLayoutBuilder builder;
1914 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1916 switch (m_shaderInterface)
1918 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1919 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1922 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1923 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1924 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1927 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1928 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1932 DE_FATAL("Impossible");
1935 return builder.build(m_vki, m_device);
1938 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
1940 return vk::DescriptorPoolBuilder()
1941 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1942 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
1943 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1946 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
1948 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
1949 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1951 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1952 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1954 const vk::VkDescriptorSetAllocateInfo allocInfo =
1956 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1963 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
1964 vk::DescriptorSetUpdateBuilder builder;
1967 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
1970 switch (m_shaderInterface)
1972 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1973 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
1976 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1977 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
1978 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
1981 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1982 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
1986 DE_FATAL("Impossible");
1989 builder.update(m_vki, m_device);
1990 return descriptorSet;
1993 tcu::TestStatus BufferComputeInstance::iterate (void)
1996 return testResourceAccess();
1999 void BufferComputeInstance::logTestPlan (void) const
2001 std::ostringstream msg;
2003 msg << "Accessing resource in a compute program.\n"
2004 << "Single descriptor set. Descriptor set contains "
2005 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2006 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
2007 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2008 (const char*)DE_NULL)
2009 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2010 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2011 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2013 if (isDynamicDescriptorType(m_descriptorType))
2015 if (m_setDynamicOffset)
2017 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2018 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2022 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2026 msg << "Destination buffer is pre-initialized to -1.\n";
2028 m_context.getTestContext().getLog()
2029 << tcu::TestLog::Message
2031 << tcu::TestLog::EndMessage;
2034 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2038 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2041 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2042 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2043 const deUint32 bindTimeOffsets[] =
2045 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2046 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2049 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2050 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2051 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2052 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2054 const deUint32 dataOffsetA = ((isDynamicCase) ? (bindTimeOffsets[0]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u));
2055 const deUint32 dataOffsetB = ((isDynamicCase) ? (bindTimeOffsets[1]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u));
2056 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2057 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2058 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2059 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2061 de::MovePtr<vk::Allocation> bufferMemA;
2062 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2064 de::MovePtr<vk::Allocation> bufferMemB;
2065 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2066 ? (vk::Move<vk::VkBuffer>())
2067 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2069 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2070 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2071 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer()));
2072 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2074 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2075 const vk::VkBufferMemoryBarrier bufferBarrierA =
2077 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2079 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2080 inputBit, // inputMask
2081 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2082 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2084 (vk::VkDeviceSize)0u, // offset
2085 (vk::VkDeviceSize)bufferSizeA, // size
2087 const vk::VkBufferMemoryBarrier bufferBarrierB =
2089 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2091 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2092 inputBit, // inputMask
2093 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2094 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2096 (vk::VkDeviceSize)0u, // offset
2097 (vk::VkDeviceSize)bufferSizeB, // size
2100 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2102 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2103 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2104 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2105 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2106 const void* const preBarriers[] = { &bufferBarrierA, &bufferBarrierB };
2107 const int numPreBarriers = numSrcBuffers;
2108 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
2109 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
2111 const ComputeCommand compute (m_vki,
2113 pipeline.getPipeline(),
2114 pipeline.getPipelineLayout(),
2115 tcu::UVec3(4, 1, 1),
2116 numDescriptorSets, descriptorSets,
2117 numDynamicOffsets, dynamicOffsets,
2118 numPreBarriers, preBarriers,
2119 numPostBarriers, postBarriers);
2121 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2122 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorB2) :
2123 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2125 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2126 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorA1) :
2127 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2129 const tcu::Vec4 references[4] =
2136 tcu::Vec4 results[4];
2138 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2139 m_result.readResultContentsTo(&results);
2142 if (results[0] == references[0] &&
2143 results[1] == references[1] &&
2144 results[2] == references[2] &&
2145 results[3] == references[3])
2147 return tcu::TestStatus::pass("Pass");
2149 else if (results[0] == tcu::Vec4(-1.0f) &&
2150 results[1] == tcu::Vec4(-1.0f) &&
2151 results[2] == tcu::Vec4(-1.0f) &&
2152 results[3] == tcu::Vec4(-1.0f))
2154 m_context.getTestContext().getLog()
2155 << tcu::TestLog::Message
2156 << "Result buffer was not written to."
2157 << tcu::TestLog::EndMessage;
2158 return tcu::TestStatus::fail("Result buffer was not written to");
2162 m_context.getTestContext().getLog()
2163 << tcu::TestLog::Message
2164 << "Error expected ["
2165 << references[0] << ", "
2166 << references[1] << ", "
2167 << references[2] << ", "
2168 << references[3] << "], got ["
2169 << results[0] << ", "
2170 << results[1] << ", "
2171 << results[2] << ", "
2172 << results[3] << "]"
2173 << tcu::TestLog::EndMessage;
2174 return tcu::TestStatus::fail("Invalid result values");
2178 class QuadrantRendederCase : public vkt::TestCase
2181 QuadrantRendederCase (tcu::TestContext& testCtx,
2183 const char* description,
2184 glu::GLSLVersion glslVersion,
2185 vk::VkShaderStageFlags exitingStages,
2186 vk::VkShaderStageFlags activeStages);
2188 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
2189 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
2190 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
2191 virtual std::string genNoAccessSource (void) const = 0;
2193 std::string genVertexSource (void) const;
2194 std::string genTessCtrlSource (void) const;
2195 std::string genTessEvalSource (void) const;
2196 std::string genGeometrySource (void) const;
2197 std::string genFragmentSource (void) const;
2198 std::string genComputeSource (void) const;
2200 void initPrograms (vk::SourceCollections& programCollection) const;
2203 const glu::GLSLVersion m_glslVersion;
2204 const vk::VkShaderStageFlags m_exitingStages;
2205 const vk::VkShaderStageFlags m_activeStages;
2208 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2210 const char* description,
2211 glu::GLSLVersion glslVersion,
2212 vk::VkShaderStageFlags exitingStages,
2213 vk::VkShaderStageFlags activeStages)
2214 : vkt::TestCase (testCtx, name, description)
2215 , m_glslVersion (glslVersion)
2216 , m_exitingStages (exitingStages)
2217 , m_activeStages (activeStages)
2219 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2222 std::string QuadrantRendederCase::genVertexSource (void) const
2224 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
2225 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2226 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2228 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2229 std::ostringstream buf;
2231 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2233 // active vertex shader
2234 buf << versionDecl << "\n"
2235 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2236 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0)
2237 << "layout(location = 0) out highp vec4 " << nextStageName << "_color;\n"
2238 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2239 << "void main (void)\n"
2241 << " highp vec4 result_position;\n"
2242 << " highp int quadrant_id;\n"
2243 << s_quadrantGenVertexPosSource
2244 << " gl_Position = result_position;\n"
2245 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2247 << " highp vec4 result_color;\n"
2248 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
2249 << " " << nextStageName << "_color = result_color;\n"
2255 buf << versionDecl << "\n"
2256 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2257 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2258 << "void main (void)\n"
2260 << " highp vec4 result_position;\n"
2261 << " highp int quadrant_id;\n"
2262 << s_quadrantGenVertexPosSource
2263 << " gl_Position = result_position;\n"
2264 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2271 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2273 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2274 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2275 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2276 std::ostringstream buf;
2278 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2280 // contributing not implemented
2281 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2284 buf << versionDecl << "\n"
2286 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2287 << "layout(vertices=3) out;\n"
2288 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
2289 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2290 << "layout(location = 0) out highp vec4 tes_color[];\n"
2291 << "void main (void)\n"
2293 << " highp vec4 result_color;\n"
2294 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2295 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2297 << " tes_color[gl_InvocationID] = result_color;\n"
2299 << " // no dynamic input block indexing\n"
2300 << " highp vec4 position;\n"
2301 << " if (gl_InvocationID == 0)\n"
2302 << " position = gl_in[0].gl_Position;\n"
2303 << " else if (gl_InvocationID == 1)\n"
2304 << " position = gl_in[1].gl_Position;\n"
2306 << " position = gl_in[2].gl_Position;\n"
2307 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2308 << " gl_TessLevelInner[0] = 2.8;\n"
2309 << " gl_TessLevelInner[1] = 2.8;\n"
2310 << " gl_TessLevelOuter[0] = 2.8;\n"
2311 << " gl_TessLevelOuter[1] = 2.8;\n"
2312 << " gl_TessLevelOuter[2] = 2.8;\n"
2313 << " gl_TessLevelOuter[3] = 2.8;\n"
2316 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2318 // active te shader, tc passthru
2319 buf << versionDecl << "\n"
2321 << "layout(vertices=3) out;\n"
2322 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2323 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2324 << "void main (void)\n"
2326 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2328 << " // no dynamic input block indexing\n"
2329 << " highp vec4 position;\n"
2330 << " if (gl_InvocationID == 0)\n"
2331 << " position = gl_in[0].gl_Position;\n"
2332 << " else if (gl_InvocationID == 1)\n"
2333 << " position = gl_in[1].gl_Position;\n"
2335 << " position = gl_in[2].gl_Position;\n"
2336 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2337 << " gl_TessLevelInner[0] = 2.8;\n"
2338 << " gl_TessLevelInner[1] = 2.8;\n"
2339 << " gl_TessLevelOuter[0] = 2.8;\n"
2340 << " gl_TessLevelOuter[1] = 2.8;\n"
2341 << " gl_TessLevelOuter[2] = 2.8;\n"
2342 << " gl_TessLevelOuter[3] = 2.8;\n"
2347 // passthrough not implemented
2348 DE_FATAL("not implemented");
2354 std::string QuadrantRendederCase::genTessEvalSource (void) const
2356 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2357 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2358 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2359 std::ostringstream buf;
2361 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2363 // contributing not implemented
2364 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
2367 buf << versionDecl << "\n"
2369 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2370 << "layout(triangles) in;\n"
2371 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
2372 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2373 << "layout(location = 0) out highp vec4 frag_color;\n"
2374 << "void main (void)\n"
2376 << " highp vec4 result_color;\n"
2377 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2378 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2380 << " frag_color = result_color;\n"
2381 << " 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"
2384 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2386 // contributing not implemented
2387 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2389 // active tc shader, te is passthru
2390 buf << versionDecl << "\n"
2392 << "layout(triangles) in;\n"
2393 << "layout(location = 0) in highp vec4 tes_color[];\n"
2394 << "layout(location = 0) out highp vec4 frag_color;\n"
2395 << "void main (void)\n"
2397 << " frag_color = tes_color[0];\n"
2398 << " 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"
2403 // passthrough not implemented
2404 DE_FATAL("not implemented");
2410 std::string QuadrantRendederCase::genGeometrySource (void) const
2412 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2413 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2414 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
2415 std::ostringstream buf;
2417 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2419 // contributing not implemented
2420 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
2422 // active geometry shader
2423 buf << versionDecl << "\n"
2425 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2426 << "layout(triangles) in;\n"
2427 << "layout(triangle_strip, max_vertices=4) out;\n"
2428 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
2429 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
2430 << "layout(location = 0) out highp vec4 frag_color;\n"
2431 << "void main (void)\n"
2433 << " highp int quadrant_id;\n"
2434 << " highp vec4 result_color;\n"
2436 << " quadrant_id = geo_quadrant_id[0];\n"
2437 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2438 << " frag_color = result_color;\n"
2439 << " gl_Position = gl_in[0].gl_Position;\n"
2440 << " EmitVertex();\n"
2442 << " quadrant_id = geo_quadrant_id[1];\n"
2443 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2444 << " frag_color = result_color;\n"
2445 << " gl_Position = gl_in[1].gl_Position;\n"
2446 << " EmitVertex();\n"
2448 << " quadrant_id = geo_quadrant_id[2];\n"
2449 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2450 << " frag_color = result_color;\n"
2451 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
2452 << " EmitVertex();\n"
2454 << " quadrant_id = geo_quadrant_id[0];\n"
2455 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2456 << " frag_color = result_color;\n"
2457 << " gl_Position = gl_in[2].gl_Position;\n"
2458 << " EmitVertex();\n"
2463 // passthrough not implemented
2464 DE_FATAL("not implemented");
2470 std::string QuadrantRendederCase::genFragmentSource (void) const
2472 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2473 std::ostringstream buf;
2475 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2477 buf << versionDecl << "\n"
2478 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2479 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
2481 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2483 // there are other stages, this is just a contributor
2484 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
2487 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2488 << "layout(location = 0) out mediump vec4 o_color;\n"
2489 << "void main (void)\n"
2491 << " highp int quadrant_id = frag_quadrant_id;\n"
2492 << " highp vec4 result_color;\n"
2493 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
2495 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2498 buf << " if (frag_quadrant_id < 2)\n"
2499 << " o_color = result_color;\n"
2501 << " o_color = frag_color;\n";
2504 buf << " o_color = result_color;\n";
2508 else if (m_activeStages == 0u)
2510 // special case, no active stages
2511 buf << versionDecl << "\n"
2512 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2513 << "layout(location = 0) out mediump vec4 o_color;\n"
2514 << "void main (void)\n"
2516 << " highp int quadrant_id = frag_quadrant_id;\n"
2517 << " highp vec4 result_color;\n"
2518 << genNoAccessSource()
2519 << " o_color = result_color;\n"
2525 buf << versionDecl << "\n"
2526 << "layout(location = 0) in mediump vec4 frag_color;\n"
2527 "layout(location = 0) out mediump vec4 o_color;\n"
2528 "void main (void)\n"
2530 " o_color = frag_color;\n"
2537 std::string QuadrantRendederCase::genComputeSource (void) const
2539 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2540 std::ostringstream buf;
2542 buf << versionDecl << "\n"
2543 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2544 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2545 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
2546 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
2548 << " highp vec4 read_colors[4];\n"
2550 << "void main(void)\n"
2552 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
2553 << " highp vec4 result_color;\n"
2554 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2555 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
2561 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
2563 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2564 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
2566 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2567 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
2569 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2570 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
2572 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2573 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
2575 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2576 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
2578 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
2579 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
2582 class BufferDescriptorCase : public QuadrantRendederCase
2587 FLAG_VIEW_OFFSET = (1u << 1u),
2588 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
2589 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
2591 // enum continues where resource flags ends
2592 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
2594 BufferDescriptorCase (tcu::TestContext& testCtx,
2596 const char* description,
2597 bool isPrimaryCmdBuf,
2598 vk::VkDescriptorType descriptorType,
2599 vk::VkShaderStageFlags exitingStages,
2600 vk::VkShaderStageFlags activeStages,
2601 ShaderInputInterface shaderInterface,
2605 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
2606 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
2607 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
2608 std::string genNoAccessSource (void) const;
2610 vkt::TestInstance* createInstance (vkt::Context& context) const;
2612 const bool m_viewOffset;
2613 const bool m_dynamicOffsetSet;
2614 const bool m_dynamicOffsetNonZero;
2615 const bool m_isPrimaryCmdBuf;
2616 const vk::VkDescriptorType m_descriptorType;
2617 const ShaderInputInterface m_shaderInterface;
2620 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
2622 const char* description,
2623 bool isPrimaryCmdBuf,
2624 vk::VkDescriptorType descriptorType,
2625 vk::VkShaderStageFlags exitingStages,
2626 vk::VkShaderStageFlags activeStages,
2627 ShaderInputInterface shaderInterface,
2629 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
2630 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
2631 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
2632 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
2633 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
2634 , m_descriptorType (descriptorType)
2635 , m_shaderInterface (shaderInterface)
2639 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
2645 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
2649 const bool isUniform = isUniformDescriptorType(m_descriptorType);
2650 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
2651 std::ostringstream buf;
2653 switch (m_shaderInterface)
2655 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2656 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2658 << " highp vec4 colorA;\n"
2659 << " highp vec4 colorB;\n"
2660 << "} b_instance;\n";
2663 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2664 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
2666 << " highp vec4 colorA;\n"
2667 << " highp vec4 colorB;\n"
2668 << "} b_instanceA;\n"
2669 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
2671 << " highp vec4 colorA;\n"
2672 << " highp vec4 colorB;\n"
2673 << "} b_instanceB;\n";
2676 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2677 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2679 << " highp vec4 colorA;\n"
2680 << " highp vec4 colorB;\n"
2681 << "} b_instances[2];\n";
2685 DE_FATAL("Impossible");
2691 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
2695 std::ostringstream buf;
2697 switch (m_shaderInterface)
2699 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2700 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2701 << " result_color = b_instance.colorA;\n"
2703 << " result_color = b_instance.colorB;\n";
2706 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2707 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2708 << " result_color = b_instanceA.colorA;\n"
2710 << " result_color = b_instanceB.colorB;\n";
2713 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2714 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2715 << " result_color = b_instances[0].colorA;\n"
2717 << " result_color = b_instances[1].colorB;\n";
2721 DE_FATAL("Impossible");
2727 std::string BufferDescriptorCase::genNoAccessSource (void) const
2729 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
2730 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2732 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
2735 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
2737 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
2739 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
2740 return new BufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2743 return new BufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2746 class ImageInstanceImages
2749 ImageInstanceImages (const vk::DeviceInterface& vki,
2750 vk::VkDevice device,
2751 deUint32 queueFamilyIndex,
2753 vk::Allocator& allocator,
2754 vk::VkDescriptorType descriptorType,
2755 vk::VkImageViewType viewType,
2757 deUint32 baseMipLevel,
2758 deUint32 baseArraySlice);
2761 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
2762 vk::VkDevice device,
2763 vk::Allocator& allocator,
2764 vk::VkDescriptorType descriptorType,
2765 vk::VkImageViewType viewType,
2766 const tcu::TextureLevelPyramid& sourceImage,
2767 de::MovePtr<vk::Allocation>* outAllocation);
2769 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
2770 vk::VkDevice device,
2771 vk::VkImageViewType viewType,
2772 const tcu::TextureLevelPyramid& sourceImage,
2774 deUint32 baseMipLevel,
2775 deUint32 baseArraySlice);
2777 void populateSourceImage (tcu::TextureLevelPyramid* dst,
2778 bool isFirst) const;
2780 void uploadImage (const vk::DeviceInterface& vki,
2781 vk::VkDevice device,
2782 deUint32 queueFamilyIndex,
2784 vk::Allocator& allocator,
2786 const tcu::TextureLevelPyramid& data);
2796 const vk::VkImageViewType m_viewType;
2797 const deUint32 m_baseMipLevel;
2798 const deUint32 m_baseArraySlice;
2800 const tcu::TextureFormat m_imageFormat;
2801 tcu::TextureLevelPyramid m_sourceImageA;
2802 tcu::TextureLevelPyramid m_sourceImageB;
2804 de::MovePtr<vk::Allocation> m_imageMemoryA;
2805 de::MovePtr<vk::Allocation> m_imageMemoryB;
2806 vk::Move<vk::VkImage> m_imageA;
2807 vk::Move<vk::VkImage> m_imageB;
2808 vk::Move<vk::VkImageView> m_imageViewA;
2809 vk::Move<vk::VkImageView> m_imageViewB;
2812 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
2813 vk::VkDevice device,
2814 deUint32 queueFamilyIndex,
2816 vk::Allocator& allocator,
2817 vk::VkDescriptorType descriptorType,
2818 vk::VkImageViewType viewType,
2820 deUint32 baseMipLevel,
2821 deUint32 baseArraySlice)
2822 : m_viewType (viewType)
2823 , m_baseMipLevel (baseMipLevel)
2824 , m_baseArraySlice (baseArraySlice)
2825 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
2826 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
2827 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
2828 , m_imageMemoryA (DE_NULL)
2829 , m_imageMemoryB (DE_NULL)
2830 , m_imageA (vk::Move<vk::VkImage>())
2831 , m_imageB (vk::Move<vk::VkImage>())
2832 , m_imageViewA (vk::Move<vk::VkImageView>())
2833 , m_imageViewB (vk::Move<vk::VkImageView>())
2835 DE_ASSERT(numImages == 1 || numImages == 2);
2837 populateSourceImage(&m_sourceImageA, true);
2838 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
2839 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
2840 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, m_sourceImageA);
2844 populateSourceImage(&m_sourceImageB, false);
2845 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
2846 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
2847 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, m_sourceImageB);
2851 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
2852 vk::VkDevice device,
2853 vk::Allocator& allocator,
2854 vk::VkDescriptorType descriptorType,
2855 vk::VkImageViewType viewType,
2856 const tcu::TextureLevelPyramid& sourceImage,
2857 de::MovePtr<vk::Allocation>* outAllocation)
2859 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2860 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
2861 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
2862 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
2863 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
2864 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
2865 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2866 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
2868 const vk::VkExtent3D extent =
2871 (deInt32)baseLevel.getWidth(),
2874 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (deInt32)baseLevel.getHeight(),
2877 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deInt32)baseLevel.getDepth()) : (1),
2879 const vk::VkImageCreateInfo createInfo =
2881 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2883 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
2884 viewTypeToImageType(viewType), // imageType
2885 vk::mapTextureFormat(baseLevel.getFormat()), // format
2887 (deUint32)sourceImage.getNumLevels(), // mipLevels
2888 arraySize, // arraySize
2889 vk::VK_SAMPLE_COUNT_1_BIT, // samples
2890 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
2891 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
2892 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2893 0u, // queueFamilyCount
2894 DE_NULL, // pQueueFamilyIndices
2895 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2897 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
2899 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
2903 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
2904 vk::VkDevice device,
2905 vk::VkImageViewType viewType,
2906 const tcu::TextureLevelPyramid& sourceImage,
2908 deUint32 baseMipLevel,
2909 deUint32 baseArraySlice)
2911 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2912 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
2913 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
2914 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
2915 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
2916 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
2917 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2918 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
2919 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
2922 DE_ASSERT(viewArraySize > 0);
2924 const vk::VkImageSubresourceRange resourceRange =
2926 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
2927 baseMipLevel, // baseMipLevel
2928 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
2929 viewTypeBaseSlice, // baseArraySlice
2930 viewArraySize, // arraySize
2932 const vk::VkImageViewCreateInfo createInfo =
2934 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
2936 (vk::VkImageViewCreateFlags)0,
2938 viewType, // viewType
2939 vk::mapTextureFormat(baseLevel.getFormat()), // format
2941 vk::VK_COMPONENT_SWIZZLE_R,
2942 vk::VK_COMPONENT_SWIZZLE_G,
2943 vk::VK_COMPONENT_SWIZZLE_B,
2944 vk::VK_COMPONENT_SWIZZLE_A
2946 resourceRange, // subresourceRange
2948 return vk::createImageView(vki, device, &createInfo);
2951 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
2953 const int numLevels = dst->getNumLevels();
2955 for (int level = 0; level < numLevels; ++level)
2957 const int width = IMAGE_SIZE >> level;
2958 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
2959 : (IMAGE_SIZE >> level);
2960 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
2961 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
2962 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
2963 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
2966 dst->allocLevel(level, width, height, depth);
2969 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
2971 for (int z = 0; z < depth; ++z)
2972 for (int y = 0; y < height; ++y)
2973 for (int x = 0; x < width; ++x)
2975 const int gradPos = x + y + z;
2976 const int gradMax = width + height + depth - 3;
2978 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
2979 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
2980 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
2982 DE_ASSERT(de::inRange(red, 0, 255));
2983 DE_ASSERT(de::inRange(green, 0, 255));
2984 DE_ASSERT(de::inRange(blue, 0, 255));
2986 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
2992 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
2993 vk::VkDevice device,
2994 deUint32 queueFamilyIndex,
2996 vk::Allocator& allocator,
2998 const tcu::TextureLevelPyramid& data)
3000 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3001 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3002 ((deUint32)ARRAY_SIZE);
3003 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3004 const vk::VkBufferCreateInfo bufferCreateInfo =
3006 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3009 dataBufferSize, // size
3010 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
3011 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3012 0u, // queueFamilyCount
3013 DE_NULL, // pQueueFamilyIndices
3015 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3016 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3017 const vk::VkFenceCreateInfo fenceCreateInfo =
3019 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3023 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3025 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3027 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
3028 vk::VK_ACCESS_TRANSFER_READ_BIT, // inputMask
3029 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3030 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3031 *dataBuffer, // buffer
3033 dataBufferSize, // size
3035 const vk::VkImageSubresourceRange fullSubrange =
3037 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3039 (deUint32)data.getNumLevels(), // mipLevels
3040 0u, // baseArraySlice
3041 arraySize, // arraySize
3043 const vk::VkImageMemoryBarrier preImageBarrier =
3045 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3049 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3050 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout
3051 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3052 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3054 fullSubrange // subresourceRange
3056 const vk::VkImageMemoryBarrier postImageBarrier =
3058 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3060 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask
3061 vk::VK_ACCESS_SHADER_READ_BIT, // inputMask
3062 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout
3063 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
3064 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3065 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3067 fullSubrange // subresourceRange
3069 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
3071 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
3073 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
3074 queueFamilyIndex, // queueFamilyIndex
3076 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3077 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
3079 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
3081 *cmdPool, // cmdPool
3082 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
3085 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
3087 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3089 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
3090 (vk::VkRenderPass)0u, // renderPass
3092 (vk::VkFramebuffer)0u, // framebuffer
3093 vk::VK_FALSE, // occlusionQueryEnable
3094 (vk::VkQueryControlFlags)0,
3095 (vk::VkQueryPipelineStatisticFlags)0,
3098 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(vki, device, &cmdBufCreateInfo));
3099 const void* const preBarriers[2] = { &preMemoryBarrier, &preImageBarrier };
3100 const void* const postBarriers[1] = { &postImageBarrier };
3101 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device, &fenceCreateInfo));
3102 const deUint64 infiniteTimeout = ~(deUint64)0u;
3103 std::vector<vk::VkBufferImageCopy> copySlices;
3105 // copy data to buffer
3106 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3107 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3109 // record command buffer
3110 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3111 vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_FALSE, DE_LENGTH_OF_ARRAY(preBarriers), preBarriers);
3112 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3113 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);
3114 VK_CHECK(vki.endCommandBuffer(*cmd));
3116 // submit and wait for command buffer to complete before killing it
3118 const vk::VkSubmitInfo submitInfo =
3120 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
3123 (const vk::VkSemaphore*)0,
3127 (const vk::VkSemaphore*)0,
3129 VK_CHECK(vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
3131 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3134 class ImageFetchInstanceImages : private ImageInstanceImages
3137 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3138 vk::VkDevice device,
3139 deUint32 queueFamilyIndex,
3141 vk::Allocator& allocator,
3142 vk::VkDescriptorType descriptorType,
3143 ShaderInputInterface shaderInterface,
3144 vk::VkImageViewType viewType,
3145 deUint32 baseMipLevel,
3146 deUint32 baseArraySlice);
3148 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3149 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3151 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3152 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3157 // some arbitrary sample points for all four quadrants
3158 SAMPLE_POINT_0_X = 6,
3159 SAMPLE_POINT_0_Y = 13,
3160 SAMPLE_POINT_0_Z = 49,
3162 SAMPLE_POINT_1_X = 51,
3163 SAMPLE_POINT_1_Y = 40,
3164 SAMPLE_POINT_1_Z = 44,
3166 SAMPLE_POINT_2_X = 42,
3167 SAMPLE_POINT_2_Y = 26,
3168 SAMPLE_POINT_2_Z = 19,
3170 SAMPLE_POINT_3_X = 25,
3171 SAMPLE_POINT_3_Y = 25,
3172 SAMPLE_POINT_3_Z = 18,
3175 const ShaderInputInterface m_shaderInterface;
3178 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3179 vk::VkDevice device,
3180 deUint32 queueFamilyIndex,
3182 vk::Allocator& allocator,
3183 vk::VkDescriptorType descriptorType,
3184 ShaderInputInterface shaderInterface,
3185 vk::VkImageViewType viewType,
3186 deUint32 baseMipLevel,
3187 deUint32 baseArraySlice)
3188 : ImageInstanceImages (vki,
3195 getInterfaceNumResources(shaderInterface), // numImages
3198 , m_shaderInterface (shaderInterface)
3202 bool isImageViewTypeArray (vk::VkImageViewType type)
3204 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;
3207 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3209 const tcu::IVec3 fetchPositions[4] =
3211 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3212 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3213 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3214 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3216 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3217 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3218 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3222 case vk::VK_IMAGE_VIEW_TYPE_1D:
3223 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3224 case vk::VK_IMAGE_VIEW_TYPE_2D:
3225 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3226 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3227 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3228 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3230 DE_FATAL("Impossible");
3231 return tcu::IVec3();
3235 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3237 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3239 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3240 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3241 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3242 tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3244 // add base array layer into the appropriate coordinate, based on the view type
3245 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
3246 fetchPos.z() += 6 * m_baseArraySlice;
3247 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3248 fetchPos.y() += m_baseArraySlice;
3250 fetchPos.z() += m_baseArraySlice;
3252 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3255 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3258 ImageFetchRenderInstance (vkt::Context& context,
3259 bool isPrimaryCmdBuf,
3260 vk::VkDescriptorType descriptorType,
3261 vk::VkShaderStageFlags stageFlags,
3262 ShaderInputInterface shaderInterface,
3263 vk::VkImageViewType viewType,
3264 deUint32 baseMipLevel,
3265 deUint32 baseArraySlice);
3268 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3269 vk::VkDevice device,
3270 vk::VkDescriptorType descriptorType,
3271 ShaderInputInterface shaderInterface,
3272 vk::VkShaderStageFlags stageFlags);
3274 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3275 vk::VkDevice device,
3276 vk::VkDescriptorSetLayout descriptorSetLayout);
3278 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3279 vk::VkDevice device,
3280 vk::VkDescriptorType descriptorType,
3281 ShaderInputInterface shaderInterface);
3283 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3284 vk::VkDevice device,
3285 vk::VkDescriptorType descriptorType,
3286 ShaderInputInterface shaderInterface,
3287 vk::VkDescriptorSetLayout layout,
3288 vk::VkDescriptorPool pool,
3289 vk::VkImageView viewA,
3290 vk::VkImageView viewB);
3292 void logTestPlan (void) const;
3293 vk::VkPipelineLayout getPipelineLayout (void) const;
3294 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
3295 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3302 const vk::VkDescriptorType m_descriptorType;
3303 const vk::VkShaderStageFlags m_stageFlags;
3304 const ShaderInputInterface m_shaderInterface;
3305 const vk::VkImageViewType m_viewType;
3306 const deUint32 m_baseMipLevel;
3307 const deUint32 m_baseArraySlice;
3309 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3310 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3311 const ImageFetchInstanceImages m_images;
3312 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3313 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3316 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3317 bool isPrimaryCmdBuf,
3318 vk::VkDescriptorType descriptorType,
3319 vk::VkShaderStageFlags stageFlags,
3320 ShaderInputInterface shaderInterface,
3321 vk::VkImageViewType viewType,
3322 deUint32 baseMipLevel,
3323 deUint32 baseArraySlice)
3324 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3325 , m_descriptorType (descriptorType)
3326 , m_stageFlags (stageFlags)
3327 , m_shaderInterface (shaderInterface)
3328 , m_viewType (viewType)
3329 , m_baseMipLevel (baseMipLevel)
3330 , m_baseArraySlice (baseArraySlice)
3331 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
3332 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3333 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3334 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3335 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_images.getImageViewA(), m_images.getImageViewB()))
3339 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3340 vk::VkDevice device,
3341 vk::VkDescriptorType descriptorType,
3342 ShaderInputInterface shaderInterface,
3343 vk::VkShaderStageFlags stageFlags)
3345 vk::DescriptorSetLayoutBuilder builder;
3347 switch (shaderInterface)
3349 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3350 builder.addSingleBinding(descriptorType, stageFlags);
3353 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3354 builder.addSingleBinding(descriptorType, stageFlags);
3355 builder.addSingleBinding(descriptorType, stageFlags);
3358 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3359 builder.addArrayBinding(descriptorType, 2u, stageFlags);
3363 DE_FATAL("Impossible");
3366 return builder.build(vki, device);
3369 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
3370 vk::VkDevice device,
3371 vk::VkDescriptorSetLayout descriptorSetLayout)
3373 const vk::VkPipelineLayoutCreateInfo createInfo =
3375 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3377 (vk::VkPipelineLayoutCreateFlags)0,
3378 1, // descriptorSetCount
3379 &descriptorSetLayout, // pSetLayouts
3380 0u, // pushConstantRangeCount
3381 DE_NULL, // pPushConstantRanges
3383 return vk::createPipelineLayout(vki, device, &createInfo);
3386 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
3387 vk::VkDevice device,
3388 vk::VkDescriptorType descriptorType,
3389 ShaderInputInterface shaderInterface)
3391 return vk::DescriptorPoolBuilder()
3392 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
3393 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3396 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
3397 vk::VkDevice device,
3398 vk::VkDescriptorType descriptorType,
3399 ShaderInputInterface shaderInterface,
3400 vk::VkDescriptorSetLayout layout,
3401 vk::VkDescriptorPool pool,
3402 vk::VkImageView viewA,
3403 vk::VkImageView viewB)
3405 const vk::VkDescriptorImageInfo imageInfos[2] =
3407 makeDescriptorImageInfo(viewA, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3408 makeDescriptorImageInfo(viewB, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3410 const vk::VkDescriptorSetAllocateInfo allocInfo =
3412 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3419 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
3420 vk::DescriptorSetUpdateBuilder builder;
3422 switch (shaderInterface)
3424 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3425 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3428 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3429 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3430 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
3433 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3434 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
3438 DE_FATAL("Impossible");
3441 builder.update(vki, device);
3442 return descriptorSet;
3445 void ImageFetchRenderInstance::logTestPlan (void) const
3447 std::ostringstream msg;
3449 msg << "Rendering 2x2 grid.\n"
3450 << "Single descriptor set. Descriptor set contains "
3451 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3452 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3453 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3454 (const char*)DE_NULL)
3455 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3456 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3459 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3460 if (m_baseArraySlice)
3461 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3463 if (m_stageFlags == 0u)
3465 msg << "Descriptors are not accessed in any shader stage.\n";
3469 msg << "Color in each cell is fetched using the descriptor(s):\n";
3471 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3473 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3475 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3477 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3478 msg << " from descriptor " << srcResourceNdx;
3484 msg << "Descriptors are accessed in {"
3485 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
3486 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
3487 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
3488 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
3489 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
3493 m_context.getTestContext().getLog()
3494 << tcu::TestLog::Message
3496 << tcu::TestLog::EndMessage;
3499 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
3501 return *m_pipelineLayout;
3504 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
3506 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
3507 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
3510 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
3512 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3513 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
3514 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
3515 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
3516 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
3517 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
3518 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
3519 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
3521 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
3523 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
3524 return tcu::TestStatus::fail("Image verification failed");
3526 return tcu::TestStatus::pass("Pass");
3529 class ImageFetchComputeInstance : public vkt::TestInstance
3532 ImageFetchComputeInstance (vkt::Context& context,
3533 vk::VkDescriptorType descriptorType,
3534 ShaderInputInterface shaderInterface,
3535 vk::VkImageViewType viewType,
3536 deUint32 baseMipLevel,
3537 deUint32 baseArraySlice);
3540 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
3541 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
3542 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
3544 tcu::TestStatus iterate (void);
3545 void logTestPlan (void) const;
3546 tcu::TestStatus testResourceAccess (void);
3548 const vk::VkDescriptorType m_descriptorType;
3549 const ShaderInputInterface m_shaderInterface;
3550 const vk::VkImageViewType m_viewType;
3551 const deUint32 m_baseMipLevel;
3552 const deUint32 m_baseArraySlice;
3554 const vk::DeviceInterface& m_vki;
3555 const vk::VkDevice m_device;
3556 const vk::VkQueue m_queue;
3557 const deUint32 m_queueFamilyIndex;
3558 vk::Allocator& m_allocator;
3560 const ComputeInstanceResultBuffer m_result;
3561 const ImageFetchInstanceImages m_images;
3564 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
3565 vk::VkDescriptorType descriptorType,
3566 ShaderInputInterface shaderInterface,
3567 vk::VkImageViewType viewType,
3568 deUint32 baseMipLevel,
3569 deUint32 baseArraySlice)
3570 : vkt::TestInstance (context)
3571 , m_descriptorType (descriptorType)
3572 , m_shaderInterface (shaderInterface)
3573 , m_viewType (viewType)
3574 , m_baseMipLevel (baseMipLevel)
3575 , m_baseArraySlice (baseArraySlice)
3576 , m_vki (context.getDeviceInterface())
3577 , m_device (context.getDevice())
3578 , m_queue (context.getUniversalQueue())
3579 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
3580 , m_allocator (context.getDefaultAllocator())
3581 , m_result (m_vki, m_device, m_allocator)
3582 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3586 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
3588 vk::DescriptorSetLayoutBuilder builder;
3590 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3592 switch (m_shaderInterface)
3594 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3595 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3598 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3599 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3600 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3603 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3604 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3608 DE_FATAL("Impossible");
3611 return builder.build(m_vki, m_device);
3614 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
3616 return vk::DescriptorPoolBuilder()
3617 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3618 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
3619 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3622 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
3624 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
3625 const vk::VkDescriptorImageInfo imageInfos[2] =
3627 makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3628 makeDescriptorImageInfo(m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3630 const vk::VkDescriptorSetAllocateInfo allocInfo =
3632 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3639 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
3640 vk::DescriptorSetUpdateBuilder builder;
3643 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
3646 switch (m_shaderInterface)
3648 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3649 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3652 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3653 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3654 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
3657 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3658 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
3662 DE_FATAL("Impossible");
3665 builder.update(m_vki, m_device);
3666 return descriptorSet;
3669 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
3672 return testResourceAccess();
3675 void ImageFetchComputeInstance::logTestPlan (void) const
3677 std::ostringstream msg;
3679 msg << "Fetching 4 values from image in compute shader.\n"
3680 << "Single descriptor set. Descriptor set contains "
3681 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3682 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3683 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3684 (const char*)DE_NULL)
3685 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3686 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3689 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3690 if (m_baseArraySlice)
3691 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3693 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3695 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3697 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3699 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3700 msg << " from descriptor " << srcResourceNdx;
3706 m_context.getTestContext().getLog()
3707 << tcu::TestLog::Message
3709 << tcu::TestLog::EndMessage;
3712 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
3714 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
3715 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
3716 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
3717 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
3719 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
3720 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
3721 const deUint32* const dynamicOffsets = DE_NULL;
3722 const int numDynamicOffsets = 0;
3723 const void* const* preBarriers = DE_NULL;
3724 const int numPreBarriers = 0;
3725 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
3726 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
3728 const ComputeCommand compute (m_vki,
3730 pipeline.getPipeline(),
3731 pipeline.getPipelineLayout(),
3732 tcu::UVec3(4, 1, 1),
3733 numDescriptorSets, descriptorSets,
3734 numDynamicOffsets, dynamicOffsets,
3735 numPreBarriers, preBarriers,
3736 numPostBarriers, postBarriers);
3738 tcu::Vec4 results[4];
3739 bool anyResultSet = false;
3740 bool allResultsOk = true;
3742 compute.submitAndWait(m_queueFamilyIndex, m_queue);
3743 m_result.readResultContentsTo(&results);
3746 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3748 const tcu::Vec4 result = results[resultNdx];
3749 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
3750 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
3752 if (result != tcu::Vec4(-1.0f))
3753 anyResultSet = true;
3755 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
3757 allResultsOk = false;
3759 m_context.getTestContext().getLog()
3760 << tcu::TestLog::Message
3761 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
3762 << tcu::TestLog::EndMessage;
3766 // read back and verify
3768 return tcu::TestStatus::pass("Pass");
3769 else if (anyResultSet)
3770 return tcu::TestStatus::fail("Invalid result values");
3773 m_context.getTestContext().getLog()
3774 << tcu::TestLog::Message
3775 << "Result buffer was not written to."
3776 << tcu::TestLog::EndMessage;
3777 return tcu::TestStatus::fail("Result buffer was not written to");
3781 class ImageSampleInstanceImages : private ImageInstanceImages
3784 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3785 vk::VkDevice device,
3786 deUint32 queueFamilyIndex,
3788 vk::Allocator& allocator,
3789 vk::VkDescriptorType descriptorType,
3790 ShaderInputInterface shaderInterface,
3791 vk::VkImageViewType viewType,
3792 deUint32 baseMipLevel,
3793 deUint32 baseArraySlice,
3796 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
3797 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
3799 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3800 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3801 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
3802 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
3803 inline bool isImmutable (void) const { return m_isImmutable; }
3806 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
3807 static tcu::Sampler createRefSampler (bool isFirst);
3808 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
3810 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3811 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3812 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3813 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3815 const vk::VkDescriptorType m_descriptorType;
3816 const ShaderInputInterface m_shaderInterface;
3817 const bool m_isImmutable;
3819 const tcu::Sampler m_refSamplerA;
3820 const tcu::Sampler m_refSamplerB;
3821 const vk::Unique<vk::VkSampler> m_samplerA;
3822 const vk::Unique<vk::VkSampler> m_samplerB;
3825 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3826 vk::VkDevice device,
3827 deUint32 queueFamilyIndex,
3829 vk::Allocator& allocator,
3830 vk::VkDescriptorType descriptorType,
3831 ShaderInputInterface shaderInterface,
3832 vk::VkImageViewType viewType,
3833 deUint32 baseMipLevel,
3834 deUint32 baseArraySlice,
3836 : ImageInstanceImages (vki,
3843 getNumImages(descriptorType, shaderInterface),
3846 , m_descriptorType (descriptorType)
3847 , m_shaderInterface (shaderInterface)
3848 , m_isImmutable (immutable)
3849 , m_refSamplerA (createRefSampler(true))
3850 , m_refSamplerB (createRefSampler(false))
3851 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
3852 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
3853 ? vk::Move<vk::VkSampler>()
3854 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
3858 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
3860 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3862 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3863 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3865 // choose arbitrary values that are not ambiguous with NEAREST filtering
3869 case vk::VK_IMAGE_VIEW_TYPE_1D:
3870 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
3871 case vk::VK_IMAGE_VIEW_TYPE_2D:
3872 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
3873 case vk::VK_IMAGE_VIEW_TYPE_3D:
3875 const tcu::Vec3 coords[4] =
3879 (float)(12u % imageSize) + 0.25f),
3881 tcu::Vec3((float)(23u % imageSize) + 0.25f,
3882 (float)(73u % imageSize) + 0.5f,
3883 (float)(16u % imageSize) + 0.5f + (float)imageSize),
3885 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
3886 (float)(84u % imageSize) + 0.5f + (float)imageSize,
3887 (float)(117u % imageSize) + 0.75f),
3889 tcu::Vec3((float)imageSize + 0.5f,
3890 (float)(75u % imageSize) + 0.25f,
3891 (float)(83u % imageSize) + 0.25f + (float)imageSize),
3893 const deUint32 slices[4] =
3901 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3902 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3903 (float)slices[samplePosNdx],
3906 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
3907 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3908 coords[samplePosNdx].y() / (float)imageSize,
3909 (float)slices[samplePosNdx],
3911 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
3912 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3913 coords[samplePosNdx].y() / (float)imageSize,
3914 coords[samplePosNdx].z() / (float)imageSize,
3918 DE_FATAL("Impossible");
3923 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3924 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
3926 // \note these values are in [0, texSize]*3 space for convenience
3927 const tcu::Vec3 coords[4] =
3933 tcu::Vec3((float)(13u % imageSize) + 0.25f,
3935 (float)(16u % imageSize) + 0.5f),
3938 (float)(84u % imageSize) + 0.5f,
3939 (float)(10u % imageSize) + 0.75f),
3941 tcu::Vec3((float)imageSize,
3942 (float)(75u % imageSize) + 0.25f,
3943 (float)(83u % imageSize) + 0.75f),
3945 const deUint32 slices[4] =
3953 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
3954 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
3955 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
3957 // map to [-1, 1]*3 space
3958 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
3959 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
3960 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
3961 (float)slices[samplePosNdx]);
3965 DE_FATAL("Impossible");
3970 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
3972 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3974 // texture order is ABAB
3975 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
3976 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
3977 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3978 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
3980 // sampler order is ABAB
3981 const tcu::Sampler& samplerA = m_refSamplerA;
3982 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
3983 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
3985 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
3986 const float lod = 0.0f;
3987 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
3991 case vk::VK_IMAGE_VIEW_TYPE_1D:
3992 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
3993 case vk::VK_IMAGE_VIEW_TYPE_2D:
3994 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);
3995 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
3996 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3997 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);
4001 DE_FATAL("Impossible");
4007 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
4009 // If we are testing separate samplers, just one image is enough
4010 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4012 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4014 // combined: numImages == numSamplers
4015 return getInterfaceNumResources(shaderInterface);
4019 DE_FATAL("Impossible");
4024 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4029 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4033 // nearest, clamping
4034 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4038 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4040 const bool compareEnabled = (sampler.compare != tcu::Sampler::COMPAREMODE_NONE);
4041 const vk::VkCompareOp compareOp = (compareEnabled) ? (vk::mapCompareMode(sampler.compare)) : (vk::VK_COMPARE_OP_ALWAYS);
4042 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4043 const bool isIntTexture = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4044 const vk::VkBorderColor borderColor = (isIntTexture) ? (vk::VK_BORDER_COLOR_INT_OPAQUE_WHITE) : (vk::VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE);
4045 const vk::VkSamplerCreateInfo createInfo =
4047 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
4049 (vk::VkSamplerCreateFlags)0,
4050 vk::mapFilterMode(sampler.magFilter), // magFilter
4051 vk::mapFilterMode(sampler.minFilter), // minFilter
4052 vk::mapMipmapMode(sampler.minFilter), // mipMode
4053 vk::mapWrapMode(sampler.wrapS), // addressU
4054 vk::mapWrapMode(sampler.wrapT), // addressV
4055 vk::mapWrapMode(sampler.wrapR), // addressW
4058 (vk::VkBool32)(compareEnabled ? vk::VK_TRUE : vk::VK_FALSE), // compareEnable
4059 compareOp, // compareOp
4062 borderColor, // borderColor
4063 vk::VK_FALSE, // unnormalizedCoords
4065 return vk::createSampler(vki, device, &createInfo);
4068 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4070 DE_ASSERT(levelStorage->empty());
4072 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4073 const deUint32 numLevels = (deUint32)source.getNumLevels();
4075 // cut pyramid from baseMipLevel
4076 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4078 // cut levels from baseArraySlice
4079 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4080 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4081 levelStorage->push_back(cutLevel);
4084 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4087 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4089 DE_ASSERT(levelStorage->empty());
4091 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4092 const deUint32 numLevels = (deUint32)source.getNumLevels();
4094 // cut pyramid from baseMipLevel
4095 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4097 // cut levels from baseArraySlice
4098 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4099 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4100 levelStorage->push_back(cutLevel);
4103 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4106 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4108 DE_ASSERT(levelStorage->empty());
4109 DE_ASSERT(baseArraySlice == 0);
4110 DE_UNREF(baseArraySlice);
4112 const deUint32 numLevels = (deUint32)source.getNumLevels();
4114 // cut pyramid from baseMipLevel
4115 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4116 levelStorage->push_back(source.getLevel(level));
4118 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
4121 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4123 DE_ASSERT(levelStorage->empty());
4125 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
4126 const deUint32 numLevels = (deUint32)source.getNumLevels();
4128 // cut pyramid from baseMipLevel
4129 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4131 // cut levels from baseArraySlice
4132 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4133 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
4134 levelStorage->push_back(cutLevel);
4137 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
4140 class ImageSampleRenderInstance : public SingleCmdRenderInstance
4143 ImageSampleRenderInstance (vkt::Context& context,
4144 bool isPrimaryCmdBuf,
4145 vk::VkDescriptorType descriptorType,
4146 vk::VkShaderStageFlags stageFlags,
4147 ShaderInputInterface shaderInterface,
4148 vk::VkImageViewType viewType,
4149 deUint32 baseMipLevel,
4150 deUint32 baseArraySlice,
4154 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
4155 vk::VkDevice device,
4156 vk::VkDescriptorType descriptorType,
4157 ShaderInputInterface shaderInterface,
4158 vk::VkShaderStageFlags stageFlags,
4159 const ImageSampleInstanceImages& images);
4161 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4162 vk::VkDevice device,
4163 vk::VkDescriptorSetLayout descriptorSetLayout);
4165 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4166 vk::VkDevice device,
4167 vk::VkDescriptorType descriptorType,
4168 ShaderInputInterface shaderInterface,
4171 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
4172 vk::VkDevice device,
4173 vk::VkDescriptorType descriptorType,
4174 ShaderInputInterface shaderInterface,
4175 vk::VkDescriptorSetLayout layout,
4176 vk::VkDescriptorPool pool,
4178 const ImageSampleInstanceImages& images);
4180 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4181 vk::VkDevice device,
4182 ShaderInputInterface shaderInterface,
4184 const ImageSampleInstanceImages& images,
4185 vk::VkDescriptorSet descriptorSet);
4187 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4188 vk::VkDevice device,
4189 ShaderInputInterface shaderInterface,
4191 const ImageSampleInstanceImages& images,
4192 vk::VkDescriptorSet descriptorSet);
4194 void logTestPlan (void) const;
4195 vk::VkPipelineLayout getPipelineLayout (void) const;
4196 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
4197 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4204 const vk::VkDescriptorType m_descriptorType;
4205 const vk::VkShaderStageFlags m_stageFlags;
4206 const ShaderInputInterface m_shaderInterface;
4207 const vk::VkImageViewType m_viewType;
4208 const deUint32 m_baseMipLevel;
4209 const deUint32 m_baseArraySlice;
4211 const ImageSampleInstanceImages m_images;
4212 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
4213 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4214 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4215 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
4218 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
4219 bool isPrimaryCmdBuf,
4220 vk::VkDescriptorType descriptorType,
4221 vk::VkShaderStageFlags stageFlags,
4222 ShaderInputInterface shaderInterface,
4223 vk::VkImageViewType viewType,
4224 deUint32 baseMipLevel,
4225 deUint32 baseArraySlice,
4227 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4228 , m_descriptorType (descriptorType)
4229 , m_stageFlags (stageFlags)
4230 , m_shaderInterface (shaderInterface)
4231 , m_viewType (viewType)
4232 , m_baseMipLevel (baseMipLevel)
4233 , m_baseArraySlice (baseArraySlice)
4234 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
4235 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images))
4236 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
4237 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface, isImmutable))
4238 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, isImmutable, m_images))
4242 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
4243 vk::VkDevice device,
4244 vk::VkDescriptorType descriptorType,
4245 ShaderInputInterface shaderInterface,
4246 vk::VkShaderStageFlags stageFlags,
4247 const ImageSampleInstanceImages& images)
4249 const vk::VkSampler samplers[2] =
4251 images.getSamplerA(),
4252 images.getSamplerB(),
4255 vk::DescriptorSetLayoutBuilder builder;
4257 // with samplers, separate texture at binding 0
4258 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4259 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4261 // (combined)samplers follow
4262 switch (shaderInterface)
4264 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4265 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4268 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4269 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4270 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4273 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4274 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
4278 DE_FATAL("Impossible");
4281 return builder.build(vki, device);
4284 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4285 vk::VkDevice device,
4286 vk::VkDescriptorSetLayout descriptorSetLayout)
4288 const vk::VkPipelineLayoutCreateInfo createInfo =
4290 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4292 (vk::VkPipelineLayoutCreateFlags)0,
4293 1, // descriptorSetCount
4294 &descriptorSetLayout, // pSetLayouts
4295 0u, // pushConstantRangeCount
4296 DE_NULL, // pPushConstantRanges
4298 return vk::createPipelineLayout(vki, device, &createInfo);
4301 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4302 vk::VkDevice device,
4303 vk::VkDescriptorType descriptorType,
4304 ShaderInputInterface shaderInterface,
4307 vk::DescriptorPoolBuilder builder;
4309 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4311 // separate samplers need image to sample
4312 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4314 // samplers needed only if they are specified in the descriptor set
4316 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
4318 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4320 // combined image samplers
4321 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
4324 DE_FATAL("Impossible");
4326 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4329 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
4330 vk::VkDevice device,
4331 vk::VkDescriptorType descriptorType,
4332 ShaderInputInterface shaderInterface,
4333 vk::VkDescriptorSetLayout layout,
4334 vk::VkDescriptorPool pool,
4336 const ImageSampleInstanceImages& images)
4338 const vk::VkDescriptorSetAllocateInfo allocInfo =
4340 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4347 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4349 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4350 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4351 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4352 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4354 DE_FATAL("Impossible");
4356 return descriptorSet;
4359 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4360 vk::VkDevice device,
4361 ShaderInputInterface shaderInterface,
4363 const ImageSampleInstanceImages& images,
4364 vk::VkDescriptorSet descriptorSet)
4366 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4367 const vk::VkDescriptorImageInfo samplersInfos[2] =
4369 makeDescriptorImageInfo(images.getSamplerA()),
4370 makeDescriptorImageInfo(images.getSamplerB()),
4373 vk::DescriptorSetUpdateBuilder builder;
4375 // stand alone texture
4376 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4381 switch (shaderInterface)
4383 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4384 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4387 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4388 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4389 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4392 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4393 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4397 DE_FATAL("Impossible");
4401 builder.update(vki, device);
4404 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4405 vk::VkDevice device,
4406 ShaderInputInterface shaderInterface,
4408 const ImageSampleInstanceImages& images,
4409 vk::VkDescriptorSet descriptorSet)
4411 const vk::VkSampler samplers[2] =
4413 (isImmutable) ? (0) : (images.getSamplerA()),
4414 (isImmutable) ? (0) : (images.getSamplerB()),
4416 const vk::VkDescriptorImageInfo imageSamplers[2] =
4418 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4419 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4422 vk::DescriptorSetUpdateBuilder builder;
4424 // combined image samplers
4425 switch (shaderInterface)
4427 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4428 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4431 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4432 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4433 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4436 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4437 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4441 DE_FATAL("Impossible");
4444 builder.update(vki, device);
4447 void ImageSampleRenderInstance::logTestPlan (void) const
4449 std::ostringstream msg;
4451 msg << "Rendering 2x2 grid.\n";
4453 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4455 msg << "Single descriptor set. Descriptor set contains "
4456 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4457 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4458 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4459 (const char*)DE_NULL)
4460 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4462 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4464 msg << "Single descriptor set. Descriptor set contains "
4465 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4466 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4467 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4468 (const char*)DE_NULL)
4469 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4472 DE_FATAL("Impossible");
4474 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4477 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4478 if (m_baseArraySlice)
4479 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4481 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4482 msg << "Sampler mode is LINEAR, with WRAP\n";
4484 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4486 if (m_stageFlags == 0u)
4488 msg << "Descriptors are not accessed in any shader stage.\n";
4492 msg << "Color in each cell is fetched using the descriptor(s):\n";
4494 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4496 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4498 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4500 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4502 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4503 msg << " using sampler " << srcResourceNdx;
4504 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4505 msg << " from combined image sampler " << srcResourceNdx;
4507 DE_FATAL("Impossible");
4512 msg << "Descriptors are accessed in {"
4513 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4514 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4515 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4516 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4517 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4521 m_context.getTestContext().getLog()
4522 << tcu::TestLog::Message
4524 << tcu::TestLog::EndMessage;
4527 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
4529 return *m_pipelineLayout;
4532 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4534 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4535 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
4538 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4540 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4541 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4542 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4543 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
4544 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
4545 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
4546 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
4547 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
4548 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4550 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4552 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
4553 return tcu::TestStatus::fail("Image verification failed");
4555 return tcu::TestStatus::pass("Pass");
4558 class ImageSampleComputeInstance : public vkt::TestInstance
4561 ImageSampleComputeInstance (vkt::Context& context,
4562 vk::VkDescriptorType descriptorType,
4563 ShaderInputInterface shaderInterface,
4564 vk::VkImageViewType viewType,
4565 deUint32 baseMipLevel,
4566 deUint32 baseArraySlice,
4567 bool isImmutableSampler);
4570 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4571 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4572 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
4573 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4574 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4576 tcu::TestStatus iterate (void);
4577 void logTestPlan (void) const;
4578 tcu::TestStatus testResourceAccess (void);
4580 const vk::VkDescriptorType m_descriptorType;
4581 const ShaderInputInterface m_shaderInterface;
4582 const vk::VkImageViewType m_viewType;
4583 const deUint32 m_baseMipLevel;
4584 const deUint32 m_baseArraySlice;
4585 const bool m_isImmutableSampler;
4587 const vk::DeviceInterface& m_vki;
4588 const vk::VkDevice m_device;
4589 const vk::VkQueue m_queue;
4590 const deUint32 m_queueFamilyIndex;
4591 vk::Allocator& m_allocator;
4593 const ComputeInstanceResultBuffer m_result;
4594 const ImageSampleInstanceImages m_images;
4597 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
4598 vk::VkDescriptorType descriptorType,
4599 ShaderInputInterface shaderInterface,
4600 vk::VkImageViewType viewType,
4601 deUint32 baseMipLevel,
4602 deUint32 baseArraySlice,
4603 bool isImmutableSampler)
4604 : vkt::TestInstance (context)
4605 , m_descriptorType (descriptorType)
4606 , m_shaderInterface (shaderInterface)
4607 , m_viewType (viewType)
4608 , m_baseMipLevel (baseMipLevel)
4609 , m_baseArraySlice (baseArraySlice)
4610 , m_isImmutableSampler (isImmutableSampler)
4611 , m_vki (context.getDeviceInterface())
4612 , m_device (context.getDevice())
4613 , m_queue (context.getUniversalQueue())
4614 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4615 , m_allocator (context.getDefaultAllocator())
4616 , m_result (m_vki, m_device, m_allocator)
4617 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
4621 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
4623 const vk::VkSampler samplers[2] =
4625 m_images.getSamplerA(),
4626 m_images.getSamplerB(),
4629 vk::DescriptorSetLayoutBuilder builder;
4632 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4634 // with samplers, separate texture at binding 0
4635 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4636 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4638 // (combined)samplers follow
4639 switch (m_shaderInterface)
4641 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4642 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4645 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4646 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4647 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4650 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4651 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
4655 DE_FATAL("Impossible");
4658 return builder.build(m_vki, m_device);
4661 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
4663 vk::DescriptorPoolBuilder builder;
4665 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
4666 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
4668 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4669 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4671 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4674 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
4676 const vk::VkDescriptorSetAllocateInfo allocInfo =
4678 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4685 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4687 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4688 writeSamplerDescriptorSet(*descriptorSet);
4689 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4690 writeImageSamplerDescriptorSet(*descriptorSet);
4692 DE_FATAL("Impossible");
4694 return descriptorSet;
4697 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4699 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4700 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4701 const vk::VkDescriptorImageInfo samplersInfos[2] =
4703 makeDescriptorImageInfo(m_images.getSamplerA()),
4704 makeDescriptorImageInfo(m_images.getSamplerB()),
4707 vk::DescriptorSetUpdateBuilder builder;
4710 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4712 // stand alone texture
4713 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4716 if (!m_isImmutableSampler)
4718 switch (m_shaderInterface)
4720 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4721 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4724 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4725 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4726 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4729 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4730 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4734 DE_FATAL("Impossible");
4738 builder.update(m_vki, m_device);
4741 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4743 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4744 const vk::VkSampler samplers[2] =
4746 (m_isImmutableSampler) ? (0) : (m_images.getSamplerA()),
4747 (m_isImmutableSampler) ? (0) : (m_images.getSamplerB()),
4749 const vk::VkDescriptorImageInfo imageSamplers[2] =
4751 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4752 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4755 vk::DescriptorSetUpdateBuilder builder;
4758 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4760 // combined image samplers
4761 switch (m_shaderInterface)
4763 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4764 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4767 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4768 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4769 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4772 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4773 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4777 DE_FATAL("Impossible");
4780 builder.update(m_vki, m_device);
4783 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
4786 return testResourceAccess();
4789 void ImageSampleComputeInstance::logTestPlan (void) const
4791 std::ostringstream msg;
4793 msg << "Accessing resource in a compute program.\n";
4795 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4797 msg << "Single descriptor set. Descriptor set contains "
4798 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4799 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4800 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4801 (const char*)DE_NULL)
4802 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4804 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4806 msg << "Single descriptor set. Descriptor set contains "
4807 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4808 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4809 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4810 (const char*)DE_NULL)
4811 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4814 DE_FATAL("Impossible");
4816 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4819 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4820 if (m_baseArraySlice)
4821 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4823 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4824 msg << "Sampler mode is LINEAR, with WRAP\n";
4826 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4828 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4830 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4832 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4834 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4836 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4837 msg << " using sampler " << srcResourceNdx;
4838 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4839 msg << " from combined image sampler " << srcResourceNdx;
4841 DE_FATAL("Impossible");
4846 m_context.getTestContext().getLog()
4847 << tcu::TestLog::Message
4849 << tcu::TestLog::EndMessage;
4852 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
4854 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4855 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4856 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4857 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4859 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4860 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
4861 const deUint32* const dynamicOffsets = DE_NULL;
4862 const int numDynamicOffsets = 0;
4863 const void* const* preBarriers = DE_NULL;
4864 const int numPreBarriers = 0;
4865 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
4866 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
4868 const ComputeCommand compute (m_vki,
4870 pipeline.getPipeline(),
4871 pipeline.getPipelineLayout(),
4872 tcu::UVec3(4, 1, 1),
4873 numDescriptorSets, descriptorSets,
4874 numDynamicOffsets, dynamicOffsets,
4875 numPreBarriers, preBarriers,
4876 numPostBarriers, postBarriers);
4878 tcu::Vec4 results[4];
4879 bool anyResultSet = false;
4880 bool allResultsOk = true;
4882 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4883 m_result.readResultContentsTo(&results);
4886 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4888 const tcu::Vec4 result = results[resultNdx];
4889 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
4891 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
4892 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
4894 if (result != tcu::Vec4(-1.0f))
4895 anyResultSet = true;
4897 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
4899 allResultsOk = false;
4901 m_context.getTestContext().getLog()
4902 << tcu::TestLog::Message
4903 << "Test sample " << resultNdx << ":\n"
4904 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
4905 << "\tError expected " << reference << ", got " << result
4906 << tcu::TestLog::EndMessage;
4910 // read back and verify
4912 return tcu::TestStatus::pass("Pass");
4913 else if (anyResultSet)
4914 return tcu::TestStatus::fail("Invalid result values");
4917 m_context.getTestContext().getLog()
4918 << tcu::TestLog::Message
4919 << "Result buffer was not written to."
4920 << tcu::TestLog::EndMessage;
4921 return tcu::TestStatus::fail("Result buffer was not written to");
4925 class ImageDescriptorCase : public QuadrantRendederCase
4930 FLAG_BASE_MIP = (1u << 1u),
4931 FLAG_BASE_SLICE = (1u << 2u),
4933 // enum continues where resource flags ends
4934 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
4936 ImageDescriptorCase (tcu::TestContext& testCtx,
4938 const char* description,
4939 bool isPrimaryCmdBuf,
4940 vk::VkDescriptorType descriptorType,
4941 vk::VkShaderStageFlags exitingStages,
4942 vk::VkShaderStageFlags activeStages,
4943 ShaderInputInterface shaderInterface,
4944 vk::VkImageViewType viewType,
4948 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
4949 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
4950 std::string genFetchCoordStr (int fetchPosNdx) const;
4951 std::string genSampleCoordStr (int samplePosNdx) const;
4952 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
4953 std::string genNoAccessSource (void) const;
4955 vkt::TestInstance* createInstance (vkt::Context& context) const;
4958 const bool m_isPrimaryCmdBuf;
4959 const vk::VkDescriptorType m_descriptorType;
4960 const ShaderInputInterface m_shaderInterface;
4961 const vk::VkImageViewType m_viewType;
4962 const deUint32 m_baseMipLevel;
4963 const deUint32 m_baseArraySlice;
4964 const bool m_isImmutableSampler;
4967 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
4969 const char* description,
4970 bool isPrimaryCmdBuf,
4971 vk::VkDescriptorType descriptorType,
4972 vk::VkShaderStageFlags exitingStages,
4973 vk::VkShaderStageFlags activeStages,
4974 ShaderInputInterface shaderInterface,
4975 vk::VkImageViewType viewType,
4977 : QuadrantRendederCase (testCtx, name, description,
4978 // \note 1D textures are not supported in ES
4979 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
4980 exitingStages, activeStages)
4981 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
4982 , m_descriptorType (descriptorType)
4983 , m_shaderInterface (shaderInterface)
4984 , m_viewType (viewType)
4985 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
4986 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
4987 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
4991 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
4995 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
4996 return "#extension GL_OES_texture_cube_map_array : require\n";
5001 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
5005 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
5006 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
5007 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
5008 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5009 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
5011 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5012 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5013 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5014 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5016 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
5018 switch (m_shaderInterface)
5020 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5022 switch (m_descriptorType)
5024 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5025 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5026 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
5027 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5028 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
5029 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5030 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
5031 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5032 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
5034 DE_FATAL("invalid descriptor");
5039 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5040 switch (m_descriptorType)
5042 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5043 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5044 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
5045 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5046 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5047 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
5048 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
5049 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5050 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
5051 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
5052 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5053 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
5054 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
5056 DE_FATAL("invalid descriptor");
5060 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5061 switch (m_descriptorType)
5063 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5064 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5065 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler[2];\n";
5066 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5067 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
5068 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5069 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
5070 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5071 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
5073 DE_FATAL("invalid descriptor");
5078 DE_FATAL("Impossible");
5083 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
5085 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
5086 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
5088 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5090 return de::toString(fetchPos.x());
5092 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5094 std::ostringstream buf;
5095 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
5100 std::ostringstream buf;
5101 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
5106 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
5108 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
5109 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5111 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5113 std::ostringstream buf;
5114 buf << "float(" << fetchPos.x() << ")";
5117 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5119 std::ostringstream buf;
5120 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
5123 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5125 std::ostringstream buf;
5126 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
5131 std::ostringstream buf;
5132 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
5137 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
5141 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
5142 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5143 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
5144 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5145 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5146 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
5147 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5149 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5150 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
5151 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
5153 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5154 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
5155 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
5158 switch (m_descriptorType)
5160 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5161 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5163 const std::string coodStr[4] =
5165 genSampleCoordStr(0),
5166 genSampleCoordStr(1),
5167 genSampleCoordStr(2),
5168 genSampleCoordStr(3),
5170 std::ostringstream buf;
5172 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5174 buf << " if (quadrant_id == 0)\n"
5175 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
5176 << " else if (quadrant_id == 1)\n"
5177 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
5178 << " else if (quadrant_id == 2)\n"
5179 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
5181 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
5185 buf << " if (quadrant_id == 0)\n"
5186 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
5187 << " else if (quadrant_id == 1)\n"
5188 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
5189 << " else if (quadrant_id == 2)\n"
5190 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
5192 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
5198 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5200 const std::string coodStr[4] =
5202 genFetchCoordStr(0),
5203 genFetchCoordStr(1),
5204 genFetchCoordStr(2),
5205 genFetchCoordStr(3),
5207 std::ostringstream buf;
5209 buf << " if (quadrant_id == 0)\n"
5210 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
5211 << " else if (quadrant_id == 1)\n"
5212 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
5213 << " else if (quadrant_id == 2)\n"
5214 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
5216 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
5222 DE_FATAL("invalid descriptor");
5227 std::string ImageDescriptorCase::genNoAccessSource (void) const
5229 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
5230 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5232 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
5235 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
5237 switch (m_descriptorType)
5239 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5240 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5241 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5243 DE_ASSERT(m_isPrimaryCmdBuf);
5244 return new ImageSampleComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5247 return new ImageSampleRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5249 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5250 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5251 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5253 DE_ASSERT(m_isPrimaryCmdBuf);
5254 return new ImageFetchComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5257 return new ImageFetchRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5260 DE_FATAL("Impossible");
5265 class TexelBufferInstanceBuffers
5268 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5269 vk::VkDevice device,
5270 vk::Allocator& allocator,
5271 vk::VkDescriptorType descriptorType,
5272 int numTexelBuffers,
5273 bool hasViewOffset);
5276 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
5277 vk::VkDevice device,
5278 vk::Allocator& allocator,
5279 vk::VkDescriptorType descriptorType,
5280 de::MovePtr<vk::Allocation> *outAllocation);
5282 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
5283 vk::VkDevice device,
5284 const tcu::TextureFormat& textureFormat,
5286 vk::VkBuffer buffer);
5288 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
5290 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
5291 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
5294 static int getFetchPos (int fetchPosNdx);
5295 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
5297 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
5298 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
5299 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
5300 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
5301 inline const void* getBufferInitBarrierA (void) const { return &m_bufferBarrierA; }
5302 inline const void* getBufferInitBarrierB (void) const { return &m_bufferBarrierB; }
5308 VIEW_OFFSET_VALUE = 256,
5309 VIEW_DATA_SIZE = 256, //!< size in bytes
5310 VIEW_WIDTH = 64, //!< size in pixels
5314 // some arbitrary points
5316 SAMPLE_POINT_1 = 51,
5317 SAMPLE_POINT_2 = 42,
5318 SAMPLE_POINT_3 = 25,
5321 const deUint32 m_numTexelBuffers;
5322 const tcu::TextureFormat m_imageFormat;
5323 const deUint32 m_viewOffset;
5325 de::ArrayBuffer<deUint8> m_sourceBufferA;
5326 de::ArrayBuffer<deUint8> m_sourceBufferB;
5327 const tcu::ConstPixelBufferAccess m_sourceViewA;
5328 const tcu::ConstPixelBufferAccess m_sourceViewB;
5330 de::MovePtr<vk::Allocation> m_bufferMemoryA;
5331 de::MovePtr<vk::Allocation> m_bufferMemoryB;
5332 const vk::Unique<vk::VkBuffer> m_bufferA;
5333 const vk::Unique<vk::VkBuffer> m_bufferB;
5334 const vk::Unique<vk::VkBufferView> m_bufferViewA;
5335 const vk::Unique<vk::VkBufferView> m_bufferViewB;
5336 const vk::VkBufferMemoryBarrier m_bufferBarrierA;
5337 const vk::VkBufferMemoryBarrier m_bufferBarrierB;
5340 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5341 vk::VkDevice device,
5342 vk::Allocator& allocator,
5343 vk::VkDescriptorType descriptorType,
5344 int numTexelBuffers,
5346 : m_numTexelBuffers (numTexelBuffers)
5347 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
5348 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
5349 , m_sourceBufferA (BUFFER_SIZE)
5350 , m_sourceBufferB ((numTexelBuffers == 1)
5352 : ((size_t)BUFFER_SIZE))
5353 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
5354 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
5355 , m_bufferMemoryA (DE_NULL)
5356 , m_bufferMemoryB (DE_NULL)
5357 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
5358 , m_bufferB ((numTexelBuffers == 1)
5359 ? vk::Move<vk::VkBuffer>()
5360 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
5361 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
5362 , m_bufferViewB ((numTexelBuffers == 1)
5363 ? vk::Move<vk::VkBufferView>()
5364 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
5365 , m_bufferBarrierA (createBarrier(descriptorType, *m_bufferA))
5366 , m_bufferBarrierB (createBarrier(descriptorType, *m_bufferB))
5368 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
5369 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
5370 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
5372 // specify and upload
5374 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
5375 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
5377 if (numTexelBuffers == 2)
5379 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
5380 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
5384 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
5385 vk::VkDevice device,
5386 vk::Allocator& allocator,
5387 vk::VkDescriptorType descriptorType,
5388 de::MovePtr<vk::Allocation> *outAllocation)
5390 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
5391 const vk::VkBufferCreateInfo createInfo =
5393 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
5396 (vk::VkDeviceSize)BUFFER_SIZE, // size
5398 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
5399 0u, // queueFamilyCount
5400 DE_NULL, // pQueueFamilyIndices
5402 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
5403 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
5405 *outAllocation = allocation;
5409 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
5410 vk::VkDevice device,
5411 const tcu::TextureFormat& textureFormat,
5413 vk::VkBuffer buffer)
5415 const vk::VkBufferViewCreateInfo createInfo =
5417 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
5419 (vk::VkBufferViewCreateFlags)0,
5421 vk::mapTextureFormat(textureFormat), // format
5422 (vk::VkDeviceSize)offset, // offset
5423 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
5425 return vk::createBufferView(vki, device, &createInfo);
5428 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
5430 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
5431 const vk::VkBufferMemoryBarrier barrier =
5433 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
5435 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
5436 inputBit, // inputMask
5437 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
5438 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
5441 (vk::VkDeviceSize)BUFFER_SIZE // size
5446 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
5448 DE_ASSERT(access.getHeight() == 1);
5449 DE_ASSERT(access.getDepth() == 1);
5451 const deInt32 width = access.getWidth();
5453 for (int x = 0; x < width; ++x)
5455 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
5456 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
5457 const int blue = 16 * (x % 16); //!< 16-long triangle wave
5459 DE_ASSERT(de::inRange(red, 0, 255));
5460 DE_ASSERT(de::inRange(green, 0, 255));
5461 DE_ASSERT(de::inRange(blue, 0, 255));
5463 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
5467 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
5469 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
5470 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
5473 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
5475 static const int fetchPositions[4] =
5482 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
5485 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
5487 // source order is ABAB
5488 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
5489 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
5490 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
5492 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
5495 class TexelBufferRenderInstance : public SingleCmdRenderInstance
5498 TexelBufferRenderInstance (vkt::Context& context,
5499 bool isPrimaryCmdBuf,
5500 vk::VkDescriptorType descriptorType,
5501 vk::VkShaderStageFlags stageFlags,
5502 ShaderInputInterface shaderInterface,
5503 bool nonzeroViewOffset);
5506 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
5507 vk::VkDevice device,
5508 vk::VkDescriptorType descriptorType,
5509 ShaderInputInterface shaderInterface,
5510 vk::VkShaderStageFlags stageFlags);
5512 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5513 vk::VkDevice device,
5514 vk::VkDescriptorSetLayout descriptorSetLayout);
5516 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5517 vk::VkDevice device,
5518 vk::VkDescriptorType descriptorType,
5519 ShaderInputInterface shaderInterface);
5521 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
5522 vk::VkDevice device,
5523 vk::VkDescriptorType descriptorType,
5524 ShaderInputInterface shaderInterface,
5525 vk::VkDescriptorSetLayout layout,
5526 vk::VkDescriptorPool pool,
5527 vk::VkBufferView viewA,
5528 vk::VkBufferView viewB);
5530 void logTestPlan (void) const;
5531 vk::VkPipelineLayout getPipelineLayout (void) const;
5532 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5533 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5540 const vk::VkDescriptorType m_descriptorType;
5541 const vk::VkShaderStageFlags m_stageFlags;
5542 const ShaderInputInterface m_shaderInterface;
5543 const bool m_nonzeroViewOffset;
5545 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5546 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5547 const TexelBufferInstanceBuffers m_texelBuffers;
5548 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5549 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5552 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
5553 bool isPrimaryCmdBuf,
5554 vk::VkDescriptorType descriptorType,
5555 vk::VkShaderStageFlags stageFlags,
5556 ShaderInputInterface shaderInterface,
5557 bool nonzeroViewOffset)
5558 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5559 , m_descriptorType (descriptorType)
5560 , m_stageFlags (stageFlags)
5561 , m_shaderInterface (shaderInterface)
5562 , m_nonzeroViewOffset (nonzeroViewOffset)
5563 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
5564 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5565 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5566 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5567 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_texelBuffers.getBufferViewA(), m_texelBuffers.getBufferViewB()))
5571 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5572 vk::VkDevice device,
5573 vk::VkDescriptorType descriptorType,
5574 ShaderInputInterface shaderInterface,
5575 vk::VkShaderStageFlags stageFlags)
5577 vk::DescriptorSetLayoutBuilder builder;
5579 switch (shaderInterface)
5581 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5582 builder.addSingleBinding(descriptorType, stageFlags);
5585 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5586 builder.addSingleBinding(descriptorType, stageFlags);
5587 builder.addSingleBinding(descriptorType, stageFlags);
5590 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5591 builder.addArrayBinding(descriptorType, 2u, stageFlags);
5595 DE_FATAL("Impossible");
5598 return builder.build(vki, device);
5601 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5602 vk::VkDevice device,
5603 vk::VkDescriptorSetLayout descriptorSetLayout)
5605 const vk::VkPipelineLayoutCreateInfo createInfo =
5607 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5609 (vk::VkPipelineLayoutCreateFlags)0,
5610 1, // descriptorSetCount
5611 &descriptorSetLayout, // pSetLayouts
5612 0u, // pushConstantRangeCount
5613 DE_NULL, // pPushConstantRanges
5615 return vk::createPipelineLayout(vki, device, &createInfo);
5618 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5619 vk::VkDevice device,
5620 vk::VkDescriptorType descriptorType,
5621 ShaderInputInterface shaderInterface)
5623 return vk::DescriptorPoolBuilder()
5624 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
5625 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5628 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5629 vk::VkDevice device,
5630 vk::VkDescriptorType descriptorType,
5631 ShaderInputInterface shaderInterface,
5632 vk::VkDescriptorSetLayout layout,
5633 vk::VkDescriptorPool pool,
5634 vk::VkBufferView viewA,
5635 vk::VkBufferView viewB)
5637 const vk::VkBufferView texelBufferInfos[2] =
5642 const vk::VkDescriptorSetAllocateInfo allocInfo =
5644 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5651 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5652 vk::DescriptorSetUpdateBuilder builder;
5654 switch (shaderInterface)
5656 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5657 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5660 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5661 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5662 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
5665 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5666 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
5670 DE_FATAL("Impossible");
5673 builder.update(vki, device);
5674 return descriptorSet;
5677 void TexelBufferRenderInstance::logTestPlan (void) const
5679 std::ostringstream msg;
5681 msg << "Rendering 2x2 grid.\n"
5682 << "Single descriptor set. Descriptor set contains "
5683 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5684 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5685 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5686 (const char*)DE_NULL)
5687 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5688 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5689 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5691 if (m_stageFlags == 0u)
5693 msg << "Descriptors are not accessed in any shader stage.\n";
5697 msg << "Color in each cell is fetched using the descriptor(s):\n";
5699 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5701 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5703 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5705 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5706 msg << " from texelBuffer " << srcResourceNdx;
5712 msg << "Descriptors are accessed in {"
5713 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5714 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5715 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5716 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5717 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5721 m_context.getTestContext().getLog()
5722 << tcu::TestLog::Message
5724 << tcu::TestLog::EndMessage;
5727 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
5729 return *m_pipelineLayout;
5732 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
5734 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
5735 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
5738 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5740 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5741 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5742 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5743 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
5744 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
5745 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
5746 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
5747 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5749 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5751 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
5752 return tcu::TestStatus::fail("Image verification failed");
5754 return tcu::TestStatus::pass("Pass");
5757 class TexelBufferComputeInstance : public vkt::TestInstance
5760 TexelBufferComputeInstance (vkt::Context& context,
5761 vk::VkDescriptorType descriptorType,
5762 ShaderInputInterface shaderInterface,
5763 bool nonzeroViewOffset);
5766 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5767 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5768 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
5770 tcu::TestStatus iterate (void);
5771 void logTestPlan (void) const;
5772 tcu::TestStatus testResourceAccess (void);
5774 const vk::VkDescriptorType m_descriptorType;
5775 const ShaderInputInterface m_shaderInterface;
5776 const bool m_nonzeroViewOffset;
5778 const vk::DeviceInterface& m_vki;
5779 const vk::VkDevice m_device;
5780 const vk::VkQueue m_queue;
5781 const deUint32 m_queueFamilyIndex;
5782 vk::Allocator& m_allocator;
5784 const ComputeInstanceResultBuffer m_result;
5785 const TexelBufferInstanceBuffers m_texelBuffers;
5788 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
5789 vk::VkDescriptorType descriptorType,
5790 ShaderInputInterface shaderInterface,
5791 bool nonzeroViewOffset)
5792 : vkt::TestInstance (context)
5793 , m_descriptorType (descriptorType)
5794 , m_shaderInterface (shaderInterface)
5795 , m_nonzeroViewOffset (nonzeroViewOffset)
5796 , m_vki (context.getDeviceInterface())
5797 , m_device (context.getDevice())
5798 , m_queue (context.getUniversalQueue())
5799 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5800 , m_allocator (context.getDefaultAllocator())
5801 , m_result (m_vki, m_device, m_allocator)
5802 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5806 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
5808 vk::DescriptorSetLayoutBuilder builder;
5810 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5812 switch (m_shaderInterface)
5814 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5815 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5818 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5819 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5820 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5823 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5824 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5828 DE_FATAL("Impossible");
5831 return builder.build(m_vki, m_device);
5834 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
5836 return vk::DescriptorPoolBuilder()
5837 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
5838 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
5839 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5842 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
5844 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5845 const vk::VkBufferView texelBufferInfos[2] =
5847 m_texelBuffers.getBufferViewA(),
5848 m_texelBuffers.getBufferViewB(),
5850 const vk::VkDescriptorSetAllocateInfo allocInfo =
5852 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5859 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
5860 vk::DescriptorSetUpdateBuilder builder;
5863 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5866 switch (m_shaderInterface)
5868 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5869 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5872 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5873 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5874 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
5877 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5878 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
5882 DE_FATAL("Impossible");
5885 builder.update(m_vki, m_device);
5886 return descriptorSet;
5889 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
5892 return testResourceAccess();
5895 void TexelBufferComputeInstance::logTestPlan (void) const
5897 std::ostringstream msg;
5899 msg << "Fetching 4 values from image in compute shader.\n"
5900 << "Single descriptor set. Descriptor set contains "
5901 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5902 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5903 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5904 (const char*)DE_NULL)
5905 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5906 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5907 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5909 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5911 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5913 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5915 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5916 msg << " from texelBuffer " << srcResourceNdx;
5922 m_context.getTestContext().getLog()
5923 << tcu::TestLog::Message
5925 << tcu::TestLog::EndMessage;
5928 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
5930 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
5931 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5932 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
5933 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
5935 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
5936 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
5937 const deUint32* const dynamicOffsets = DE_NULL;
5938 const int numDynamicOffsets = 0;
5939 const void* const preBarriers[] = { m_texelBuffers.getBufferInitBarrierA(), m_texelBuffers.getBufferInitBarrierB() };
5940 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
5941 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
5942 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
5944 const ComputeCommand compute (m_vki,
5946 pipeline.getPipeline(),
5947 pipeline.getPipelineLayout(),
5948 tcu::UVec3(4, 1, 1),
5949 numDescriptorSets, descriptorSets,
5950 numDynamicOffsets, dynamicOffsets,
5951 numPreBarriers, preBarriers,
5952 numPostBarriers, postBarriers);
5954 tcu::Vec4 results[4];
5955 bool anyResultSet = false;
5956 bool allResultsOk = true;
5958 compute.submitAndWait(m_queueFamilyIndex, m_queue);
5959 m_result.readResultContentsTo(&results);
5962 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5964 const tcu::Vec4 result = results[resultNdx];
5965 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
5966 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
5968 if (result != tcu::Vec4(-1.0f))
5969 anyResultSet = true;
5971 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
5973 allResultsOk = false;
5975 m_context.getTestContext().getLog()
5976 << tcu::TestLog::Message
5977 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
5978 << tcu::TestLog::EndMessage;
5982 // read back and verify
5984 return tcu::TestStatus::pass("Pass");
5985 else if (anyResultSet)
5986 return tcu::TestStatus::fail("Invalid result values");
5989 m_context.getTestContext().getLog()
5990 << tcu::TestLog::Message
5991 << "Result buffer was not written to."
5992 << tcu::TestLog::EndMessage;
5993 return tcu::TestStatus::fail("Result buffer was not written to");
5997 class TexelBufferDescriptorCase : public QuadrantRendederCase
6002 FLAG_VIEW_OFFSET = (1u << 1u),
6004 // enum continues where resource flags ends
6005 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
6007 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6009 const char* description,
6010 bool isPrimaryCmdBuf,
6011 vk::VkDescriptorType descriptorType,
6012 vk::VkShaderStageFlags exitingStages,
6013 vk::VkShaderStageFlags activeStages,
6014 ShaderInputInterface shaderInterface,
6018 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
6019 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
6020 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
6021 std::string genNoAccessSource (void) const;
6023 vkt::TestInstance* createInstance (vkt::Context& context) const;
6025 const bool m_isPrimaryCmdBuf;
6026 const vk::VkDescriptorType m_descriptorType;
6027 const ShaderInputInterface m_shaderInterface;
6028 const bool m_nonzeroViewOffset;
6031 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6033 const char* description,
6034 bool isPrimaryCmdBuf,
6035 vk::VkDescriptorType descriptorType,
6036 vk::VkShaderStageFlags exitingStages,
6037 vk::VkShaderStageFlags activeStages,
6038 ShaderInputInterface shaderInterface,
6040 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
6041 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6042 , m_descriptorType (descriptorType)
6043 , m_shaderInterface (shaderInterface)
6044 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
6048 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
6051 return "#extension GL_EXT_texture_buffer : require\n";
6054 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
6058 const bool isUniform = isUniformDescriptorType(m_descriptorType);
6059 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
6060 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
6062 switch (m_shaderInterface)
6064 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6065 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
6067 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
6068 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
6069 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
6071 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6072 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
6075 DE_FATAL("Impossible");
6080 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
6084 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6085 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
6086 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6088 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6089 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
6090 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6092 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
6093 std::ostringstream buf;
6095 buf << " if (quadrant_id == 0)\n"
6096 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
6097 << " else if (quadrant_id == 1)\n"
6098 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
6099 << " else if (quadrant_id == 2)\n"
6100 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
6102 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
6107 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
6109 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6110 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6112 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6115 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
6117 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6119 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
6120 return new TexelBufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
6123 return new TexelBufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
6126 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
6127 bool isPrimaryCmdBuf,
6128 vk::VkDescriptorType descriptorType,
6129 vk::VkShaderStageFlags exitingStages,
6130 vk::VkShaderStageFlags activeStages,
6131 ShaderInputInterface dimension,
6132 deUint32 resourceFlags)
6136 vk::VkImageViewType viewType;
6138 const char* description;
6142 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
6143 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6144 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6146 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
6147 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6148 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6150 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
6151 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6152 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6154 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
6155 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6156 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6158 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
6159 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6160 // no 3d array textures
6162 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
6163 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6164 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6166 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
6167 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6168 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6171 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
6174 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
6176 group->addChild(new ImageDescriptorCase(group->getTestContext(),
6177 s_imageTypes[ndx].name,
6178 s_imageTypes[ndx].description,
6184 s_imageTypes[ndx].viewType,
6185 s_imageTypes[ndx].flags | resourceFlags));
6189 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
6190 bool isPrimaryCmdBuf,
6191 vk::VkDescriptorType descriptorType,
6192 vk::VkShaderStageFlags exitingStages,
6193 vk::VkShaderStageFlags activeStages,
6194 ShaderInputInterface dimension,
6195 deUint32 resourceFlags)
6197 DE_ASSERT(resourceFlags == 0);
6198 DE_UNREF(resourceFlags);
6203 const char* description;
6205 } s_texelBufferTypes[] =
6207 { "offset_zero", "View offset is zero", 0u },
6208 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
6211 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
6213 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
6214 s_texelBufferTypes[ndx].name,
6215 s_texelBufferTypes[ndx].description,
6221 s_texelBufferTypes[ndx].flags));
6225 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
6226 bool isPrimaryCmdBuf,
6227 vk::VkDescriptorType descriptorType,
6228 vk::VkShaderStageFlags exitingStages,
6229 vk::VkShaderStageFlags activeStages,
6230 ShaderInputInterface dimension,
6231 deUint32 resourceFlags)
6233 DE_ASSERT(resourceFlags == 0u);
6234 DE_UNREF(resourceFlags);
6239 const char* description;
6240 bool isForDynamicCases;
6244 { "offset_view_zero", "View offset is zero", false, 0u },
6245 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6247 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6248 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
6249 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6250 { "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 },
6253 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
6255 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
6257 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
6258 group->addChild(new BufferDescriptorCase(group->getTestContext(),
6259 s_bufferTypes[ndx].name,
6260 s_bufferTypes[ndx].description,
6266 s_bufferTypes[ndx].flags));
6272 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
6276 const bool isPrimary;
6278 const char* description;
6281 { true, "primary_cmd_buf", "Bind in primary command buffer" },
6282 { false, "secondary_cmd_buf", "Bind in secondary command buffer" },
6286 const vk::VkDescriptorType descriptorType;
6288 const char* description;
6290 } s_descriptorTypes[] =
6292 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
6293 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6294 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
6295 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6296 // \note No way to access SAMPLED_IMAGE without a sampler
6297 // { vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
6298 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
6299 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
6300 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
6301 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
6302 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
6303 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
6304 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
6309 const char* description;
6310 vk::VkShaderStageFlags existingStages; //!< stages that exists
6311 vk::VkShaderStageFlags activeStages; //!< stages that access resource
6312 bool supportsSecondaryCmdBufs;
6313 } s_shaderStages[] =
6317 "No accessing stages",
6318 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6325 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6326 vk::VK_SHADER_STAGE_VERTEX_BIT,
6331 "Tessellation control stage",
6332 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,
6333 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
6338 "Tessellation evaluation stage",
6339 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,
6340 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
6346 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6347 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
6353 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6354 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6360 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6361 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6366 "Vertex and fragment stages",
6367 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6368 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6374 ShaderInputInterface dimension;
6376 const char* description;
6377 } s_variableDimensions[] =
6379 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
6380 { SHADER_INPUT_MULTIPLE_DESCRIPTORS, "multiple_descriptors", "Multiple descriptors" },
6381 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
6384 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
6386 // .primary_cmd_buf...
6387 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
6389 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
6391 // .sampler, .combined_image_sampler, other resource types ...
6392 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
6394 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
6396 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
6398 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
6400 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
6402 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
6404 de::MovePtr<tcu::TestCaseGroup> dimensionGroup(new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
6405 void (*createTestsFunc)(tcu::TestCaseGroup* group,
6406 bool isPrimaryCmdBuf,
6407 vk::VkDescriptorType descriptorType,
6408 vk::VkShaderStageFlags existingStages,
6409 vk::VkShaderStageFlags activeStages,
6410 ShaderInputInterface dimension,
6411 deUint32 resourceFlags);
6413 switch (s_descriptorTypes[descriptorNdx].descriptorType)
6415 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6416 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6417 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6418 createTestsFunc = createShaderAccessImageTests;
6421 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
6422 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
6423 createTestsFunc = createShaderAccessTexelBufferTests;
6426 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
6427 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
6428 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
6429 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
6430 createTestsFunc = createShaderAccessBufferTests;
6434 createTestsFunc = DE_NULL;
6435 DE_FATAL("Impossible");
6438 if (createTestsFunc)
6440 createTestsFunc(dimensionGroup.get(),
6441 s_bindTypes[bindTypeNdx].isPrimary,
6442 s_descriptorTypes[descriptorNdx].descriptorType,
6443 s_shaderStages[stageNdx].existingStages,
6444 s_shaderStages[stageNdx].activeStages,
6445 s_variableDimensions[dimensionNdx].dimension,
6446 s_descriptorTypes[descriptorNdx].flags);
6449 DE_FATAL("Impossible");
6451 stageGroup->addChild(dimensionGroup.release());
6454 typeGroup->addChild(stageGroup.release());
6458 bindGroup->addChild(typeGroup.release());
6461 group->addChild(bindGroup.release());
6464 return group.release();