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"
48 #include "tcuVector.hpp"
49 #include "tcuVectorUtil.hpp"
50 #include "tcuTexture.hpp"
51 #include "tcuTextureUtil.hpp"
52 #include "tcuResultCollector.hpp"
53 #include "tcuTestLog.hpp"
54 #include "tcuRGBA.hpp"
55 #include "tcuSurface.hpp"
56 #include "tcuImageCompare.hpp"
58 #include "deUniquePtr.hpp"
59 #include "deSharedPtr.hpp"
60 #include "deStringUtil.hpp"
61 #include "deArrayUtil.hpp"
67 namespace BindingModel
74 RESOURCE_FLAG_IMMUTABLE_SAMPLER = (1u << 0u),
76 RESOURCE_FLAG_LAST = (1u << 1u)
79 static const char* const s_quadrantGenVertexPosSource = " highp int quadPhase = gl_VertexID % 6;\n"
80 " highp int quadXcoord = int(quadPhase == 1 || quadPhase == 4 || quadPhase == 5);\n"
81 " highp int quadYcoord = int(quadPhase == 2 || quadPhase == 3 || quadPhase == 5);\n"
82 " highp int quadOriginX = (gl_VertexID / 6) % 2;\n"
83 " highp int quadOriginY = (gl_VertexID / 6) / 2;\n"
84 " quadrant_id = gl_VertexID / 6;\n"
85 " result_position = vec4(float(quadOriginX + quadXcoord - 1), float(quadOriginY + quadYcoord - 1), 0.0, 1.0);\n";
87 bool isUniformDescriptorType (vk::VkDescriptorType type)
89 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
90 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
91 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
94 bool isDynamicDescriptorType (vk::VkDescriptorType type)
96 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || type == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
99 vk::VkFormat mapToVkTextureFormat (const tcu::TextureFormat& format)
101 if (format == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
102 return vk::VK_FORMAT_R8G8B8A8_UNORM;
104 DE_FATAL("Not implemented");
105 return vk::VK_FORMAT_UNDEFINED;
108 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type)
112 case vk::VK_IMAGE_VIEW_TYPE_1D:
113 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return vk::VK_IMAGE_TYPE_1D;
114 case vk::VK_IMAGE_VIEW_TYPE_2D:
115 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return vk::VK_IMAGE_TYPE_2D;
116 case vk::VK_IMAGE_VIEW_TYPE_3D: return vk::VK_IMAGE_TYPE_3D;
117 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
118 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return vk::VK_IMAGE_TYPE_2D;
121 DE_FATAL("Impossible");
122 return (vk::VkImageType)0;
126 vk::VkTexFilter mapMagFilterToVkTexFilter (tcu::Sampler::FilterMode mode)
130 case tcu::Sampler::NEAREST: return vk::VK_TEX_FILTER_NEAREST;
131 case tcu::Sampler::LINEAR: return vk::VK_TEX_FILTER_LINEAR;
134 DE_FATAL("Illegal filter mode");
135 return (vk::VkTexFilter)0;
139 vk::VkTexFilter mapMinFilterToVkTexFilter (tcu::Sampler::FilterMode mode)
143 case tcu::Sampler::NEAREST: return vk::VK_TEX_FILTER_NEAREST;
144 case tcu::Sampler::LINEAR: return vk::VK_TEX_FILTER_LINEAR;
145 case tcu::Sampler::NEAREST_MIPMAP_NEAREST: return vk::VK_TEX_FILTER_NEAREST;
146 case tcu::Sampler::LINEAR_MIPMAP_NEAREST: return vk::VK_TEX_FILTER_LINEAR;
147 case tcu::Sampler::NEAREST_MIPMAP_LINEAR: return vk::VK_TEX_FILTER_NEAREST;
148 case tcu::Sampler::LINEAR_MIPMAP_LINEAR: return vk::VK_TEX_FILTER_LINEAR;
151 DE_FATAL("Illegal filter mode");
152 return (vk::VkTexFilter)0;
156 vk::VkTexMipmapMode mapMinFilterToVkTexMipmapMode (tcu::Sampler::FilterMode mode)
160 case tcu::Sampler::NEAREST: return vk::VK_TEX_MIPMAP_MODE_BASE;
161 case tcu::Sampler::LINEAR: return vk::VK_TEX_MIPMAP_MODE_BASE;
162 case tcu::Sampler::NEAREST_MIPMAP_NEAREST: return vk::VK_TEX_MIPMAP_MODE_NEAREST;
163 case tcu::Sampler::LINEAR_MIPMAP_NEAREST: return vk::VK_TEX_MIPMAP_MODE_NEAREST;
164 case tcu::Sampler::NEAREST_MIPMAP_LINEAR: return vk::VK_TEX_MIPMAP_MODE_LINEAR;
165 case tcu::Sampler::LINEAR_MIPMAP_LINEAR: return vk::VK_TEX_MIPMAP_MODE_LINEAR;
168 DE_FATAL("Illegal filter mode");
169 return (vk::VkTexMipmapMode)0;
173 vk::VkTexAddressMode mapToVkTexAddressMode (tcu::Sampler::WrapMode mode)
177 case tcu::Sampler::CLAMP_TO_EDGE: return vk::VK_TEX_ADDRESS_MODE_CLAMP;
178 case tcu::Sampler::CLAMP_TO_BORDER: return vk::VK_TEX_ADDRESS_MODE_CLAMP_BORDER;
179 case tcu::Sampler::REPEAT_GL: return vk::VK_TEX_ADDRESS_MODE_WRAP;
180 case tcu::Sampler::MIRRORED_REPEAT_GL: return vk::VK_TEX_ADDRESS_MODE_MIRROR;
183 DE_FATAL("Illegal wrap mode");
184 return (vk::VkTexAddressMode)0;
188 vk::VkCompareOp mapToVkCompareOp (tcu::Sampler::CompareMode mode)
192 case tcu::Sampler::COMPAREMODE_LESS: return vk::VK_COMPARE_OP_LESS;
193 case tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL: return vk::VK_COMPARE_OP_LESS_EQUAL;
194 case tcu::Sampler::COMPAREMODE_GREATER: return vk::VK_COMPARE_OP_GREATER;
195 case tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL: return vk::VK_COMPARE_OP_GREATER_EQUAL;
196 case tcu::Sampler::COMPAREMODE_EQUAL: return vk::VK_COMPARE_OP_EQUAL;
197 case tcu::Sampler::COMPAREMODE_NOT_EQUAL: return vk::VK_COMPARE_OP_NOT_EQUAL;
198 case tcu::Sampler::COMPAREMODE_ALWAYS: return vk::VK_COMPARE_OP_ALWAYS;
199 case tcu::Sampler::COMPAREMODE_NEVER: return vk::VK_COMPARE_OP_NEVER;
202 DE_FATAL("Illegal compare mode");
203 return (vk::VkCompareOp)0;
207 deUint32 getTextureLevelPyramidDataSize (const tcu::TextureLevelPyramid& srcImage)
209 deUint32 dataSize = 0;
210 for (int level = 0; level < srcImage.getNumLevels(); ++level)
212 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
215 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
217 dataSize += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
222 void writeTextureLevelPyramidData (void* dst, deUint32 dstLen, const tcu::TextureLevelPyramid& srcImage, vk::VkImageViewType viewType, std::vector<vk::VkBufferImageCopy>* copySlices)
224 // \note cube is copied face-by-face
225 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (srcImage.getLevel(0).getHeight()) :
226 (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
227 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
228 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
230 deUint32 levelOffset = 0;
232 DE_ASSERT(arraySize != 0);
234 for (int level = 0; level < srcImage.getNumLevels(); ++level)
236 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
237 const tcu::PixelBufferAccess dstAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), (deUint8*)dst + levelOffset);
238 const deUint32 dataSize = srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
239 const deUint32 sliceDataSize = dataSize / arraySize;
240 const deInt32 sliceHeight = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (srcAccess.getHeight());
241 const deInt32 sliceDepth = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (srcAccess.getDepth()) : (1);
242 const tcu::IVec3 sliceSize (srcAccess.getWidth(), sliceHeight, sliceDepth);
245 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
247 for (int sliceNdx = 0; sliceNdx < (int)arraySize; ++sliceNdx)
249 const vk::VkBufferImageCopy copySlice =
251 (vk::VkDeviceSize)levelOffset + sliceNdx * sliceDataSize, // bufferOffset
252 (deUint32)sliceSize.x(), // bufferRowLength
253 (deUint32)sliceSize.y(), // bufferImageHeight
255 vk::VK_IMAGE_ASPECT_COLOR, // aspect
256 (deUint32)level, // mipLevel
257 (deUint32)sliceNdx, // arrayLayer
259 }, // imageSubresource
271 copySlices->push_back(copySlice);
274 DE_ASSERT(arraySize * sliceDataSize == dataSize);
276 tcu::copy(dstAccess, srcAccess);
277 levelOffset += dataSize;
280 DE_ASSERT(dstLen == levelOffset);
284 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement)
286 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer);
287 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
289 VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
293 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkImage image, vk::MemoryRequirement requirement)
295 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vki, device, image);
296 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
298 VK_CHECK(vki.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
302 vk::VkDescriptorInfo createDescriptorInfo (vk::VkBuffer buffer, vk::VkDeviceSize offset, vk::VkDeviceSize range)
304 const vk::VkDescriptorInfo resultInfo =
309 (vk::VkImageLayout)0, // imageLayout
310 { buffer, offset, range } // bufferInfo
315 vk::VkDescriptorInfo createDescriptorInfo (vk::VkBufferView bufferView)
317 const vk::VkDescriptorInfo resultInfo =
319 bufferView, // bufferView
322 (vk::VkImageLayout)0, // imageLayout
323 { (vk::VkBuffer)0, 0, 0 } // bufferInfo
328 vk::VkDescriptorInfo createDescriptorInfo (vk::VkSampler sampler)
330 const vk::VkDescriptorInfo resultInfo =
335 (vk::VkImageLayout)0, // imageLayout
336 { (vk::VkBuffer)0, 0, 0 } // bufferInfo
341 vk::VkDescriptorInfo createDescriptorInfo (vk::VkImageView imageView, vk::VkImageLayout layout)
343 const vk::VkDescriptorInfo resultInfo =
347 imageView, // imageView
348 layout, // imageLayout
349 { (vk::VkBuffer)0, 0, 0 } // bufferInfo
354 vk::VkDescriptorInfo createDescriptorInfo (vk::VkSampler sampler, vk::VkImageView imageView, vk::VkImageLayout layout)
356 const vk::VkDescriptorInfo resultInfo =
360 imageView, // imageView
361 layout, // imageLayout
362 { (vk::VkBuffer)0, 0, 0 } // bufferInfo
367 vk::VkClearValue createClearValueColor (const tcu::Vec4& color)
369 vk::VkClearValue retVal;
371 retVal.color.float32[0] = color.x();
372 retVal.color.float32[1] = color.y();
373 retVal.color.float32[2] = color.z();
374 retVal.color.float32[3] = color.w();
379 void drawQuadrantReferenceResult (const tcu::PixelBufferAccess& dst, const tcu::Vec4& c1, const tcu::Vec4& c2, const tcu::Vec4& c3, const tcu::Vec4& c4)
381 tcu::clear(tcu::getSubregion(dst, 0, 0, dst.getWidth() / 2, dst.getHeight() / 2), c1);
382 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, 0, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() / 2), c2);
383 tcu::clear(tcu::getSubregion(dst, 0, dst.getHeight() / 2, dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c3);
384 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, dst.getHeight() / 2, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c4);
387 class SingleTargetRenderInstance : public vkt::TestInstance
390 SingleTargetRenderInstance (Context& context,
391 const tcu::UVec2& size);
394 static vk::Move<vk::VkImage> createColorAttachment (const vk::DeviceInterface& vki,
396 vk::Allocator& allocator,
397 const tcu::TextureFormat& format,
398 const tcu::UVec2& size,
399 de::MovePtr<vk::Allocation>* outAllocation);
401 static vk::Move<vk::VkImageView> createColorAttachmentView (const vk::DeviceInterface& vki,
403 const tcu::TextureFormat& format,
406 static vk::Move<vk::VkRenderPass> createRenderPass (const vk::DeviceInterface& vki,
408 const tcu::TextureFormat& format);
410 static vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vki,
412 vk::VkRenderPass renderpass,
413 vk::VkImageView colorAttachmentView,
414 const tcu::UVec2& size);
416 static vk::Move<vk::VkCmdPool> createCommandPool (const vk::DeviceInterface& vki,
418 deUint32 queueFamilyIndex);
420 virtual void logTestPlan (void) const = 0;
421 virtual void renderToTarget (void) = 0;
422 virtual tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const = 0;
424 void readRenderTarget (tcu::TextureLevel& dst);
425 tcu::TestStatus iterate (void);
428 const tcu::TextureFormat m_targetFormat;
429 const tcu::UVec2 m_targetSize;
431 const vk::DeviceInterface& m_vki;
432 const vk::VkDevice m_device;
433 const vk::VkQueue m_queue;
434 const deUint32 m_queueFamilyIndex;
435 vk::Allocator& m_allocator;
436 de::MovePtr<vk::Allocation> m_colorAttachmentMemory;
437 const vk::Unique<vk::VkImage> m_colorAttachmentImage;
438 const vk::Unique<vk::VkImageView> m_colorAttachmentView;
439 const vk::Unique<vk::VkRenderPass> m_renderPass;
440 const vk::Unique<vk::VkFramebuffer> m_framebuffer;
441 const vk::Unique<vk::VkCmdPool> m_cmdPool;
443 bool m_firstIteration;
446 SingleTargetRenderInstance::SingleTargetRenderInstance (Context& context,
447 const tcu::UVec2& size)
448 : vkt::TestInstance (context)
449 , m_targetFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
450 , m_targetSize (size)
451 , m_vki (context.getDeviceInterface())
452 , m_device (context.getDevice())
453 , m_queue (context.getUniversalQueue())
454 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
455 , m_allocator (context.getDefaultAllocator())
456 , m_colorAttachmentMemory (DE_NULL)
457 , m_colorAttachmentImage (createColorAttachment(m_vki, m_device, m_allocator, m_targetFormat, m_targetSize, &m_colorAttachmentMemory))
458 , m_colorAttachmentView (createColorAttachmentView(m_vki, m_device, m_targetFormat, *m_colorAttachmentImage))
459 , m_renderPass (createRenderPass(m_vki, m_device, m_targetFormat))
460 , m_framebuffer (createFramebuffer(m_vki, m_device, *m_renderPass, *m_colorAttachmentView, m_targetSize))
461 , m_cmdPool (createCommandPool(m_vki, m_device, context.getUniversalQueueFamilyIndex()))
462 , m_firstIteration (true)
466 vk::Move<vk::VkImage> SingleTargetRenderInstance::createColorAttachment (const vk::DeviceInterface& vki,
468 vk::Allocator& allocator,
469 const tcu::TextureFormat& format,
470 const tcu::UVec2& size,
471 de::MovePtr<vk::Allocation>* outAllocation)
473 const vk::VkImageCreateInfo imageInfo =
475 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
477 vk::VK_IMAGE_TYPE_2D, // imageType
478 mapToVkTextureFormat(format), // format
479 { (deInt32)size.x(), (deInt32)size.y(), 1 }, // extent
483 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
484 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, // usage
486 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
487 0u, // queueFamilyCount
488 DE_NULL, // pQueueFamilyIndices
489 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
492 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &imageInfo));
493 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any));
495 *outAllocation = allocation;
499 vk::Move<vk::VkImageView> SingleTargetRenderInstance::createColorAttachmentView (const vk::DeviceInterface& vki,
501 const tcu::TextureFormat& format,
504 const vk::VkImageViewCreateInfo createInfo =
506 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
509 vk::VK_IMAGE_VIEW_TYPE_2D, // viewType
510 mapToVkTextureFormat(format), // format
511 { vk::VK_CHANNEL_SWIZZLE_R, vk::VK_CHANNEL_SWIZZLE_G, vk::VK_CHANNEL_SWIZZLE_B, vk::VK_CHANNEL_SWIZZLE_A },
513 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
516 0u, // baseArrayLayer
522 return vk::createImageView(vki, device, &createInfo);
525 vk::Move<vk::VkRenderPass> SingleTargetRenderInstance::createRenderPass (const vk::DeviceInterface& vki,
527 const tcu::TextureFormat& format)
529 const vk::VkAttachmentDescription attachmentDescription =
531 vk::VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
533 mapToVkTextureFormat(format), // format
535 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp
536 vk::VK_ATTACHMENT_STORE_OP_STORE, // storeOp
537 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
538 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
539 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
540 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout
543 const vk::VkAttachmentReference colorAttachment =
546 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
548 const vk::VkAttachmentReference depthStencilAttachment =
550 vk::VK_NO_ATTACHMENT, // attachment
551 vk::VK_IMAGE_LAYOUT_UNDEFINED // layout
553 const vk::VkSubpassDescription subpass =
555 vk::VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
557 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
560 DE_NULL, // inputAttachments
562 &colorAttachment, // pColorAttachments
563 DE_NULL, // pResolveAttachments
564 depthStencilAttachment, // depthStencilAttachment
566 DE_NULL // pPreserveAttachments
568 const vk::VkRenderPassCreateInfo renderPassCreateInfo =
570 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
572 1u, // attachmentCount
573 &attachmentDescription, // pAttachments
575 &subpass, // pSubpasses
576 0u, // dependencyCount
577 DE_NULL, // pDependencies
580 return vk::createRenderPass(vki, device, &renderPassCreateInfo);
583 vk::Move<vk::VkFramebuffer> SingleTargetRenderInstance::createFramebuffer (const vk::DeviceInterface& vki,
585 vk::VkRenderPass renderpass,
586 vk::VkImageView colorAttachmentView,
587 const tcu::UVec2& size)
589 const vk::VkFramebufferCreateInfo framebufferCreateInfo =
591 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
593 renderpass, // renderPass
594 1u, // attachmentCount
595 &colorAttachmentView, // pAttachments
601 return vk::createFramebuffer(vki, device, &framebufferCreateInfo);
604 vk::Move<vk::VkCmdPool> SingleTargetRenderInstance::createCommandPool (const vk::DeviceInterface& vki,
606 deUint32 queueFamilyIndex)
608 const vk::VkCmdPoolCreateInfo createInfo =
610 vk::VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,
612 queueFamilyIndex, // queueFamilyIndex
613 vk::VK_CMD_POOL_CREATE_TRANSIENT_BIT, // flags
615 return vk::createCommandPool(vki, device, &createInfo);
618 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
620 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
621 const vk::VkBufferCreateInfo bufferCreateInfo =
623 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
625 pixelDataSize, // size
626 vk::VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, // usage
628 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
629 0u, // queueFamilyCount
630 DE_NULL, // pQueueFamilyIndices
632 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
633 const vk::VkImageSubresourceRange fullSubrange =
635 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
638 0u, // baseArraySlice
641 const vk::VkImageMemoryBarrier imageBarrier =
643 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
645 vk::VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT, // outputMask
646 vk::VK_MEMORY_INPUT_TRANSFER_BIT, // inputMask
647 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
648 vk::VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, // newLayout
649 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
650 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
651 *m_colorAttachmentImage, // image
652 fullSubrange, // subresourceRange
654 const vk::VkBufferMemoryBarrier memoryBarrier =
656 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
658 vk::VK_MEMORY_OUTPUT_TRANSFER_BIT, // outputMask
659 vk::VK_MEMORY_INPUT_HOST_READ_BIT, // inputMask
660 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
661 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
664 (vk::VkDeviceSize)pixelDataSize // size
666 const vk::VkCmdBufferCreateInfo cmdBufCreateInfo =
668 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
670 *m_cmdPool, // cmdPool
671 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
674 const vk::VkFenceCreateInfo fenceCreateInfo =
676 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
680 const vk::VkCmdBufferBeginInfo cmdBufBeginInfo =
682 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
684 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
685 (vk::VkRenderPass)0u, // renderPass
687 (vk::VkFramebuffer)0u, // framebuffer
689 const vk::VkImageSubresourceCopy firstSlice =
691 vk::VK_IMAGE_ASPECT_COLOR, // aspect
696 const vk::VkBufferImageCopy copyRegion =
699 m_targetSize.x(), // bufferRowLength
700 m_targetSize.y(), // bufferImageHeight
701 firstSlice, // imageSubresource
702 { 0, 0, 0 }, // imageOffset
703 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y(), 1 } // imageExtent
706 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
708 const vk::Unique<vk::VkCmdBuffer> cmd (vk::createCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
709 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
710 const void* const imageBarrierPtr = &imageBarrier;
711 const void* const bufferBarrierPtr = &memoryBarrier;
712 const deUint64 infiniteTimeout = ~(deUint64)0u;
714 // copy content to buffer
715 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
716 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_FALSE, 1, &imageBarrierPtr);
717 m_vki.cmdCopyImageToBuffer(*cmd, *m_colorAttachmentImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *buffer, 1, ©Region);
718 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, 1, &bufferBarrierPtr);
719 VK_CHECK(m_vki.endCommandBuffer(*cmd));
721 // wait for transfer to complete
722 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &cmd.get(), *cmdCompleteFence));
723 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
725 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
728 invalidateMappedMemoryRange(m_vki, m_device, bufferMemory->getMemory(), bufferMemory->getOffset(), pixelDataSize);
729 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
732 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
734 tcu::TextureLevel resultImage;
737 if (m_firstIteration)
740 m_firstIteration = false;
745 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
746 const vk::VkImageSubresourceRange fullSubrange =
748 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
751 0u, // baseArraySlice
754 const vk::VkImageMemoryBarrier imageBarrier =
756 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
759 vk::VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT, // inputMask
760 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
761 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
762 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
763 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
764 *m_colorAttachmentImage, // image
765 fullSubrange, // subresourceRange
767 const vk::VkCmdBufferCreateInfo cmdBufCreateInfo =
769 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
771 *m_cmdPool, // cmdPool
772 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
775 const vk::VkCmdBufferBeginInfo cmdBufBeginInfo =
777 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
779 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
780 (vk::VkRenderPass)0u, // renderPass
782 (vk::VkFramebuffer)0u, // framebuffer
785 const vk::Unique<vk::VkCmdBuffer> cmd (vk::createCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
786 const void* const imageBarrierPtr = &imageBarrier;
788 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
789 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);
790 VK_CHECK(m_vki.endCommandBuffer(*cmd));
791 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &cmd.get(), 0));
793 // and then render to
798 readRenderTarget(resultImage);
799 return verifyResultImage(resultImage.getAccess());
802 class RenderInstanceShaders
805 RenderInstanceShaders (const vk::DeviceInterface& vki,
807 const vk::BinaryCollection& programCollection);
809 inline bool hasTessellationStage (void) const { return *m_tessCtrlShader != 0 || *m_tessEvalShader != 0; }
810 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
811 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
814 void addStage (const vk::DeviceInterface& vki,
816 const vk::BinaryCollection& programCollection,
818 vk::VkShaderStage stage,
819 vk::Move<vk::VkShaderModule>* outModule,
820 vk::Move<vk::VkShader>* outShader);
822 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStage stage, vk::VkShader shader) const;
824 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
825 vk::Move<vk::VkShader> m_vertexShader;
826 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
827 vk::Move<vk::VkShader> m_tessCtrlShader;
828 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
829 vk::Move<vk::VkShader> m_tessEvalShader;
830 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
831 vk::Move<vk::VkShader> m_geometryShader;
832 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
833 vk::Move<vk::VkShader> m_fragmentShader;
834 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
837 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
839 const vk::BinaryCollection& programCollection)
841 addStage(vki, device, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX, &m_vertexShaderModule, &m_vertexShader);
842 addStage(vki, device, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESS_CONTROL, &m_tessCtrlShaderModule, &m_tessCtrlShader);
843 addStage(vki, device, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESS_EVALUATION, &m_tessEvalShaderModule, &m_tessEvalShader);
844 addStage(vki, device, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY, &m_geometryShaderModule, &m_geometryShader);
845 addStage(vki, device, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT, &m_fragmentShaderModule, &m_fragmentShader);
847 DE_ASSERT(!m_stageInfos.empty());
850 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
852 const vk::BinaryCollection& programCollection,
854 vk::VkShaderStage stage,
855 vk::Move<vk::VkShaderModule>* outModule,
856 vk::Move<vk::VkShader>* outShader)
858 if (programCollection.contains(name))
860 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
861 const vk::VkShaderCreateInfo createInfo =
863 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
870 vk::Move<vk::VkShader> shader = vk::createShader(vki, device, &createInfo);
872 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *shader));
878 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStage stage, vk::VkShader shader) const
880 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
882 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
886 DE_NULL, // pSpecializationInfo
888 return stageCreateInfo;
891 class SingleCmdRenderInstance : public SingleTargetRenderInstance
894 SingleCmdRenderInstance (Context& context,
895 bool isPrimaryCmdBuf,
896 const tcu::UVec2& renderSize);
899 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
901 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
902 virtual void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const = 0;
904 void renderToTarget (void);
906 const bool m_isPrimaryCmdBuf;
909 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
910 bool isPrimaryCmdBuf,
911 const tcu::UVec2& renderSize)
912 : SingleTargetRenderInstance (context, renderSize)
913 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
917 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
919 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getBinaryCollection());
920 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
921 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
923 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
926 DE_NULL, // pVertexBindingDescriptions
927 0u, // attributeCount
928 DE_NULL, // pVertexAttributeDescriptions
930 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
932 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
934 topology, // topology
935 vk::VK_FALSE, // primitiveRestartEnable
937 const vk::VkPipelineTessellationStateCreateInfo tessState =
939 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
941 3u, // patchControlPoints
943 const vk::VkViewport viewport =
947 float(m_targetSize.x()), // width
948 float(m_targetSize.y()), // height
952 const vk::VkRect2D renderArea =
955 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y() }, // extent
957 const vk::VkPipelineViewportStateCreateInfo vpState =
959 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
966 const vk::VkPipelineRasterStateCreateInfo rsState =
968 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
970 vk::VK_TRUE, // depthClipEnable
971 vk::VK_FALSE, // rasterizerDiscardEnable
972 vk::VK_FILL_MODE_SOLID, // fillMode
973 vk::VK_CULL_MODE_NONE, // cullMode
974 vk::VK_FRONT_FACE_CCW, // frontFace
975 vk::VK_FALSE, // depthBiasEnable
977 0.0f, // depthBiasClamp
978 0.0f, // slopeScaledDepthBias
981 const vk::VkSampleMask sampleMask = 0x01u;
982 const vk::VkPipelineMultisampleStateCreateInfo msState =
984 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
987 vk::VK_FALSE, // sampleShadingEnable
988 0.0f, // minSampleShading
989 &sampleMask // sampleMask
991 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
993 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
995 vk::VK_FALSE, // depthTestEnable
996 vk::VK_FALSE, // depthWriteEnable
997 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
998 vk::VK_FALSE, // depthBoundsTestEnable
999 vk::VK_FALSE, // stencilTestEnable
1000 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
1001 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
1002 -1.0f, // minDepthBounds
1003 +1.0f, // maxDepthBounds
1005 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
1007 vk::VK_FALSE, // blendEnable
1008 vk::VK_BLEND_ZERO, // srcBlendColor
1009 vk::VK_BLEND_ZERO, // destBlendColor
1010 vk::VK_BLEND_OP_ADD, // blendOpColor
1011 vk::VK_BLEND_ZERO, // srcBlendAlpha
1012 vk::VK_BLEND_ZERO, // destBlendAlpha
1013 vk::VK_BLEND_OP_ADD, // blendOpAlpha
1014 vk::VK_CHANNEL_R_BIT | vk::VK_CHANNEL_G_BIT | vk::VK_CHANNEL_B_BIT | vk::VK_CHANNEL_A_BIT, // channelWriteMask
1016 const vk::VkPipelineColorBlendStateCreateInfo cbState =
1018 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1020 vk::VK_FALSE, // alphaToCoverageEnable
1021 vk::VK_FALSE, // alphaToOneEnable
1022 vk::VK_FALSE, // logicOpEnable
1023 vk::VK_LOGIC_OP_CLEAR, // logicOp
1024 1u, // attachmentCount
1025 &cbAttachment, // pAttachments
1026 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
1028 const vk::VkPipelineDynamicStateCreateInfo dynState =
1030 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
1032 0u, // dynamicStateCount
1033 DE_NULL, // pDynamicStates
1035 const vk::VkGraphicsPipelineCreateInfo createInfo =
1037 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1039 shaderStages.getNumStages(), // stageCount
1040 shaderStages.getStages(), // pStages
1041 &vertexInputState, // pVertexInputState
1042 &iaState, // pInputAssemblyState
1043 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
1044 &vpState, // pViewportState
1045 &rsState, // pRasterState
1046 &msState, // pMultisampleState
1047 &dsState, // pDepthStencilState
1048 &cbState, // pColorBlendState
1049 &dynState, // pDynamicState
1051 pipelineLayout, // layout
1052 *m_renderPass, // renderPass
1054 (vk::VkPipeline)0, // basePipelineHandle
1055 0u, // basePipelineIndex
1057 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
1060 void SingleCmdRenderInstance::renderToTarget (void)
1062 const vk::VkRect2D renderArea =
1065 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y() }, // extent
1067 const vk::VkCmdBufferCreateInfo mainCmdBufCreateInfo =
1069 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
1071 *m_cmdPool, // cmdPool
1072 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
1075 const vk::VkCmdBufferBeginInfo mainCmdBufBeginInfo =
1077 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
1079 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
1080 (vk::VkRenderPass)0u, // renderPass
1082 (vk::VkFramebuffer)0u, // framebuffer
1084 const vk::VkCmdBufferCreateInfo passCmdBufCreateInfo =
1086 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
1088 *m_cmdPool, // cmdPool
1089 vk::VK_CMD_BUFFER_LEVEL_SECONDARY, // level
1092 const vk::VkCmdBufferBeginInfo passCmdBufBeginInfo =
1094 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
1096 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
1097 (vk::VkRenderPass)*m_renderPass, // renderPass
1099 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
1101 const vk::VkFenceCreateInfo fenceCreateInfo =
1103 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1107 const vk::VkClearValue clearValue = createClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
1108 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1110 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1112 *m_renderPass, // renderPass
1113 *m_framebuffer, // framebuffer
1114 renderArea, // renderArea
1115 1u, // clearValueCount
1116 &clearValue, // pClearValues
1119 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1120 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1121 const vk::Unique<vk::VkCmdBuffer> mainCmd (vk::createCommandBuffer(m_vki, m_device, &mainCmdBufCreateInfo));
1122 const vk::Unique<vk::VkCmdBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCmdBuffer>()) : (vk::createCommandBuffer(m_vki, m_device, &passCmdBufCreateInfo)));
1123 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1124 const deUint64 infiniteTimeout = ~(deUint64)0u;
1125 const vk::VkRenderPassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_RENDER_PASS_CONTENTS_INLINE) : (vk::VK_RENDER_PASS_CONTENTS_SECONDARY_CMD_BUFFERS);
1127 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1128 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1130 if (m_isPrimaryCmdBuf)
1132 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1133 writeDrawCmdBuffer(*mainCmd);
1137 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1138 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1139 writeDrawCmdBuffer(*passCmd);
1140 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1142 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1145 m_vki.cmdEndRenderPass(*mainCmd);
1146 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1148 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1149 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &mainCmd.get(), *fence));
1150 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1153 enum ShaderInputInterface
1155 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1156 SHADER_INPUT_MULTIPLE_DESCRIPTORS, //!< multiple descriptors
1157 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1162 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1164 switch (shaderInterface)
1166 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1167 case SHADER_INPUT_MULTIPLE_DESCRIPTORS: return 2u;
1168 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1171 DE_FATAL("Impossible");
1176 class BufferRenderInstance : public SingleCmdRenderInstance
1179 BufferRenderInstance (Context& context,
1180 bool isPrimaryCmdBuf,
1181 vk::VkDescriptorType descriptorType,
1182 vk::VkShaderStageFlags stageFlags,
1183 ShaderInputInterface shaderInterface,
1186 bool dynamicOffsetNonZero);
1188 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1189 vk::VkDevice device,
1190 vk::Allocator& allocator,
1191 vk::VkDescriptorType descriptorType,
1193 deUint32 bufferSize,
1194 de::MovePtr<vk::Allocation>* outMemory);
1196 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1197 vk::VkDevice device,
1198 vk::VkDescriptorType descriptorType,
1199 ShaderInputInterface shaderInterface);
1201 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1202 vk::VkDevice device,
1203 vk::VkDescriptorType descriptorType,
1204 ShaderInputInterface shaderInterface,
1205 vk::VkShaderStageFlags stageFlags);
1207 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1208 vk::VkDevice device,
1209 vk::VkDescriptorSetLayout descriptorSetLayout,
1210 vk::VkDescriptorPool descriptorPool,
1211 vk::VkDescriptorType descriptorType,
1212 ShaderInputInterface shaderInterface,
1213 vk::VkBuffer sourceBufferA,
1214 const deUint32 viewOffsetA,
1215 vk::VkBuffer sourceBufferB,
1216 const deUint32 viewOffsetB);
1218 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1219 vk::VkDevice device,
1220 vk::VkDescriptorSetLayout descriptorSetLayout);
1222 void logTestPlan (void) const;
1223 vk::VkPipelineLayout getPipelineLayout (void) const;
1224 void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const;
1225 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1230 BUFFER_DATA_SIZE = 8 * sizeof(float),
1231 BUFFER_SIZE_A = 2048, //!< a lot more than required
1232 BUFFER_SIZE_B = 2560, //!< a lot more than required
1234 STATIC_OFFSET_VALUE_A = 256,
1235 DYNAMIC_OFFSET_VALUE_A = 512,
1236 STATIC_OFFSET_VALUE_B = 1024,
1237 DYNAMIC_OFFSET_VALUE_B = 768,
1240 const vk::VkDescriptorType m_descriptorType;
1241 const ShaderInputInterface m_shaderInterface;
1242 const bool m_setViewOffset;
1243 const bool m_setDynamicOffset;
1244 const bool m_dynamicOffsetNonZero;
1245 const vk::VkShaderStageFlags m_stageFlags;
1247 const deUint32 m_viewOffsetA;
1248 const deUint32 m_viewOffsetB;
1249 const deUint32 m_dynamicOffsetA;
1250 const deUint32 m_dynamicOffsetB;
1251 const deUint32 m_effectiveOffsetA;
1252 const deUint32 m_effectiveOffsetB;
1253 const deUint32 m_bufferSizeA;
1254 const deUint32 m_bufferSizeB;
1256 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1257 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1258 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1259 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1260 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1261 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1262 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1263 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1266 BufferRenderInstance::BufferRenderInstance (Context& context,
1267 bool isPrimaryCmdBuf,
1268 vk::VkDescriptorType descriptorType,
1269 vk::VkShaderStageFlags stageFlags,
1270 ShaderInputInterface shaderInterface,
1273 bool dynamicOffsetNonZero)
1274 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1275 , m_descriptorType (descriptorType)
1276 , m_shaderInterface (shaderInterface)
1277 , m_setViewOffset (viewOffset)
1278 , m_setDynamicOffset (dynamicOffset)
1279 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1280 , m_stageFlags (stageFlags)
1281 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1282 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1283 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1284 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1285 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_dynamicOffsetA) : (m_viewOffsetA))
1286 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_dynamicOffsetB) : (m_viewOffsetB))
1287 , m_bufferSizeA (BUFFER_SIZE_A)
1288 , m_bufferSizeB (BUFFER_SIZE_B)
1289 , m_bufferMemoryA (DE_NULL)
1290 , m_bufferMemoryB (DE_NULL)
1291 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1292 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1293 ? vk::Move<vk::VkBuffer>()
1294 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1295 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1296 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
1297 , m_descriptorSet (createDescriptorSet(m_vki, m_device, *m_descriptorSetLayout, *m_descriptorPool, m_descriptorType, m_shaderInterface, *m_sourceBufferA, m_viewOffsetA, *m_sourceBufferB, m_viewOffsetB))
1298 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1300 if (m_setDynamicOffset)
1301 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1302 if (m_dynamicOffsetNonZero)
1303 DE_ASSERT(m_setDynamicOffset);
1306 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1307 vk::VkDevice device,
1308 vk::Allocator& allocator,
1309 vk::VkDescriptorType descriptorType,
1311 deUint32 bufferSize,
1312 de::MovePtr<vk::Allocation>* outMemory)
1314 static const float s_colors[] =
1316 0.0f, 1.0f, 0.0f, 1.0f, // green
1317 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1319 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1320 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1321 DE_ASSERT(offset % sizeof(float) == 0);
1322 DE_ASSERT(bufferSize % sizeof(float) == 0);
1324 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1325 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1326 const float preGuardValue = 0.5f;
1327 const float postGuardValue = 0.75f;
1328 const vk::VkBufferCreateInfo bufferCreateInfo =
1330 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1333 usageFlags, // usage
1335 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1336 0u, // queueFamilyCount
1337 DE_NULL, // pQueueFamilyIndices
1339 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1340 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1341 void* const mapPtr = bufferMemory->getHostPtr();
1343 // guard with interesting values
1344 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1345 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1347 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1348 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1349 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1350 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
1352 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1354 *outMemory = bufferMemory;
1358 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1359 vk::VkDevice device,
1360 vk::VkDescriptorType descriptorType,
1361 ShaderInputInterface shaderInterface)
1363 return vk::DescriptorPoolBuilder()
1364 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1365 .build(vki, device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
1368 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1369 vk::VkDevice device,
1370 vk::VkDescriptorType descriptorType,
1371 ShaderInputInterface shaderInterface,
1372 vk::VkShaderStageFlags stageFlags)
1374 vk::DescriptorSetLayoutBuilder builder;
1376 switch (shaderInterface)
1378 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1379 builder.addSingleBinding(descriptorType, stageFlags);
1382 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1383 builder.addSingleBinding(descriptorType, stageFlags);
1384 builder.addSingleBinding(descriptorType, stageFlags);
1387 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1388 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1392 DE_FATAL("Impossible");
1395 return builder.build(vki, device);
1398 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1399 vk::VkDevice device,
1400 vk::VkDescriptorSetLayout descriptorSetLayout,
1401 vk::VkDescriptorPool descriptorPool,
1402 vk::VkDescriptorType descriptorType,
1403 ShaderInputInterface shaderInterface,
1404 vk::VkBuffer bufferA,
1406 vk::VkBuffer bufferB,
1409 const vk::VkDescriptorInfo bufferInfos[2] =
1411 createDescriptorInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1412 createDescriptorInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1415 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(vki, device, descriptorPool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, descriptorSetLayout);
1416 vk::DescriptorSetUpdateBuilder builder;
1418 switch (shaderInterface)
1420 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1421 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1424 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1425 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1426 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1429 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1430 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1434 DE_FATAL("Impossible");
1437 builder.update(vki, device);
1438 return descriptorSet;
1441 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1442 vk::VkDevice device,
1443 vk::VkDescriptorSetLayout descriptorSetLayout)
1445 const vk::VkPipelineLayoutCreateInfo createInfo =
1447 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1449 1, // descriptorSetCount
1450 &descriptorSetLayout, // pSetLayouts
1451 0u, // pushConstantRangeCount
1452 DE_NULL, // pPushConstantRanges
1455 return vk::createPipelineLayout(vki, device, &createInfo);
1458 void BufferRenderInstance::logTestPlan (void) const
1460 std::ostringstream msg;
1462 msg << "Rendering 2x2 yellow-green grid.\n"
1463 << "Single descriptor set. Descriptor set contains "
1464 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1465 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
1466 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1467 (const char*)DE_NULL)
1468 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1469 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1471 if (isDynamicDescriptorType(m_descriptorType))
1473 if (m_setDynamicOffset)
1475 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1476 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1480 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1484 if (m_stageFlags == 0u)
1486 msg << "Descriptors are not accessed in any shader stage.\n";
1490 msg << "Descriptors are accessed in {"
1491 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1492 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1493 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1494 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1495 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1499 m_context.getTestContext().getLog()
1500 << tcu::TestLog::Message
1502 << tcu::TestLog::EndMessage;
1505 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1507 return *m_pipelineLayout;
1510 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const
1512 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1514 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1515 const deUint32 dynamicOffsets[] =
1520 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1521 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1523 // make host writes device-visible
1524 const vk::VkMemoryInputFlags inputBit = (isUniformBuffer) ? (vk::VK_MEMORY_INPUT_UNIFORM_READ_BIT) : (vk::VK_MEMORY_INPUT_SHADER_READ_BIT);
1525 const vk::VkBufferMemoryBarrier memoryBarrierA =
1527 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1529 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
1530 inputBit, // inputMask
1531 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1532 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1533 *m_sourceBufferA, // buffer
1535 (vk::VkDeviceSize)m_bufferSizeA, // size
1537 const vk::VkBufferMemoryBarrier memoryBarrierB =
1539 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1541 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
1542 inputBit, // inputMask
1543 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1544 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1545 *m_sourceBufferB, // buffer
1547 (vk::VkDeviceSize)m_bufferSizeB, // size
1549 const void* const memoryBarriers[2] =
1554 const deUint32 numMemoryBarriers = getInterfaceNumResources(m_shaderInterface);
1556 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1557 m_vki.cmdPipelineBarrier(cmd, 0u, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS, vk::VK_FALSE, numMemoryBarriers, memoryBarriers);
1558 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1561 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1563 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1564 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1565 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1567 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1569 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1570 return tcu::TestStatus::fail("Image verification failed");
1572 return tcu::TestStatus::pass("Pass");
1575 class ComputeInstanceResultBuffer
1580 DATA_SIZE = sizeof(tcu::Vec4[4])
1583 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1584 vk::VkDevice device,
1585 vk::Allocator& allocator);
1587 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1589 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1590 inline const void* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1593 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1594 vk::VkDevice device,
1595 vk::Allocator& allocator,
1596 de::MovePtr<vk::Allocation>* outAllocation);
1598 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1600 const vk::DeviceInterface& m_vki;
1601 const vk::VkDevice m_device;
1603 de::MovePtr<vk::Allocation> m_bufferMem;
1604 const vk::Unique<vk::VkBuffer> m_buffer;
1605 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1608 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1609 vk::VkDevice device,
1610 vk::Allocator& allocator)
1613 , m_bufferMem (DE_NULL)
1614 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1615 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1619 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1621 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1622 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1625 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1626 vk::VkDevice device,
1627 vk::Allocator& allocator,
1628 de::MovePtr<vk::Allocation>* outAllocation)
1630 const vk::VkBufferCreateInfo createInfo =
1632 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1634 (vk::VkDeviceSize)DATA_SIZE, // size
1635 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1637 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1638 0u, // queueFamilyCount
1639 DE_NULL, // pQueueFamilyIndices
1641 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1642 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1643 const float clearValue = -1.0f;
1644 void* mapPtr = allocation->getHostPtr();
1646 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1647 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1649 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1651 *outAllocation = allocation;
1655 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1657 const vk::VkBufferMemoryBarrier bufferBarrier =
1659 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1661 vk::VK_MEMORY_OUTPUT_SHADER_WRITE_BIT, // outputMask
1662 vk::VK_MEMORY_INPUT_HOST_READ_BIT, // inputMask
1663 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1664 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1666 (vk::VkDeviceSize)0u, // offset
1669 return bufferBarrier;
1672 class ComputePipeline
1675 ComputePipeline (const vk::DeviceInterface& vki,
1676 vk::VkDevice device,
1677 const vk::BinaryCollection& programCollection,
1678 deUint32 numDescriptorSets,
1679 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1681 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1682 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1685 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1686 vk::VkDevice device,
1687 deUint32 numDescriptorSets,
1688 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1690 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1691 vk::VkDevice device,
1692 const vk::BinaryCollection& programCollection,
1693 vk::VkPipelineLayout layout);
1695 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1696 const vk::Unique<vk::VkPipeline> m_pipeline;
1699 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1700 vk::VkDevice device,
1701 const vk::BinaryCollection& programCollection,
1702 deUint32 numDescriptorSets,
1703 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1704 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
1705 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
1709 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
1710 vk::VkDevice device,
1711 deUint32 numDescriptorSets,
1712 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1714 const vk::VkPipelineLayoutCreateInfo createInfo =
1716 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1718 numDescriptorSets, // descriptorSetCount
1719 descriptorSetLayouts, // pSetLayouts
1720 0u, // pushConstantRangeCount
1721 DE_NULL, // pPushConstantRanges
1723 return vk::createPipelineLayout(vki, device, &createInfo);
1726 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
1727 vk::VkDevice device,
1728 const vk::BinaryCollection& programCollection,
1729 vk::VkPipelineLayout layout)
1731 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
1732 const vk::VkShaderCreateInfo shaderCreateInfo =
1734 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1736 *computeModule, // module
1739 vk::VK_SHADER_STAGE_COMPUTE
1741 const vk::Unique<vk::VkShader> computeShader (vk::createShader(vki, device, &shaderCreateInfo));
1742 const vk::VkPipelineShaderStageCreateInfo cs =
1744 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1746 vk::VK_SHADER_STAGE_COMPUTE, // stage
1747 *computeShader, // shader
1748 DE_NULL, // pSpecializationInfo
1750 const vk::VkComputePipelineCreateInfo createInfo =
1752 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1757 (vk::VkPipeline)0, // basePipelineHandle
1758 0u, // basePipelineIndex
1760 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
1763 class ComputeCommand
1766 ComputeCommand (const vk::DeviceInterface& vki,
1767 vk::VkDevice device,
1768 vk::VkPipeline pipeline,
1769 vk::VkPipelineLayout pipelineLayout,
1770 const tcu::UVec3& numWorkGroups,
1771 int numDescriptorSets,
1772 const vk::VkDescriptorSet* descriptorSets,
1773 int numDynamicOffsets,
1774 const deUint32* dynamicOffsets,
1776 const void* const* preBarriers,
1777 int numPostBarriers,
1778 const void* const* postBarriers);
1780 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const;
1783 const vk::DeviceInterface& m_vki;
1784 const vk::VkDevice m_device;
1785 const vk::VkPipeline m_pipeline;
1786 const vk::VkPipelineLayout m_pipelineLayout;
1787 const tcu::UVec3& m_numWorkGroups;
1788 const int m_numDescriptorSets;
1789 const vk::VkDescriptorSet* const m_descriptorSets;
1790 const int m_numDynamicOffsets;
1791 const deUint32* const m_dynamicOffsets;
1792 const int m_numPreBarriers;
1793 const void* const* const m_preBarriers;
1794 const int m_numPostBarriers;
1795 const void* const* const m_postBarriers;
1798 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
1799 vk::VkDevice device,
1800 vk::VkPipeline pipeline,
1801 vk::VkPipelineLayout pipelineLayout,
1802 const tcu::UVec3& numWorkGroups,
1803 int numDescriptorSets,
1804 const vk::VkDescriptorSet* descriptorSets,
1805 int numDynamicOffsets,
1806 const deUint32* dynamicOffsets,
1808 const void* const* preBarriers,
1809 int numPostBarriers,
1810 const void* const* postBarriers)
1813 , m_pipeline (pipeline)
1814 , m_pipelineLayout (pipelineLayout)
1815 , m_numWorkGroups (numWorkGroups)
1816 , m_numDescriptorSets (numDescriptorSets)
1817 , m_descriptorSets (descriptorSets)
1818 , m_numDynamicOffsets (numDynamicOffsets)
1819 , m_dynamicOffsets (dynamicOffsets)
1820 , m_numPreBarriers (numPreBarriers)
1821 , m_preBarriers (preBarriers)
1822 , m_numPostBarriers (numPostBarriers)
1823 , m_postBarriers (postBarriers)
1827 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const
1829 const vk::VkCmdPoolCreateInfo cmdPoolCreateInfo =
1831 vk::VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,
1833 queueFamilyIndex, // queueFamilyIndex
1834 vk::VK_CMD_POOL_CREATE_TRANSIENT_BIT, // flags
1836 const vk::Unique<vk::VkCmdPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
1838 const vk::VkFenceCreateInfo fenceCreateInfo =
1840 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1845 const vk::VkCmdBufferCreateInfo cmdBufCreateInfo =
1847 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
1849 *cmdPool, // cmdPool
1850 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
1853 const vk::VkCmdBufferBeginInfo cmdBufBeginInfo =
1855 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
1857 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
1858 (vk::VkRenderPass)0u, // renderPass
1860 (vk::VkFramebuffer)0u, // framebuffer
1863 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1864 const vk::Unique<vk::VkCmdBuffer> cmd (vk::createCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
1865 const deUint64 infiniteTimeout = ~(deUint64)0u;
1867 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
1869 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
1870 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
1872 if (m_numPreBarriers)
1873 m_vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_FALSE, m_numPreBarriers, m_preBarriers);
1875 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
1876 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);
1877 VK_CHECK(m_vki.endCommandBuffer(*cmd));
1880 VK_CHECK(m_vki.queueSubmit(queue, 1, &cmd.get(), *cmdCompleteFence));
1881 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1884 class BufferComputeInstance : public vkt::TestInstance
1887 BufferComputeInstance (Context& context,
1888 vk::VkDescriptorType descriptorType,
1889 ShaderInputInterface shaderInterface,
1892 bool dynamicOffsetNonZero);
1895 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
1896 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
1897 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
1898 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
1899 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;
1901 tcu::TestStatus iterate (void);
1902 void logTestPlan (void) const;
1903 tcu::TestStatus testResourceAccess (void);
1907 STATIC_OFFSET_VALUE_A = 256,
1908 DYNAMIC_OFFSET_VALUE_A = 512,
1909 STATIC_OFFSET_VALUE_B = 1024,
1910 DYNAMIC_OFFSET_VALUE_B = 768,
1913 const vk::VkDescriptorType m_descriptorType;
1914 const ShaderInputInterface m_shaderInterface;
1915 const bool m_setViewOffset;
1916 const bool m_setDynamicOffset;
1917 const bool m_dynamicOffsetNonZero;
1919 const vk::DeviceInterface& m_vki;
1920 const vk::VkDevice m_device;
1921 const vk::VkQueue m_queue;
1922 const deUint32 m_queueFamilyIndex;
1923 vk::Allocator& m_allocator;
1925 const ComputeInstanceResultBuffer m_result;
1928 BufferComputeInstance::BufferComputeInstance (Context& context,
1929 vk::VkDescriptorType descriptorType,
1930 ShaderInputInterface shaderInterface,
1933 bool dynamicOffsetNonZero)
1934 : vkt::TestInstance (context)
1935 , m_descriptorType (descriptorType)
1936 , m_shaderInterface (shaderInterface)
1937 , m_setViewOffset (viewOffset)
1938 , m_setDynamicOffset (dynamicOffset)
1939 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1940 , m_vki (context.getDeviceInterface())
1941 , m_device (context.getDevice())
1942 , m_queue (context.getUniversalQueue())
1943 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
1944 , m_allocator (context.getDefaultAllocator())
1945 , m_result (m_vki, m_device, m_allocator)
1947 if (m_dynamicOffsetNonZero)
1948 DE_ASSERT(m_setDynamicOffset);
1951 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
1953 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
1955 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1956 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1957 const vk::VkBufferCreateInfo createInfo =
1959 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1961 (vk::VkDeviceSize)bufferSize, // size
1962 usageFlags, // usage
1964 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1965 0u, // queueFamilyCount
1966 DE_NULL, // pQueueFamilyIndices
1968 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
1969 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
1970 void* mapPtr = allocation->getHostPtr();
1973 deMemset(mapPtr, 0x5A, (size_t)offset);
1974 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
1975 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
1976 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
1978 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
1980 *outAllocation = allocation;
1984 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
1986 vk::DescriptorSetLayoutBuilder builder;
1988 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1990 switch (m_shaderInterface)
1992 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1993 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1996 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1997 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1998 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2001 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2002 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2006 DE_FATAL("Impossible");
2009 return builder.build(m_vki, m_device);
2012 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
2014 return vk::DescriptorPoolBuilder()
2015 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2016 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
2017 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
2020 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
2022 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2023 const vk::VkDescriptorInfo bufferInfos[2] =
2025 createDescriptorInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2026 createDescriptorInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2029 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
2030 vk::DescriptorSetUpdateBuilder builder;
2033 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
2036 switch (m_shaderInterface)
2038 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2039 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2042 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2043 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2044 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
2047 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2048 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
2052 DE_FATAL("Impossible");
2055 builder.update(m_vki, m_device);
2056 return descriptorSet;
2059 tcu::TestStatus BufferComputeInstance::iterate (void)
2062 return testResourceAccess();
2065 void BufferComputeInstance::logTestPlan (void) const
2067 std::ostringstream msg;
2069 msg << "Accessing resource in a compute program.\n"
2070 << "Single descriptor set. Descriptor set contains "
2071 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2072 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
2073 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2074 (const char*)DE_NULL)
2075 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2076 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2077 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2079 if (isDynamicDescriptorType(m_descriptorType))
2081 if (m_setDynamicOffset)
2083 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2084 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2088 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2092 msg << "Destination buffer is pre-initialized to -1.\n";
2094 m_context.getTestContext().getLog()
2095 << tcu::TestLog::Message
2097 << tcu::TestLog::EndMessage;
2100 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2104 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2107 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2108 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2109 const deUint32 bindTimeOffsets[] =
2111 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2112 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2115 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2116 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2117 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2118 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2120 const deUint32 dataOffsetA = (isDynamicCase) ? (bindTimeOffsets[0]) : (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2121 const deUint32 dataOffsetB = (isDynamicCase) ? (bindTimeOffsets[1]) : (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2122 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2123 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2124 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2125 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2127 de::MovePtr<vk::Allocation> bufferMemA;
2128 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2130 de::MovePtr<vk::Allocation> bufferMemB;
2131 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2132 ? (vk::Move<vk::VkBuffer>())
2133 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2135 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2136 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2137 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer()));
2138 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2140 const vk::VkMemoryInputFlags inputBit = (isUniformBuffer) ? (vk::VK_MEMORY_INPUT_UNIFORM_READ_BIT) : (vk::VK_MEMORY_INPUT_SHADER_READ_BIT);
2141 const vk::VkBufferMemoryBarrier bufferBarrierA =
2143 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2145 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
2146 inputBit, // inputMask
2147 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2148 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2150 (vk::VkDeviceSize)0u, // offset
2151 (vk::VkDeviceSize)bufferSizeA, // size
2153 const vk::VkBufferMemoryBarrier bufferBarrierB =
2155 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2157 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
2158 inputBit, // inputMask
2159 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2160 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2162 (vk::VkDeviceSize)0u, // offset
2163 (vk::VkDeviceSize)bufferSizeB, // size
2166 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2168 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2169 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2170 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2171 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2172 const void* const preBarriers[] = { &bufferBarrierA, &bufferBarrierB };
2173 const int numPreBarriers = numSrcBuffers;
2174 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
2175 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
2177 const ComputeCommand compute (m_vki,
2179 pipeline.getPipeline(),
2180 pipeline.getPipelineLayout(),
2181 tcu::UVec3(4, 1, 1),
2182 numDescriptorSets, descriptorSets,
2183 numDynamicOffsets, dynamicOffsets,
2184 numPreBarriers, preBarriers,
2185 numPostBarriers, postBarriers);
2187 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2188 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorB2) :
2189 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2191 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2192 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorA1) :
2193 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2195 const tcu::Vec4 references[4] =
2202 tcu::Vec4 results[4];
2204 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2205 m_result.readResultContentsTo(&results);
2208 if (results[0] == references[0] &&
2209 results[1] == references[1] &&
2210 results[2] == references[2] &&
2211 results[3] == references[3])
2213 return tcu::TestStatus::pass("Pass");
2215 else if (results[0] == tcu::Vec4(-1.0f) &&
2216 results[1] == tcu::Vec4(-1.0f) &&
2217 results[2] == tcu::Vec4(-1.0f) &&
2218 results[3] == tcu::Vec4(-1.0f))
2220 m_context.getTestContext().getLog()
2221 << tcu::TestLog::Message
2222 << "Result buffer was not written to."
2223 << tcu::TestLog::EndMessage;
2224 return tcu::TestStatus::fail("Result buffer was not written to");
2228 m_context.getTestContext().getLog()
2229 << tcu::TestLog::Message
2230 << "Error expected ["
2231 << references[0] << ", "
2232 << references[1] << ", "
2233 << references[2] << ", "
2234 << references[3] << "], got ["
2235 << results[0] << ", "
2236 << results[1] << ", "
2237 << results[2] << ", "
2238 << results[3] << "]"
2239 << tcu::TestLog::EndMessage;
2240 return tcu::TestStatus::fail("Invalid result values");
2244 class QuadrantRendederCase : public vkt::TestCase
2247 QuadrantRendederCase (tcu::TestContext& testCtx,
2249 const char* description,
2250 glu::GLSLVersion glslVersion,
2251 vk::VkShaderStageFlags exitingStages,
2252 vk::VkShaderStageFlags activeStages);
2254 virtual std::string genExtensionDeclarations (vk::VkShaderStage stage) const = 0;
2255 virtual std::string genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const = 0;
2256 virtual std::string genResourceAccessSource (vk::VkShaderStage stage) const = 0;
2257 virtual std::string genNoAccessSource (void) const = 0;
2259 std::string genVertexSource (void) const;
2260 std::string genTessCtrlSource (void) const;
2261 std::string genTessEvalSource (void) const;
2262 std::string genGeometrySource (void) const;
2263 std::string genFragmentSource (void) const;
2264 std::string genComputeSource (void) const;
2266 void initPrograms (vk::SourceCollections& programCollection) const;
2269 const glu::GLSLVersion m_glslVersion;
2270 const vk::VkShaderStageFlags m_exitingStages;
2271 const vk::VkShaderStageFlags m_activeStages;
2274 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2276 const char* description,
2277 glu::GLSLVersion glslVersion,
2278 vk::VkShaderStageFlags exitingStages,
2279 vk::VkShaderStageFlags activeStages)
2280 : vkt::TestCase (testCtx, name, description)
2281 , m_glslVersion (glslVersion)
2282 , m_exitingStages (exitingStages)
2283 , m_activeStages (activeStages)
2285 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2288 std::string QuadrantRendederCase::genVertexSource (void) const
2290 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0u) ? ("tsc")
2291 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2292 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2294 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2295 std::ostringstream buf;
2297 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2299 // active vertex shader
2300 buf << versionDecl << "\n"
2301 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX)
2302 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX, 0)
2303 << "layout(location = 0) out highp vec4 " << nextStageName << "_color;\n"
2304 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2305 << "void main (void)\n"
2307 << " highp vec4 result_position;\n"
2308 << " highp int quadrant_id;\n"
2309 << s_quadrantGenVertexPosSource
2310 << " gl_Position = result_position;\n"
2311 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2313 << " highp vec4 result_color;\n"
2314 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX)
2315 << " " << nextStageName << "_color = result_color;\n"
2321 buf << versionDecl << "\n"
2322 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX)
2323 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2324 << "void main (void)\n"
2326 << " highp vec4 result_position;\n"
2327 << " highp int quadrant_id;\n"
2328 << s_quadrantGenVertexPosSource
2329 << " gl_Position = result_position;\n"
2330 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2337 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2339 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2340 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2341 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2342 std::ostringstream buf;
2344 if ((m_activeStages & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0u)
2346 // contributing not implemented
2347 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESS_CONTROL_BIT);
2350 buf << versionDecl << "\n"
2352 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESS_CONTROL)
2353 << "layout(vertices=3) out;\n"
2354 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESS_CONTROL, 0)
2355 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2356 << "layout(location = 0) out highp vec4 tes_color[];\n"
2357 << "void main (void)\n"
2359 << " highp vec4 result_color;\n"
2360 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2361 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESS_CONTROL)
2363 << " tes_color[gl_InvocationID] = result_color;\n"
2365 << " // no dynamic input block indexing\n"
2366 << " highp vec4 position;\n"
2367 << " if (gl_InvocationID == 0)\n"
2368 << " position = gl_in[0].gl_Position;\n"
2369 << " else if (gl_InvocationID == 1)\n"
2370 << " position = gl_in[1].gl_Position;\n"
2372 << " position = gl_in[2].gl_Position;\n"
2373 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2374 << " gl_TessLevelInner[0] = 2.8;\n"
2375 << " gl_TessLevelInner[1] = 2.8;\n"
2376 << " gl_TessLevelOuter[0] = 2.8;\n"
2377 << " gl_TessLevelOuter[1] = 2.8;\n"
2378 << " gl_TessLevelOuter[2] = 2.8;\n"
2379 << " gl_TessLevelOuter[3] = 2.8;\n"
2382 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0u)
2384 // active te shader, tc passthru
2385 buf << versionDecl << "\n"
2387 << "layout(vertices=3) out;\n"
2388 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2389 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2390 << "void main (void)\n"
2392 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2394 << " // no dynamic input block indexing\n"
2395 << " highp vec4 position;\n"
2396 << " if (gl_InvocationID == 0)\n"
2397 << " position = gl_in[0].gl_Position;\n"
2398 << " else if (gl_InvocationID == 1)\n"
2399 << " position = gl_in[1].gl_Position;\n"
2401 << " position = gl_in[2].gl_Position;\n"
2402 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2403 << " gl_TessLevelInner[0] = 2.8;\n"
2404 << " gl_TessLevelInner[1] = 2.8;\n"
2405 << " gl_TessLevelOuter[0] = 2.8;\n"
2406 << " gl_TessLevelOuter[1] = 2.8;\n"
2407 << " gl_TessLevelOuter[2] = 2.8;\n"
2408 << " gl_TessLevelOuter[3] = 2.8;\n"
2413 // passthrough not implemented
2414 DE_FATAL("not implemented");
2420 std::string QuadrantRendederCase::genTessEvalSource (void) const
2422 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2423 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2424 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2425 std::ostringstream buf;
2427 if ((m_activeStages & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0u)
2429 // contributing not implemented
2430 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT);
2433 buf << versionDecl << "\n"
2435 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESS_EVALUATION)
2436 << "layout(triangles) in;\n"
2437 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESS_EVALUATION, 0)
2438 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2439 << "layout(location = 0) out highp vec4 frag_color;\n"
2440 << "void main (void)\n"
2442 << " highp vec4 result_color;\n"
2443 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2444 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESS_EVALUATION)
2446 << " frag_color = result_color;\n"
2447 << " 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"
2450 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0u)
2452 // contributing not implemented
2453 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESS_CONTROL_BIT);
2455 // active tc shader, te is passthru
2456 buf << versionDecl << "\n"
2458 << "layout(triangles) in;\n"
2459 << "layout(location = 0) in highp vec4 tes_color[];\n"
2460 << "layout(location = 0) out highp vec4 frag_color;\n"
2461 << "void main (void)\n"
2463 << " frag_color = tes_color[0];\n"
2464 << " 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"
2469 // passthrough not implemented
2470 DE_FATAL("not implemented");
2476 std::string QuadrantRendederCase::genGeometrySource (void) const
2478 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2479 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2480 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
2481 std::ostringstream buf;
2483 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2485 // contributing not implemented
2486 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
2488 // active geometry shader
2489 buf << versionDecl << "\n"
2491 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY)
2492 << "layout(triangles) in;\n"
2493 << "layout(triangle_strip, max_vertices=4) out;\n"
2494 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY, 0)
2495 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
2496 << "layout(location = 0) out highp vec4 frag_color;\n"
2497 << "void main (void)\n"
2499 << " highp int quadrant_id;\n"
2500 << " highp vec4 result_color;\n"
2502 << " quadrant_id = geo_quadrant_id[0];\n"
2503 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY)
2504 << " frag_color = result_color;\n"
2505 << " gl_Position = gl_in[0].gl_Position;\n"
2506 << " EmitVertex();\n"
2508 << " quadrant_id = geo_quadrant_id[1];\n"
2509 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY)
2510 << " frag_color = result_color;\n"
2511 << " gl_Position = gl_in[1].gl_Position;\n"
2512 << " EmitVertex();\n"
2514 << " quadrant_id = geo_quadrant_id[2];\n"
2515 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY)
2516 << " frag_color = result_color;\n"
2517 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
2518 << " EmitVertex();\n"
2520 << " quadrant_id = geo_quadrant_id[0];\n"
2521 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY)
2522 << " frag_color = result_color;\n"
2523 << " gl_Position = gl_in[2].gl_Position;\n"
2524 << " EmitVertex();\n"
2529 // passthrough not implemented
2530 DE_FATAL("not implemented");
2536 std::string QuadrantRendederCase::genFragmentSource (void) const
2538 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2539 std::ostringstream buf;
2541 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2543 buf << versionDecl << "\n"
2544 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY)
2545 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT, 0);
2547 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2549 // there are other stages, this is just a contributor
2550 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
2553 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2554 << "layout(location = 0) out mediump vec4 o_color;\n"
2555 << "void main (void)\n"
2557 << " highp int quadrant_id = frag_quadrant_id;\n"
2558 << " highp vec4 result_color;\n"
2559 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT);
2561 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2564 buf << " if (frag_quadrant_id < 2)\n"
2565 << " o_color = result_color;\n"
2567 << " o_color = frag_color;\n";
2570 buf << " o_color = result_color;\n";
2574 else if (m_activeStages == 0u)
2576 // special case, no active stages
2577 buf << versionDecl << "\n"
2578 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2579 << "layout(location = 0) out mediump vec4 o_color;\n"
2580 << "void main (void)\n"
2582 << " highp int quadrant_id = frag_quadrant_id;\n"
2583 << " highp vec4 result_color;\n"
2584 << genNoAccessSource()
2585 << " o_color = result_color;\n"
2591 buf << versionDecl << "\n"
2592 << "layout(location = 0) in mediump vec4 frag_color;\n"
2593 "layout(location = 0) out mediump vec4 o_color;\n"
2594 "void main (void)\n"
2596 " o_color = frag_color;\n"
2603 std::string QuadrantRendederCase::genComputeSource (void) const
2605 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2606 std::ostringstream buf;
2608 buf << versionDecl << "\n"
2609 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE)
2610 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2611 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE, 1)
2612 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
2614 << " highp vec4 read_colors[4];\n"
2616 << "void main(void)\n"
2618 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
2619 << " highp vec4 result_color;\n"
2620 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE)
2621 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
2627 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
2629 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2630 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
2632 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0u)
2633 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
2635 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0u)
2636 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
2638 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2639 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
2641 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2642 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
2644 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
2645 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
2648 class BufferDescriptorCase : public QuadrantRendederCase
2653 FLAG_VIEW_OFFSET = (1u << 1u),
2654 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
2655 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
2657 // enum continues where resource flags ends
2658 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
2660 BufferDescriptorCase (tcu::TestContext& testCtx,
2662 const char* description,
2663 bool isPrimaryCmdBuf,
2664 vk::VkDescriptorType descriptorType,
2665 vk::VkShaderStageFlags exitingStages,
2666 vk::VkShaderStageFlags activeStages,
2667 ShaderInputInterface shaderInterface,
2671 std::string genExtensionDeclarations (vk::VkShaderStage stage) const;
2672 std::string genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const;
2673 std::string genResourceAccessSource (vk::VkShaderStage stage) const;
2674 std::string genNoAccessSource (void) const;
2676 vkt::TestInstance* createInstance (vkt::Context& context) const;
2678 const bool m_viewOffset;
2679 const bool m_dynamicOffsetSet;
2680 const bool m_dynamicOffsetNonZero;
2681 const bool m_isPrimaryCmdBuf;
2682 const vk::VkDescriptorType m_descriptorType;
2683 const ShaderInputInterface m_shaderInterface;
2686 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
2688 const char* description,
2689 bool isPrimaryCmdBuf,
2690 vk::VkDescriptorType descriptorType,
2691 vk::VkShaderStageFlags exitingStages,
2692 vk::VkShaderStageFlags activeStages,
2693 ShaderInputInterface shaderInterface,
2695 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
2696 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
2697 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
2698 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
2699 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
2700 , m_descriptorType (descriptorType)
2701 , m_shaderInterface (shaderInterface)
2705 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStage stage) const
2711 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const
2715 const bool isUniform = isUniformDescriptorType(m_descriptorType);
2716 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
2717 std::ostringstream buf;
2719 switch (m_shaderInterface)
2721 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2722 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2724 << " highp vec4 colorA;\n"
2725 << " highp vec4 colorB;\n"
2726 << "} b_instance;\n";
2729 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2730 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
2732 << " highp vec4 colorA;\n"
2733 << " highp vec4 colorB;\n"
2734 << "} b_instanceA;\n"
2735 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
2737 << " highp vec4 colorA;\n"
2738 << " highp vec4 colorB;\n"
2739 << "} b_instanceB;\n";
2742 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2743 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2745 << " highp vec4 colorA;\n"
2746 << " highp vec4 colorB;\n"
2747 << "} b_instances[2];\n";
2751 DE_FATAL("Impossible");
2757 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStage stage) const
2761 std::ostringstream buf;
2763 switch (m_shaderInterface)
2765 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2766 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2767 << " result_color = b_instance.colorA;\n"
2769 << " result_color = b_instance.colorB;\n";
2772 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2773 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2774 << " result_color = b_instanceA.colorA;\n"
2776 << " result_color = b_instanceB.colorB;\n";
2779 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2780 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2781 << " result_color = b_instances[0].colorA;\n"
2783 << " result_color = b_instances[1].colorB;\n";
2787 DE_FATAL("Impossible");
2793 std::string BufferDescriptorCase::genNoAccessSource (void) const
2795 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
2796 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2798 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
2801 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
2803 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
2805 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
2806 return new BufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2809 return new BufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2812 class ImageInstanceImages
2815 ImageInstanceImages (const vk::DeviceInterface& vki,
2816 vk::VkDevice device,
2817 deUint32 queueFamilyIndex,
2819 vk::Allocator& allocator,
2820 vk::VkDescriptorType descriptorType,
2821 vk::VkImageViewType viewType,
2823 deUint32 baseMipLevel,
2824 deUint32 baseArraySlice);
2827 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
2828 vk::VkDevice device,
2829 vk::Allocator& allocator,
2830 vk::VkDescriptorType descriptorType,
2831 vk::VkImageViewType viewType,
2832 const tcu::TextureLevelPyramid& sourceImage,
2833 de::MovePtr<vk::Allocation>* outAllocation);
2835 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
2836 vk::VkDevice device,
2837 vk::VkImageViewType viewType,
2838 const tcu::TextureLevelPyramid& sourceImage,
2840 deUint32 baseMipLevel,
2841 deUint32 baseArraySlice);
2843 void populateSourceImage (tcu::TextureLevelPyramid* dst,
2844 bool isFirst) const;
2846 void uploadImage (const vk::DeviceInterface& vki,
2847 vk::VkDevice device,
2848 deUint32 queueFamilyIndex,
2850 vk::Allocator& allocator,
2852 const tcu::TextureLevelPyramid& data);
2862 const vk::VkImageViewType m_viewType;
2863 const deUint32 m_baseMipLevel;
2864 const deUint32 m_baseArraySlice;
2866 const tcu::TextureFormat m_imageFormat;
2867 tcu::TextureLevelPyramid m_sourceImageA;
2868 tcu::TextureLevelPyramid m_sourceImageB;
2870 de::MovePtr<vk::Allocation> m_imageMemoryA;
2871 de::MovePtr<vk::Allocation> m_imageMemoryB;
2872 vk::Move<vk::VkImage> m_imageA;
2873 vk::Move<vk::VkImage> m_imageB;
2874 vk::Move<vk::VkImageView> m_imageViewA;
2875 vk::Move<vk::VkImageView> m_imageViewB;
2878 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
2879 vk::VkDevice device,
2880 deUint32 queueFamilyIndex,
2882 vk::Allocator& allocator,
2883 vk::VkDescriptorType descriptorType,
2884 vk::VkImageViewType viewType,
2886 deUint32 baseMipLevel,
2887 deUint32 baseArraySlice)
2888 : m_viewType (viewType)
2889 , m_baseMipLevel (baseMipLevel)
2890 , m_baseArraySlice (baseArraySlice)
2891 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
2892 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
2893 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
2894 , m_imageMemoryA (DE_NULL)
2895 , m_imageMemoryB (DE_NULL)
2896 , m_imageA (vk::Move<vk::VkImage>())
2897 , m_imageB (vk::Move<vk::VkImage>())
2898 , m_imageViewA (vk::Move<vk::VkImageView>())
2899 , m_imageViewB (vk::Move<vk::VkImageView>())
2901 DE_ASSERT(numImages == 1 || numImages == 2);
2903 populateSourceImage(&m_sourceImageA, true);
2904 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
2905 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
2906 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, m_sourceImageA);
2910 populateSourceImage(&m_sourceImageB, false);
2911 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
2912 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
2913 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, m_sourceImageB);
2917 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
2918 vk::VkDevice device,
2919 vk::Allocator& allocator,
2920 vk::VkDescriptorType descriptorType,
2921 vk::VkImageViewType viewType,
2922 const tcu::TextureLevelPyramid& sourceImage,
2923 de::MovePtr<vk::Allocation>* outAllocation)
2925 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2926 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
2927 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
2928 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
2929 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
2930 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
2931 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2932 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
2934 const vk::VkExtent3D extent =
2937 (deInt32)baseLevel.getWidth(),
2940 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (deInt32)baseLevel.getHeight(),
2943 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deInt32)baseLevel.getDepth()) : (1),
2945 const vk::VkImageCreateInfo createInfo =
2947 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2949 viewTypeToImageType(viewType), // imageType
2950 mapToVkTextureFormat(baseLevel.getFormat()), // format
2952 (deUint32)sourceImage.getNumLevels(), // mipLevels
2953 arraySize, // arraySize
2955 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
2956 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, // usage
2957 isCube ? ((deUint32)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) : (0u), // flags
2958 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2959 0u, // queueFamilyCount
2960 DE_NULL, // pQueueFamilyIndices
2961 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2963 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
2965 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
2969 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
2970 vk::VkDevice device,
2971 vk::VkImageViewType viewType,
2972 const tcu::TextureLevelPyramid& sourceImage,
2974 deUint32 baseMipLevel,
2975 deUint32 baseArraySlice)
2977 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2978 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
2979 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
2980 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
2981 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
2982 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
2983 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2984 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
2985 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
2988 DE_ASSERT(viewArraySize > 0);
2990 const vk::VkImageSubresourceRange resourceRange =
2992 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
2993 baseMipLevel, // baseMipLevel
2994 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
2995 viewTypeBaseSlice, // baseArraySlice
2996 viewArraySize, // arraySize
2998 const vk::VkImageViewCreateInfo createInfo =
3000 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3003 viewType, // viewType
3004 mapToVkTextureFormat(baseLevel.getFormat()), // format
3006 vk::VK_CHANNEL_SWIZZLE_R,
3007 vk::VK_CHANNEL_SWIZZLE_G,
3008 vk::VK_CHANNEL_SWIZZLE_B,
3009 vk::VK_CHANNEL_SWIZZLE_A
3011 resourceRange, // subresourceRange
3014 return vk::createImageView(vki, device, &createInfo);
3017 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
3019 const int numLevels = dst->getNumLevels();
3021 for (int level = 0; level < numLevels; ++level)
3023 const int width = IMAGE_SIZE >> level;
3024 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
3025 : (IMAGE_SIZE >> level);
3026 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
3027 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
3028 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
3029 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
3032 dst->allocLevel(level, width, height, depth);
3035 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
3037 for (int z = 0; z < depth; ++z)
3038 for (int y = 0; y < height; ++y)
3039 for (int x = 0; x < width; ++x)
3041 const int gradPos = x + y + z;
3042 const int gradMax = width + height + depth - 3;
3044 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
3045 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
3046 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
3048 DE_ASSERT(de::inRange(red, 0, 255));
3049 DE_ASSERT(de::inRange(green, 0, 255));
3050 DE_ASSERT(de::inRange(blue, 0, 255));
3052 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3058 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3059 vk::VkDevice device,
3060 deUint32 queueFamilyIndex,
3062 vk::Allocator& allocator,
3064 const tcu::TextureLevelPyramid& data)
3066 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3067 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3068 ((deUint32)ARRAY_SIZE);
3069 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3070 const vk::VkBufferCreateInfo bufferCreateInfo =
3072 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3074 dataBufferSize, // size
3075 vk::VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT, // usage
3077 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3078 0u, // queueFamilyCount
3079 DE_NULL, // pQueueFamilyIndices
3081 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3082 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3083 const vk::VkFenceCreateInfo fenceCreateInfo =
3085 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3089 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3091 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3093 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
3094 vk::VK_MEMORY_INPUT_TRANSFER_BIT, // inputMask
3095 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3096 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3097 *dataBuffer, // buffer
3099 dataBufferSize, // size
3101 const vk::VkImageSubresourceRange fullSubrange =
3103 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3105 (deUint32)data.getNumLevels(), // mipLevels
3106 0u, // baseArraySlice
3107 arraySize, // arraySize
3109 const vk::VkImageMemoryBarrier preImageBarrier =
3111 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3115 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3116 vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, // newLayout
3117 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3118 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3120 fullSubrange // subresourceRange
3122 const vk::VkImageMemoryBarrier postImageBarrier =
3124 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3126 vk::VK_MEMORY_OUTPUT_TRANSFER_BIT, // outputMask
3127 vk::VK_MEMORY_INPUT_SHADER_READ_BIT, // inputMask
3128 vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, // oldLayout
3129 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
3130 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3131 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3133 fullSubrange // subresourceRange
3135 const vk::VkCmdPoolCreateInfo cmdPoolCreateInfo =
3137 vk::VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,
3139 queueFamilyIndex, // queueFamilyIndex
3140 vk::VK_CMD_POOL_CREATE_TRANSIENT_BIT, // flags
3142 const vk::Unique<vk::VkCmdPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3143 const vk::VkCmdBufferCreateInfo cmdBufCreateInfo =
3145 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
3147 *cmdPool, // cmdPool
3148 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
3151 const vk::VkCmdBufferBeginInfo cmdBufBeginInfo =
3153 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
3155 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
3156 (vk::VkRenderPass)0u, // renderPass
3158 (vk::VkFramebuffer)0u, // framebuffer
3161 const vk::Unique<vk::VkCmdBuffer> cmd (vk::createCommandBuffer(vki, device, &cmdBufCreateInfo));
3162 const void* const preBarriers[2] = { &preMemoryBarrier, &preImageBarrier };
3163 const void* const postBarriers[1] = { &postImageBarrier };
3164 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device, &fenceCreateInfo));
3165 const deUint64 infiniteTimeout = ~(deUint64)0u;
3166 std::vector<vk::VkBufferImageCopy> copySlices;
3168 // copy data to buffer
3169 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3170 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3172 // record command buffer
3173 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3174 vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_FALSE, DE_LENGTH_OF_ARRAY(preBarriers), preBarriers);
3175 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3176 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);
3177 VK_CHECK(vki.endCommandBuffer(*cmd));
3179 // submit and wait for command buffer to complete before killing it
3180 VK_CHECK(vki.queueSubmit(queue, 1, &cmd.get(), *cmdCompleteFence));
3181 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3184 class ImageFetchInstanceImages : private ImageInstanceImages
3187 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3188 vk::VkDevice device,
3189 deUint32 queueFamilyIndex,
3191 vk::Allocator& allocator,
3192 vk::VkDescriptorType descriptorType,
3193 ShaderInputInterface shaderInterface,
3194 vk::VkImageViewType viewType,
3195 deUint32 baseMipLevel,
3196 deUint32 baseArraySlice);
3198 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3199 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3201 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3202 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3207 // some arbitrary sample points for all four quadrants
3208 SAMPLE_POINT_0_X = 6,
3209 SAMPLE_POINT_0_Y = 13,
3210 SAMPLE_POINT_0_Z = 49,
3212 SAMPLE_POINT_1_X = 51,
3213 SAMPLE_POINT_1_Y = 40,
3214 SAMPLE_POINT_1_Z = 44,
3216 SAMPLE_POINT_2_X = 42,
3217 SAMPLE_POINT_2_Y = 26,
3218 SAMPLE_POINT_2_Z = 19,
3220 SAMPLE_POINT_3_X = 25,
3221 SAMPLE_POINT_3_Y = 25,
3222 SAMPLE_POINT_3_Z = 18,
3225 const ShaderInputInterface m_shaderInterface;
3228 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3229 vk::VkDevice device,
3230 deUint32 queueFamilyIndex,
3232 vk::Allocator& allocator,
3233 vk::VkDescriptorType descriptorType,
3234 ShaderInputInterface shaderInterface,
3235 vk::VkImageViewType viewType,
3236 deUint32 baseMipLevel,
3237 deUint32 baseArraySlice)
3238 : ImageInstanceImages (vki,
3245 getInterfaceNumResources(shaderInterface), // numImages
3248 , m_shaderInterface (shaderInterface)
3252 bool isImageViewTypeArray (vk::VkImageViewType type)
3254 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;
3257 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3259 const tcu::IVec3 fetchPositions[4] =
3261 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3262 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3263 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3264 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3266 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3267 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3268 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3272 case vk::VK_IMAGE_VIEW_TYPE_1D:
3273 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3274 case vk::VK_IMAGE_VIEW_TYPE_2D:
3275 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3276 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3277 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3278 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3280 DE_FATAL("Impossible");
3281 return tcu::IVec3();
3285 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3287 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3289 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3290 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3291 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3292 const tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3294 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3297 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3300 ImageFetchRenderInstance (vkt::Context& context,
3301 bool isPrimaryCmdBuf,
3302 vk::VkDescriptorType descriptorType,
3303 vk::VkShaderStageFlags stageFlags,
3304 ShaderInputInterface shaderInterface,
3305 vk::VkImageViewType viewType,
3306 deUint32 baseMipLevel,
3307 deUint32 baseArraySlice);
3310 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3311 vk::VkDevice device,
3312 vk::VkDescriptorType descriptorType,
3313 ShaderInputInterface shaderInterface,
3314 vk::VkShaderStageFlags stageFlags);
3316 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3317 vk::VkDevice device,
3318 vk::VkDescriptorSetLayout descriptorSetLayout);
3320 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3321 vk::VkDevice device,
3322 vk::VkDescriptorType descriptorType,
3323 ShaderInputInterface shaderInterface);
3325 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3326 vk::VkDevice device,
3327 vk::VkDescriptorType descriptorType,
3328 ShaderInputInterface shaderInterface,
3329 vk::VkDescriptorSetLayout layout,
3330 vk::VkDescriptorPool pool,
3331 vk::VkImageView viewA,
3332 vk::VkImageView viewB);
3334 void logTestPlan (void) const;
3335 vk::VkPipelineLayout getPipelineLayout (void) const;
3336 void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const;
3337 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3344 const vk::VkDescriptorType m_descriptorType;
3345 const vk::VkShaderStageFlags m_stageFlags;
3346 const ShaderInputInterface m_shaderInterface;
3347 const vk::VkImageViewType m_viewType;
3348 const deUint32 m_baseMipLevel;
3349 const deUint32 m_baseArraySlice;
3351 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3352 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3353 const ImageFetchInstanceImages m_images;
3354 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3355 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3358 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3359 bool isPrimaryCmdBuf,
3360 vk::VkDescriptorType descriptorType,
3361 vk::VkShaderStageFlags stageFlags,
3362 ShaderInputInterface shaderInterface,
3363 vk::VkImageViewType viewType,
3364 deUint32 baseMipLevel,
3365 deUint32 baseArraySlice)
3366 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3367 , m_descriptorType (descriptorType)
3368 , m_stageFlags (stageFlags)
3369 , m_shaderInterface (shaderInterface)
3370 , m_viewType (viewType)
3371 , m_baseMipLevel (baseMipLevel)
3372 , m_baseArraySlice (baseArraySlice)
3373 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
3374 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3375 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3376 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3377 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_images.getImageViewA(), m_images.getImageViewB()))
3381 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3382 vk::VkDevice device,
3383 vk::VkDescriptorType descriptorType,
3384 ShaderInputInterface shaderInterface,
3385 vk::VkShaderStageFlags stageFlags)
3387 vk::DescriptorSetLayoutBuilder builder;
3389 switch (shaderInterface)
3391 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3392 builder.addSingleBinding(descriptorType, stageFlags);
3395 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3396 builder.addSingleBinding(descriptorType, stageFlags);
3397 builder.addSingleBinding(descriptorType, stageFlags);
3400 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3401 builder.addArrayBinding(descriptorType, 2u, stageFlags);
3405 DE_FATAL("Impossible");
3408 return builder.build(vki, device);
3411 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
3412 vk::VkDevice device,
3413 vk::VkDescriptorSetLayout descriptorSetLayout)
3415 const vk::VkPipelineLayoutCreateInfo createInfo =
3417 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3419 1, // descriptorSetCount
3420 &descriptorSetLayout, // pSetLayouts
3421 0u, // pushConstantRangeCount
3422 DE_NULL, // pPushConstantRanges
3424 return vk::createPipelineLayout(vki, device, &createInfo);
3427 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
3428 vk::VkDevice device,
3429 vk::VkDescriptorType descriptorType,
3430 ShaderInputInterface shaderInterface)
3432 return vk::DescriptorPoolBuilder()
3433 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
3434 .build(vki, device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
3437 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
3438 vk::VkDevice device,
3439 vk::VkDescriptorType descriptorType,
3440 ShaderInputInterface shaderInterface,
3441 vk::VkDescriptorSetLayout layout,
3442 vk::VkDescriptorPool pool,
3443 vk::VkImageView viewA,
3444 vk::VkImageView viewB)
3446 const vk::VkDescriptorInfo imageInfos[2] =
3448 createDescriptorInfo(viewA, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3449 createDescriptorInfo(viewB, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3452 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(vki, device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
3453 vk::DescriptorSetUpdateBuilder builder;
3455 switch (shaderInterface)
3457 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3458 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3461 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3462 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3463 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
3466 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3467 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
3471 DE_FATAL("Impossible");
3474 builder.update(vki, device);
3475 return descriptorSet;
3478 void ImageFetchRenderInstance::logTestPlan (void) const
3480 std::ostringstream msg;
3482 msg << "Rendering 2x2 grid.\n"
3483 << "Single descriptor set. Descriptor set contains "
3484 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3485 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3486 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3487 (const char*)DE_NULL)
3488 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3489 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3492 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3493 if (m_baseArraySlice)
3494 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3496 if (m_stageFlags == 0u)
3498 msg << "Descriptors are not accessed in any shader stage.\n";
3502 msg << "Color in each cell is fetched using the descriptor(s):\n";
3504 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3506 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3508 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3510 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3511 msg << " from descriptor " << srcResourceNdx;
3517 msg << "Descriptors are accessed in {"
3518 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
3519 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0) ? (" tess_control") : (""))
3520 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
3521 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
3522 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
3526 m_context.getTestContext().getLog()
3527 << tcu::TestLog::Message
3529 << tcu::TestLog::EndMessage;
3532 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
3534 return *m_pipelineLayout;
3537 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const
3539 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
3540 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
3543 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
3545 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3546 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
3547 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
3548 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
3549 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
3550 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
3551 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
3552 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
3554 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
3556 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
3557 return tcu::TestStatus::fail("Image verification failed");
3559 return tcu::TestStatus::pass("Pass");
3562 class ImageFetchComputeInstance : public vkt::TestInstance
3565 ImageFetchComputeInstance (vkt::Context& context,
3566 vk::VkDescriptorType descriptorType,
3567 ShaderInputInterface shaderInterface,
3568 vk::VkImageViewType viewType,
3569 deUint32 baseMipLevel,
3570 deUint32 baseArraySlice);
3573 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
3574 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
3575 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
3577 tcu::TestStatus iterate (void);
3578 void logTestPlan (void) const;
3579 tcu::TestStatus testResourceAccess (void);
3581 const vk::VkDescriptorType m_descriptorType;
3582 const ShaderInputInterface m_shaderInterface;
3583 const vk::VkImageViewType m_viewType;
3584 const deUint32 m_baseMipLevel;
3585 const deUint32 m_baseArraySlice;
3587 const vk::DeviceInterface& m_vki;
3588 const vk::VkDevice m_device;
3589 const vk::VkQueue m_queue;
3590 const deUint32 m_queueFamilyIndex;
3591 vk::Allocator& m_allocator;
3593 const ComputeInstanceResultBuffer m_result;
3594 const ImageFetchInstanceImages m_images;
3597 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
3598 vk::VkDescriptorType descriptorType,
3599 ShaderInputInterface shaderInterface,
3600 vk::VkImageViewType viewType,
3601 deUint32 baseMipLevel,
3602 deUint32 baseArraySlice)
3603 : vkt::TestInstance (context)
3604 , m_descriptorType (descriptorType)
3605 , m_shaderInterface (shaderInterface)
3606 , m_viewType (viewType)
3607 , m_baseMipLevel (baseMipLevel)
3608 , m_baseArraySlice (baseArraySlice)
3609 , m_vki (context.getDeviceInterface())
3610 , m_device (context.getDevice())
3611 , m_queue (context.getUniversalQueue())
3612 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
3613 , m_allocator (context.getDefaultAllocator())
3614 , m_result (m_vki, m_device, m_allocator)
3615 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3619 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
3621 vk::DescriptorSetLayoutBuilder builder;
3623 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3625 switch (m_shaderInterface)
3627 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3628 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3631 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3632 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3633 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3636 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3637 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3641 DE_FATAL("Impossible");
3644 return builder.build(m_vki, m_device);
3647 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
3649 return vk::DescriptorPoolBuilder()
3650 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3651 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
3652 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
3655 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
3657 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
3658 const vk::VkDescriptorInfo imageInfos[2] =
3660 createDescriptorInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3661 createDescriptorInfo(m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3664 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
3665 vk::DescriptorSetUpdateBuilder builder;
3668 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
3671 switch (m_shaderInterface)
3673 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3674 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3677 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3678 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3679 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
3682 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3683 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
3687 DE_FATAL("Impossible");
3690 builder.update(m_vki, m_device);
3691 return descriptorSet;
3694 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
3697 return testResourceAccess();
3700 void ImageFetchComputeInstance::logTestPlan (void) const
3702 std::ostringstream msg;
3704 msg << "Fetching 4 values from image in compute shader.\n"
3705 << "Single descriptor set. Descriptor set contains "
3706 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3707 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3708 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3709 (const char*)DE_NULL)
3710 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3711 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3714 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3715 if (m_baseArraySlice)
3716 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3718 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3720 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3722 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3724 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3725 msg << " from descriptor " << srcResourceNdx;
3731 m_context.getTestContext().getLog()
3732 << tcu::TestLog::Message
3734 << tcu::TestLog::EndMessage;
3737 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
3739 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
3740 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
3741 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
3742 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
3744 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
3745 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
3746 const deUint32* const dynamicOffsets = DE_NULL;
3747 const int numDynamicOffsets = 0;
3748 const void* const* preBarriers = DE_NULL;
3749 const int numPreBarriers = 0;
3750 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
3751 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
3753 const ComputeCommand compute (m_vki,
3755 pipeline.getPipeline(),
3756 pipeline.getPipelineLayout(),
3757 tcu::UVec3(4, 1, 1),
3758 numDescriptorSets, descriptorSets,
3759 numDynamicOffsets, dynamicOffsets,
3760 numPreBarriers, preBarriers,
3761 numPostBarriers, postBarriers);
3763 tcu::Vec4 results[4];
3764 bool anyResultSet = false;
3765 bool allResultsOk = true;
3767 compute.submitAndWait(m_queueFamilyIndex, m_queue);
3768 m_result.readResultContentsTo(&results);
3771 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3773 const tcu::Vec4 result = results[resultNdx];
3774 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
3775 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
3777 if (result != tcu::Vec4(-1.0f))
3778 anyResultSet = true;
3780 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
3782 allResultsOk = false;
3784 m_context.getTestContext().getLog()
3785 << tcu::TestLog::Message
3786 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
3787 << tcu::TestLog::EndMessage;
3791 // read back and verify
3793 return tcu::TestStatus::pass("Pass");
3794 else if (anyResultSet)
3795 return tcu::TestStatus::fail("Invalid result values");
3798 m_context.getTestContext().getLog()
3799 << tcu::TestLog::Message
3800 << "Result buffer was not written to."
3801 << tcu::TestLog::EndMessage;
3802 return tcu::TestStatus::fail("Result buffer was not written to");
3806 class ImageSampleInstanceImages : private ImageInstanceImages
3809 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3810 vk::VkDevice device,
3811 deUint32 queueFamilyIndex,
3813 vk::Allocator& allocator,
3814 vk::VkDescriptorType descriptorType,
3815 ShaderInputInterface shaderInterface,
3816 vk::VkImageViewType viewType,
3817 deUint32 baseMipLevel,
3818 deUint32 baseArraySlice,
3821 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
3822 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
3824 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3825 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3826 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
3827 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
3828 inline bool isImmutable (void) const { return m_isImmutable; }
3831 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
3832 static tcu::Sampler createRefSampler (bool isFirst);
3833 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
3835 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3836 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3837 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3838 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3840 const vk::VkDescriptorType m_descriptorType;
3841 const ShaderInputInterface m_shaderInterface;
3842 const bool m_isImmutable;
3844 const tcu::Sampler m_refSamplerA;
3845 const tcu::Sampler m_refSamplerB;
3846 const vk::Unique<vk::VkSampler> m_samplerA;
3847 const vk::Unique<vk::VkSampler> m_samplerB;
3850 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3851 vk::VkDevice device,
3852 deUint32 queueFamilyIndex,
3854 vk::Allocator& allocator,
3855 vk::VkDescriptorType descriptorType,
3856 ShaderInputInterface shaderInterface,
3857 vk::VkImageViewType viewType,
3858 deUint32 baseMipLevel,
3859 deUint32 baseArraySlice,
3861 : ImageInstanceImages (vki,
3868 getNumImages(descriptorType, shaderInterface),
3871 , m_descriptorType (descriptorType)
3872 , m_shaderInterface (shaderInterface)
3873 , m_isImmutable (immutable)
3874 , m_refSamplerA (createRefSampler(true))
3875 , m_refSamplerB (createRefSampler(false))
3876 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
3877 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
3878 ? vk::Move<vk::VkSampler>()
3879 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
3883 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
3885 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3887 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3888 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3890 // choose arbitrary values that are not ambiguous with NEAREST filtering
3894 case vk::VK_IMAGE_VIEW_TYPE_1D:
3895 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
3896 case vk::VK_IMAGE_VIEW_TYPE_2D:
3897 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
3898 case vk::VK_IMAGE_VIEW_TYPE_3D:
3900 const tcu::Vec3 coords[4] =
3904 (float)(12u % imageSize) + 0.25f),
3906 tcu::Vec3((float)(23u % imageSize) + 0.25f,
3907 (float)(73u % imageSize) + 0.5f,
3908 (float)(16u % imageSize) + 0.5f + (float)imageSize),
3910 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
3911 (float)(84u % imageSize) + 0.5f + (float)imageSize,
3912 (float)(117u % imageSize) + 0.75f),
3914 tcu::Vec3((float)imageSize + 0.5f,
3915 (float)(75u % imageSize) + 0.25f,
3916 (float)(83u % imageSize) + 0.25f + (float)imageSize),
3918 const deUint32 slices[4] =
3926 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3927 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3928 (float)slices[samplePosNdx],
3931 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
3932 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3933 coords[samplePosNdx].y() / (float)imageSize,
3934 (float)slices[samplePosNdx],
3936 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
3937 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3938 coords[samplePosNdx].y() / (float)imageSize,
3939 coords[samplePosNdx].z() / (float)imageSize,
3943 DE_FATAL("Impossible");
3948 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3949 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
3951 // \note these values are in [0, texSize]*3 space for convenience
3952 const tcu::Vec3 coords[4] =
3958 tcu::Vec3((float)(13u % imageSize) + 0.25f,
3960 (float)(16u % imageSize) + 0.5f),
3963 (float)(84u % imageSize) + 0.5f,
3964 (float)(10u % imageSize) + 0.75f),
3966 tcu::Vec3((float)imageSize,
3967 (float)(75u % imageSize) + 0.25f,
3968 (float)(83u % imageSize) + 0.75f),
3970 const deUint32 slices[4] =
3978 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
3979 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
3980 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
3982 // map to [-1, 1]*3 space
3983 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
3984 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
3985 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
3986 (float)slices[samplePosNdx]);
3990 DE_FATAL("Impossible");
3995 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
3997 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3999 // texture order is ABAB
4000 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
4001 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
4002 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
4003 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
4005 // sampler order is ABAB
4006 const tcu::Sampler& samplerA = m_refSamplerA;
4007 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
4008 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
4010 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
4011 const float lod = 0.0f;
4012 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
4016 case vk::VK_IMAGE_VIEW_TYPE_1D:
4017 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
4018 case vk::VK_IMAGE_VIEW_TYPE_2D:
4019 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);
4020 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
4021 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4022 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);
4026 DE_FATAL("Impossible");
4032 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
4034 // If we are testing separate samplers, just one image is enough
4035 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4037 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4039 // combined: numImages == numSamplers
4040 return getInterfaceNumResources(shaderInterface);
4044 DE_FATAL("Impossible");
4049 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4054 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4058 // nearest, clamping
4059 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4063 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4065 const bool compareEnabled = (sampler.compare != tcu::Sampler::COMPAREMODE_NONE);
4066 const vk::VkCompareOp compareOp = (compareEnabled) ? (mapToVkCompareOp(sampler.compare)) : (vk::VK_COMPARE_OP_ALWAYS);
4067 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4068 const bool isIntTexture = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4069 const vk::VkBorderColor borderColor = (isIntTexture) ? (vk::VK_BORDER_COLOR_INT_OPAQUE_WHITE) : (vk::VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE);
4070 const vk::VkSamplerCreateInfo createInfo =
4072 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
4074 mapMagFilterToVkTexFilter(sampler.magFilter), // magFilter
4075 mapMinFilterToVkTexFilter(sampler.minFilter), // minFilter
4076 mapMinFilterToVkTexMipmapMode(sampler.minFilter), // mipMode
4077 mapToVkTexAddressMode(sampler.wrapS), // addressU
4078 mapToVkTexAddressMode(sampler.wrapT), // addressV
4079 mapToVkTexAddressMode(sampler.wrapR), // addressW
4082 (compareEnabled) ? (vk::VkBool32)(vk::VK_TRUE) : (vk::VkBool32)(vk::VK_FALSE), // compareEnable
4083 compareOp, // compareOp
4086 borderColor, // borderColor
4087 vk::VK_FALSE, // unnormalizedCoords
4089 return vk::createSampler(vki, device, &createInfo);
4092 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4094 DE_ASSERT(levelStorage->empty());
4096 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4097 const deUint32 numLevels = (deUint32)source.getNumLevels();
4099 // cut pyramid from baseMipLevel
4100 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4102 // cut levels from baseArraySlice
4103 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4104 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4105 levelStorage->push_back(cutLevel);
4108 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4111 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4113 DE_ASSERT(levelStorage->empty());
4115 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4116 const deUint32 numLevels = (deUint32)source.getNumLevels();
4118 // cut pyramid from baseMipLevel
4119 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4121 // cut levels from baseArraySlice
4122 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4123 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4124 levelStorage->push_back(cutLevel);
4127 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4130 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4132 DE_ASSERT(levelStorage->empty());
4133 DE_ASSERT(baseArraySlice == 0);
4134 DE_UNREF(baseArraySlice);
4136 const deUint32 numLevels = (deUint32)source.getNumLevels();
4138 // cut pyramid from baseMipLevel
4139 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4140 levelStorage->push_back(source.getLevel(level));
4142 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
4145 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4147 DE_ASSERT(levelStorage->empty());
4149 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
4150 const deUint32 numLevels = (deUint32)source.getNumLevels();
4152 // cut pyramid from baseMipLevel
4153 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4155 // cut levels from baseArraySlice
4156 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4157 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
4158 levelStorage->push_back(cutLevel);
4161 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
4164 class ImageSampleRenderInstance : public SingleCmdRenderInstance
4167 ImageSampleRenderInstance (vkt::Context& context,
4168 bool isPrimaryCmdBuf,
4169 vk::VkDescriptorType descriptorType,
4170 vk::VkShaderStageFlags stageFlags,
4171 ShaderInputInterface shaderInterface,
4172 vk::VkImageViewType viewType,
4173 deUint32 baseMipLevel,
4174 deUint32 baseArraySlice,
4178 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
4179 vk::VkDevice device,
4180 vk::VkDescriptorType descriptorType,
4181 ShaderInputInterface shaderInterface,
4182 vk::VkShaderStageFlags stageFlags,
4183 const ImageSampleInstanceImages& images);
4185 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4186 vk::VkDevice device,
4187 vk::VkDescriptorSetLayout descriptorSetLayout);
4189 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4190 vk::VkDevice device,
4191 vk::VkDescriptorType descriptorType,
4192 ShaderInputInterface shaderInterface,
4195 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
4196 vk::VkDevice device,
4197 vk::VkDescriptorType descriptorType,
4198 ShaderInputInterface shaderInterface,
4199 vk::VkDescriptorSetLayout layout,
4200 vk::VkDescriptorPool pool,
4202 const ImageSampleInstanceImages& images);
4204 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4205 vk::VkDevice device,
4206 ShaderInputInterface shaderInterface,
4208 const ImageSampleInstanceImages& images,
4209 vk::VkDescriptorSet descriptorSet);
4211 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4212 vk::VkDevice device,
4213 ShaderInputInterface shaderInterface,
4215 const ImageSampleInstanceImages& images,
4216 vk::VkDescriptorSet descriptorSet);
4218 void logTestPlan (void) const;
4219 vk::VkPipelineLayout getPipelineLayout (void) const;
4220 void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const;
4221 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4228 const vk::VkDescriptorType m_descriptorType;
4229 const vk::VkShaderStageFlags m_stageFlags;
4230 const ShaderInputInterface m_shaderInterface;
4231 const vk::VkImageViewType m_viewType;
4232 const deUint32 m_baseMipLevel;
4233 const deUint32 m_baseArraySlice;
4235 const ImageSampleInstanceImages m_images;
4236 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
4237 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4238 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4239 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
4242 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
4243 bool isPrimaryCmdBuf,
4244 vk::VkDescriptorType descriptorType,
4245 vk::VkShaderStageFlags stageFlags,
4246 ShaderInputInterface shaderInterface,
4247 vk::VkImageViewType viewType,
4248 deUint32 baseMipLevel,
4249 deUint32 baseArraySlice,
4251 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4252 , m_descriptorType (descriptorType)
4253 , m_stageFlags (stageFlags)
4254 , m_shaderInterface (shaderInterface)
4255 , m_viewType (viewType)
4256 , m_baseMipLevel (baseMipLevel)
4257 , m_baseArraySlice (baseArraySlice)
4258 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
4259 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images))
4260 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
4261 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface, isImmutable))
4262 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, isImmutable, m_images))
4266 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
4267 vk::VkDevice device,
4268 vk::VkDescriptorType descriptorType,
4269 ShaderInputInterface shaderInterface,
4270 vk::VkShaderStageFlags stageFlags,
4271 const ImageSampleInstanceImages& images)
4273 const vk::VkSampler samplers[2] =
4275 images.getSamplerA(),
4276 images.getSamplerB(),
4279 vk::DescriptorSetLayoutBuilder builder;
4281 // with samplers, separate texture at binding 0
4282 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4283 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4285 // (combined)samplers follow
4286 switch (shaderInterface)
4288 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4289 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4292 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4293 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4294 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4297 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4298 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
4302 DE_FATAL("Impossible");
4305 return builder.build(vki, device);
4308 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4309 vk::VkDevice device,
4310 vk::VkDescriptorSetLayout descriptorSetLayout)
4312 const vk::VkPipelineLayoutCreateInfo createInfo =
4314 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4316 1, // descriptorSetCount
4317 &descriptorSetLayout, // pSetLayouts
4318 0u, // pushConstantRangeCount
4319 DE_NULL, // pPushConstantRanges
4321 return vk::createPipelineLayout(vki, device, &createInfo);
4324 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4325 vk::VkDevice device,
4326 vk::VkDescriptorType descriptorType,
4327 ShaderInputInterface shaderInterface,
4330 vk::DescriptorPoolBuilder builder;
4332 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4334 // separate samplers need image to sample
4335 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4337 // samplers needed only if they are specified in the descriptor set
4339 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
4341 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4343 // combined image samplers
4344 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
4347 DE_FATAL("Impossible");
4349 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
4352 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
4353 vk::VkDevice device,
4354 vk::VkDescriptorType descriptorType,
4355 ShaderInputInterface shaderInterface,
4356 vk::VkDescriptorSetLayout layout,
4357 vk::VkDescriptorPool pool,
4359 const ImageSampleInstanceImages& images)
4361 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(vki, device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
4363 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4364 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4365 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4366 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4368 DE_FATAL("Impossible");
4370 return descriptorSet;
4373 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4374 vk::VkDevice device,
4375 ShaderInputInterface shaderInterface,
4377 const ImageSampleInstanceImages& images,
4378 vk::VkDescriptorSet descriptorSet)
4380 const vk::VkDescriptorInfo imageInfo = createDescriptorInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4381 const vk::VkDescriptorInfo samplersInfos[2] =
4383 createDescriptorInfo(images.getSamplerA()),
4384 createDescriptorInfo(images.getSamplerB()),
4387 vk::DescriptorSetUpdateBuilder builder;
4389 // stand alone texture
4390 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4395 switch (shaderInterface)
4397 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4398 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4401 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4402 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4403 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4406 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4407 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4411 DE_FATAL("Impossible");
4415 builder.update(vki, device);
4418 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4419 vk::VkDevice device,
4420 ShaderInputInterface shaderInterface,
4422 const ImageSampleInstanceImages& images,
4423 vk::VkDescriptorSet descriptorSet)
4425 const vk::VkSampler samplers[2] =
4427 (isImmutable) ? (0) : (images.getSamplerA()),
4428 (isImmutable) ? (0) : (images.getSamplerB()),
4430 const vk::VkDescriptorInfo imageSamplers[2] =
4432 createDescriptorInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4433 createDescriptorInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4436 vk::DescriptorSetUpdateBuilder builder;
4438 // combined image samplers
4439 switch (shaderInterface)
4441 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4442 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4445 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4446 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4447 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4450 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4451 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4455 DE_FATAL("Impossible");
4458 builder.update(vki, device);
4461 void ImageSampleRenderInstance::logTestPlan (void) const
4463 std::ostringstream msg;
4465 msg << "Rendering 2x2 grid.\n";
4467 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4469 msg << "Single descriptor set. Descriptor set contains "
4470 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4471 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4472 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4473 (const char*)DE_NULL)
4474 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4476 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4478 msg << "Single descriptor set. Descriptor set contains "
4479 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4480 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4481 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4482 (const char*)DE_NULL)
4483 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4486 DE_FATAL("Impossible");
4488 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4491 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4492 if (m_baseArraySlice)
4493 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4495 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4496 msg << "Sampler mode is LINEAR, with WRAP\n";
4498 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4500 if (m_stageFlags == 0u)
4502 msg << "Descriptors are not accessed in any shader stage.\n";
4506 msg << "Color in each cell is fetched using the descriptor(s):\n";
4508 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4510 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4512 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4514 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4516 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4517 msg << " using sampler " << srcResourceNdx;
4518 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4519 msg << " from combined image sampler " << srcResourceNdx;
4521 DE_FATAL("Impossible");
4526 msg << "Descriptors are accessed in {"
4527 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4528 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4529 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4530 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4531 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4535 m_context.getTestContext().getLog()
4536 << tcu::TestLog::Message
4538 << tcu::TestLog::EndMessage;
4541 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
4543 return *m_pipelineLayout;
4546 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const
4548 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4549 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
4552 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4554 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4555 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4556 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4557 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
4558 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
4559 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
4560 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
4561 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
4562 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4564 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4566 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
4567 return tcu::TestStatus::fail("Image verification failed");
4569 return tcu::TestStatus::pass("Pass");
4572 class ImageSampleComputeInstance : public vkt::TestInstance
4575 ImageSampleComputeInstance (vkt::Context& context,
4576 vk::VkDescriptorType descriptorType,
4577 ShaderInputInterface shaderInterface,
4578 vk::VkImageViewType viewType,
4579 deUint32 baseMipLevel,
4580 deUint32 baseArraySlice,
4581 bool isImmutableSampler);
4584 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4585 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4586 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
4587 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4588 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4590 tcu::TestStatus iterate (void);
4591 void logTestPlan (void) const;
4592 tcu::TestStatus testResourceAccess (void);
4594 const vk::VkDescriptorType m_descriptorType;
4595 const ShaderInputInterface m_shaderInterface;
4596 const vk::VkImageViewType m_viewType;
4597 const deUint32 m_baseMipLevel;
4598 const deUint32 m_baseArraySlice;
4599 const bool m_isImmutableSampler;
4601 const vk::DeviceInterface& m_vki;
4602 const vk::VkDevice m_device;
4603 const vk::VkQueue m_queue;
4604 const deUint32 m_queueFamilyIndex;
4605 vk::Allocator& m_allocator;
4607 const ComputeInstanceResultBuffer m_result;
4608 const ImageSampleInstanceImages m_images;
4611 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
4612 vk::VkDescriptorType descriptorType,
4613 ShaderInputInterface shaderInterface,
4614 vk::VkImageViewType viewType,
4615 deUint32 baseMipLevel,
4616 deUint32 baseArraySlice,
4617 bool isImmutableSampler)
4618 : vkt::TestInstance (context)
4619 , m_descriptorType (descriptorType)
4620 , m_shaderInterface (shaderInterface)
4621 , m_viewType (viewType)
4622 , m_baseMipLevel (baseMipLevel)
4623 , m_baseArraySlice (baseArraySlice)
4624 , m_isImmutableSampler (isImmutableSampler)
4625 , m_vki (context.getDeviceInterface())
4626 , m_device (context.getDevice())
4627 , m_queue (context.getUniversalQueue())
4628 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4629 , m_allocator (context.getDefaultAllocator())
4630 , m_result (m_vki, m_device, m_allocator)
4631 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
4635 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
4637 const vk::VkSampler samplers[2] =
4639 m_images.getSamplerA(),
4640 m_images.getSamplerB(),
4643 vk::DescriptorSetLayoutBuilder builder;
4646 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4648 // with samplers, separate texture at binding 0
4649 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4650 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4652 // (combined)samplers follow
4653 switch (m_shaderInterface)
4655 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4656 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4659 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4660 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4661 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4664 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4665 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
4669 DE_FATAL("Impossible");
4672 return builder.build(m_vki, m_device);
4675 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
4677 vk::DescriptorPoolBuilder builder;
4679 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
4680 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
4682 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4683 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4685 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
4688 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
4690 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
4692 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4693 writeSamplerDescriptorSet(*descriptorSet);
4694 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4695 writeImageSamplerDescriptorSet(*descriptorSet);
4697 DE_FATAL("Impossible");
4699 return descriptorSet;
4702 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4704 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4705 const vk::VkDescriptorInfo imageInfo = createDescriptorInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4706 const vk::VkDescriptorInfo samplersInfos[2] =
4708 createDescriptorInfo(m_images.getSamplerA()),
4709 createDescriptorInfo(m_images.getSamplerB()),
4712 vk::DescriptorSetUpdateBuilder builder;
4715 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4717 // stand alone texture
4718 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4721 if (!m_isImmutableSampler)
4723 switch (m_shaderInterface)
4725 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4726 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4729 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4730 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4731 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4734 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4735 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4739 DE_FATAL("Impossible");
4743 builder.update(m_vki, m_device);
4746 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4748 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4749 const vk::VkSampler samplers[2] =
4751 (m_isImmutableSampler) ? (0) : (m_images.getSamplerA()),
4752 (m_isImmutableSampler) ? (0) : (m_images.getSamplerB()),
4754 const vk::VkDescriptorInfo imageSamplers[2] =
4756 createDescriptorInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4757 createDescriptorInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4760 vk::DescriptorSetUpdateBuilder builder;
4763 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4765 // combined image samplers
4766 switch (m_shaderInterface)
4768 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4769 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4772 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4773 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4774 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4777 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4778 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4782 DE_FATAL("Impossible");
4785 builder.update(m_vki, m_device);
4788 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
4791 return testResourceAccess();
4794 void ImageSampleComputeInstance::logTestPlan (void) const
4796 std::ostringstream msg;
4798 msg << "Accessing resource in a compute program.\n";
4800 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4802 msg << "Single descriptor set. Descriptor set contains "
4803 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4804 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4805 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4806 (const char*)DE_NULL)
4807 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4809 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4811 msg << "Single descriptor set. Descriptor set contains "
4812 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4813 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4814 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4815 (const char*)DE_NULL)
4816 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4819 DE_FATAL("Impossible");
4821 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4824 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4825 if (m_baseArraySlice)
4826 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4828 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4829 msg << "Sampler mode is LINEAR, with WRAP\n";
4831 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4833 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4835 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4837 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4839 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4841 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4842 msg << " using sampler " << srcResourceNdx;
4843 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4844 msg << " from combined image sampler " << srcResourceNdx;
4846 DE_FATAL("Impossible");
4851 m_context.getTestContext().getLog()
4852 << tcu::TestLog::Message
4854 << tcu::TestLog::EndMessage;
4857 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
4859 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4860 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4861 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4862 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4864 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4865 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
4866 const deUint32* const dynamicOffsets = DE_NULL;
4867 const int numDynamicOffsets = 0;
4868 const void* const* preBarriers = DE_NULL;
4869 const int numPreBarriers = 0;
4870 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
4871 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
4873 const ComputeCommand compute (m_vki,
4875 pipeline.getPipeline(),
4876 pipeline.getPipelineLayout(),
4877 tcu::UVec3(4, 1, 1),
4878 numDescriptorSets, descriptorSets,
4879 numDynamicOffsets, dynamicOffsets,
4880 numPreBarriers, preBarriers,
4881 numPostBarriers, postBarriers);
4883 tcu::Vec4 results[4];
4884 bool anyResultSet = false;
4885 bool allResultsOk = true;
4887 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4888 m_result.readResultContentsTo(&results);
4891 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4893 const tcu::Vec4 result = results[resultNdx];
4894 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
4896 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
4897 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
4899 if (result != tcu::Vec4(-1.0f))
4900 anyResultSet = true;
4902 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
4904 allResultsOk = false;
4906 m_context.getTestContext().getLog()
4907 << tcu::TestLog::Message
4908 << "Test sample " << resultNdx << ":\n"
4909 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
4910 << "\tError expected " << reference << ", got " << result
4911 << tcu::TestLog::EndMessage;
4915 // read back and verify
4917 return tcu::TestStatus::pass("Pass");
4918 else if (anyResultSet)
4919 return tcu::TestStatus::fail("Invalid result values");
4922 m_context.getTestContext().getLog()
4923 << tcu::TestLog::Message
4924 << "Result buffer was not written to."
4925 << tcu::TestLog::EndMessage;
4926 return tcu::TestStatus::fail("Result buffer was not written to");
4930 class ImageDescriptorCase : public QuadrantRendederCase
4935 FLAG_BASE_MIP = (1u << 1u),
4936 FLAG_BASE_SLICE = (1u << 2u),
4938 // enum continues where resource flags ends
4939 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
4941 ImageDescriptorCase (tcu::TestContext& testCtx,
4943 const char* description,
4944 bool isPrimaryCmdBuf,
4945 vk::VkDescriptorType descriptorType,
4946 vk::VkShaderStageFlags exitingStages,
4947 vk::VkShaderStageFlags activeStages,
4948 ShaderInputInterface shaderInterface,
4949 vk::VkImageViewType viewType,
4953 std::string genExtensionDeclarations (vk::VkShaderStage stage) const;
4954 std::string genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const;
4955 std::string genFetchCoordStr (int fetchPosNdx) const;
4956 std::string genSampleCoordStr (int samplePosNdx) const;
4957 std::string genResourceAccessSource (vk::VkShaderStage stage) const;
4958 std::string genNoAccessSource (void) const;
4960 vkt::TestInstance* createInstance (vkt::Context& context) const;
4963 const bool m_isPrimaryCmdBuf;
4964 const vk::VkDescriptorType m_descriptorType;
4965 const ShaderInputInterface m_shaderInterface;
4966 const vk::VkImageViewType m_viewType;
4967 const deUint32 m_baseMipLevel;
4968 const deUint32 m_baseArraySlice;
4969 const bool m_isImmutableSampler;
4972 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
4974 const char* description,
4975 bool isPrimaryCmdBuf,
4976 vk::VkDescriptorType descriptorType,
4977 vk::VkShaderStageFlags exitingStages,
4978 vk::VkShaderStageFlags activeStages,
4979 ShaderInputInterface shaderInterface,
4980 vk::VkImageViewType viewType,
4982 : QuadrantRendederCase (testCtx, name, description,
4983 // \note 1D textures are not supported in ES
4984 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
4985 exitingStages, activeStages)
4986 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
4987 , m_descriptorType (descriptorType)
4988 , m_shaderInterface (shaderInterface)
4989 , m_viewType (viewType)
4990 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
4991 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
4992 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
4996 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStage stage) const
5000 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5001 return "#extension GL_OES_texture_cube_map_array : require\n";
5006 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const
5010 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
5011 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
5012 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
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) ? ("Cube")
5016 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5017 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5018 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5019 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5021 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
5023 switch (m_shaderInterface)
5025 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5027 switch (m_descriptorType)
5029 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5030 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n"
5031 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
5032 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5033 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
5034 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5035 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
5036 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5037 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
5039 DE_FATAL("invalid descriptor");
5044 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5045 switch (m_descriptorType)
5047 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5048 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n"
5049 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
5050 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5051 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5052 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
5053 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
5054 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5055 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
5056 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
5057 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5058 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
5059 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
5061 DE_FATAL("invalid descriptor");
5065 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5066 switch (m_descriptorType)
5068 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5069 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n"
5070 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplers[2];\n";
5071 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5072 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
5073 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5074 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
5075 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5076 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
5078 DE_FATAL("invalid descriptor");
5083 DE_FATAL("Impossible");
5088 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
5090 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
5091 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
5093 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5095 return de::toString(fetchPos.x());
5097 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5099 std::ostringstream buf;
5100 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
5105 std::ostringstream buf;
5106 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
5111 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
5113 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
5114 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5116 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5118 std::ostringstream buf;
5119 buf << "float(" << fetchPos.x() << ")";
5122 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5124 std::ostringstream buf;
5125 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
5128 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5130 std::ostringstream buf;
5131 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
5136 std::ostringstream buf;
5137 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
5142 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStage stage) const
5146 const char* const dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5147 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5148 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5149 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5151 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5152 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
5153 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
5155 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5156 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
5157 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
5160 switch (m_descriptorType)
5162 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5163 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5165 const std::string coodStr[4] =
5167 genSampleCoordStr(0),
5168 genSampleCoordStr(1),
5169 genSampleCoordStr(2),
5170 genSampleCoordStr(3),
5172 std::ostringstream buf;
5174 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5176 buf << " if (quadrant_id == 0)\n"
5177 << " result_color = textureLod(sampler" << dimensionArray << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
5178 << " else if (quadrant_id == 1)\n"
5179 << " result_color = textureLod(sampler" << dimensionArray << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
5180 << " else if (quadrant_id == 2)\n"
5181 << " result_color = textureLod(sampler" << dimensionArray << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
5183 << " result_color = textureLod(sampler" << dimensionArray << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
5187 buf << " if (quadrant_id == 0)\n"
5188 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
5189 << " else if (quadrant_id == 1)\n"
5190 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
5191 << " else if (quadrant_id == 2)\n"
5192 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
5194 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
5200 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5201 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5203 const std::string coodStr[4] =
5205 genFetchCoordStr(0),
5206 genFetchCoordStr(1),
5207 genFetchCoordStr(2),
5208 genFetchCoordStr(3),
5210 std::ostringstream buf;
5212 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
5214 buf << " if (quadrant_id == 0)\n"
5215 << " result_color = textureFetch(u_separateTexture" << accessPostfixA << ", " << coodStr[0] << ", 0);\n"
5216 << " else if (quadrant_id == 1)\n"
5217 << " result_color = textureFetch(u_separateTexture" << accessPostfixB << ", " << coodStr[1] << ", 0);\n"
5218 << " else if (quadrant_id == 2)\n"
5219 << " result_color = textureFetch(u_separateTexture" << accessPostfixA << ", " << coodStr[2] << ", 0);\n"
5221 << " result_color = textureFetch(u_separateTexture" << accessPostfixB << ", " << coodStr[3] << ", 0);\n";
5225 buf << " if (quadrant_id == 0)\n"
5226 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
5227 << " else if (quadrant_id == 1)\n"
5228 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
5229 << " else if (quadrant_id == 2)\n"
5230 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
5232 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
5239 DE_FATAL("invalid descriptor");
5244 std::string ImageDescriptorCase::genNoAccessSource (void) const
5246 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
5247 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5249 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
5252 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
5254 switch (m_descriptorType)
5256 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5257 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5258 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5260 DE_ASSERT(m_isPrimaryCmdBuf);
5261 return new ImageSampleComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5264 return new ImageSampleRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5266 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5267 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5268 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5270 DE_ASSERT(m_isPrimaryCmdBuf);
5271 return new ImageFetchComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5274 return new ImageFetchRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5277 DE_FATAL("Impossible");
5282 class TexelBufferInstanceBuffers
5285 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5286 vk::VkDevice device,
5287 vk::Allocator& allocator,
5288 vk::VkDescriptorType descriptorType,
5289 int numTexelBuffers,
5290 bool hasViewOffset);
5293 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
5294 vk::VkDevice device,
5295 vk::Allocator& allocator,
5296 vk::VkDescriptorType descriptorType,
5297 de::MovePtr<vk::Allocation> *outAllocation);
5299 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
5300 vk::VkDevice device,
5301 const tcu::TextureFormat& textureFormat,
5303 vk::VkBuffer buffer);
5305 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
5307 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
5308 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
5311 static int getFetchPos (int fetchPosNdx);
5312 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
5314 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
5315 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
5316 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
5317 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
5318 inline const void* getBufferInitBarrierA (void) const { return &m_bufferBarrierA; }
5319 inline const void* getBufferInitBarrierB (void) const { return &m_bufferBarrierB; }
5325 VIEW_OFFSET_VALUE = 256,
5326 VIEW_DATA_SIZE = 256, //!< size in bytes
5327 VIEW_WIDTH = 64, //!< size in pixels
5331 // some arbitrary points
5333 SAMPLE_POINT_1 = 51,
5334 SAMPLE_POINT_2 = 42,
5335 SAMPLE_POINT_3 = 25,
5338 const deUint32 m_numTexelBuffers;
5339 const tcu::TextureFormat m_imageFormat;
5340 const deUint32 m_viewOffset;
5342 de::ArrayBuffer<deUint8> m_sourceBufferA;
5343 de::ArrayBuffer<deUint8> m_sourceBufferB;
5344 const tcu::ConstPixelBufferAccess m_sourceViewA;
5345 const tcu::ConstPixelBufferAccess m_sourceViewB;
5347 de::MovePtr<vk::Allocation> m_bufferMemoryA;
5348 de::MovePtr<vk::Allocation> m_bufferMemoryB;
5349 const vk::Unique<vk::VkBuffer> m_bufferA;
5350 const vk::Unique<vk::VkBuffer> m_bufferB;
5351 const vk::Unique<vk::VkBufferView> m_bufferViewA;
5352 const vk::Unique<vk::VkBufferView> m_bufferViewB;
5353 const vk::VkBufferMemoryBarrier m_bufferBarrierA;
5354 const vk::VkBufferMemoryBarrier m_bufferBarrierB;
5357 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5358 vk::VkDevice device,
5359 vk::Allocator& allocator,
5360 vk::VkDescriptorType descriptorType,
5361 int numTexelBuffers,
5363 : m_numTexelBuffers (numTexelBuffers)
5364 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
5365 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
5366 , m_sourceBufferA (BUFFER_SIZE)
5367 , m_sourceBufferB ((numTexelBuffers == 1)
5369 : ((size_t)BUFFER_SIZE))
5370 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
5371 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
5372 , m_bufferMemoryA (DE_NULL)
5373 , m_bufferMemoryB (DE_NULL)
5374 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
5375 , m_bufferB ((numTexelBuffers == 1)
5376 ? vk::Move<vk::VkBuffer>()
5377 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
5378 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
5379 , m_bufferViewB ((numTexelBuffers == 1)
5380 ? vk::Move<vk::VkBufferView>()
5381 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
5382 , m_bufferBarrierA (createBarrier(descriptorType, *m_bufferA))
5383 , m_bufferBarrierB (createBarrier(descriptorType, *m_bufferB))
5385 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
5386 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
5387 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
5389 // specify and upload
5391 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
5392 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
5394 if (numTexelBuffers == 2)
5396 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
5397 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
5401 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
5402 vk::VkDevice device,
5403 vk::Allocator& allocator,
5404 vk::VkDescriptorType descriptorType,
5405 de::MovePtr<vk::Allocation> *outAllocation)
5407 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
5408 const vk::VkBufferCreateInfo createInfo =
5410 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
5412 (vk::VkDeviceSize)BUFFER_SIZE, // size
5415 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
5416 0u, // queueFamilyCount
5417 DE_NULL, // pQueueFamilyIndices
5419 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
5420 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
5422 *outAllocation = allocation;
5426 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
5427 vk::VkDevice device,
5428 const tcu::TextureFormat& textureFormat,
5430 vk::VkBuffer buffer)
5432 const vk::VkBufferViewCreateInfo createInfo =
5434 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
5437 mapToVkTextureFormat(textureFormat), // format
5438 (vk::VkDeviceSize)offset, // offset
5439 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
5441 return vk::createBufferView(vki, device, &createInfo);
5444 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
5446 const vk::VkMemoryInputFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_MEMORY_INPUT_UNIFORM_READ_BIT) : (vk::VK_MEMORY_INPUT_SHADER_READ_BIT);
5447 const vk::VkBufferMemoryBarrier barrier =
5449 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
5451 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
5452 inputBit, // inputMask
5453 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
5454 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
5457 (vk::VkDeviceSize)BUFFER_SIZE // size
5462 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
5464 DE_ASSERT(access.getHeight() == 1);
5465 DE_ASSERT(access.getDepth() == 1);
5467 const deInt32 width = access.getWidth();
5469 for (int x = 0; x < width; ++x)
5471 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
5472 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
5473 const int blue = 16 * (x % 16); //!< 16-long triangle wave
5475 DE_ASSERT(de::inRange(red, 0, 255));
5476 DE_ASSERT(de::inRange(green, 0, 255));
5477 DE_ASSERT(de::inRange(blue, 0, 255));
5479 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
5483 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
5485 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
5486 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
5489 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
5491 static const int fetchPositions[4] =
5498 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
5501 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
5503 // source order is ABAB
5504 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
5505 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
5506 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
5508 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
5511 class TexelBufferRenderInstance : public SingleCmdRenderInstance
5514 TexelBufferRenderInstance (vkt::Context& context,
5515 bool isPrimaryCmdBuf,
5516 vk::VkDescriptorType descriptorType,
5517 vk::VkShaderStageFlags stageFlags,
5518 ShaderInputInterface shaderInterface,
5519 bool nonzeroViewOffset);
5522 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
5523 vk::VkDevice device,
5524 vk::VkDescriptorType descriptorType,
5525 ShaderInputInterface shaderInterface,
5526 vk::VkShaderStageFlags stageFlags);
5528 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5529 vk::VkDevice device,
5530 vk::VkDescriptorSetLayout descriptorSetLayout);
5532 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5533 vk::VkDevice device,
5534 vk::VkDescriptorType descriptorType,
5535 ShaderInputInterface shaderInterface);
5537 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
5538 vk::VkDevice device,
5539 vk::VkDescriptorType descriptorType,
5540 ShaderInputInterface shaderInterface,
5541 vk::VkDescriptorSetLayout layout,
5542 vk::VkDescriptorPool pool,
5543 vk::VkBufferView viewA,
5544 vk::VkBufferView viewB);
5546 void logTestPlan (void) const;
5547 vk::VkPipelineLayout getPipelineLayout (void) const;
5548 void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const;
5549 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5556 const vk::VkDescriptorType m_descriptorType;
5557 const vk::VkShaderStageFlags m_stageFlags;
5558 const ShaderInputInterface m_shaderInterface;
5559 const bool m_nonzeroViewOffset;
5561 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5562 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5563 const TexelBufferInstanceBuffers m_texelBuffers;
5564 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5565 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5568 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
5569 bool isPrimaryCmdBuf,
5570 vk::VkDescriptorType descriptorType,
5571 vk::VkShaderStageFlags stageFlags,
5572 ShaderInputInterface shaderInterface,
5573 bool nonzeroViewOffset)
5574 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5575 , m_descriptorType (descriptorType)
5576 , m_stageFlags (stageFlags)
5577 , m_shaderInterface (shaderInterface)
5578 , m_nonzeroViewOffset (nonzeroViewOffset)
5579 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
5580 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5581 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5582 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5583 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_texelBuffers.getBufferViewA(), m_texelBuffers.getBufferViewB()))
5587 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5588 vk::VkDevice device,
5589 vk::VkDescriptorType descriptorType,
5590 ShaderInputInterface shaderInterface,
5591 vk::VkShaderStageFlags stageFlags)
5593 vk::DescriptorSetLayoutBuilder builder;
5595 switch (shaderInterface)
5597 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5598 builder.addSingleBinding(descriptorType, stageFlags);
5601 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5602 builder.addSingleBinding(descriptorType, stageFlags);
5603 builder.addSingleBinding(descriptorType, stageFlags);
5606 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5607 builder.addArrayBinding(descriptorType, 2u, stageFlags);
5611 DE_FATAL("Impossible");
5614 return builder.build(vki, device);
5617 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5618 vk::VkDevice device,
5619 vk::VkDescriptorSetLayout descriptorSetLayout)
5621 const vk::VkPipelineLayoutCreateInfo createInfo =
5623 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5625 1, // descriptorSetCount
5626 &descriptorSetLayout, // pSetLayouts
5627 0u, // pushConstantRangeCount
5628 DE_NULL, // pPushConstantRanges
5630 return vk::createPipelineLayout(vki, device, &createInfo);
5633 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5634 vk::VkDevice device,
5635 vk::VkDescriptorType descriptorType,
5636 ShaderInputInterface shaderInterface)
5638 return vk::DescriptorPoolBuilder()
5639 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
5640 .build(vki, device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
5643 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5644 vk::VkDevice device,
5645 vk::VkDescriptorType descriptorType,
5646 ShaderInputInterface shaderInterface,
5647 vk::VkDescriptorSetLayout layout,
5648 vk::VkDescriptorPool pool,
5649 vk::VkBufferView viewA,
5650 vk::VkBufferView viewB)
5652 const vk::VkDescriptorInfo texelBufferInfos[2] =
5654 createDescriptorInfo(viewA),
5655 createDescriptorInfo(viewB),
5658 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(vki, device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
5659 vk::DescriptorSetUpdateBuilder builder;
5661 switch (shaderInterface)
5663 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5664 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5667 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5668 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5669 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
5672 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5673 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
5677 DE_FATAL("Impossible");
5680 builder.update(vki, device);
5681 return descriptorSet;
5684 void TexelBufferRenderInstance::logTestPlan (void) const
5686 std::ostringstream msg;
5688 msg << "Rendering 2x2 grid.\n"
5689 << "Single descriptor set. Descriptor set contains "
5690 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5691 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5692 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5693 (const char*)DE_NULL)
5694 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5695 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5696 << "Buffer format is " << vk::getFormatName(mapToVkTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5698 if (m_stageFlags == 0u)
5700 msg << "Descriptors are not accessed in any shader stage.\n";
5704 msg << "Color in each cell is fetched using the descriptor(s):\n";
5706 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5708 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5710 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5712 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5713 msg << " from texelBuffer " << srcResourceNdx;
5719 msg << "Descriptors are accessed in {"
5720 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5721 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5722 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5723 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5724 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5728 m_context.getTestContext().getLog()
5729 << tcu::TestLog::Message
5731 << tcu::TestLog::EndMessage;
5734 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
5736 return *m_pipelineLayout;
5739 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const
5741 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
5742 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
5745 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5747 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5748 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5749 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5750 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
5751 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
5752 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
5753 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
5754 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5756 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5758 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
5759 return tcu::TestStatus::fail("Image verification failed");
5761 return tcu::TestStatus::pass("Pass");
5764 class TexelBufferComputeInstance : public vkt::TestInstance
5767 TexelBufferComputeInstance (vkt::Context& context,
5768 vk::VkDescriptorType descriptorType,
5769 ShaderInputInterface shaderInterface,
5770 bool nonzeroViewOffset);
5773 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5774 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5775 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
5777 tcu::TestStatus iterate (void);
5778 void logTestPlan (void) const;
5779 tcu::TestStatus testResourceAccess (void);
5781 const vk::VkDescriptorType m_descriptorType;
5782 const ShaderInputInterface m_shaderInterface;
5783 const bool m_nonzeroViewOffset;
5785 const vk::DeviceInterface& m_vki;
5786 const vk::VkDevice m_device;
5787 const vk::VkQueue m_queue;
5788 const deUint32 m_queueFamilyIndex;
5789 vk::Allocator& m_allocator;
5791 const ComputeInstanceResultBuffer m_result;
5792 const TexelBufferInstanceBuffers m_texelBuffers;
5795 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
5796 vk::VkDescriptorType descriptorType,
5797 ShaderInputInterface shaderInterface,
5798 bool nonzeroViewOffset)
5799 : vkt::TestInstance (context)
5800 , m_descriptorType (descriptorType)
5801 , m_shaderInterface (shaderInterface)
5802 , m_nonzeroViewOffset (nonzeroViewOffset)
5803 , m_vki (context.getDeviceInterface())
5804 , m_device (context.getDevice())
5805 , m_queue (context.getUniversalQueue())
5806 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5807 , m_allocator (context.getDefaultAllocator())
5808 , m_result (m_vki, m_device, m_allocator)
5809 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5813 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
5815 vk::DescriptorSetLayoutBuilder builder;
5817 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5819 switch (m_shaderInterface)
5821 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5822 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5825 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5826 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5827 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5830 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5831 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5835 DE_FATAL("Impossible");
5838 return builder.build(m_vki, m_device);
5841 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
5843 return vk::DescriptorPoolBuilder()
5844 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
5845 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
5846 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
5849 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
5851 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5852 const vk::VkDescriptorInfo texelBufferInfos[2] =
5854 createDescriptorInfo(m_texelBuffers.getBufferViewA()),
5855 createDescriptorInfo(m_texelBuffers.getBufferViewB()),
5858 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
5859 vk::DescriptorSetUpdateBuilder builder;
5862 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5865 switch (m_shaderInterface)
5867 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5868 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5871 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5872 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5873 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
5876 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5877 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
5881 DE_FATAL("Impossible");
5884 builder.update(m_vki, m_device);
5885 return descriptorSet;
5888 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
5891 return testResourceAccess();
5894 void TexelBufferComputeInstance::logTestPlan (void) const
5896 std::ostringstream msg;
5898 msg << "Fetching 4 values from image in compute shader.\n"
5899 << "Single descriptor set. Descriptor set contains "
5900 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5901 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5902 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5903 (const char*)DE_NULL)
5904 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5905 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5906 << "Buffer format is " << vk::getFormatName(mapToVkTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5908 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5910 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5912 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5914 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5915 msg << " from texelBuffer " << srcResourceNdx;
5921 m_context.getTestContext().getLog()
5922 << tcu::TestLog::Message
5924 << tcu::TestLog::EndMessage;
5927 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
5929 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
5930 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5931 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
5932 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
5934 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
5935 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
5936 const deUint32* const dynamicOffsets = DE_NULL;
5937 const int numDynamicOffsets = 0;
5938 const void* const preBarriers[] = { m_texelBuffers.getBufferInitBarrierA(), m_texelBuffers.getBufferInitBarrierB() };
5939 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
5940 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
5941 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
5943 const ComputeCommand compute (m_vki,
5945 pipeline.getPipeline(),
5946 pipeline.getPipelineLayout(),
5947 tcu::UVec3(4, 1, 1),
5948 numDescriptorSets, descriptorSets,
5949 numDynamicOffsets, dynamicOffsets,
5950 numPreBarriers, preBarriers,
5951 numPostBarriers, postBarriers);
5953 tcu::Vec4 results[4];
5954 bool anyResultSet = false;
5955 bool allResultsOk = true;
5957 compute.submitAndWait(m_queueFamilyIndex, m_queue);
5958 m_result.readResultContentsTo(&results);
5961 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5963 const tcu::Vec4 result = results[resultNdx];
5964 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
5965 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
5967 if (result != tcu::Vec4(-1.0f))
5968 anyResultSet = true;
5970 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
5972 allResultsOk = false;
5974 m_context.getTestContext().getLog()
5975 << tcu::TestLog::Message
5976 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
5977 << tcu::TestLog::EndMessage;
5981 // read back and verify
5983 return tcu::TestStatus::pass("Pass");
5984 else if (anyResultSet)
5985 return tcu::TestStatus::fail("Invalid result values");
5988 m_context.getTestContext().getLog()
5989 << tcu::TestLog::Message
5990 << "Result buffer was not written to."
5991 << tcu::TestLog::EndMessage;
5992 return tcu::TestStatus::fail("Result buffer was not written to");
5996 class TexelBufferDescriptorCase : public QuadrantRendederCase
6001 FLAG_VIEW_OFFSET = (1u << 1u),
6003 // enum continues where resource flags ends
6004 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
6006 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6008 const char* description,
6009 bool isPrimaryCmdBuf,
6010 vk::VkDescriptorType descriptorType,
6011 vk::VkShaderStageFlags exitingStages,
6012 vk::VkShaderStageFlags activeStages,
6013 ShaderInputInterface shaderInterface,
6017 std::string genExtensionDeclarations (vk::VkShaderStage stage) const;
6018 std::string genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const;
6019 std::string genResourceAccessSource (vk::VkShaderStage stage) const;
6020 std::string genNoAccessSource (void) const;
6022 vkt::TestInstance* createInstance (vkt::Context& context) const;
6024 const bool m_isPrimaryCmdBuf;
6025 const vk::VkDescriptorType m_descriptorType;
6026 const ShaderInputInterface m_shaderInterface;
6027 const bool m_nonzeroViewOffset;
6030 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6032 const char* description,
6033 bool isPrimaryCmdBuf,
6034 vk::VkDescriptorType descriptorType,
6035 vk::VkShaderStageFlags exitingStages,
6036 vk::VkShaderStageFlags activeStages,
6037 ShaderInputInterface shaderInterface,
6039 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
6040 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6041 , m_descriptorType (descriptorType)
6042 , m_shaderInterface (shaderInterface)
6043 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
6047 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStage stage) const
6050 return "#extension GL_EXT_texture_buffer : require\n";
6053 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const
6057 const bool isUniform = isUniformDescriptorType(m_descriptorType);
6058 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
6059 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
6061 switch (m_shaderInterface)
6063 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6064 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
6066 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
6067 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
6068 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
6070 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6071 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
6074 DE_FATAL("Impossible");
6079 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStage stage) const
6083 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6084 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
6085 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6087 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6088 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
6089 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6091 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
6092 std::ostringstream buf;
6094 buf << " if (quadrant_id == 0)\n"
6095 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
6096 << " else if (quadrant_id == 1)\n"
6097 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
6098 << " else if (quadrant_id == 2)\n"
6099 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
6101 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
6106 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
6108 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6109 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6111 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6114 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
6116 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6118 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
6119 return new TexelBufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
6122 return new TexelBufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
6125 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
6126 bool isPrimaryCmdBuf,
6127 vk::VkDescriptorType descriptorType,
6128 vk::VkShaderStageFlags exitingStages,
6129 vk::VkShaderStageFlags activeStages,
6130 ShaderInputInterface dimension,
6131 deUint32 resourceFlags)
6135 vk::VkImageViewType viewType;
6137 const char* description;
6141 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
6142 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6143 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6145 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
6146 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6147 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6149 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
6150 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6151 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6153 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
6154 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6155 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6157 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
6158 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6159 // no 3d array textures
6161 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
6162 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6163 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6165 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
6166 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6167 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6170 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
6173 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
6175 group->addChild(new ImageDescriptorCase(group->getTestContext(),
6176 s_imageTypes[ndx].name,
6177 s_imageTypes[ndx].description,
6183 s_imageTypes[ndx].viewType,
6184 s_imageTypes[ndx].flags | resourceFlags));
6188 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
6189 bool isPrimaryCmdBuf,
6190 vk::VkDescriptorType descriptorType,
6191 vk::VkShaderStageFlags exitingStages,
6192 vk::VkShaderStageFlags activeStages,
6193 ShaderInputInterface dimension,
6194 deUint32 resourceFlags)
6196 DE_ASSERT(resourceFlags == 0);
6197 DE_UNREF(resourceFlags);
6202 const char* description;
6204 } s_texelBufferTypes[] =
6206 { "offset_zero", "View offset is zero", 0u },
6207 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
6210 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
6212 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
6213 s_texelBufferTypes[ndx].name,
6214 s_texelBufferTypes[ndx].description,
6220 s_texelBufferTypes[ndx].flags));
6224 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
6225 bool isPrimaryCmdBuf,
6226 vk::VkDescriptorType descriptorType,
6227 vk::VkShaderStageFlags exitingStages,
6228 vk::VkShaderStageFlags activeStages,
6229 ShaderInputInterface dimension,
6230 deUint32 resourceFlags)
6232 DE_ASSERT(resourceFlags == 0u);
6233 DE_UNREF(resourceFlags);
6238 const char* description;
6239 bool isForDynamicCases;
6243 { "offset_view_zero", "View offset is zero", false, 0u },
6244 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6246 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6247 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
6248 { "offset_view_zero_dynamic_not_set", "View offset is zero, dynamic offset is not supplied", true, 0u },
6249 // \note no case for offset_view_nonzero_dynamic_zero since it doesn't produce any additional coverage
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 },
6251 { "offset_view_nonzero_dynamic_not_set", "View offset is non-zero, dynamic offset is not supplied", true, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6254 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
6256 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
6258 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
6259 group->addChild(new BufferDescriptorCase(group->getTestContext(),
6260 s_bufferTypes[ndx].name,
6261 s_bufferTypes[ndx].description,
6267 s_bufferTypes[ndx].flags));
6273 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
6277 const bool isPrimary;
6279 const char* description;
6282 { true, "primary_cmd_buf", "Bind in primary command buffer" },
6283 { false, "seconday_cmd_buf", "Bind in secondary command buffer" },
6287 const vk::VkDescriptorType descriptorType;
6289 const char* description;
6291 } s_descriptorTypes[] =
6293 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
6294 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6295 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
6296 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_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_TESS_CONTROL_BIT | vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6333 vk::VK_SHADER_STAGE_TESS_CONTROL_BIT,
6338 "Tessellation evaluation stage",
6339 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESS_CONTROL_BIT | vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6340 vk::VK_SHADER_STAGE_TESS_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_SAMPLED_IMAGE:
6418 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6419 createTestsFunc = createShaderAccessImageTests;
6422 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
6423 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
6424 createTestsFunc = createShaderAccessTexelBufferTests;
6427 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
6428 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
6429 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
6430 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
6431 createTestsFunc = createShaderAccessBufferTests;
6435 createTestsFunc = DE_NULL;
6436 DE_FATAL("Impossible");
6439 if (createTestsFunc)
6441 createTestsFunc(dimensionGroup.get(),
6442 s_bindTypes[bindTypeNdx].isPrimary,
6443 s_descriptorTypes[descriptorNdx].descriptorType,
6444 s_shaderStages[stageNdx].existingStages,
6445 s_shaderStages[stageNdx].activeStages,
6446 s_variableDimensions[dimensionNdx].dimension,
6447 s_descriptorTypes[descriptorNdx].flags);
6450 DE_FATAL("Impossible");
6452 stageGroup->addChild(dimensionGroup.release());
6455 typeGroup->addChild(stageGroup.release());
6459 bindGroup->addChild(typeGroup.release());
6462 group->addChild(bindGroup.release());
6465 return group.release();