1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Binding shader access tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktBindingShaderAccessTests.hpp"
26 #include "vktTestCase.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
41 #include "tcuVector.hpp"
42 #include "tcuVectorUtil.hpp"
43 #include "tcuTexture.hpp"
44 #include "tcuTextureUtil.hpp"
45 #include "tcuResultCollector.hpp"
46 #include "tcuTestLog.hpp"
47 #include "tcuRGBA.hpp"
48 #include "tcuSurface.hpp"
49 #include "tcuImageCompare.hpp"
51 #include "deUniquePtr.hpp"
52 #include "deSharedPtr.hpp"
53 #include "deStringUtil.hpp"
54 #include "deArrayUtil.hpp"
61 namespace BindingModel
68 RESOURCE_FLAG_IMMUTABLE_SAMPLER = (1u << 0u),
70 RESOURCE_FLAG_LAST = (1u << 1u)
73 enum DescriptorUpdateMethod
75 DESCRIPTOR_UPDATE_METHOD_NORMAL = 0, //!< use vkUpdateDescriptorSets
76 DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE, //!< use descriptor update templates
77 DESCRIPTOR_UPDATE_METHOD_WITH_PUSH, //!< use push descriptor updates
78 DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE, //!< use push descriptor update templates
80 DESCRIPTOR_UPDATE_METHOD_LAST
83 std::string stringifyDescriptorUpdateMethod(DescriptorUpdateMethod method)
87 case DESCRIPTOR_UPDATE_METHOD_NORMAL:
90 case DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE:
91 return "with_template";
93 case DESCRIPTOR_UPDATE_METHOD_WITH_PUSH:
96 case DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE:
97 return "with_push_template";
104 static const char* const s_quadrantGenVertexPosSource = " highp int quadPhase = gl_VertexIndex % 6;\n"
105 " highp int quadXcoord = int(quadPhase == 1 || quadPhase == 4 || quadPhase == 5);\n"
106 " highp int quadYcoord = int(quadPhase == 2 || quadPhase == 3 || quadPhase == 5);\n"
107 " highp int quadOriginX = (gl_VertexIndex / 6) % 2;\n"
108 " highp int quadOriginY = (gl_VertexIndex / 6) / 2;\n"
109 " quadrant_id = gl_VertexIndex / 6;\n"
110 " result_position = vec4(float(quadOriginX + quadXcoord - 1), float(quadOriginY + quadYcoord - 1), 0.0, 1.0);\n";
112 std::string genPerVertexBlock (const vk::VkShaderStageFlagBits stage, const glu::GLSLVersion version)
114 static const char* const block = "gl_PerVertex {\n"
115 " vec4 gl_Position;\n"
116 " float gl_PointSize;\n" // not used, but for compatibility with how implicit block is declared in ES
118 std::ostringstream str;
120 if (!glu::glslVersionIsES(version))
123 case vk::VK_SHADER_STAGE_VERTEX_BIT:
124 str << "out " << block << ";\n";
127 case vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
128 str << "in " << block << " gl_in[gl_MaxPatchVertices];\n"
129 << "out " << block << " gl_out[];\n";
132 case vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
133 str << "in " << block << " gl_in[gl_MaxPatchVertices];\n"
134 << "out " << block << ";\n";
137 case vk::VK_SHADER_STAGE_GEOMETRY_BIT:
138 str << "in " << block << " gl_in[];\n"
139 << "out " << block << ";\n";
149 bool isUniformDescriptorType (vk::VkDescriptorType type)
151 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
152 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
153 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
156 bool isDynamicDescriptorType (vk::VkDescriptorType type)
158 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || type == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
161 void verifyDriverSupport(const deUint32 apiVersion,
162 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
163 const std::vector<std::string>& deviceExtensions,
164 DescriptorUpdateMethod updateMethod,
165 vk::VkDescriptorType descType,
166 vk::VkShaderStageFlags activeStages,
167 vk::VkImageViewType viewType = vk::VK_IMAGE_VIEW_TYPE_2D)
169 std::vector<std::string> extensionNames;
170 size_t numExtensionsNeeded = 0;
172 switch (updateMethod)
174 case DESCRIPTOR_UPDATE_METHOD_WITH_PUSH:
175 extensionNames.push_back("VK_KHR_push_descriptor");
178 case DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE:
179 extensionNames.push_back("VK_KHR_push_descriptor");
181 case DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE:
182 if (!vk::isCoreDeviceExtension(apiVersion, "VK_KHR_descriptor_update_template"))
183 extensionNames.push_back("VK_KHR_descriptor_update_template");
186 case DESCRIPTOR_UPDATE_METHOD_NORMAL:
187 // no extensions needed
191 DE_FATAL("Impossible");
194 numExtensionsNeeded = extensionNames.size();
196 if (numExtensionsNeeded > 0)
198 for (size_t deviceExtNdx = 0; deviceExtNdx < deviceExtensions.size(); deviceExtNdx++)
200 for (size_t requiredExtNdx = 0; requiredExtNdx < extensionNames.size(); requiredExtNdx++)
202 if (deStringEqual(deviceExtensions[deviceExtNdx].c_str(), extensionNames[requiredExtNdx].c_str()))
204 --numExtensionsNeeded;
209 if (numExtensionsNeeded == 0)
213 if (numExtensionsNeeded > 0)
215 TCU_THROW(NotSupportedError, (stringifyDescriptorUpdateMethod(updateMethod) + " tests are not supported").c_str());
221 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
222 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
223 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
224 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
225 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
226 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
227 // These are supported in all stages
230 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
231 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
232 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
233 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
234 if (activeStages & (vk::VK_SHADER_STAGE_VERTEX_BIT |
235 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
236 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT |
237 vk::VK_SHADER_STAGE_GEOMETRY_BIT))
239 if (!deviceFeatures.vertexPipelineStoresAndAtomics)
240 TCU_THROW(NotSupportedError, (de::toString(descType) + " is not supported in the vertex pipeline").c_str());
243 if (activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT)
245 if (!deviceFeatures.fragmentStoresAndAtomics)
246 TCU_THROW(NotSupportedError, (de::toString(descType) + " is not supported in fragment shaders").c_str());
251 DE_FATAL("Impossible");
254 if (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY && !deviceFeatures.imageCubeArray)
255 TCU_THROW(NotSupportedError, "imageCubeArray feature not supported");
258 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type)
262 case vk::VK_IMAGE_VIEW_TYPE_1D:
263 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return vk::VK_IMAGE_TYPE_1D;
264 case vk::VK_IMAGE_VIEW_TYPE_2D:
265 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return vk::VK_IMAGE_TYPE_2D;
266 case vk::VK_IMAGE_VIEW_TYPE_3D: return vk::VK_IMAGE_TYPE_3D;
267 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
268 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return vk::VK_IMAGE_TYPE_2D;
271 DE_FATAL("Impossible");
272 return (vk::VkImageType)0;
276 vk::VkImageLayout getImageLayoutForDescriptorType (vk::VkDescriptorType descType)
278 if (descType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
279 return vk::VK_IMAGE_LAYOUT_GENERAL;
281 return vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
284 deUint32 getTextureLevelPyramidDataSize (const tcu::TextureLevelPyramid& srcImage)
286 deUint32 dataSize = 0;
287 for (int level = 0; level < srcImage.getNumLevels(); ++level)
289 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
292 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
294 dataSize += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
299 void writeTextureLevelPyramidData (void* dst, deUint32 dstLen, const tcu::TextureLevelPyramid& srcImage, vk::VkImageViewType viewType, std::vector<vk::VkBufferImageCopy>* copySlices)
301 // \note cube is copied face-by-face
302 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (srcImage.getLevel(0).getHeight()) :
303 (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
304 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
305 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
307 deUint32 levelOffset = 0;
309 DE_ASSERT(arraySize != 0);
311 for (int level = 0; level < srcImage.getNumLevels(); ++level)
313 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
314 const tcu::PixelBufferAccess dstAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), (deUint8*)dst + levelOffset);
315 const deUint32 dataSize = srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
316 const deUint32 sliceDataSize = dataSize / arraySize;
317 const deInt32 sliceHeight = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (srcAccess.getHeight());
318 const deInt32 sliceDepth = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (srcAccess.getDepth()) : (1);
319 const tcu::IVec3 sliceSize (srcAccess.getWidth(), sliceHeight, sliceDepth);
322 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
324 for (int sliceNdx = 0; sliceNdx < (int)arraySize; ++sliceNdx)
326 const vk::VkBufferImageCopy copySlice =
328 (vk::VkDeviceSize)levelOffset + sliceNdx * sliceDataSize, // bufferOffset
329 (deUint32)sliceSize.x(), // bufferRowLength
330 (deUint32)sliceSize.y(), // bufferImageHeight
332 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
333 (deUint32)level, // mipLevel
334 (deUint32)sliceNdx, // arrayLayer
336 }, // imageSubresource
343 (deUint32)sliceSize.x(),
344 (deUint32)sliceSize.y(),
345 (deUint32)sliceSize.z(),
348 copySlices->push_back(copySlice);
351 DE_ASSERT(arraySize * sliceDataSize == dataSize);
353 tcu::copy(dstAccess, srcAccess);
354 levelOffset += dataSize;
357 DE_ASSERT(dstLen == levelOffset);
361 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement)
363 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer);
364 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
366 VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
370 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkImage image, vk::MemoryRequirement requirement)
372 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vki, device, image);
373 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
375 VK_CHECK(vki.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
379 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkSampler sampler)
381 return vk::makeDescriptorImageInfo(sampler, (vk::VkImageView)0, (vk::VkImageLayout)0);
384 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkImageView imageView, vk::VkImageLayout layout)
386 return vk::makeDescriptorImageInfo((vk::VkSampler)0, imageView, layout);
389 void drawQuadrantReferenceResult (const tcu::PixelBufferAccess& dst, const tcu::Vec4& c1, const tcu::Vec4& c2, const tcu::Vec4& c3, const tcu::Vec4& c4)
391 tcu::clear(tcu::getSubregion(dst, 0, 0, dst.getWidth() / 2, dst.getHeight() / 2), c1);
392 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, 0, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() / 2), c2);
393 tcu::clear(tcu::getSubregion(dst, 0, dst.getHeight() / 2, dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c3);
394 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, dst.getHeight() / 2, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c4);
397 #ifndef CTS_USES_VULKANSC
398 static const vk::VkDescriptorUpdateTemplateEntry createTemplateBinding (deUint32 binding, deUint32 arrayElement, deUint32 descriptorCount, vk::VkDescriptorType descriptorType, size_t offset, size_t stride)
400 const vk::VkDescriptorUpdateTemplateEntry updateBinding =
410 return updateBinding;
413 class RawUpdateRegistry
416 RawUpdateRegistry (void);
418 template<typename Type>
419 void addWriteObject (const Type& updateObject);
420 size_t getWriteObjectOffset (const deUint32 objectId);
421 const deUint8* getRawPointer () const;
425 std::vector<deUint8> m_updateEntries;
426 std::vector<size_t> m_updateEntryOffsets;
430 RawUpdateRegistry::RawUpdateRegistry (void)
432 , m_updateEntryOffsets()
437 template<typename Type>
438 void RawUpdateRegistry::addWriteObject (const Type& updateObject)
440 m_updateEntryOffsets.push_back(m_nextOffset);
442 // in this case, elements <=> bytes
443 m_updateEntries.resize(m_nextOffset + sizeof(updateObject));
444 Type* t = reinterpret_cast<Type*>(m_updateEntries.data() + m_nextOffset);
446 m_nextOffset += sizeof(updateObject);
449 size_t RawUpdateRegistry::getWriteObjectOffset (const deUint32 objectId)
451 return m_updateEntryOffsets[objectId];
454 const deUint8* RawUpdateRegistry::getRawPointer () const
456 return m_updateEntries.data();
460 class SingleTargetRenderInstance : public vkt::TestInstance
463 SingleTargetRenderInstance (Context& context,
464 const tcu::UVec2& size);
467 static vk::Move<vk::VkImage> createColorAttachment (const vk::DeviceInterface& vki,
469 vk::Allocator& allocator,
470 const tcu::TextureFormat& format,
471 const tcu::UVec2& size,
472 de::MovePtr<vk::Allocation>* outAllocation);
474 static vk::Move<vk::VkImageView> createColorAttachmentView (const vk::DeviceInterface& vki,
476 const tcu::TextureFormat& format,
479 static vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vki,
481 vk::VkRenderPass renderpass,
482 vk::VkImageView colorAttachmentView,
483 const tcu::UVec2& size);
485 static vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vki,
487 deUint32 queueFamilyIndex);
489 virtual void logTestPlan (void) const = 0;
490 virtual void renderToTarget (void) = 0;
491 virtual tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const = 0;
493 void readRenderTarget (tcu::TextureLevel& dst);
494 tcu::TestStatus iterate (void);
497 const tcu::TextureFormat m_targetFormat;
498 const tcu::UVec2 m_targetSize;
500 const vk::DeviceInterface& m_vki;
501 const vk::VkDevice m_device;
502 const vk::VkQueue m_queue;
503 const deUint32 m_queueFamilyIndex;
504 vk::Allocator& m_allocator;
505 de::MovePtr<vk::Allocation> m_colorAttachmentMemory;
506 const vk::Unique<vk::VkImage> m_colorAttachmentImage;
507 const vk::Unique<vk::VkImageView> m_colorAttachmentView;
508 const vk::Unique<vk::VkRenderPass> m_renderPass;
509 const vk::Unique<vk::VkFramebuffer> m_framebuffer;
510 const vk::Unique<vk::VkCommandPool> m_cmdPool;
512 bool m_firstIteration;
515 SingleTargetRenderInstance::SingleTargetRenderInstance (Context& context,
516 const tcu::UVec2& size)
517 : vkt::TestInstance (context)
518 , m_targetFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
519 , m_targetSize (size)
520 , m_vki (context.getDeviceInterface())
521 , m_device (context.getDevice())
522 , m_queue (context.getUniversalQueue())
523 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
524 , m_allocator (context.getDefaultAllocator())
525 , m_colorAttachmentMemory (DE_NULL)
526 , m_colorAttachmentImage (createColorAttachment(m_vki, m_device, m_allocator, m_targetFormat, m_targetSize, &m_colorAttachmentMemory))
527 , m_colorAttachmentView (createColorAttachmentView(m_vki, m_device, m_targetFormat, *m_colorAttachmentImage))
528 , m_renderPass (makeRenderPass(m_vki, m_device, vk::mapTextureFormat(m_targetFormat)))
529 , m_framebuffer (createFramebuffer(m_vki, m_device, *m_renderPass, *m_colorAttachmentView, m_targetSize))
530 , m_cmdPool (createCommandPool(m_vki, m_device, context.getUniversalQueueFamilyIndex()))
531 , m_firstIteration (true)
535 vk::Move<vk::VkImage> SingleTargetRenderInstance::createColorAttachment (const vk::DeviceInterface& vki,
537 vk::Allocator& allocator,
538 const tcu::TextureFormat& format,
539 const tcu::UVec2& size,
540 de::MovePtr<vk::Allocation>* outAllocation)
542 const vk::VkImageCreateInfo imageInfo =
544 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
546 (vk::VkImageCreateFlags)0,
547 vk::VK_IMAGE_TYPE_2D, // imageType
548 vk::mapTextureFormat(format), // format
549 { size.x(), size.y(), 1u }, // extent
552 vk::VK_SAMPLE_COUNT_1_BIT, // samples
553 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
554 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
555 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
556 0u, // queueFamilyCount
557 DE_NULL, // pQueueFamilyIndices
558 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
561 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &imageInfo));
562 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any));
564 *outAllocation = allocation;
568 vk::Move<vk::VkImageView> SingleTargetRenderInstance::createColorAttachmentView (const vk::DeviceInterface& vki,
570 const tcu::TextureFormat& format,
573 const vk::VkImageViewCreateInfo createInfo =
575 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
577 (vk::VkImageViewCreateFlags)0,
579 vk::VK_IMAGE_VIEW_TYPE_2D, // viewType
580 vk::mapTextureFormat(format), // format
581 vk::makeComponentMappingRGBA(),
583 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
586 0u, // baseArrayLayer
591 return vk::createImageView(vki, device, &createInfo);
594 vk::Move<vk::VkFramebuffer> SingleTargetRenderInstance::createFramebuffer (const vk::DeviceInterface& vki,
596 vk::VkRenderPass renderpass,
597 vk::VkImageView colorAttachmentView,
598 const tcu::UVec2& size)
600 const vk::VkFramebufferCreateInfo framebufferCreateInfo =
602 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
604 (vk::VkFramebufferCreateFlags)0,
605 renderpass, // renderPass
606 1u, // attachmentCount
607 &colorAttachmentView, // pAttachments
613 return vk::createFramebuffer(vki, device, &framebufferCreateInfo);
616 vk::Move<vk::VkCommandPool> SingleTargetRenderInstance::createCommandPool (const vk::DeviceInterface& vki,
618 deUint32 queueFamilyIndex)
620 return vk::createCommandPool(vki, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
623 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
625 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
626 const vk::VkBufferCreateInfo bufferCreateInfo =
628 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
631 pixelDataSize, // size
632 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
633 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
634 0u, // queueFamilyCount
635 DE_NULL, // pQueueFamilyIndices
637 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
639 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
641 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
643 // copy content to buffer
644 beginCommandBuffer(m_vki, *cmd);
645 copyImageToBuffer(m_vki, *cmd, *m_colorAttachmentImage, *buffer, tcu::IVec2(m_targetSize.x(), m_targetSize.y()));
646 endCommandBuffer(m_vki, *cmd);
648 submitCommandsAndWait(m_vki, m_device, m_queue, cmd.get());
650 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
653 invalidateAlloc(m_vki, m_device, *bufferMemory);
654 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
657 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
659 tcu::TextureLevel resultImage;
662 if (m_firstIteration)
665 m_firstIteration = false;
670 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
671 const vk::VkImageSubresourceRange fullSubrange =
673 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
676 0u, // baseArraySlice
679 const vk::VkImageMemoryBarrier imageBarrier =
681 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
684 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
685 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
686 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
687 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
688 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
689 *m_colorAttachmentImage, // image
690 fullSubrange, // subresourceRange
693 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
695 beginCommandBuffer(m_vki, *cmd);
696 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0,
697 0, (const vk::VkMemoryBarrier*)DE_NULL,
698 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
700 endCommandBuffer(m_vki, *cmd);
702 submitCommandsAndWait(m_vki, m_device, m_queue, cmd.get());
708 readRenderTarget(resultImage);
709 #ifdef CTS_USES_VULKANSC
710 // skip costly verification in main process
711 if (!m_context.getTestContext().getCommandLine().isSubProcess())
712 return tcu::TestStatus::pass("Success");
713 #endif // CTS_USES_VULKANSC
714 return verifyResultImage(resultImage.getAccess());
717 class RenderInstanceShaders
720 RenderInstanceShaders (const vk::DeviceInterface& vki,
722 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
723 const vk::BinaryCollection& programCollection);
725 inline bool hasTessellationStage (void) const { return *m_tessCtrlShaderModule != 0 || *m_tessEvalShaderModule != 0; }
726 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
727 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
730 void addStage (const vk::DeviceInterface& vki,
732 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
733 const vk::BinaryCollection& programCollection,
735 vk::VkShaderStageFlagBits stage,
736 vk::Move<vk::VkShaderModule>* outModule);
738 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const;
740 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
741 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
742 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
743 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
744 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
745 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
748 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
750 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
751 const vk::BinaryCollection& programCollection)
753 addStage(vki, device, deviceFeatures, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX_BIT, &m_vertexShaderModule);
754 addStage(vki, device, deviceFeatures, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessCtrlShaderModule);
755 addStage(vki, device, deviceFeatures, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvalShaderModule);
756 addStage(vki, device, deviceFeatures, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule);
757 addStage(vki, device, deviceFeatures, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule);
759 DE_ASSERT(!m_stageInfos.empty());
762 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
764 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
765 const vk::BinaryCollection& programCollection,
767 vk::VkShaderStageFlagBits stage,
768 vk::Move<vk::VkShaderModule>* outModule)
770 if (programCollection.contains(name))
772 if (vk::isShaderStageSupported(deviceFeatures, stage))
774 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
776 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *module));
781 // Wait for the GPU to idle so that throwing the exception
782 // below doesn't free in-use GPU resource.
783 vki.deviceWaitIdle(device);
784 TCU_THROW(NotSupportedError, (de::toString(stage) + " is not supported").c_str());
789 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const
791 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
793 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
795 (vk::VkPipelineShaderStageCreateFlags)0,
799 DE_NULL, // pSpecializationInfo
801 return stageCreateInfo;
804 class SingleCmdRenderInstance : public SingleTargetRenderInstance
807 SingleCmdRenderInstance (Context& context,
808 bool isPrimaryCmdBuf,
809 const tcu::UVec2& renderSize);
812 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
814 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
815 virtual void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const = 0;
817 void renderToTarget (void);
819 const bool m_isPrimaryCmdBuf;
822 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
823 bool isPrimaryCmdBuf,
824 const tcu::UVec2& renderSize)
825 : SingleTargetRenderInstance (context, renderSize)
826 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
830 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
832 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getDeviceFeatures(), m_context.getBinaryCollection());
833 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
834 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
836 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
838 (vk::VkPipelineVertexInputStateCreateFlags)0,
840 DE_NULL, // pVertexBindingDescriptions
841 0u, // attributeCount
842 DE_NULL, // pVertexAttributeDescriptions
844 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
846 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
848 (vk::VkPipelineInputAssemblyStateCreateFlags)0,
849 topology, // topology
850 VK_FALSE, // primitiveRestartEnable
852 const vk::VkPipelineTessellationStateCreateInfo tessState =
854 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
856 (vk::VkPipelineTessellationStateCreateFlags)0,
857 3u, // patchControlPoints
859 const vk::VkViewport viewport = vk::makeViewport(m_targetSize);
860 const vk::VkRect2D renderArea = vk::makeRect2D(m_targetSize);
861 const vk::VkPipelineViewportStateCreateInfo vpState =
863 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
865 (vk::VkPipelineViewportStateCreateFlags)0,
871 const vk::VkPipelineRasterizationStateCreateInfo rsState =
873 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
875 (vk::VkPipelineRasterizationStateCreateFlags)0,
876 VK_FALSE, // depthClipEnable
877 VK_FALSE, // rasterizerDiscardEnable
878 vk::VK_POLYGON_MODE_FILL, // fillMode
879 vk::VK_CULL_MODE_NONE, // cullMode
880 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
881 VK_FALSE, // depthBiasEnable
883 0.0f, // depthBiasClamp
884 0.0f, // slopeScaledDepthBias
887 const vk::VkSampleMask sampleMask = 0x01u;
888 const vk::VkPipelineMultisampleStateCreateInfo msState =
890 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
892 (vk::VkPipelineMultisampleStateCreateFlags)0,
893 vk::VK_SAMPLE_COUNT_1_BIT, // rasterSamples
894 VK_FALSE, // sampleShadingEnable
895 0.0f, // minSampleShading
896 &sampleMask, // sampleMask
897 VK_FALSE, // alphaToCoverageEnable
898 VK_FALSE, // alphaToOneEnable
900 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
902 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
904 (vk::VkPipelineDepthStencilStateCreateFlags)0,
905 VK_FALSE, // depthTestEnable
906 VK_FALSE, // depthWriteEnable
907 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
908 VK_FALSE, // depthBoundsTestEnable
909 VK_FALSE, // stencilTestEnable
910 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
911 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
912 -1.0f, // minDepthBounds
913 +1.0f, // maxDepthBounds
915 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
917 VK_FALSE, // blendEnable
918 vk::VK_BLEND_FACTOR_ZERO, // srcBlendColor
919 vk::VK_BLEND_FACTOR_ZERO, // destBlendColor
920 vk::VK_BLEND_OP_ADD, // blendOpColor
921 vk::VK_BLEND_FACTOR_ZERO, // srcBlendAlpha
922 vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha
923 vk::VK_BLEND_OP_ADD, // blendOpAlpha
924 (vk::VK_COLOR_COMPONENT_R_BIT |
925 vk::VK_COLOR_COMPONENT_G_BIT |
926 vk::VK_COLOR_COMPONENT_B_BIT |
927 vk::VK_COLOR_COMPONENT_A_BIT), // channelWriteMask
929 const vk::VkPipelineColorBlendStateCreateInfo cbState =
931 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
933 (vk::VkPipelineColorBlendStateCreateFlags)0,
934 VK_FALSE, // logicOpEnable
935 vk::VK_LOGIC_OP_CLEAR, // logicOp
936 1u, // attachmentCount
937 &cbAttachment, // pAttachments
938 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
940 const vk::VkGraphicsPipelineCreateInfo createInfo =
942 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
944 (vk::VkPipelineCreateFlags)0,
945 shaderStages.getNumStages(), // stageCount
946 shaderStages.getStages(), // pStages
947 &vertexInputState, // pVertexInputState
948 &iaState, // pInputAssemblyState
949 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
950 &vpState, // pViewportState
951 &rsState, // pRasterState
952 &msState, // pMultisampleState
953 &dsState, // pDepthStencilState
954 &cbState, // pColorBlendState
955 (const vk::VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
956 pipelineLayout, // layout
957 *m_renderPass, // renderPass
959 (vk::VkPipeline)0, // basePipelineHandle
960 0u, // basePipelineIndex
962 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
965 void SingleCmdRenderInstance::renderToTarget (void)
967 const vk::VkRect2D renderArea =
970 { m_targetSize.x(), m_targetSize.y() }, // extent
972 const vk::VkCommandBufferInheritanceInfo passCmdBufInheritInfo =
974 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
976 (vk::VkRenderPass)*m_renderPass, // renderPass
978 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
979 VK_FALSE, // occlusionQueryEnable
980 (vk::VkQueryControlFlags)0,
981 (vk::VkQueryPipelineStatisticFlags)0,
983 const vk::VkCommandBufferBeginInfo passCmdBufBeginInfo =
985 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
987 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
988 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // flags
989 &passCmdBufInheritInfo,
992 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
993 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
994 const vk::Unique<vk::VkCommandBuffer> mainCmd (vk::allocateCommandBuffer(m_vki, m_device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
995 const vk::Unique<vk::VkCommandBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCommandBuffer>()) : (vk::allocateCommandBuffer(m_vki, m_device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY)));
996 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device));
997 const vk::VkSubpassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_SUBPASS_CONTENTS_INLINE) : (vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
999 if (!m_isPrimaryCmdBuf)
1001 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1002 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1003 writeDrawCmdBuffer(*passCmd);
1004 endCommandBuffer(m_vki, *passCmd);
1007 beginCommandBuffer(m_vki, *mainCmd);
1008 beginRenderPass(m_vki, *mainCmd, *m_renderPass, *m_framebuffer, renderArea, tcu::Vec4(0.0f), passContents);
1010 if (m_isPrimaryCmdBuf)
1012 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1013 writeDrawCmdBuffer(*mainCmd);
1017 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1020 endRenderPass(m_vki, *mainCmd);
1021 endCommandBuffer(m_vki, *mainCmd);
1023 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1024 submitCommandsAndWait(m_vki, m_device, m_queue, mainCmd.get());
1027 enum DescriptorSetCount
1029 DESCRIPTOR_SET_COUNT_SINGLE = 0, //!< single descriptor set
1030 DESCRIPTOR_SET_COUNT_MULTIPLE, //!< multiple descriptor sets
1031 DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS, //!< multiple discontiguous descriptor sets
1033 DESCRIPTOR_SET_COUNT_LAST
1036 deUint32 getDescriptorSetCount (DescriptorSetCount count)
1040 case DESCRIPTOR_SET_COUNT_SINGLE:
1042 case DESCRIPTOR_SET_COUNT_MULTIPLE:
1043 case DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS:
1046 DE_FATAL("Impossible");
1051 deUint32 getDescriptorSetNdx (DescriptorSetCount count, deUint32 setNdx)
1053 DE_ASSERT(setNdx < getDescriptorSetCount(count));
1055 const deUint32 contiguousNdx[] = { 0, 1 };
1056 const deUint32 discontiguousNdx[] = { 0, 2 };
1060 case DESCRIPTOR_SET_COUNT_SINGLE:
1062 case DESCRIPTOR_SET_COUNT_MULTIPLE:
1063 return contiguousNdx[setNdx];
1064 case DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS:
1065 return discontiguousNdx[setNdx];
1067 DE_FATAL("Impossible");
1072 enum ShaderInputInterface
1074 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1075 SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with contiguous binding id's
1076 SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with discontiguous binding id's
1077 SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS, //!< multiple descriptors with large gaps between binding id's
1078 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1083 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1085 switch (shaderInterface)
1087 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1088 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS: return 2u;
1089 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS: return 2u;
1090 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS: return 2u;
1091 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1094 DE_FATAL("Impossible");
1099 deUint32 getArbitraryBindingIndex (deUint32 ndx)
1103 // Binding decoration value can be any 32-bit unsigned integer value.
1104 // 0xFFFE is the largest binding value accepted by glslang
1106 const deUint32 bufferIndices[] =
1108 #ifndef CTS_USES_VULKANSC
1112 // Use smaller values for VulkanSC since these can produce huge static memory allocations
1118 return bufferIndices[ndx];
1121 typedef de::MovePtr<vk::Allocation> AllocationMp;
1122 typedef de::SharedPtr<vk::Allocation> AllocationSp;
1123 typedef vk::Unique<vk::VkBuffer> BufferHandleUp;
1124 typedef de::SharedPtr<BufferHandleUp> BufferHandleSp;
1125 typedef vk::Unique<vk::VkBufferView> BufferViewHandleUp;
1126 typedef de::SharedPtr<BufferViewHandleUp> BufferViewHandleSp;
1127 typedef vk::Unique<vk::VkSampler> SamplerHandleUp;
1128 typedef de::SharedPtr<SamplerHandleUp> SamplerHandleSp;
1129 typedef vk::Unique<vk::VkImage> ImageHandleUp;
1130 typedef de::SharedPtr<ImageHandleUp> ImageHandleSp;
1131 typedef vk::Unique<vk::VkImageView> ImageViewHandleUp;
1132 typedef de::SharedPtr<ImageViewHandleUp> ImageViewHandleSp;
1133 typedef vk::Unique<vk::VkDescriptorSet> DescriptorSetHandleUp;
1134 typedef de::SharedPtr<DescriptorSetHandleUp> DescriptorSetHandleSp;
1135 typedef vk::Unique<vk::VkDescriptorSetLayout> DescriptorSetLayoutHandleUp;
1136 typedef de::SharedPtr<DescriptorSetLayoutHandleUp> DescriptorSetLayoutHandleSp;
1137 #ifndef CTS_USES_VULKANSC
1138 typedef vk::Unique<vk::VkDescriptorUpdateTemplate> UpdateTemplateHandleUp;
1139 typedef de::SharedPtr<UpdateTemplateHandleUp> UpdateTemplateHandleSp;
1142 class BufferRenderInstance : public SingleCmdRenderInstance
1145 BufferRenderInstance (Context& context,
1146 DescriptorUpdateMethod updateMethod,
1147 bool isPrimaryCmdBuf,
1148 vk::VkDescriptorType descriptorType,
1149 DescriptorSetCount descriptorSetCount,
1150 vk::VkShaderStageFlags stageFlags,
1151 ShaderInputInterface shaderInterface,
1154 bool dynamicOffsetNonZero);
1156 static std::vector<deUint32> getViewOffsets (DescriptorSetCount descriptorSetCount,
1157 ShaderInputInterface shaderInterface,
1158 bool setViewOffset);
1160 static std::vector<deUint32> getDynamicOffsets (DescriptorSetCount descriptorSetCount,
1161 ShaderInputInterface shaderInterface,
1162 bool dynamicOffsetNonZero);
1164 static std::vector<BufferHandleSp> createSourceBuffers (const vk::DeviceInterface& vki,
1165 vk::VkDevice device,
1166 vk::Allocator& allocator,
1167 vk::VkDescriptorType descriptorType,
1168 DescriptorSetCount descriptorSetCount,
1169 ShaderInputInterface shaderInterface,
1170 const std::vector<deUint32>& viewOffset,
1171 const std::vector<deUint32>& dynamicOffset,
1172 std::vector<AllocationSp>& bufferMemory);
1174 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1175 vk::VkDevice device,
1176 vk::Allocator& allocator,
1177 vk::VkDescriptorType descriptorType,
1180 deUint32 bufferSize,
1181 de::MovePtr<vk::Allocation>* outMemory);
1183 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1184 vk::VkDevice device,
1185 vk::VkDescriptorType descriptorType,
1186 DescriptorSetCount descriptorSetCount,
1187 ShaderInputInterface shaderInterface);
1189 static std::vector<DescriptorSetLayoutHandleSp> createDescriptorSetLayouts (const vk::DeviceInterface& vki,
1190 vk::VkDevice device,
1191 vk::VkDescriptorType descriptorType,
1192 DescriptorSetCount descriptorSetCount,
1193 ShaderInputInterface shaderInterface,
1194 vk::VkShaderStageFlags stageFlags,
1195 DescriptorUpdateMethod updateMethod);
1197 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1198 vk::VkDevice device,
1199 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout);
1201 static std::vector<DescriptorSetHandleSp> createDescriptorSets (const vk::DeviceInterface& vki,
1202 DescriptorUpdateMethod updateMethod,
1203 vk::VkDevice device,
1204 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
1205 vk::VkDescriptorPool descriptorPool,
1206 vk::VkDescriptorType descriptorType,
1207 DescriptorSetCount descriptorSetCount,
1208 ShaderInputInterface shaderInterface,
1209 const std::vector<BufferHandleSp>& buffers,
1210 const std::vector<deUint32>& offsets,
1211 vk::DescriptorSetUpdateBuilder& updateBuilder,
1212 std::vector<deUint32>& descriptorsPerSet,
1213 #ifndef CTS_USES_VULKANSC
1214 std::vector<UpdateTemplateHandleSp>& updateTemplates,
1215 std::vector<RawUpdateRegistry>& updateRegistry,
1217 vk::VkPipelineLayout pipelineLayout = DE_NULL);
1219 static void writeDescriptorSet (const vk::DeviceInterface& vki,
1220 vk::VkDevice device,
1221 vk::VkDescriptorType descriptorType,
1222 ShaderInputInterface shaderInterface,
1223 vk::VkBuffer sourceBufferA,
1224 const deUint32 viewOffsetA,
1225 vk::VkBuffer sourceBufferB,
1226 const deUint32 viewOffsetB,
1227 vk::VkDescriptorSet descriptorSet,
1228 vk::DescriptorSetUpdateBuilder& updateBuilder,
1229 std::vector<deUint32>& descriptorsPerSet,
1230 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
1232 #ifndef CTS_USES_VULKANSC
1233 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
1234 vk::VkDevice device,
1235 vk::VkDescriptorSetLayout descriptorSetLayout,
1237 vk::VkDescriptorPool descriptorPool,
1238 vk::VkDescriptorType descriptorType,
1239 ShaderInputInterface shaderInterface,
1240 vk::VkBuffer sourceBufferA,
1241 const deUint32 viewOffsetA,
1242 vk::VkBuffer sourceBufferB,
1243 const deUint32 viewOffsetB,
1244 vk::VkDescriptorSet descriptorSet,
1245 std::vector<UpdateTemplateHandleSp>& updateTemplates,
1246 std::vector<RawUpdateRegistry>& registry,
1247 bool withPush = false,
1248 vk::VkPipelineLayout pipelineLayout = 0);
1251 void logTestPlan (void) const;
1252 vk::VkPipelineLayout getPipelineLayout (void) const;
1253 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1254 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1259 BUFFER_DATA_SIZE = 8 * sizeof(float),
1260 BUFFER_SIZE_A = 2048, //!< a lot more than required
1261 BUFFER_SIZE_B = 2560, //!< a lot more than required
1262 BUFFER_SIZE_C = 2128, //!< a lot more than required
1263 BUFFER_SIZE_D = 2136, //!< a lot more than required
1265 STATIC_OFFSET_VALUE_A = 256,
1266 DYNAMIC_OFFSET_VALUE_A = 512,
1267 STATIC_OFFSET_VALUE_B = 1024,
1268 DYNAMIC_OFFSET_VALUE_B = 768,
1269 STATIC_OFFSET_VALUE_C = 512,
1270 DYNAMIC_OFFSET_VALUE_C = 512,
1271 STATIC_OFFSET_VALUE_D = 768,
1272 DYNAMIC_OFFSET_VALUE_D = 1024,
1275 const DescriptorUpdateMethod m_updateMethod;
1276 const vk::VkDescriptorType m_descriptorType;
1277 const DescriptorSetCount m_descriptorSetCount;
1278 const ShaderInputInterface m_shaderInterface;
1279 const bool m_setViewOffset;
1280 const bool m_setDynamicOffset;
1281 const bool m_dynamicOffsetNonZero;
1282 const vk::VkShaderStageFlags m_stageFlags;
1284 const std::vector<deUint32> m_viewOffset;
1285 const std::vector<deUint32> m_dynamicOffset;
1287 std::vector<AllocationSp> m_bufferMemory;
1288 const std::vector<BufferHandleSp> m_sourceBuffer;
1289 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1290 #ifndef CTS_USES_VULKANSC
1291 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
1292 std::vector<RawUpdateRegistry> m_updateRegistry;
1294 vk::DescriptorSetUpdateBuilder m_updateBuilder;
1295 const std::vector<DescriptorSetLayoutHandleSp> m_descriptorSetLayouts;
1296 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1297 std::vector<deUint32> m_descriptorsPerSet;
1298 const std::vector<DescriptorSetHandleSp> m_descriptorSets;
1301 BufferRenderInstance::BufferRenderInstance (Context& context,
1302 DescriptorUpdateMethod updateMethod,
1303 bool isPrimaryCmdBuf,
1304 vk::VkDescriptorType descriptorType,
1305 DescriptorSetCount descriptorSetCount,
1306 vk::VkShaderStageFlags stageFlags,
1307 ShaderInputInterface shaderInterface,
1310 bool dynamicOffsetNonZero)
1311 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1312 , m_updateMethod (updateMethod)
1313 , m_descriptorType (descriptorType)
1314 , m_descriptorSetCount (descriptorSetCount)
1315 , m_shaderInterface (shaderInterface)
1316 , m_setViewOffset (viewOffset)
1317 , m_setDynamicOffset (dynamicOffset)
1318 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1319 , m_stageFlags (stageFlags)
1320 , m_viewOffset (getViewOffsets(m_descriptorSetCount, m_shaderInterface, m_setViewOffset))
1321 , m_dynamicOffset (getDynamicOffsets(m_descriptorSetCount, m_shaderInterface, m_dynamicOffsetNonZero))
1323 , m_sourceBuffer (createSourceBuffers(m_vki, m_device, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewOffset, m_dynamicOffset, m_bufferMemory))
1324 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface))
1325 #ifndef CTS_USES_VULKANSC
1326 , m_updateTemplates ()
1327 , m_updateRegistry ()
1329 , m_updateBuilder ()
1330 , m_descriptorSetLayouts (createDescriptorSetLayouts(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_stageFlags, m_updateMethod))
1331 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, m_descriptorSetLayouts))
1332 , m_descriptorsPerSet ()
1333 , m_descriptorSets (createDescriptorSets(m_vki, m_updateMethod, m_device, m_descriptorSetLayouts, *m_descriptorPool, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_sourceBuffer, m_viewOffset, m_updateBuilder, m_descriptorsPerSet,
1334 #ifndef CTS_USES_VULKANSC
1340 if (m_setDynamicOffset)
1341 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1342 if (m_dynamicOffsetNonZero)
1343 DE_ASSERT(m_setDynamicOffset);
1346 std::vector<deUint32> BufferRenderInstance::getViewOffsets (DescriptorSetCount descriptorSetCount,
1347 ShaderInputInterface shaderInterface,
1350 const int numBuffers = getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface);
1351 std::vector<deUint32> viewOffset;
1353 for (int bufferNdx = 0; bufferNdx < numBuffers; bufferNdx++)
1355 const deUint32 staticOffsetValues[] =
1357 STATIC_OFFSET_VALUE_A,
1358 STATIC_OFFSET_VALUE_B,
1359 STATIC_OFFSET_VALUE_C,
1360 STATIC_OFFSET_VALUE_D
1363 viewOffset.push_back(setViewOffset ? (staticOffsetValues[bufferNdx % getInterfaceNumResources(shaderInterface)]) : (0u));
1369 std::vector<deUint32> BufferRenderInstance::getDynamicOffsets (DescriptorSetCount descriptorSetCount,
1370 ShaderInputInterface shaderInterface,
1371 bool dynamicOffsetNonZero)
1373 const int numBuffers = getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface);
1374 std::vector<deUint32> dynamicOffset;
1376 for (int bufferNdx = 0; bufferNdx < numBuffers; bufferNdx++)
1378 const deUint32 dynamicOffsetValues[] =
1380 DYNAMIC_OFFSET_VALUE_A,
1381 DYNAMIC_OFFSET_VALUE_B,
1382 DYNAMIC_OFFSET_VALUE_C,
1383 DYNAMIC_OFFSET_VALUE_D
1386 dynamicOffset.push_back(dynamicOffsetNonZero ? (dynamicOffsetValues[bufferNdx % getInterfaceNumResources(shaderInterface)]) : (0u));
1389 return dynamicOffset;
1392 std::vector<BufferHandleSp> BufferRenderInstance::createSourceBuffers (const vk::DeviceInterface& vki,
1393 vk::VkDevice device,
1394 vk::Allocator& allocator,
1395 vk::VkDescriptorType descriptorType,
1396 DescriptorSetCount descriptorSetCount,
1397 ShaderInputInterface shaderInterface,
1398 const std::vector<deUint32>& viewOffset,
1399 const std::vector<deUint32>& dynamicOffset,
1400 std::vector<AllocationSp>& bufferMemory)
1402 const int numBuffers = getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface);
1403 std::vector<deUint32> effectiveOffset;
1404 std::vector<deUint32> bufferSize;
1405 std::vector<BufferHandleSp> sourceBuffers;
1407 for (int bufferNdx = 0; bufferNdx < numBuffers; bufferNdx++)
1409 const deUint32 bufferSizeValues[] =
1417 effectiveOffset.push_back(isDynamicDescriptorType(descriptorType) ? (viewOffset[bufferNdx] + dynamicOffset[bufferNdx]) : (viewOffset[bufferNdx]));
1418 bufferSize.push_back(bufferSizeValues[bufferNdx % getInterfaceNumResources(shaderInterface)]);
1422 // Create source buffers
1423 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
1425 for (deUint32 bufferNdx = 0; bufferNdx < getInterfaceNumResources(shaderInterface); bufferNdx++)
1427 de::MovePtr<vk::Allocation> memory;
1428 vk::Move<vk::VkBuffer> buffer = createSourceBuffer(vki, device, allocator, descriptorType, setNdx, effectiveOffset[bufferNdx], bufferSize[bufferNdx], &memory);
1430 bufferMemory.push_back(AllocationSp(memory.release()));
1431 sourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(buffer)));
1435 return sourceBuffers;
1438 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1439 vk::VkDevice device,
1440 vk::Allocator& allocator,
1441 vk::VkDescriptorType descriptorType,
1444 deUint32 bufferSize,
1445 de::MovePtr<vk::Allocation>* outMemory)
1447 static const float s_colors[] =
1449 0.0f, 1.0f, 0.0f, 1.0f, // green
1450 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1451 0.0f, 0.0f, 1.0f, 1.0f, // blue
1452 1.0f, 0.0f, 0.0f, 1.0f // red
1454 DE_STATIC_ASSERT(sizeof(s_colors) / 2 == BUFFER_DATA_SIZE);
1455 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1456 DE_ASSERT(offset % sizeof(float) == 0);
1457 DE_ASSERT(bufferSize % sizeof(float) == 0);
1459 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1460 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1461 const float preGuardValue = 0.5f;
1462 const float postGuardValue = 0.75f;
1463 const vk::VkBufferCreateInfo bufferCreateInfo =
1465 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1469 usageFlags, // usage
1470 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1471 0u, // queueFamilyCount
1472 DE_NULL, // pQueueFamilyIndices
1474 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1475 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1476 void* const mapPtr = bufferMemory->getHostPtr();
1478 // guard with interesting values
1479 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1480 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1482 deMemcpy((deUint8*)mapPtr + offset, &s_colors[8 * (setNdx % 2)], sizeof(s_colors) / 2);
1483 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors) / 2; postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1484 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1485 deMemset((deUint8*)mapPtr + offset + sizeof(s_colors) / 2, 0x5A, (size_t)bufferSize - (size_t)offset - sizeof(s_colors) / 2); // fill with interesting pattern that produces valid floats
1487 flushAlloc(vki, device, *bufferMemory);
1489 // Flushed host-visible memory is automatically made available to the GPU, no barrier is needed.
1491 *outMemory = bufferMemory;
1495 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1496 vk::VkDevice device,
1497 vk::VkDescriptorType descriptorType,
1498 DescriptorSetCount descriptorSetCount,
1499 ShaderInputInterface shaderInterface)
1501 return vk::DescriptorPoolBuilder()
1502 .addType(descriptorType, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface))
1503 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(descriptorSetCount));
1506 std::vector<DescriptorSetLayoutHandleSp> BufferRenderInstance::createDescriptorSetLayouts (const vk::DeviceInterface& vki,
1507 vk::VkDevice device,
1508 vk::VkDescriptorType descriptorType,
1509 DescriptorSetCount descriptorSetCount,
1510 ShaderInputInterface shaderInterface,
1511 vk::VkShaderStageFlags stageFlags,
1512 DescriptorUpdateMethod updateMethod)
1514 #ifdef CTS_USES_VULKANSC
1515 DE_UNREF(updateMethod);
1517 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
1519 #ifndef CTS_USES_VULKANSC
1520 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
1521 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1523 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
1527 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
1529 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
1531 vk::DescriptorSetLayoutBuilder builder;
1532 switch (shaderInterface)
1534 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1535 builder.addSingleBinding(descriptorType, stageFlags);
1538 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1539 builder.addSingleBinding(descriptorType, stageFlags);
1540 builder.addSingleBinding(descriptorType, stageFlags);
1543 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
1544 builder.addSingleIndexedBinding(descriptorType, stageFlags, 0u);
1545 builder.addSingleIndexedBinding(descriptorType, stageFlags, 2u);
1548 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
1549 builder.addSingleIndexedBinding(descriptorType, stageFlags, getArbitraryBindingIndex(0));
1550 builder.addSingleIndexedBinding(descriptorType, stageFlags, getArbitraryBindingIndex(1));
1553 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1554 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1558 DE_FATAL("Impossible");
1561 vk::Move<vk::VkDescriptorSetLayout> layout = builder.build(vki, device, extraFlags);
1562 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
1564 // Add an empty descriptor set layout between sets 0 and 2
1565 if (setNdx == 0 && descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS)
1567 vk::DescriptorSetLayoutBuilder emptyBuilder;
1568 vk::Move<vk::VkDescriptorSetLayout> emptyLayout = emptyBuilder.build(vki, device, (vk::VkDescriptorSetLayoutCreateFlags)0);
1569 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(emptyLayout)));
1572 return descriptorSetLayouts;
1575 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1576 vk::VkDevice device,
1577 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout)
1579 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
1580 for (size_t setNdx = 0; setNdx < descriptorSetLayout.size(); setNdx++)
1581 layoutHandles.push_back(**descriptorSetLayout[setNdx]);
1583 const vk::VkPipelineLayoutCreateInfo createInfo =
1585 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1587 (vk::VkPipelineLayoutCreateFlags)0,
1588 (deUint32)layoutHandles.size(), // descriptorSetCount
1589 &layoutHandles.front(), // pSetLayouts
1590 0u, // pushConstantRangeCount
1591 DE_NULL, // pPushConstantRanges
1593 return vk::createPipelineLayout(vki, device, &createInfo);
1596 std::vector<DescriptorSetHandleSp> BufferRenderInstance::createDescriptorSets (const vk::DeviceInterface& vki,
1597 DescriptorUpdateMethod updateMethod,
1598 vk::VkDevice device,
1599 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
1600 vk::VkDescriptorPool descriptorPool,
1601 vk::VkDescriptorType descriptorType,
1602 DescriptorSetCount descriptorSetCount,
1603 ShaderInputInterface shaderInterface,
1604 const std::vector<BufferHandleSp>& buffers,
1605 const std::vector<deUint32>& offsets,
1606 vk::DescriptorSetUpdateBuilder& updateBuilder,
1607 std::vector<deUint32>& descriptorsPerSet,
1608 #ifndef CTS_USES_VULKANSC
1609 std::vector<UpdateTemplateHandleSp>& updateTemplates,
1610 std::vector<RawUpdateRegistry>& updateRegistry,
1612 vk::VkPipelineLayout pipelineLayout)
1614 #ifdef CTS_USES_VULKANSC
1615 DE_UNREF(pipelineLayout);
1617 std::vector<DescriptorSetHandleSp> descriptorSets;
1619 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
1621 vk::VkDescriptorSetLayout layout = **descriptorSetLayouts[getDescriptorSetNdx(descriptorSetCount, setNdx)];
1622 const vk::VkDescriptorSetAllocateInfo allocInfo =
1624 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1631 vk::VkBuffer bufferA = **buffers[(setNdx * getInterfaceNumResources(shaderInterface)) % buffers.size()];
1632 vk::VkBuffer bufferB = **buffers[(setNdx * getInterfaceNumResources(shaderInterface) + 1) % buffers.size()];
1633 deUint32 offsetA = offsets[(setNdx * getInterfaceNumResources(shaderInterface)) % offsets.size()];
1634 deUint32 offsetB = offsets[(setNdx * getInterfaceNumResources(shaderInterface) + 1) % offsets.size()];
1636 vk::Move<vk::VkDescriptorSet> descriptorSet;
1638 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1640 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1644 descriptorSet = vk::Move<vk::VkDescriptorSet>();
1647 #ifndef CTS_USES_VULKANSC
1648 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
1650 writeDescriptorSetWithTemplate(vki, device, layout, setNdx, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateTemplates, updateRegistry);
1652 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1654 writeDescriptorSetWithTemplate(vki, device, layout, setNdx, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateTemplates, updateRegistry, true, pipelineLayout);
1656 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1658 writeDescriptorSet(vki, device, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateBuilder, descriptorsPerSet, updateMethod);
1660 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
1663 writeDescriptorSet(vki, device, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateBuilder, descriptorsPerSet);
1666 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(descriptorSet)));
1668 return descriptorSets;
1671 void BufferRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
1672 vk::VkDevice device,
1673 vk::VkDescriptorType descriptorType,
1674 ShaderInputInterface shaderInterface,
1675 vk::VkBuffer bufferA,
1676 const deUint32 offsetA,
1677 vk::VkBuffer bufferB,
1678 const deUint32 offsetB,
1679 vk::VkDescriptorSet descriptorSet,
1680 vk::DescriptorSetUpdateBuilder& updateBuilder,
1681 std::vector<deUint32>& descriptorsPerSet,
1682 DescriptorUpdateMethod updateMethod)
1684 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1686 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1687 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1689 deUint32 numDescriptors = 0u;
1691 switch (shaderInterface)
1693 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1694 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1698 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1699 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1700 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1701 numDescriptors += 2;
1704 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
1705 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1706 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), descriptorType, &bufferInfos[1]);
1707 numDescriptors += 2;
1710 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
1711 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), descriptorType, &bufferInfos[0]);
1712 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), descriptorType, &bufferInfos[1]);
1713 numDescriptors += 2;
1716 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1717 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1722 DE_FATAL("Impossible");
1725 descriptorsPerSet.push_back(numDescriptors);
1727 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
1729 updateBuilder.update(vki, device);
1730 updateBuilder.clear();
1734 #ifndef CTS_USES_VULKANSC
1735 void BufferRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
1736 vk::VkDevice device,
1737 vk::VkDescriptorSetLayout layout,
1739 vk::VkDescriptorPool descriptorPool,
1740 vk::VkDescriptorType descriptorType,
1741 ShaderInputInterface shaderInterface,
1742 vk::VkBuffer bufferA,
1743 const deUint32 offsetA,
1744 vk::VkBuffer bufferB,
1745 const deUint32 offsetB,
1746 vk::VkDescriptorSet descriptorSet,
1747 std::vector<UpdateTemplateHandleSp>& updateTemplates,
1748 std::vector<RawUpdateRegistry>& registry,
1750 vk::VkPipelineLayout pipelineLayout)
1752 DE_UNREF(descriptorPool);
1753 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1755 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1756 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1758 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
1759 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
1761 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
1764 0, // descriptorUpdateEntryCount
1765 DE_NULL, // pDescriptorUpdateEntries
1766 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
1768 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
1773 RawUpdateRegistry updateRegistry;
1775 updateRegistry.addWriteObject(bufferInfos[0]);
1776 updateRegistry.addWriteObject(bufferInfos[1]);
1778 switch (shaderInterface)
1780 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1781 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1784 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1785 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1786 updateEntries.push_back(createTemplateBinding(1u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
1789 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
1790 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1791 updateEntries.push_back(createTemplateBinding(2u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
1794 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
1795 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1796 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
1799 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1800 updateEntries.push_back(createTemplateBinding(0u, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(bufferInfos[0])));
1804 DE_FATAL("Impossible");
1807 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
1808 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
1810 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(vki, device, &templateCreateInfo);
1811 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
1812 registry.push_back(updateRegistry);
1816 vki.updateDescriptorSetWithTemplate(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
1821 void BufferRenderInstance::logTestPlan (void) const
1823 std::ostringstream msg;
1825 msg << "Rendering 2x2 yellow-green grid.\n"
1826 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
1827 << "Each descriptor set contains "
1828 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1829 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
1830 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
1831 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
1832 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1833 (const char*)DE_NULL)
1834 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1835 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1837 if (isDynamicDescriptorType(m_descriptorType))
1839 if (m_setDynamicOffset)
1841 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1842 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1846 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1850 if (m_stageFlags == 0u)
1852 msg << "Descriptors are not accessed in any shader stage.\n";
1856 msg << "Descriptors are accessed in {"
1857 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1858 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1859 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1860 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1861 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1865 m_context.getTestContext().getLog()
1866 << tcu::TestLog::Message
1868 << tcu::TestLog::EndMessage;
1871 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1873 return *m_pipelineLayout;
1876 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1878 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1880 std::vector<vk::VkDescriptorSet> sets;
1881 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
1882 sets.push_back(**m_descriptorSets[setNdx]);
1884 switch (m_descriptorSetCount)
1886 case DESCRIPTOR_SET_COUNT_SINGLE:
1887 case DESCRIPTOR_SET_COUNT_MULTIPLE:
1889 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1890 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : ((deUint32)m_dynamicOffset.size());
1891 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (&m_dynamicOffset.front());
1893 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, (int)sets.size(), &sets.front(), numOffsets, dynamicOffsetPtr);
1896 case DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS:
1898 deUint32 dynamicOffsetNdx = 0u;
1900 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
1902 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1903 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1904 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (&m_dynamicOffset[dynamicOffsetNdx]);
1905 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
1907 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), descriptorSetNdx, 1, &sets[setNdx], numOffsets, dynamicOffsetPtr);
1909 dynamicOffsetNdx += getInterfaceNumResources(m_shaderInterface);
1914 DE_FATAL("Impossible");
1917 #ifndef CTS_USES_VULKANSC
1918 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1920 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
1921 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, **m_updateTemplates[setNdx], getPipelineLayout(), setNdx, (const void*)m_updateRegistry[setNdx].getRawPointer());
1923 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1925 deUint32 descriptorNdx = 0u;
1926 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
1928 const deUint32 numDescriptors = m_descriptorsPerSet[setNdx];
1929 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, setNdx, descriptorNdx, numDescriptors);
1930 descriptorNdx += numDescriptors;
1935 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1938 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1940 const deUint32 numDescriptorSets = getDescriptorSetCount(m_descriptorSetCount);
1941 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1942 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1943 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1945 tcu::Vec4 sample0 = tcu::Vec4(0.0f);
1946 tcu::Vec4 sample1 = tcu::Vec4(0.0f);
1950 const tcu::Vec4 colors[] =
1952 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), // green
1953 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), // yellow
1954 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), // blue
1955 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), // red
1959 for (deUint32 setNdx = 0; setNdx < numDescriptorSets; setNdx++)
1961 sample0 += colors[2 * (setNdx % 2)];
1962 sample1 += colors[2 * (setNdx % 2) + 1];
1965 if (numDescriptorSets > 1)
1967 sample0 = sample0 / tcu::Vec4(float(numDescriptorSets));
1968 sample1 = sample1 / tcu::Vec4(float(numDescriptorSets));
1977 drawQuadrantReferenceResult(reference.getAccess(), sample1, sample0, sample0, sample1);
1979 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1980 return tcu::TestStatus::fail("Image verification failed");
1982 return tcu::TestStatus::pass("Pass");
1985 class ComputeInstanceResultBuffer
1990 DATA_SIZE = sizeof(tcu::Vec4[4])
1993 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1994 vk::VkDevice device,
1995 vk::Allocator& allocator);
1997 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1999 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
2000 inline const vk::VkBufferMemoryBarrier* getResultReadBarrier (void) const { return &m_bufferBarrier; }
2003 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
2004 vk::VkDevice device,
2005 vk::Allocator& allocator,
2006 de::MovePtr<vk::Allocation>* outAllocation);
2008 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
2010 const vk::DeviceInterface& m_vki;
2011 const vk::VkDevice m_device;
2013 de::MovePtr<vk::Allocation> m_bufferMem;
2014 const vk::Unique<vk::VkBuffer> m_buffer;
2015 const vk::VkBufferMemoryBarrier m_bufferBarrier;
2018 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
2019 vk::VkDevice device,
2020 vk::Allocator& allocator)
2023 , m_bufferMem (DE_NULL)
2024 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
2025 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
2029 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
2031 invalidateAlloc(m_vki, m_device, *m_bufferMem);
2032 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
2035 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
2036 vk::VkDevice device,
2037 vk::Allocator& allocator,
2038 de::MovePtr<vk::Allocation>* outAllocation)
2040 const vk::VkBufferCreateInfo createInfo =
2042 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
2045 (vk::VkDeviceSize)DATA_SIZE, // size
2046 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
2047 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2048 0u, // queueFamilyCount
2049 DE_NULL, // pQueueFamilyIndices
2051 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
2052 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
2053 const float clearValue = -1.0f;
2054 void* mapPtr = allocation->getHostPtr();
2056 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
2057 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
2059 flushAlloc(vki, device, *allocation);
2061 *outAllocation = allocation;
2065 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
2067 const vk::VkBufferMemoryBarrier bufferBarrier =
2069 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2071 vk::VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask
2072 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
2073 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2074 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2076 (vk::VkDeviceSize)0u, // offset
2079 return bufferBarrier;
2082 class ComputePipeline
2085 ComputePipeline (const vk::DeviceInterface& vki,
2086 vk::VkDevice device,
2087 const vk::BinaryCollection& programCollection,
2088 deUint32 numDescriptorSets,
2089 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
2091 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; }
2092 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; }
2095 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
2096 vk::VkDevice device,
2097 deUint32 numDescriptorSets,
2098 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
2100 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
2101 vk::VkDevice device,
2102 const vk::BinaryCollection& programCollection,
2103 vk::VkPipelineLayout layout);
2105 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
2106 const vk::Unique<vk::VkPipeline> m_pipeline;
2109 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
2110 vk::VkDevice device,
2111 const vk::BinaryCollection& programCollection,
2112 deUint32 numDescriptorSets,
2113 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
2114 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
2115 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
2119 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
2120 vk::VkDevice device,
2121 deUint32 numDescriptorSets,
2122 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
2124 const vk::VkPipelineLayoutCreateInfo createInfo =
2126 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2128 (vk::VkPipelineLayoutCreateFlags)0,
2129 numDescriptorSets, // descriptorSetCount
2130 descriptorSetLayouts, // pSetLayouts
2131 0u, // pushConstantRangeCount
2132 DE_NULL, // pPushConstantRanges
2134 return vk::createPipelineLayout(vki, device, &createInfo);
2137 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
2138 vk::VkDevice device,
2139 const vk::BinaryCollection& programCollection,
2140 vk::VkPipelineLayout layout)
2142 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
2143 const vk::VkPipelineShaderStageCreateInfo cs =
2145 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2147 (vk::VkPipelineShaderStageCreateFlags)0,
2148 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
2149 *computeModule, // shader
2151 DE_NULL, // pSpecializationInfo
2153 const vk::VkComputePipelineCreateInfo createInfo =
2155 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2160 (vk::VkPipeline)0, // basePipelineHandle
2161 0u, // basePipelineIndex
2163 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
2166 class ComputeCommand
2169 ComputeCommand (const vk::DeviceInterface& vki,
2170 vk::VkDevice device,
2171 vk::VkPipeline pipeline,
2172 vk::VkPipelineLayout pipelineLayout,
2173 const tcu::UVec3& numWorkGroups,
2174 ShaderInputInterface shaderInterface,
2175 DescriptorSetCount descriptorSetCount,
2176 const vk::VkDescriptorSet* descriptorSets,
2177 int numDynamicOffsets,
2178 const deUint32* dynamicOffsets,
2180 const vk::VkBufferMemoryBarrier* preBarriers,
2181 int numPostBarriers,
2182 const vk::VkBufferMemoryBarrier* postBarriers);
2184 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue
2185 #ifndef CTS_USES_VULKANSC
2186 , std::vector<UpdateTemplateHandleSp>* updateTemplates = DE_NULL
2187 , std::vector<RawUpdateRegistry>* updateRegistry = DE_NULL
2190 #ifndef CTS_USES_VULKANSC
2191 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::DescriptorSetUpdateBuilder& updateBuilder, std::vector<deUint32>& descriptorsPerSet) const;
2195 const vk::DeviceInterface& m_vki;
2196 const vk::VkDevice m_device;
2197 const vk::VkPipeline m_pipeline;
2198 const vk::VkPipelineLayout m_pipelineLayout;
2199 const tcu::UVec3 m_numWorkGroups;
2200 const ShaderInputInterface m_shaderInterface;
2201 const DescriptorSetCount m_descriptorSetCount;
2202 const vk::VkDescriptorSet* const m_descriptorSets;
2203 const int m_numDynamicOffsets;
2204 const deUint32* const m_dynamicOffsets;
2205 const int m_numPreBarriers;
2206 const vk::VkBufferMemoryBarrier* const m_preBarriers;
2207 const int m_numPostBarriers;
2208 const vk::VkBufferMemoryBarrier* const m_postBarriers;
2211 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
2212 vk::VkDevice device,
2213 vk::VkPipeline pipeline,
2214 vk::VkPipelineLayout pipelineLayout,
2215 const tcu::UVec3& numWorkGroups,
2216 ShaderInputInterface shaderInterface,
2217 DescriptorSetCount descriptorSetCount,
2218 const vk::VkDescriptorSet* descriptorSets,
2219 int numDynamicOffsets,
2220 const deUint32* dynamicOffsets,
2222 const vk::VkBufferMemoryBarrier* preBarriers,
2223 int numPostBarriers,
2224 const vk::VkBufferMemoryBarrier* postBarriers)
2227 , m_pipeline (pipeline)
2228 , m_pipelineLayout (pipelineLayout)
2229 , m_numWorkGroups (numWorkGroups)
2230 , m_shaderInterface (shaderInterface)
2231 , m_descriptorSetCount (descriptorSetCount)
2232 , m_descriptorSets (descriptorSets)
2233 , m_numDynamicOffsets (numDynamicOffsets)
2234 , m_dynamicOffsets (dynamicOffsets)
2235 , m_numPreBarriers (numPreBarriers)
2236 , m_preBarriers (preBarriers)
2237 , m_numPostBarriers (numPostBarriers)
2238 , m_postBarriers (postBarriers)
2242 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue
2243 #ifndef CTS_USES_VULKANSC
2244 , std::vector<UpdateTemplateHandleSp>* updateTemplates
2245 , std::vector<RawUpdateRegistry>* updateRegistry
2249 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
2251 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2253 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
2254 queueFamilyIndex, // queueFamilyIndex
2256 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
2258 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
2260 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
2262 *cmdPool, // cmdPool
2263 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
2267 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
2269 beginCommandBuffer(m_vki, *cmd);
2271 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
2274 #ifndef CTS_USES_VULKANSC
2275 if (updateTemplates == DE_NULL)
2278 switch (m_descriptorSetCount)
2280 case DESCRIPTOR_SET_COUNT_SINGLE:
2281 case DESCRIPTOR_SET_COUNT_MULTIPLE:
2283 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, getDescriptorSetCount(m_descriptorSetCount), m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
2286 case DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS:
2288 deUint32 dynamicOffsetNdx = 0u;
2290 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2292 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
2293 const deUint32 numOffsets = (!m_numDynamicOffsets) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
2294 const deUint32* const dynamicOffsetPtr = (!m_numDynamicOffsets) ? (DE_NULL) : (&m_dynamicOffsets[dynamicOffsetNdx]);
2295 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
2297 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, descriptorSetNdx, 1u, &m_descriptorSets[setNdx], numOffsets, dynamicOffsetPtr);
2299 dynamicOffsetNdx += getInterfaceNumResources(m_shaderInterface);
2304 DE_FATAL("Impossible");
2307 #ifndef CTS_USES_VULKANSC
2308 // update with push template
2311 for (deUint32 setNdx = 0; setNdx < (deUint32)(*updateTemplates).size(); setNdx++)
2312 m_vki.cmdPushDescriptorSetWithTemplateKHR(*cmd, **(*updateTemplates)[setNdx], m_pipelineLayout, getDescriptorSetNdx(m_descriptorSetCount, setNdx), (const void*)(*updateRegistry)[setNdx].getRawPointer());
2316 if (m_numPreBarriers)
2317 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
2318 0, (const vk::VkMemoryBarrier*)DE_NULL,
2319 m_numPreBarriers, m_preBarriers,
2320 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2322 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
2323 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0,
2324 0, (const vk::VkMemoryBarrier*)DE_NULL,
2325 m_numPostBarriers, m_postBarriers,
2326 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2327 endCommandBuffer(m_vki, *cmd);
2329 submitCommandsAndWait(m_vki, m_device, queue, cmd.get());
2332 #ifndef CTS_USES_VULKANSC
2333 //cmdPushDescriptorSet variant
2334 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::DescriptorSetUpdateBuilder& updateBuilder, std::vector<deUint32>& descriptorsPerSet) const
2336 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
2338 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2340 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
2341 queueFamilyIndex, // queueFamilyIndex
2343 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
2345 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2347 beginCommandBuffer(m_vki, *cmd);
2349 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
2352 deUint32 descriptorNdx = 0u;
2353 for (deUint32 setNdx = 0; setNdx < (deUint32)descriptorsPerSet.size(); setNdx++)
2355 const deUint32 numDescriptors = descriptorsPerSet[setNdx];
2356 updateBuilder.updateWithPush(m_vki, *cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, getDescriptorSetNdx(m_descriptorSetCount, setNdx), descriptorNdx, numDescriptors);
2357 descriptorNdx += numDescriptors;
2361 if (m_numPreBarriers)
2362 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
2363 0, (const vk::VkMemoryBarrier*)DE_NULL,
2364 m_numPreBarriers, m_preBarriers,
2365 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2367 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
2368 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0,
2369 0, (const vk::VkMemoryBarrier*)DE_NULL,
2370 m_numPostBarriers, m_postBarriers,
2371 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2372 endCommandBuffer(m_vki, *cmd);
2374 submitCommandsAndWait(m_vki, m_device, queue, cmd.get());
2378 class BufferComputeInstance : public vkt::TestInstance
2381 BufferComputeInstance (Context& context,
2382 DescriptorUpdateMethod updateMethod,
2383 vk::VkDescriptorType descriptorType,
2384 DescriptorSetCount descriptorSetCount,
2385 ShaderInputInterface shaderInterface,
2388 bool dynamicOffsetNonZero);
2391 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
2392 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (deUint32 setNdx) const;
2393 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
2394 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf);
2395 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf);
2396 #ifndef CTS_USES_VULKANSC
2397 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
2400 tcu::TestStatus iterate (void);
2401 void logTestPlan (void) const;
2402 tcu::TestStatus testResourceAccess (void);
2406 STATIC_OFFSET_VALUE_A = 256,
2407 DYNAMIC_OFFSET_VALUE_A = 512,
2408 STATIC_OFFSET_VALUE_B = 1024,
2409 DYNAMIC_OFFSET_VALUE_B = 768,
2412 const DescriptorUpdateMethod m_updateMethod;
2413 const vk::VkDescriptorType m_descriptorType;
2414 const DescriptorSetCount m_descriptorSetCount;
2415 const ShaderInputInterface m_shaderInterface;
2416 const bool m_setViewOffset;
2417 const bool m_setDynamicOffset;
2418 const bool m_dynamicOffsetNonZero;
2420 #ifndef CTS_USES_VULKANSC
2421 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
2423 const vk::DeviceInterface& m_vki;
2424 const vk::VkDevice m_device;
2425 const vk::VkQueue m_queue;
2426 const deUint32 m_queueFamilyIndex;
2427 vk::Allocator& m_allocator;
2429 const ComputeInstanceResultBuffer m_result;
2431 #ifndef CTS_USES_VULKANSC
2432 std::vector<RawUpdateRegistry> m_updateRegistry;
2434 vk::DescriptorSetUpdateBuilder m_updateBuilder;
2435 std::vector<deUint32> m_descriptorsPerSet;
2438 BufferComputeInstance::BufferComputeInstance (Context& context,
2439 DescriptorUpdateMethod updateMethod,
2440 vk::VkDescriptorType descriptorType,
2441 DescriptorSetCount descriptorSetCount,
2442 ShaderInputInterface shaderInterface,
2445 bool dynamicOffsetNonZero)
2446 : vkt::TestInstance (context)
2447 , m_updateMethod (updateMethod)
2448 , m_descriptorType (descriptorType)
2449 , m_descriptorSetCount (descriptorSetCount)
2450 , m_shaderInterface (shaderInterface)
2451 , m_setViewOffset (viewOffset)
2452 , m_setDynamicOffset (dynamicOffset)
2453 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
2454 #ifndef CTS_USES_VULKANSC
2455 , m_updateTemplates ()
2457 , m_vki (context.getDeviceInterface())
2458 , m_device (context.getDevice())
2459 , m_queue (context.getUniversalQueue())
2460 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
2461 , m_allocator (context.getDefaultAllocator())
2462 , m_result (m_vki, m_device, m_allocator)
2463 #ifndef CTS_USES_VULKANSC
2464 , m_updateRegistry ()
2466 , m_updateBuilder ()
2467 , m_descriptorsPerSet ()
2469 if (m_dynamicOffsetNonZero)
2470 DE_ASSERT(m_setDynamicOffset);
2473 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
2475 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
2477 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2478 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2479 const vk::VkBufferCreateInfo createInfo =
2481 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
2484 (vk::VkDeviceSize)bufferSize, // size
2485 usageFlags, // usage
2486 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2487 0u, // queueFamilyCount
2488 DE_NULL, // pQueueFamilyIndices
2490 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
2491 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
2492 void* mapPtr = allocation->getHostPtr();
2495 deMemset(mapPtr, 0x5A, (size_t)offset);
2496 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
2497 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
2498 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
2500 flushAlloc(m_vki, m_device, *allocation);
2502 *outAllocation = allocation;
2506 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (deUint32 setNdx) const
2508 vk::DescriptorSetLayoutBuilder builder;
2509 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
2510 deUint32 binding = 0;
2512 #ifndef CTS_USES_VULKANSC
2513 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
2514 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
2516 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
2521 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++);
2523 switch (m_shaderInterface)
2525 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2526 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2529 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2530 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2531 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2534 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
2535 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding + 0u);
2536 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding + 2u);
2539 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
2540 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, getArbitraryBindingIndex(0));
2541 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, getArbitraryBindingIndex(1));
2544 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2545 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2549 DE_FATAL("Impossible");
2552 return builder.build(m_vki, m_device, extraFlags);
2555 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
2557 return vk::DescriptorPoolBuilder()
2558 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2559 .addType(m_descriptorType, getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface))
2560 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(m_descriptorSetCount));
2563 vk::Move<vk::VkDescriptorSet> BufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf)
2565 const vk::VkDescriptorSetAllocateInfo allocInfo =
2567 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2574 vk::Move<vk::VkDescriptorSet> descriptorSet;
2575 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
2577 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
2581 descriptorSet = vk::Move<vk::VkDescriptorSet>();
2584 #ifndef CTS_USES_VULKANSC
2585 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
2587 writeDescriptorSetWithTemplate(*descriptorSet, layout, setNdx, viewA, offsetA, viewB, offsetB, resBuf);
2591 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
2593 writeDescriptorSet(*descriptorSet, setNdx, viewA, offsetA, viewB, offsetB, resBuf);
2596 return descriptorSet;
2599 void BufferComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf)
2601 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2602 const vk::VkDescriptorBufferInfo bufferInfos[2] =
2604 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2605 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2608 deUint32 numDescriptors = 0u;
2609 deUint32 binding = 0u;
2614 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
2619 switch (m_shaderInterface)
2621 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2622 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &bufferInfos[0]);
2626 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2627 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &bufferInfos[0]);
2628 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &bufferInfos[1]);
2629 numDescriptors += 2;
2632 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
2633 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding), m_descriptorType, &bufferInfos[0]);
2634 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding + 2), m_descriptorType, &bufferInfos[1]);
2635 numDescriptors += 2;
2638 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
2639 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), m_descriptorType, &bufferInfos[0]);
2640 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), m_descriptorType, &bufferInfos[1]);
2641 numDescriptors += 2;
2644 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2645 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, 2u, bufferInfos);
2650 DE_FATAL("Impossible");
2653 m_descriptorsPerSet.push_back(numDescriptors);
2655 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
2657 m_updateBuilder.update(m_vki, m_device);
2658 m_updateBuilder.clear();
2662 #ifndef CTS_USES_VULKANSC
2663 void BufferComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf, bool withPush, vk::VkPipelineLayout pipelineLayout)
2665 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2666 const vk::VkDescriptorBufferInfo bufferInfos[2] =
2668 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2669 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2671 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
2672 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
2674 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
2677 0, // descriptorUpdateEntryCount
2678 DE_NULL, // pDescriptorUpdateEntries
2679 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
2681 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
2685 deUint32 binding = 0u;
2686 deUint32 offset = 0u;
2687 RawUpdateRegistry updateRegistry;
2690 updateRegistry.addWriteObject(resultInfo);
2692 updateRegistry.addWriteObject(bufferInfos[0]);
2693 updateRegistry.addWriteObject(bufferInfos[1]);
2697 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
2700 switch (m_shaderInterface)
2702 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2703 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2706 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2707 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2708 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2711 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
2712 updateEntries.push_back(createTemplateBinding(binding, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2713 updateEntries.push_back(createTemplateBinding(binding + 2, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2716 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
2717 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2718 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2721 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2722 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), sizeof(bufferInfos[0])));
2726 DE_FATAL("Impossible");
2729 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
2730 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
2732 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(m_vki, m_device, &templateCreateInfo);
2733 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
2734 m_updateRegistry.push_back(updateRegistry);
2738 m_vki.updateDescriptorSetWithTemplate(m_device, descriptorSet, **m_updateTemplates.back(), m_updateRegistry.back().getRawPointer());
2743 tcu::TestStatus BufferComputeInstance::iterate (void)
2746 return testResourceAccess();
2749 void BufferComputeInstance::logTestPlan (void) const
2751 std::ostringstream msg;
2753 msg << "Accessing resource in a compute program.\n"
2754 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
2755 << "Each descriptor set contains "
2756 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2757 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
2758 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
2759 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
2760 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2761 (const char*)DE_NULL)
2762 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2763 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2764 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2766 if (isDynamicDescriptorType(m_descriptorType))
2768 if (m_setDynamicOffset)
2770 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2771 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2775 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2779 msg << "Destination buffer is pre-initialized to -1.\n";
2781 m_context.getTestContext().getLog()
2782 << tcu::TestLog::Message
2784 << tcu::TestLog::EndMessage;
2787 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2791 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2794 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2795 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2797 const tcu::Vec4 color[] =
2799 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), // green
2800 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), // yellow
2801 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), // blue
2802 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), // red
2805 std::vector<deUint32> bindTimeOffsets;
2806 std::vector<tcu::Vec4> colors;
2807 std::vector<deUint32> dataOffsets;
2808 std::vector<deUint32> viewOffsets;
2809 std::vector<deUint32> bufferSizes;
2810 std::vector<AllocationSp> bufferMems;
2811 std::vector<BufferHandleSp> buffers;
2813 for (deUint32 bufferNdx = 0; bufferNdx < getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface); bufferNdx++)
2815 const deUint32 staticOffsets[] =
2817 STATIC_OFFSET_VALUE_A,
2818 STATIC_OFFSET_VALUE_B
2821 const deUint32 dynamicOffset[] =
2823 DYNAMIC_OFFSET_VALUE_A,
2824 DYNAMIC_OFFSET_VALUE_B
2827 const deUint32 parity = bufferNdx % 2;
2828 bindTimeOffsets.push_back((m_dynamicOffsetNonZero) ? (dynamicOffset[parity]) : (0u));
2830 const deUint32 dataOffset = ((isDynamicCase) ? (bindTimeOffsets.back()) : 0) + ((m_setViewOffset) ? (staticOffsets[parity]) : (0u));
2831 const deUint32 viewOffset = ((m_setViewOffset) ? (staticOffsets[parity]) : (0u));
2833 colors.push_back(color[bufferNdx % DE_LENGTH_OF_ARRAY(color)]);
2834 dataOffsets.push_back(dataOffset);
2835 viewOffsets.push_back(viewOffset);
2836 bufferSizes.push_back(dataOffsets.back() + ADDRESSABLE_SIZE);
2838 de::MovePtr<vk::Allocation> bufferMem;
2839 vk::Move<vk::VkBuffer> buffer (createColorDataBuffer(dataOffsets.back(), bufferSizes.back(), color[(bufferNdx * 2) % DE_LENGTH_OF_ARRAY(color)], color[(bufferNdx * 2 + 1) % DE_LENGTH_OF_ARRAY(color)], &bufferMem));
2841 bufferMems.push_back(AllocationSp(bufferMem.release()));
2842 buffers.push_back(BufferHandleSp(new BufferHandleUp(buffer)));
2845 const vk::Unique<vk::VkDescriptorPool> descriptorPool(createDescriptorPool());
2846 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
2847 std::vector<DescriptorSetHandleSp> descriptorSets;
2848 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
2849 std::vector<vk::VkDescriptorSet> setHandles;
2851 const deUint32 numSrcBuffers = getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface);
2853 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2855 const deUint32 ndx0 = (setNdx * getInterfaceNumResources(m_shaderInterface)) % numSrcBuffers;
2856 const deUint32 ndx1 = (setNdx * getInterfaceNumResources(m_shaderInterface) + 1) % numSrcBuffers;
2858 vk::Move<vk::VkDescriptorSetLayout> layout = createDescriptorSetLayout(setNdx);
2859 vk::Move<vk::VkDescriptorSet> set = createDescriptorSet(*descriptorPool, *layout, setNdx, **buffers[ndx0], viewOffsets[ndx0], **buffers[ndx1], viewOffsets[ndx1], m_result.getBuffer());
2861 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
2862 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(set)));
2864 layoutHandles.push_back(**descriptorSetLayouts.back());
2865 setHandles.push_back(**descriptorSets.back());
2867 // Add an empty descriptor set layout between sets 0 and 2
2868 if (setNdx == 0 && m_descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS)
2870 vk::DescriptorSetLayoutBuilder emptyBuilder;
2871 vk::Move<vk::VkDescriptorSetLayout> emptyLayout = emptyBuilder.build(m_vki, m_device, (vk::VkDescriptorSetLayoutCreateFlags)0);
2873 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(emptyLayout)));
2874 layoutHandles.push_back(**descriptorSetLayouts.back());
2878 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), (int)layoutHandles.size(), &layoutHandles.front());
2879 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2881 std::vector<vk::VkBufferMemoryBarrier> bufferBarriers;
2883 for (deUint32 bufferNdx = 0; bufferNdx < numSrcBuffers; bufferNdx++)
2885 const vk::VkBufferMemoryBarrier barrier =
2887 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2889 vk::VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask
2890 inputBit, // dstAccessMask
2891 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2892 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2893 **buffers[bufferNdx], // buffer
2894 (vk::VkDeviceSize)0u, // offset
2895 (vk::VkDeviceSize)bufferSizes[bufferNdx], // size
2898 bufferBarriers.push_back(barrier);
2901 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (&bindTimeOffsets.front()) : (DE_NULL);
2902 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2903 const vk::VkBufferMemoryBarrier* const preBarriers = &bufferBarriers.front();
2904 const int numPreBarriers = numSrcBuffers;
2905 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
2906 const int numPostBarriers = 1;
2908 const ComputeCommand compute (m_vki,
2910 pipeline.getPipeline(),
2911 pipeline.getPipelineLayout(),
2912 tcu::UVec3(4, 1, 1),
2914 m_descriptorSetCount, &setHandles.front(),
2915 numDynamicOffsets, dynamicOffsets,
2916 numPreBarriers, preBarriers,
2917 numPostBarriers, postBarriers);
2919 tcu::Vec4 refQuadrantValue14 = tcu::Vec4(0.0f);
2920 tcu::Vec4 refQuadrantValue23 = tcu::Vec4(0.0f);
2922 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2924 deUint32 offset = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? 1 : 3;
2925 refQuadrantValue14 += color[(2 * setNdx * getInterfaceNumResources(m_shaderInterface) + offset) % DE_LENGTH_OF_ARRAY(color)];
2926 refQuadrantValue23 += color[(2 * setNdx * getInterfaceNumResources(m_shaderInterface)) % DE_LENGTH_OF_ARRAY(color)];
2929 refQuadrantValue14 = refQuadrantValue14 / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
2930 refQuadrantValue23 = refQuadrantValue23 / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
2932 const tcu::Vec4 references[4] =
2939 tcu::Vec4 results[4];
2941 #ifndef CTS_USES_VULKANSC
2942 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
2944 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2946 const deUint32 ndx0 = (setNdx * getInterfaceNumResources(m_shaderInterface)) % numSrcBuffers;
2947 const deUint32 ndx1 = (setNdx * getInterfaceNumResources(m_shaderInterface) + 1) % numSrcBuffers;
2949 writeDescriptorSetWithTemplate(DE_NULL, layoutHandles[setNdx], setNdx, **buffers[ndx0], viewOffsets[ndx0], **buffers[ndx1], viewOffsets[ndx1], m_result.getBuffer(), true, pipeline.getPipelineLayout());
2951 compute.submitAndWait(m_queueFamilyIndex, m_queue, &m_updateTemplates, &m_updateRegistry);
2953 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
2955 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2957 const deUint32 ndx0 = (setNdx * getInterfaceNumResources(m_shaderInterface)) % numSrcBuffers;
2958 const deUint32 ndx1 = (setNdx * getInterfaceNumResources(m_shaderInterface) + 1) % numSrcBuffers;
2960 writeDescriptorSet(DE_NULL, setNdx, **buffers[ndx0], viewOffsets[ndx0], **buffers[ndx1], viewOffsets[ndx1], m_result.getBuffer());
2963 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder, m_descriptorsPerSet);
2968 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2970 m_result.readResultContentsTo(&results);
2973 if (results[0] == references[0] &&
2974 results[1] == references[1] &&
2975 results[2] == references[2] &&
2976 results[3] == references[3])
2978 return tcu::TestStatus::pass("Pass");
2980 else if (results[0] == tcu::Vec4(-1.0f) &&
2981 results[1] == tcu::Vec4(-1.0f) &&
2982 results[2] == tcu::Vec4(-1.0f) &&
2983 results[3] == tcu::Vec4(-1.0f))
2985 m_context.getTestContext().getLog()
2986 << tcu::TestLog::Message
2987 << "Result buffer was not written to."
2988 << tcu::TestLog::EndMessage;
2989 return tcu::TestStatus::fail("Result buffer was not written to");
2993 m_context.getTestContext().getLog()
2994 << tcu::TestLog::Message
2995 << "Error expected ["
2996 << references[0] << ", "
2997 << references[1] << ", "
2998 << references[2] << ", "
2999 << references[3] << "], got ["
3000 << results[0] << ", "
3001 << results[1] << ", "
3002 << results[2] << ", "
3003 << results[3] << "]"
3004 << tcu::TestLog::EndMessage;
3005 return tcu::TestStatus::fail("Invalid result values");
3009 class QuadrantRendederCase : public vkt::TestCase
3012 QuadrantRendederCase (tcu::TestContext& testCtx,
3014 const char* description,
3015 glu::GLSLVersion glslVersion,
3016 vk::VkShaderStageFlags exitingStages,
3017 vk::VkShaderStageFlags activeStages,
3018 DescriptorSetCount descriptorSetCount);
3020 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
3021 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
3022 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
3023 virtual std::string genNoAccessSource (void) const = 0;
3025 std::string genVertexSource (void) const;
3026 std::string genTessCtrlSource (void) const;
3027 std::string genTessEvalSource (void) const;
3028 std::string genGeometrySource (void) const;
3029 std::string genFragmentSource (void) const;
3030 std::string genComputeSource (void) const;
3032 void initPrograms (vk::SourceCollections& programCollection) const;
3035 const glu::GLSLVersion m_glslVersion;
3036 const vk::VkShaderStageFlags m_exitingStages;
3037 const vk::VkShaderStageFlags m_activeStages;
3038 const DescriptorSetCount m_descriptorSetCount;
3041 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
3043 const char* description,
3044 glu::GLSLVersion glslVersion,
3045 vk::VkShaderStageFlags exitingStages,
3046 vk::VkShaderStageFlags activeStages,
3047 DescriptorSetCount descriptorSetCount)
3048 : vkt::TestCase (testCtx, name, description)
3049 , m_glslVersion (glslVersion)
3050 , m_exitingStages (exitingStages)
3051 , m_activeStages (activeStages)
3052 , m_descriptorSetCount (descriptorSetCount)
3054 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
3057 std::string QuadrantRendederCase::genVertexSource (void) const
3059 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
3060 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
3061 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
3063 const char* const fragColorPrec = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? "highp" : "mediump";
3064 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3065 std::ostringstream buf;
3067 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
3069 const bool onlyVS = (m_activeStages == vk::VK_SHADER_STAGE_VERTEX_BIT);
3071 // active vertex shader
3072 buf << versionDecl << "\n"
3073 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT);
3074 buf << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0);
3075 buf << "layout(location = 0) out " << fragColorPrec << " vec4 " << nextStageName << "_color;\n"
3076 << (onlyVS ? "" : "layout(location = 1) flat out highp int " + de::toString(nextStageName) + "_quadrant_id;\n")
3077 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
3078 << "void main (void)\n"
3080 << " highp vec4 result_position;\n"
3081 << " highp int quadrant_id;\n"
3082 << s_quadrantGenVertexPosSource
3083 << " gl_Position = result_position;\n"
3084 << (onlyVS ? "" : "\t" + de::toString(nextStageName) + "_quadrant_id = quadrant_id;\n")
3086 << " highp vec4 result_color;\n"
3087 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
3088 << " " << nextStageName << "_color = result_color;\n"
3094 buf << versionDecl << "\n"
3095 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
3096 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
3097 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
3098 << "void main (void)\n"
3100 << " highp vec4 result_position;\n"
3101 << " highp int quadrant_id;\n"
3102 << s_quadrantGenVertexPosSource
3103 << " gl_Position = result_position;\n"
3104 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
3111 std::string QuadrantRendederCase::genTessCtrlSource (void) const
3113 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3114 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
3115 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
3116 std::ostringstream buf;
3118 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
3120 // contributing not implemented
3121 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
3124 buf << versionDecl << "\n"
3126 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3127 << "layout(vertices=3) out;\n"
3128 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
3129 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
3130 << "layout(location = 0) out highp vec4 tes_color[];\n"
3131 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
3132 << "void main (void)\n"
3134 << " highp vec4 result_color;\n"
3135 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
3136 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3138 << " tes_color[gl_InvocationID] = result_color;\n"
3140 << " // no dynamic input block indexing\n"
3141 << " highp vec4 position;\n"
3142 << " if (gl_InvocationID == 0)\n"
3143 << " position = gl_in[0].gl_Position;\n"
3144 << " else if (gl_InvocationID == 1)\n"
3145 << " position = gl_in[1].gl_Position;\n"
3147 << " position = gl_in[2].gl_Position;\n"
3148 << " gl_out[gl_InvocationID].gl_Position = position;\n"
3149 << " gl_TessLevelInner[0] = 2.8;\n"
3150 << " gl_TessLevelInner[1] = 2.8;\n"
3151 << " gl_TessLevelOuter[0] = 2.8;\n"
3152 << " gl_TessLevelOuter[1] = 2.8;\n"
3153 << " gl_TessLevelOuter[2] = 2.8;\n"
3154 << " gl_TessLevelOuter[3] = 2.8;\n"
3157 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
3159 // active te shader, tc passthru
3160 buf << versionDecl << "\n"
3162 << "layout(vertices=3) out;\n"
3163 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
3164 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
3165 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
3166 << "void main (void)\n"
3168 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
3170 << " // no dynamic input block indexing\n"
3171 << " highp vec4 position;\n"
3172 << " if (gl_InvocationID == 0)\n"
3173 << " position = gl_in[0].gl_Position;\n"
3174 << " else if (gl_InvocationID == 1)\n"
3175 << " position = gl_in[1].gl_Position;\n"
3177 << " position = gl_in[2].gl_Position;\n"
3178 << " gl_out[gl_InvocationID].gl_Position = position;\n"
3179 << " gl_TessLevelInner[0] = 2.8;\n"
3180 << " gl_TessLevelInner[1] = 2.8;\n"
3181 << " gl_TessLevelOuter[0] = 2.8;\n"
3182 << " gl_TessLevelOuter[1] = 2.8;\n"
3183 << " gl_TessLevelOuter[2] = 2.8;\n"
3184 << " gl_TessLevelOuter[3] = 2.8;\n"
3189 // passthrough not implemented
3190 DE_FATAL("not implemented");
3196 std::string QuadrantRendederCase::genTessEvalSource (void) const
3198 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3199 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
3200 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
3201 std::ostringstream buf;
3203 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
3205 // contributing not implemented
3206 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
3209 buf << versionDecl << "\n"
3211 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3212 << "layout(triangles) in;\n"
3213 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
3214 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
3215 << "layout(location = 0) out mediump vec4 frag_color;\n"
3216 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
3217 << "void main (void)\n"
3219 << " highp vec4 result_color;\n"
3220 << " highp int quadrant_id = tes_quadrant_id[0];\n"
3221 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3223 << " frag_color = result_color;\n"
3224 << " 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"
3227 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
3229 // contributing not implemented
3230 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
3232 // active tc shader, te is passthru
3233 buf << versionDecl << "\n"
3235 << "layout(triangles) in;\n"
3236 << "layout(location = 0) in highp vec4 tes_color[];\n"
3237 << "layout(location = 0) out mediump vec4 frag_color;\n"
3238 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
3239 << "void main (void)\n"
3241 << " frag_color = tes_color[0];\n"
3242 << " 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"
3247 // passthrough not implemented
3248 DE_FATAL("not implemented");
3254 std::string QuadrantRendederCase::genGeometrySource (void) const
3256 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3257 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
3258 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
3259 std::ostringstream buf;
3261 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
3263 // contributing not implemented
3264 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
3266 // active geometry shader
3267 buf << versionDecl << "\n"
3269 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3270 << "layout(triangles) in;\n"
3271 << "layout(triangle_strip, max_vertices=4) out;\n"
3272 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
3273 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
3274 << "layout(location = 0) out mediump vec4 frag_color;\n"
3275 << genPerVertexBlock(vk::VK_SHADER_STAGE_GEOMETRY_BIT, m_glslVersion)
3276 << "void main (void)\n"
3278 << " highp int quadrant_id;\n"
3279 << " highp vec4 result_color;\n"
3281 << " quadrant_id = geo_quadrant_id[0];\n"
3282 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3283 << " frag_color = result_color;\n"
3284 << " gl_Position = gl_in[0].gl_Position;\n"
3285 << " EmitVertex();\n"
3287 << " quadrant_id = geo_quadrant_id[1];\n"
3288 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3289 << " frag_color = result_color;\n"
3290 << " gl_Position = gl_in[1].gl_Position;\n"
3291 << " EmitVertex();\n"
3293 << " quadrant_id = geo_quadrant_id[2];\n"
3294 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3295 << " frag_color = result_color;\n"
3296 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
3297 << " EmitVertex();\n"
3299 << " quadrant_id = geo_quadrant_id[0];\n"
3300 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3301 << " frag_color = result_color;\n"
3302 << " gl_Position = gl_in[2].gl_Position;\n"
3303 << " EmitVertex();\n"
3308 // passthrough not implemented
3309 DE_FATAL("not implemented");
3315 std::string QuadrantRendederCase::genFragmentSource (void) const
3317 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3318 std::ostringstream buf;
3320 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
3322 buf << versionDecl << "\n"
3323 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3324 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
3326 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
3328 // there are other stages, this is just a contributor
3329 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
3332 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
3333 << "layout(location = 0) out mediump vec4 o_color;\n"
3334 << "void main (void)\n"
3336 << " highp int quadrant_id = frag_quadrant_id;\n"
3337 << " highp vec4 result_color;\n"
3338 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
3340 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
3343 buf << " if (frag_quadrant_id < 2)\n"
3344 << " o_color = result_color;\n"
3346 << " o_color = frag_color;\n";
3349 buf << " o_color = result_color;\n";
3353 else if (m_activeStages == 0u)
3355 // special case, no active stages
3356 buf << versionDecl << "\n"
3357 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
3358 << "layout(location = 0) out mediump vec4 o_color;\n"
3359 << "void main (void)\n"
3361 << " highp int quadrant_id = frag_quadrant_id;\n"
3362 << " highp vec4 result_color;\n"
3363 << genNoAccessSource()
3364 << " o_color = result_color;\n"
3370 buf << versionDecl << "\n"
3371 << "layout(location = 0) in mediump vec4 frag_color;\n"
3372 "layout(location = 0) out mediump vec4 o_color;\n"
3373 "void main (void)\n"
3375 " o_color = frag_color;\n"
3382 std::string QuadrantRendederCase::genComputeSource (void) const
3384 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3385 std::ostringstream buf;
3387 buf << versionDecl << "\n"
3388 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
3389 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3390 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
3391 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
3393 << " highp vec4 read_colors[4];\n"
3395 << "void main (void)\n"
3397 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
3398 << " highp vec4 result_color;\n"
3399 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
3400 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
3406 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
3408 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
3409 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
3411 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
3412 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
3414 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
3415 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
3417 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
3418 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
3420 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
3421 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
3423 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
3424 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
3427 class BufferDescriptorCase : public QuadrantRendederCase
3432 FLAG_VIEW_OFFSET = (1u << 1u),
3433 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
3434 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
3436 // enum continues where resource flags ends
3437 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
3439 BufferDescriptorCase (tcu::TestContext& testCtx,
3440 DescriptorUpdateMethod updateMethod,
3442 const char* description,
3443 bool isPrimaryCmdBuf,
3444 vk::VkDescriptorType descriptorType,
3445 vk::VkShaderStageFlags exitingStages,
3446 vk::VkShaderStageFlags activeStages,
3447 DescriptorSetCount descriptorSetCount,
3448 ShaderInputInterface shaderInterface,
3452 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
3453 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
3454 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
3455 std::string genNoAccessSource (void) const;
3457 vkt::TestInstance* createInstance (vkt::Context& context) const;
3459 const DescriptorUpdateMethod m_updateMethod;
3460 const bool m_viewOffset;
3461 const bool m_dynamicOffsetSet;
3462 const bool m_dynamicOffsetNonZero;
3463 const bool m_isPrimaryCmdBuf;
3464 const vk::VkDescriptorType m_descriptorType;
3465 const DescriptorSetCount m_descriptorSetCount;
3466 const ShaderInputInterface m_shaderInterface;
3469 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
3470 DescriptorUpdateMethod updateMethod,
3472 const char* description,
3473 bool isPrimaryCmdBuf,
3474 vk::VkDescriptorType descriptorType,
3475 vk::VkShaderStageFlags exitingStages,
3476 vk::VkShaderStageFlags activeStages,
3477 DescriptorSetCount descriptorSetCount,
3478 ShaderInputInterface shaderInterface,
3480 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages, descriptorSetCount)
3481 , m_updateMethod (updateMethod)
3482 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
3483 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
3484 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
3485 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
3486 , m_descriptorType (descriptorType)
3487 , m_descriptorSetCount (descriptorSetCount)
3488 , m_shaderInterface (shaderInterface)
3492 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
3498 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
3502 const bool isUniform = isUniformDescriptorType(m_descriptorType);
3503 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
3504 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
3506 std::ostringstream buf;
3508 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
3510 // Result buffer is bound only to the first descriptor set in compute shader cases
3511 const int descBinding = numUsedBindings - ((m_activeStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) ? (setNdx == 0 ? 0 : 1) : 0);
3512 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
3513 const deUint32 descriptorSet = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
3515 switch (m_shaderInterface)
3517 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3518 buf << "layout(set = " << descriptorSet << ", binding = " << (descBinding) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "\n"
3520 << " highp vec4 colorA;\n"
3521 << " highp vec4 colorB;\n"
3522 << "} b_instance" << setNdxPostfix << ";\n";
3525 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3526 buf << "layout(set = " << descriptorSet << ", binding = " << (descBinding) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "A\n"
3528 << " highp vec4 colorA;\n"
3529 << " highp vec4 colorB;\n"
3530 << "} b_instance" << setNdxPostfix << "A;\n"
3531 << "layout(set = " << descriptorSet << ", binding = " << (descBinding + 1) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "B\n"
3533 << " highp vec4 colorA;\n"
3534 << " highp vec4 colorB;\n"
3535 << "} b_instance" << setNdxPostfix << "B;\n";
3538 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
3539 buf << "layout(set = " << descriptorSet << ", binding = " << de::toString(descBinding) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "A\n"
3541 << " highp vec4 colorA;\n"
3542 << " highp vec4 colorB;\n"
3543 << "} b_instance" << setNdxPostfix << "A;\n"
3544 << "layout(set = " << descriptorSet << ", binding = " << de::toString(descBinding + 2) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "B\n"
3546 << " highp vec4 colorA;\n"
3547 << " highp vec4 colorB;\n"
3548 << "} b_instance" << setNdxPostfix << "B;\n";
3551 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
3552 buf << "layout(set = " << descriptorSet << ", binding = " << de::toString(getArbitraryBindingIndex(0)) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "A\n"
3554 << " highp vec4 colorA;\n"
3555 << " highp vec4 colorB;\n"
3556 << "} b_instance" << setNdxPostfix << "A;\n"
3557 << "layout(set = " << descriptorSet << ", binding = " << de::toString(getArbitraryBindingIndex(1)) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "B\n"
3559 << " highp vec4 colorA;\n"
3560 << " highp vec4 colorB;\n"
3561 << "} b_instance" << setNdxPostfix << "B;\n";
3564 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3565 buf << "layout(set = " << descriptorSet << ", binding = " << (descBinding) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "\n"
3567 << " highp vec4 colorA;\n"
3568 << " highp vec4 colorB;\n"
3569 << "} b_instances" << setNdxPostfix << "[2];\n";
3573 DE_FATAL("Impossible");
3579 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
3583 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
3584 std::ostringstream buf;
3586 buf << " result_color = vec4(0.0);\n";
3588 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
3590 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
3592 switch (m_shaderInterface)
3594 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3595 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3596 << " result_color += b_instance" << setNdxPostfix << ".colorA;\n"
3598 << " result_color += b_instance" << setNdxPostfix << ".colorB;\n";
3601 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3602 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
3603 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
3604 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3605 << " result_color += b_instance" << setNdxPostfix << "A.colorA;\n"
3607 << " result_color += b_instance" << setNdxPostfix << "B.colorB;\n";
3610 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3611 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3612 << " result_color += b_instances" << setNdxPostfix << "[0].colorA;\n"
3614 << " result_color += b_instances" << setNdxPostfix << "[1].colorB;\n";
3618 DE_FATAL("Impossible");
3622 if (getDescriptorSetCount(m_descriptorSetCount) > 1)
3623 buf << " result_color /= vec4(" << getDescriptorSetCount(m_descriptorSetCount) << ".0);\n";
3628 std::string BufferDescriptorCase::genNoAccessSource (void) const
3630 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
3631 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3633 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
3636 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
3638 verifyDriverSupport(context.getUsedApiVersion(), context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
3640 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
3642 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
3643 return new BufferComputeInstance(context, m_updateMethod, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
3646 return new BufferRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_descriptorSetCount, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
3649 class ImageInstanceImages
3652 ImageInstanceImages (const vk::DeviceInterface& vki,
3653 vk::VkDevice device,
3654 deUint32 queueFamilyIndex,
3656 vk::Allocator& allocator,
3657 vk::VkDescriptorType descriptorType,
3658 vk::VkImageViewType viewType,
3660 deUint32 baseMipLevel,
3661 deUint32 baseArraySlice);
3664 static std::vector<tcu::TextureLevelPyramid> createSourceImages (int numImages,
3665 vk::VkImageViewType viewType,
3666 tcu::TextureFormat imageFormat);
3668 static std::vector<ImageHandleSp> createImages (const vk::DeviceInterface& vki,
3669 vk::VkDevice device,
3670 vk::Allocator& allocator,
3671 deUint32 queueFamilyIndex,
3673 vk::VkDescriptorType descriptorType,
3674 vk::VkImageViewType viewType,
3675 std::vector<AllocationSp>& imageMemory,
3676 const std::vector<tcu::TextureLevelPyramid>& sourceImages);
3678 static std::vector<ImageViewHandleSp> createImageViews (const vk::DeviceInterface& vki,
3679 vk::VkDevice device,
3680 vk::VkImageViewType viewType,
3681 const std::vector<tcu::TextureLevelPyramid>& sourceImages,
3682 const std::vector<ImageHandleSp>& images,
3683 deUint32 baseMipLevel,
3684 deUint32 baseArraySlice);
3686 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
3687 vk::VkDevice device,
3688 vk::Allocator& allocator,
3689 vk::VkDescriptorType descriptorType,
3690 vk::VkImageViewType viewType,
3691 const tcu::TextureLevelPyramid& sourceImage,
3692 de::MovePtr<vk::Allocation>* outAllocation);
3694 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
3695 vk::VkDevice device,
3696 vk::VkImageViewType viewType,
3697 const tcu::TextureLevelPyramid& sourceImage,
3699 deUint32 baseMipLevel,
3700 deUint32 baseArraySlice);
3702 static void populateSourceImage (tcu::TextureLevelPyramid* dst,
3703 vk::VkImageViewType viewType,
3706 static void uploadImage (const vk::DeviceInterface& vki,
3707 vk::VkDevice device,
3708 deUint32 queueFamilyIndex,
3710 vk::Allocator& allocator,
3712 vk::VkImageLayout layout,
3713 vk::VkImageViewType viewType,
3714 const tcu::TextureLevelPyramid& data);
3724 const vk::VkImageViewType m_viewType;
3725 const deUint32 m_baseMipLevel;
3726 const deUint32 m_baseArraySlice;
3727 const tcu::TextureFormat m_imageFormat;
3728 const std::vector<tcu::TextureLevelPyramid> m_sourceImage;
3729 std::vector<AllocationSp> m_imageMemory;
3730 const std::vector<ImageHandleSp> m_image;
3731 const std::vector<ImageViewHandleSp> m_imageView;
3734 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
3735 vk::VkDevice device,
3736 deUint32 queueFamilyIndex,
3738 vk::Allocator& allocator,
3739 vk::VkDescriptorType descriptorType,
3740 vk::VkImageViewType viewType,
3742 deUint32 baseMipLevel,
3743 deUint32 baseArraySlice)
3744 : m_viewType (viewType)
3745 , m_baseMipLevel (baseMipLevel)
3746 , m_baseArraySlice (baseArraySlice)
3747 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
3748 , m_sourceImage (createSourceImages(numImages, viewType, m_imageFormat))
3750 , m_image (createImages(vki, device, allocator, queueFamilyIndex, queue, descriptorType, viewType, m_imageMemory, m_sourceImage))
3751 , m_imageView (createImageViews(vki, device, viewType, m_sourceImage, m_image, m_baseMipLevel, m_baseArraySlice))
3755 std::vector<tcu::TextureLevelPyramid> ImageInstanceImages::createSourceImages (int numImages,
3756 vk::VkImageViewType viewType,
3757 tcu::TextureFormat imageFormat)
3759 std::vector<tcu::TextureLevelPyramid> sourceImages(numImages, tcu::TextureLevelPyramid(imageFormat, NUM_MIP_LEVELS));
3761 for (int imageNdx = 0; imageNdx < numImages; imageNdx++)
3762 populateSourceImage(&sourceImages.at(imageNdx), viewType, imageNdx);
3764 return sourceImages;
3767 std::vector<ImageHandleSp> ImageInstanceImages::createImages (const vk::DeviceInterface& vki,
3768 vk::VkDevice device,
3769 vk::Allocator& allocator,
3770 deUint32 queueFamilyIndex,
3772 vk::VkDescriptorType descriptorType,
3773 vk::VkImageViewType viewType,
3774 std::vector<AllocationSp>& imageMemory,
3775 const std::vector<tcu::TextureLevelPyramid>& sourceImages)
3777 std::vector<ImageHandleSp> images;
3778 const vk::VkImageLayout layout = getImageLayoutForDescriptorType(descriptorType);
3780 for (int imageNdx = 0; imageNdx < (int)sourceImages.size(); imageNdx++)
3782 de::MovePtr<vk::Allocation> memory;
3783 vk::Move<vk::VkImage> image = createImage(vki, device, allocator, descriptorType, viewType, sourceImages[imageNdx], &memory);
3785 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *image, layout, viewType, sourceImages[imageNdx]);
3787 imageMemory.push_back(AllocationSp(memory.release()));
3788 images.push_back(ImageHandleSp(new ImageHandleUp(image)));
3793 std::vector<ImageViewHandleSp> ImageInstanceImages::createImageViews (const vk::DeviceInterface& vki,
3794 vk::VkDevice device,
3795 vk::VkImageViewType viewType,
3796 const std::vector<tcu::TextureLevelPyramid>& sourceImages,
3797 const std::vector<ImageHandleSp>& images,
3798 deUint32 baseMipLevel,
3799 deUint32 baseArraySlice)
3801 std::vector<ImageViewHandleSp> imageViews;
3802 for (int imageNdx = 0; imageNdx < (int)sourceImages.size(); imageNdx++)
3804 vk::Move<vk::VkImageView> imageView = createImageView(vki, device, viewType, sourceImages[imageNdx], **images[imageNdx], baseMipLevel, baseArraySlice);
3805 imageViews.push_back(ImageViewHandleSp(new ImageViewHandleUp(imageView)));
3810 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
3811 vk::VkDevice device,
3812 vk::Allocator& allocator,
3813 vk::VkDescriptorType descriptorType,
3814 vk::VkImageViewType viewType,
3815 const tcu::TextureLevelPyramid& sourceImage,
3816 de::MovePtr<vk::Allocation>* outAllocation)
3818 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3819 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
3820 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
3821 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
3822 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
3823 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
3824 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3825 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
3827 const vk::VkExtent3D extent =
3830 (deUint32)baseLevel.getWidth(),
3833 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1u) : (deUint32)baseLevel.getHeight(),
3836 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deUint32)baseLevel.getDepth()) : (1u),
3838 const vk::VkImageCreateInfo createInfo =
3840 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3842 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
3843 viewTypeToImageType(viewType), // imageType
3844 vk::mapTextureFormat(baseLevel.getFormat()), // format
3846 (deUint32)sourceImage.getNumLevels(), // mipLevels
3847 arraySize, // arraySize
3848 vk::VK_SAMPLE_COUNT_1_BIT, // samples
3849 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
3850 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
3851 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3852 0u, // queueFamilyCount
3853 DE_NULL, // pQueueFamilyIndices
3854 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
3856 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
3858 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
3862 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
3863 vk::VkDevice device,
3864 vk::VkImageViewType viewType,
3865 const tcu::TextureLevelPyramid& sourceImage,
3867 deUint32 baseMipLevel,
3868 deUint32 baseArraySlice)
3870 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3871 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
3872 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
3873 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
3874 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
3875 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
3876 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3877 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
3878 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
3881 DE_ASSERT(viewArraySize > 0);
3883 const vk::VkImageSubresourceRange resourceRange =
3885 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3886 baseMipLevel, // baseMipLevel
3887 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
3888 viewTypeBaseSlice, // baseArraySlice
3889 viewArraySize, // arraySize
3891 const vk::VkImageViewCreateInfo createInfo =
3893 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3895 (vk::VkImageViewCreateFlags)0,
3897 viewType, // viewType
3898 vk::mapTextureFormat(baseLevel.getFormat()), // format
3900 vk::VK_COMPONENT_SWIZZLE_R,
3901 vk::VK_COMPONENT_SWIZZLE_G,
3902 vk::VK_COMPONENT_SWIZZLE_B,
3903 vk::VK_COMPONENT_SWIZZLE_A
3905 resourceRange, // subresourceRange
3907 return vk::createImageView(vki, device, &createInfo);
3910 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, vk::VkImageViewType viewType, int imageNdx)
3912 const int numLevels = dst->getNumLevels();
3914 for (int level = 0; level < numLevels; ++level)
3916 const int width = IMAGE_SIZE >> level;
3917 const int height = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
3918 : (IMAGE_SIZE >> level);
3919 const int depth = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
3920 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
3921 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
3922 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
3925 dst->allocLevel(level, width, height, depth);
3928 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
3930 for (int z = 0; z < depth; ++z)
3931 for (int y = 0; y < height; ++y)
3932 for (int x = 0; x < width; ++x)
3934 const int gradPos = x + y + z;
3935 const int gradMax = width + height + depth - 3;
3937 int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
3938 int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
3939 int blue = (128 * level / numLevels) + ((imageNdx % 2 == 0) ? 127 : 0); //!< level and image index (detects incorrect lod / image)
3941 DE_ASSERT(de::inRange(red, 0, 255));
3942 DE_ASSERT(de::inRange(green, 0, 255));
3943 DE_ASSERT(de::inRange(blue, 0, 255));
3945 if (imageNdx % 3 == 0) red = 255 - red;
3946 if (imageNdx % 4 == 0) green = 255 - green;
3947 if (imageNdx % 5 == 0) blue = 255 - blue;
3949 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3955 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3956 vk::VkDevice device,
3957 deUint32 queueFamilyIndex,
3959 vk::Allocator& allocator,
3961 vk::VkImageLayout layout,
3962 vk::VkImageViewType viewType,
3963 const tcu::TextureLevelPyramid& data)
3965 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3966 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3967 ((deUint32)ARRAY_SIZE);
3968 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3969 const vk::VkBufferCreateInfo bufferCreateInfo =
3971 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3974 dataBufferSize, // size
3975 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
3976 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3977 0u, // queueFamilyCount
3978 DE_NULL, // pQueueFamilyIndices
3981 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3982 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3983 std::vector<vk::VkBufferImageCopy> copySlices;
3984 // copy data to buffer
3985 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, viewType , ©Slices);
3986 flushAlloc(vki, device, *dataBufferMemory);
3988 // copy buffer to image
3989 copyBufferToImage(vki, device, queue, queueFamilyIndex, *dataBuffer, dataBufferSize, copySlices, DE_NULL, vk::VK_IMAGE_ASPECT_COLOR_BIT, data.getNumLevels(), arraySize, image, layout);
3992 class ImageFetchInstanceImages : private ImageInstanceImages
3995 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3996 vk::VkDevice device,
3997 deUint32 queueFamilyIndex,
3999 vk::Allocator& allocator,
4000 vk::VkDescriptorType descriptorType,
4001 DescriptorSetCount descriptorSetCount,
4002 ShaderInputInterface shaderInterface,
4003 vk::VkImageViewType viewType,
4004 deUint32 baseMipLevel,
4005 deUint32 baseArraySlice);
4007 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType,
4008 deUint32 baseMipLevel,
4009 deUint32 baseArraySlice,
4012 tcu::Vec4 fetchImageValue (int fetchPosNdx, int setNdx) const;
4014 inline tcu::TextureLevelPyramid getSourceImage (int ndx) const { return m_sourceImage[ndx]; }
4015 inline vk::VkImageView getImageView (int ndx) const { return **m_imageView[ndx % m_imageView.size()]; }
4020 // some arbitrary sample points for all four quadrants
4021 SAMPLE_POINT_0_X = 6,
4022 SAMPLE_POINT_0_Y = 13,
4023 SAMPLE_POINT_0_Z = 49,
4025 SAMPLE_POINT_1_X = 51,
4026 SAMPLE_POINT_1_Y = 40,
4027 SAMPLE_POINT_1_Z = 44,
4029 SAMPLE_POINT_2_X = 42,
4030 SAMPLE_POINT_2_Y = 26,
4031 SAMPLE_POINT_2_Z = 19,
4033 SAMPLE_POINT_3_X = 25,
4034 SAMPLE_POINT_3_Y = 25,
4035 SAMPLE_POINT_3_Z = 18,
4038 const ShaderInputInterface m_shaderInterface;
4041 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
4042 vk::VkDevice device,
4043 deUint32 queueFamilyIndex,
4045 vk::Allocator& allocator,
4046 vk::VkDescriptorType descriptorType,
4047 DescriptorSetCount descriptorSetCount,
4048 ShaderInputInterface shaderInterface,
4049 vk::VkImageViewType viewType,
4050 deUint32 baseMipLevel,
4051 deUint32 baseArraySlice)
4052 : ImageInstanceImages (vki,
4059 getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface), // numImages
4062 , m_shaderInterface (shaderInterface)
4066 bool isImageViewTypeArray (vk::VkImageViewType type)
4068 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;
4071 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
4073 const tcu::IVec3 fetchPositions[4] =
4075 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
4076 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
4077 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
4078 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
4080 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
4081 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
4082 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
4086 case vk::VK_IMAGE_VIEW_TYPE_1D:
4087 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
4088 case vk::VK_IMAGE_VIEW_TYPE_2D:
4089 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
4090 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4091 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
4092 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
4094 DE_FATAL("Impossible");
4095 return tcu::IVec3();
4099 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx, int setNdx) const
4101 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
4103 const tcu::TextureLevelPyramid& fetchSrcA = getSourceImage(setNdx * getInterfaceNumResources(m_shaderInterface));
4104 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? fetchSrcA : getSourceImage(setNdx * getInterfaceNumResources(m_shaderInterface) + 1);
4105 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
4106 tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
4108 // add base array layer into the appropriate coordinate, based on the view type
4109 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
4110 fetchPos.z() += 6 * m_baseArraySlice;
4111 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
4112 fetchPos.y() += m_baseArraySlice;
4114 fetchPos.z() += m_baseArraySlice;
4116 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
4119 class ImageFetchRenderInstance : public SingleCmdRenderInstance
4122 ImageFetchRenderInstance (vkt::Context& context,
4123 DescriptorUpdateMethod updateMethod,
4124 bool isPrimaryCmdBuf,
4125 vk::VkDescriptorType descriptorType,
4126 DescriptorSetCount descriptorSetCount,
4127 vk::VkShaderStageFlags stageFlags,
4128 ShaderInputInterface shaderInterface,
4129 vk::VkImageViewType viewType,
4130 deUint32 baseMipLevel,
4131 deUint32 baseArraySlice);
4134 static std::vector<DescriptorSetLayoutHandleSp> createDescriptorSetLayouts (const vk::DeviceInterface& vki,
4135 vk::VkDevice device,
4136 vk::VkDescriptorType descriptorType,
4137 DescriptorSetCount descriptorSetCount,
4138 ShaderInputInterface shaderInterface,
4139 vk::VkShaderStageFlags stageFlags,
4140 DescriptorUpdateMethod updateMethod);
4142 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4143 vk::VkDevice device,
4144 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout);
4146 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4147 vk::VkDevice device,
4148 vk::VkDescriptorType descriptorType,
4149 DescriptorSetCount descriptorSetCount,
4150 ShaderInputInterface shaderInterface);
4152 static std::vector<DescriptorSetHandleSp> createDescriptorSets (const vk::DeviceInterface& vki,
4153 DescriptorUpdateMethod updateMethod,
4154 vk::VkDevice device,
4155 vk::VkDescriptorType descriptorType,
4156 DescriptorSetCount descriptorSetCount,
4157 ShaderInputInterface shaderInterface,
4158 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
4159 vk::VkDescriptorPool pool,
4160 const ImageFetchInstanceImages& images,
4161 vk::DescriptorSetUpdateBuilder& updateBuilder,
4162 #ifndef CTS_USES_VULKANSC
4163 std::vector<UpdateTemplateHandleSp>& updateTemplates,
4164 std::vector<RawUpdateRegistry>& updateRegistry,
4166 std::vector<deUint32>& descriptorsPerSet,
4167 vk::VkPipelineLayout pipelineLayout = DE_NULL);
4169 static void writeDescriptorSet (const vk::DeviceInterface& vki,
4170 vk::VkDevice device,
4171 vk::VkDescriptorType descriptorType,
4172 ShaderInputInterface shaderInterface,
4173 vk::VkDescriptorSetLayout layout,
4174 vk::VkDescriptorPool pool,
4175 vk::VkImageView viewA,
4176 vk::VkImageView viewB,
4177 vk::VkDescriptorSet descriptorSet,
4178 vk::DescriptorSetUpdateBuilder& updateBuilder,
4179 std::vector<deUint32>& descriptorsPerSet,
4180 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
4182 #ifndef CTS_USES_VULKANSC
4183 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
4184 vk::VkDevice device,
4185 vk::VkDescriptorType descriptorType,
4186 ShaderInputInterface shaderInterface,
4187 vk::VkDescriptorSetLayout layout,
4188 vk::VkDescriptorPool pool,
4189 vk::VkImageView viewA,
4190 vk::VkImageView viewB,
4191 vk::VkDescriptorSet descriptorSet,
4192 std::vector<UpdateTemplateHandleSp>& updateTemplates,
4193 std::vector<RawUpdateRegistry>& registry,
4194 bool withPush = false,
4195 vk::VkPipelineLayout pipelineLayout = 0);
4198 void logTestPlan (void) const;
4199 vk::VkPipelineLayout getPipelineLayout (void) const;
4200 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
4201 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4208 const DescriptorUpdateMethod m_updateMethod;
4209 const vk::VkDescriptorType m_descriptorType;
4210 const DescriptorSetCount m_descriptorSetCount;
4211 const vk::VkShaderStageFlags m_stageFlags;
4212 const ShaderInputInterface m_shaderInterface;
4213 const vk::VkImageViewType m_viewType;
4214 const deUint32 m_baseMipLevel;
4215 const deUint32 m_baseArraySlice;
4217 #ifndef CTS_USES_VULKANSC
4218 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
4219 std::vector<RawUpdateRegistry> m_updateRegistry;
4221 vk::DescriptorSetUpdateBuilder m_updateBuilder;
4222 const std::vector<DescriptorSetLayoutHandleSp> m_descriptorSetLayouts;
4223 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4224 const ImageFetchInstanceImages m_images;
4225 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4226 std::vector<deUint32> m_descriptorsPerSet;
4227 const std::vector<DescriptorSetHandleSp> m_descriptorSets;
4230 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
4231 DescriptorUpdateMethod updateMethod,
4232 bool isPrimaryCmdBuf,
4233 vk::VkDescriptorType descriptorType,
4234 DescriptorSetCount descriptorSetCount,
4235 vk::VkShaderStageFlags stageFlags,
4236 ShaderInputInterface shaderInterface,
4237 vk::VkImageViewType viewType,
4238 deUint32 baseMipLevel,
4239 deUint32 baseArraySlice)
4240 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4241 , m_updateMethod (updateMethod)
4242 , m_descriptorType (descriptorType)
4243 , m_descriptorSetCount (descriptorSetCount)
4244 , m_stageFlags (stageFlags)
4245 , m_shaderInterface (shaderInterface)
4246 , m_viewType (viewType)
4247 , m_baseMipLevel (baseMipLevel)
4248 , m_baseArraySlice (baseArraySlice)
4249 #ifndef CTS_USES_VULKANSC
4250 , m_updateTemplates ()
4251 , m_updateRegistry ()
4253 , m_updateBuilder ()
4254 , m_descriptorSetLayouts (createDescriptorSetLayouts(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_stageFlags, m_updateMethod))
4255 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, m_descriptorSetLayouts))
4256 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
4257 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface))
4258 , m_descriptorsPerSet ()
4259 , m_descriptorSets (createDescriptorSets(m_vki, m_updateMethod, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_descriptorSetLayouts, *m_descriptorPool, m_images, m_updateBuilder,
4260 #ifndef CTS_USES_VULKANSC
4264 m_descriptorsPerSet, *m_pipelineLayout))
4268 std::vector<DescriptorSetLayoutHandleSp> ImageFetchRenderInstance::createDescriptorSetLayouts (const vk::DeviceInterface& vki,
4269 vk::VkDevice device,
4270 vk::VkDescriptorType descriptorType,
4271 DescriptorSetCount descriptorSetCount,
4272 ShaderInputInterface shaderInterface,
4273 vk::VkShaderStageFlags stageFlags,
4274 DescriptorUpdateMethod updateMethod)
4276 #ifdef CTS_USES_VULKANSC
4277 DE_UNREF(updateMethod);
4279 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
4280 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
4282 #ifndef CTS_USES_VULKANSC
4283 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
4284 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4286 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
4290 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
4292 vk::DescriptorSetLayoutBuilder builder;
4294 switch (shaderInterface)
4296 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4297 builder.addSingleBinding(descriptorType, stageFlags);
4300 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4301 builder.addSingleBinding(descriptorType, stageFlags);
4302 builder.addSingleBinding(descriptorType, stageFlags);
4305 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4306 builder.addSingleIndexedBinding(descriptorType, stageFlags, 0u);
4307 builder.addSingleIndexedBinding(descriptorType, stageFlags, 2u);
4310 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
4311 builder.addSingleIndexedBinding(descriptorType, stageFlags, getArbitraryBindingIndex(0));
4312 builder.addSingleIndexedBinding(descriptorType, stageFlags, getArbitraryBindingIndex(1));
4315 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4316 builder.addArrayBinding(descriptorType, 2u, stageFlags);
4320 DE_FATAL("Impossible");
4323 vk::Move<vk::VkDescriptorSetLayout> layout = builder.build(vki, device, extraFlags);
4324 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
4326 // Add an empty descriptor set layout between sets 0 and 2
4327 if (setNdx == 0 && descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS)
4329 vk::DescriptorSetLayoutBuilder emptyBuilder;
4330 vk::Move<vk::VkDescriptorSetLayout> emptyLayout = emptyBuilder.build(vki, device, (vk::VkDescriptorSetLayoutCreateFlags)0);
4331 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(emptyLayout)));
4334 return descriptorSetLayouts;
4337 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4338 vk::VkDevice device,
4339 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout)
4341 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
4342 for (size_t setNdx = 0; setNdx < descriptorSetLayout.size(); setNdx++)
4343 layoutHandles.push_back(**descriptorSetLayout[setNdx]);
4345 const vk::VkPipelineLayoutCreateInfo createInfo =
4347 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4349 (vk::VkPipelineLayoutCreateFlags)0,
4350 (deUint32)layoutHandles.size(), // descriptorSetCount
4351 &layoutHandles.front(), // pSetLayouts
4352 0u, // pushConstantRangeCount
4353 DE_NULL, // pPushConstantRanges
4355 return vk::createPipelineLayout(vki, device, &createInfo);
4358 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4359 vk::VkDevice device,
4360 vk::VkDescriptorType descriptorType,
4361 DescriptorSetCount descriptorSetCount,
4362 ShaderInputInterface shaderInterface)
4364 return vk::DescriptorPoolBuilder()
4365 .addType(descriptorType, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface))
4366 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(descriptorSetCount));
4369 std::vector<DescriptorSetHandleSp> ImageFetchRenderInstance::createDescriptorSets (const vk::DeviceInterface& vki,
4370 DescriptorUpdateMethod updateMethod,
4371 vk::VkDevice device,
4372 vk::VkDescriptorType descriptorType,
4373 DescriptorSetCount descriptorSetCount,
4374 ShaderInputInterface shaderInterface,
4375 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
4376 vk::VkDescriptorPool pool,
4377 const ImageFetchInstanceImages& images,
4378 vk::DescriptorSetUpdateBuilder& updateBuilder,
4379 #ifndef CTS_USES_VULKANSC
4380 std::vector<UpdateTemplateHandleSp>& updateTemplates,
4381 std::vector<RawUpdateRegistry>& updateRegistry,
4383 std::vector<deUint32>& descriptorsPerSet,
4384 vk::VkPipelineLayout pipelineLayout)
4386 #ifdef CTS_USES_VULKANSC
4387 DE_UNREF(pipelineLayout);
4389 std::vector<DescriptorSetHandleSp> descriptorSets;
4391 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
4393 vk::VkDescriptorSetLayout layout = **descriptorSetLayouts[getDescriptorSetNdx(descriptorSetCount, setNdx)];
4395 const vk::VkDescriptorSetAllocateInfo allocInfo =
4397 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4404 vk::VkImageView viewA = images.getImageView(setNdx * getInterfaceNumResources(shaderInterface));
4405 vk::VkImageView viewB = images.getImageView(setNdx * getInterfaceNumResources(shaderInterface) + 1);
4407 vk::Move<vk::VkDescriptorSet> descriptorSet;
4408 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4410 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4414 descriptorSet = vk::Move<vk::VkDescriptorSet>();
4417 #ifndef CTS_USES_VULKANSC
4418 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
4420 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplates, updateRegistry);
4422 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4424 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplates, updateRegistry, true, pipelineLayout);
4426 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4428 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, descriptorsPerSet, updateMethod);
4430 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4433 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, descriptorsPerSet);
4436 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(descriptorSet)));
4438 return descriptorSets;
4441 void ImageFetchRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
4442 vk::VkDevice device,
4443 vk::VkDescriptorType descriptorType,
4444 ShaderInputInterface shaderInterface,
4445 vk::VkDescriptorSetLayout layout,
4446 vk::VkDescriptorPool pool,
4447 vk::VkImageView viewA,
4448 vk::VkImageView viewB,
4449 vk::VkDescriptorSet descriptorSet,
4450 vk::DescriptorSetUpdateBuilder& updateBuilder,
4451 std::vector<deUint32>& descriptorsPerSet,
4452 DescriptorUpdateMethod updateMethod)
4456 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
4457 const vk::VkDescriptorImageInfo imageInfos[2] =
4459 makeDescriptorImageInfo(viewA, imageLayout),
4460 makeDescriptorImageInfo(viewB, imageLayout),
4462 deUint32 numDescriptors = 0u;
4464 switch (shaderInterface)
4466 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4467 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4471 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4472 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4473 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
4474 numDescriptors += 2;
4477 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4478 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4479 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), descriptorType, &imageInfos[1]);
4480 numDescriptors += 2;
4483 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
4484 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), descriptorType, &imageInfos[0]);
4485 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), descriptorType, &imageInfos[1]);
4486 numDescriptors += 2;
4489 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4490 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
4495 DE_FATAL("Impossible");
4498 descriptorsPerSet.push_back(numDescriptors);
4500 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4502 updateBuilder.update(vki, device);
4503 updateBuilder.clear();
4507 #ifndef CTS_USES_VULKANSC
4508 void ImageFetchRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
4509 vk::VkDevice device,
4510 vk::VkDescriptorType descriptorType,
4511 ShaderInputInterface shaderInterface,
4512 vk::VkDescriptorSetLayout layout,
4513 vk::VkDescriptorPool pool,
4514 vk::VkImageView viewA,
4515 vk::VkImageView viewB,
4516 vk::VkDescriptorSet descriptorSet,
4517 std::vector<UpdateTemplateHandleSp>& updateTemplates,
4518 std::vector<RawUpdateRegistry>& registry,
4520 vk::VkPipelineLayout pipelineLayout)
4523 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
4524 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
4526 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
4530 DE_NULL, // pUpdates
4531 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
4533 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
4537 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
4538 const vk::VkDescriptorImageInfo imageInfos[2] =
4540 makeDescriptorImageInfo(viewA, imageLayout),
4541 makeDescriptorImageInfo(viewB, imageLayout),
4544 RawUpdateRegistry updateRegistry;
4546 updateRegistry.addWriteObject(imageInfos[0]);
4547 updateRegistry.addWriteObject(imageInfos[1]);
4549 switch (shaderInterface)
4551 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4552 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4555 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4556 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4557 updateEntries.push_back(createTemplateBinding(1, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
4560 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4561 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4562 updateEntries.push_back(createTemplateBinding(2, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
4565 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
4566 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4567 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
4570 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4571 updateEntries.push_back(createTemplateBinding(0, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(imageInfos[0])));
4575 DE_FATAL("Impossible");
4578 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
4579 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
4581 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(vki, device, &templateCreateInfo);
4582 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
4583 registry.push_back(updateRegistry);
4587 vki.updateDescriptorSetWithTemplate(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
4592 void ImageFetchRenderInstance::logTestPlan (void) const
4594 std::ostringstream msg;
4596 msg << "Rendering 2x2 grid.\n"
4597 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
4598 << "Each descriptor set contains "
4599 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4600 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4601 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
4602 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
4603 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4604 (const char*)DE_NULL)
4605 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
4606 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4609 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4610 if (m_baseArraySlice)
4611 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4613 if (m_stageFlags == 0u)
4615 msg << "Descriptors are not accessed in any shader stage.\n";
4619 msg << "Color in each cell is fetched using the descriptor(s):\n";
4621 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4623 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4625 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4627 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4628 msg << " from descriptor " << srcResourceNdx;
4634 msg << "Descriptors are accessed in {"
4635 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4636 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4637 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4638 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4639 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4643 m_context.getTestContext().getLog()
4644 << tcu::TestLog::Message
4646 << tcu::TestLog::EndMessage;
4649 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
4651 return *m_pipelineLayout;
4654 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4656 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4658 std::vector<vk::VkDescriptorSet> sets;
4659 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
4660 sets.push_back(**m_descriptorSets[setNdx]);
4662 switch (m_descriptorSetCount)
4664 case DESCRIPTOR_SET_COUNT_SINGLE:
4665 case DESCRIPTOR_SET_COUNT_MULTIPLE:
4667 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, (int)sets.size(), &sets.front(), 0, DE_NULL);
4670 case DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS:
4672 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
4674 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
4675 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), descriptorSetNdx, 1, &sets[setNdx], 0, DE_NULL);
4680 DE_FATAL("Impossible");
4683 #ifndef CTS_USES_VULKANSC
4684 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4686 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
4687 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, **m_updateTemplates[setNdx], getPipelineLayout(), getDescriptorSetNdx(m_descriptorSetCount, setNdx), (const void*)m_updateRegistry[setNdx].getRawPointer());
4689 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4691 deUint32 descriptorNdx = 0u;
4692 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
4694 const deUint32 numDescriptors = m_descriptorsPerSet[setNdx];
4695 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, getDescriptorSetNdx(m_descriptorSetCount, setNdx), descriptorNdx, numDescriptors);
4696 descriptorNdx += numDescriptors;
4701 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
4704 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4706 const deUint32 numDescriptorSets = getDescriptorSetCount(m_descriptorSetCount);
4707 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4708 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4709 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4711 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4713 tcu::Vec4 sample0 = tcu::Vec4(0.0f);
4714 tcu::Vec4 sample1 = tcu::Vec4(0.0f);
4715 tcu::Vec4 sample2 = tcu::Vec4(0.0f);
4716 tcu::Vec4 sample3 = tcu::Vec4(0.0f);
4718 for (deUint32 setNdx = 0; setNdx < numDescriptorSets; setNdx++)
4720 sample0 += (!doFetch) ? (yellow) : (m_images.fetchImageValue(0, setNdx));
4721 sample1 += (!doFetch) ? (green) : (m_images.fetchImageValue(1, setNdx));
4722 sample2 += (!doFetch) ? (green) : (m_images.fetchImageValue(2, setNdx));
4723 sample3 += (!doFetch) ? (yellow) : (m_images.fetchImageValue(3, setNdx));
4726 if (numDescriptorSets > 1)
4728 sample0 = sample0 / tcu::Vec4(float(numDescriptorSets));
4729 sample1 = sample1 / tcu::Vec4(float(numDescriptorSets));
4730 sample2 = sample2 / tcu::Vec4(float(numDescriptorSets));
4731 sample3 = sample3 / tcu::Vec4(float(numDescriptorSets));
4734 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4736 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
4737 return tcu::TestStatus::fail("Image verification failed");
4739 return tcu::TestStatus::pass("Pass");
4742 class ImageFetchComputeInstance : public vkt::TestInstance
4745 ImageFetchComputeInstance (vkt::Context& context,
4746 DescriptorUpdateMethod updateMethod,
4747 vk::VkDescriptorType descriptorType,
4748 DescriptorSetCount descriptorSetCount,
4749 ShaderInputInterface shaderInterface,
4750 vk::VkImageViewType viewType,
4751 deUint32 baseMipLevel,
4752 deUint32 baseArraySlice);
4755 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (deUint32 setNdx) const;
4756 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4757 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx);
4758 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx);
4759 #ifndef CTS_USES_VULKANSC
4760 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
4763 tcu::TestStatus iterate (void);
4764 void logTestPlan (void) const;
4765 tcu::TestStatus testResourceAccess (void);
4767 const DescriptorUpdateMethod m_updateMethod;
4768 const vk::VkDescriptorType m_descriptorType;
4769 const DescriptorSetCount m_descriptorSetCount;
4770 const ShaderInputInterface m_shaderInterface;
4771 const vk::VkImageViewType m_viewType;
4772 const deUint32 m_baseMipLevel;
4773 const deUint32 m_baseArraySlice;
4774 #ifndef CTS_USES_VULKANSC
4775 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
4777 const vk::DeviceInterface& m_vki;
4778 const vk::VkDevice m_device;
4779 const vk::VkQueue m_queue;
4780 const deUint32 m_queueFamilyIndex;
4781 vk::Allocator& m_allocator;
4782 const ComputeInstanceResultBuffer m_result;
4783 const ImageFetchInstanceImages m_images;
4784 #ifndef CTS_USES_VULKANSC
4785 std::vector<RawUpdateRegistry> m_updateRegistry;
4787 vk::DescriptorSetUpdateBuilder m_updateBuilder;
4788 std::vector<deUint32> m_descriptorsPerSet;
4791 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
4792 DescriptorUpdateMethod updateMethod,
4793 vk::VkDescriptorType descriptorType,
4794 DescriptorSetCount descriptorSetCount,
4795 ShaderInputInterface shaderInterface,
4796 vk::VkImageViewType viewType,
4797 deUint32 baseMipLevel,
4798 deUint32 baseArraySlice)
4799 : vkt::TestInstance (context)
4800 , m_updateMethod (updateMethod)
4801 , m_descriptorType (descriptorType)
4802 , m_descriptorSetCount (descriptorSetCount)
4803 , m_shaderInterface (shaderInterface)
4804 , m_viewType (viewType)
4805 , m_baseMipLevel (baseMipLevel)
4806 , m_baseArraySlice (baseArraySlice)
4807 #ifndef CTS_USES_VULKANSC
4808 , m_updateTemplates ()
4810 , m_vki (context.getDeviceInterface())
4811 , m_device (context.getDevice())
4812 , m_queue (context.getUniversalQueue())
4813 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4814 , m_allocator (context.getDefaultAllocator())
4815 , m_result (m_vki, m_device, m_allocator)
4816 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
4817 #ifndef CTS_USES_VULKANSC
4818 , m_updateRegistry ()
4820 , m_updateBuilder ()
4821 , m_descriptorsPerSet ()
4825 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (deUint32 setNdx) const
4827 vk::DescriptorSetLayoutBuilder builder;
4828 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
4829 deUint32 binding = 0;
4831 #ifndef CTS_USES_VULKANSC
4832 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
4833 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4835 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
4840 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++);
4842 switch (m_shaderInterface)
4844 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4845 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4848 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4849 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4850 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4853 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4854 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding);
4855 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding + 2);
4858 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
4859 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, getArbitraryBindingIndex(0));
4860 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, getArbitraryBindingIndex(1));
4863 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4864 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4868 DE_FATAL("Impossible");
4871 return builder.build(m_vki, m_device, extraFlags);
4874 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
4876 return vk::DescriptorPoolBuilder()
4877 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
4878 .addType(m_descriptorType, getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface))
4879 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(m_descriptorSetCount));
4882 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx)
4884 const vk::VkDescriptorSetAllocateInfo allocInfo =
4886 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4893 vk::Move<vk::VkDescriptorSet> descriptorSet;
4894 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4896 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4900 descriptorSet = vk::Move<vk::VkDescriptorSet>();
4903 #ifndef CTS_USES_VULKANSC
4904 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
4906 writeDescriptorSetWithTemplate(*descriptorSet, layout, setNdx);
4910 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4912 writeDescriptorSet(*descriptorSet, setNdx);
4915 return descriptorSet;
4918 void ImageFetchComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx)
4920 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4921 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
4922 const vk::VkDescriptorImageInfo imageInfos[2] =
4924 makeDescriptorImageInfo(m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface)), imageLayout),
4925 makeDescriptorImageInfo(m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1), imageLayout),
4928 deUint32 binding = 0u;
4929 deUint32 numDescriptors = 0u;
4934 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4939 switch (m_shaderInterface)
4941 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4942 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &imageInfos[0]);
4946 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4947 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &imageInfos[0]);
4948 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &imageInfos[1]);
4949 numDescriptors += 2;
4952 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4953 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding), m_descriptorType, &imageInfos[0]);
4954 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding + 2), m_descriptorType, &imageInfos[1]);
4955 numDescriptors += 2;
4958 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
4959 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), m_descriptorType, &imageInfos[0]);
4960 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), m_descriptorType, &imageInfos[1]);
4961 numDescriptors += 2;
4964 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4965 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, 2u, imageInfos);
4970 DE_FATAL("Impossible");
4973 m_descriptorsPerSet.push_back(numDescriptors);
4975 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4977 m_updateBuilder.update(m_vki, m_device);
4978 m_updateBuilder.clear();
4982 #ifndef CTS_USES_VULKANSC
4983 void ImageFetchComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush, vk::VkPipelineLayout pipelineLayout)
4985 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4986 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
4987 const vk::VkDescriptorImageInfo imageInfos[2] =
4989 makeDescriptorImageInfo(m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface)), imageLayout),
4990 makeDescriptorImageInfo(m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1), imageLayout),
4992 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
4993 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
4995 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
4999 DE_NULL, // pUpdates
5000 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
5002 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
5007 deUint32 binding = 0u;
5008 deUint32 offset = 0u;
5009 RawUpdateRegistry updateRegistry;
5012 updateRegistry.addWriteObject(resultInfo);
5014 updateRegistry.addWriteObject(imageInfos[0]);
5015 updateRegistry.addWriteObject(imageInfos[1]);
5019 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
5022 switch (m_shaderInterface)
5024 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5025 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5028 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5029 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5030 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5033 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5034 updateEntries.push_back(createTemplateBinding(binding, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5035 updateEntries.push_back(createTemplateBinding(binding + 2, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5038 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
5039 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5040 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5043 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5044 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), sizeof(imageInfos[0])));
5048 DE_FATAL("Impossible");
5051 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
5052 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
5054 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(m_vki, m_device, &templateCreateInfo);
5055 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
5056 m_updateRegistry.push_back(updateRegistry);
5060 m_vki.updateDescriptorSetWithTemplate(m_device, descriptorSet, **m_updateTemplates.back(), m_updateRegistry.back().getRawPointer());
5065 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
5068 return testResourceAccess();
5071 void ImageFetchComputeInstance::logTestPlan (void) const
5073 std::ostringstream msg;
5075 msg << "Fetching 4 values from image in compute shader.\n"
5076 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
5077 << "Each descriptor set contains "
5078 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5079 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5080 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
5081 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
5082 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5083 (const char*)DE_NULL)
5084 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5085 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
5088 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
5089 if (m_baseArraySlice)
5090 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
5092 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5094 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
5096 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5098 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5099 msg << " from descriptor " << srcResourceNdx;
5105 m_context.getTestContext().getLog()
5106 << tcu::TestLog::Message
5108 << tcu::TestLog::EndMessage;
5111 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
5113 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5114 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
5115 std::vector<DescriptorSetHandleSp> descriptorSets;
5116 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
5117 std::vector<vk::VkDescriptorSet> setHandles;
5119 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
5121 vk::Move<vk::VkDescriptorSetLayout> layout = createDescriptorSetLayout(setNdx);
5122 vk::Move<vk::VkDescriptorSet> set = createDescriptorSet(*descriptorPool, *layout, setNdx);
5124 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
5125 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(set)));
5127 layoutHandles.push_back(**descriptorSetLayouts.back());
5128 setHandles.push_back(**descriptorSets.back());
5130 // Add an empty descriptor set layout between sets 0 and 2
5131 if (setNdx == 0 && m_descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS)
5133 vk::DescriptorSetLayoutBuilder emptyBuilder;
5134 vk::Move<vk::VkDescriptorSetLayout> emptyLayout = emptyBuilder.build(m_vki, m_device, (vk::VkDescriptorSetLayoutCreateFlags)0);
5136 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(emptyLayout)));
5137 layoutHandles.push_back(**descriptorSetLayouts.back());
5141 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), (int)layoutHandles.size(), &layoutHandles.front());
5142 const deUint32* const dynamicOffsets = DE_NULL;
5143 const int numDynamicOffsets = 0;
5144 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
5145 const int numPreBarriers = 0;
5146 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
5147 const int numPostBarriers = 1;
5149 const ComputeCommand compute (m_vki,
5151 pipeline.getPipeline(),
5152 pipeline.getPipelineLayout(),
5153 tcu::UVec3(4, 1, 1),
5155 m_descriptorSetCount, &setHandles.front(),
5156 numDynamicOffsets, dynamicOffsets,
5157 numPreBarriers, preBarriers,
5158 numPostBarriers, postBarriers);
5160 tcu::Vec4 results[4];
5161 bool anyResultSet = false;
5162 bool allResultsOk = true;
5164 #ifndef CTS_USES_VULKANSC
5165 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5167 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
5168 writeDescriptorSetWithTemplate(DE_NULL, layoutHandles[setNdx], setNdx, true, pipeline.getPipelineLayout());
5170 compute.submitAndWait(m_queueFamilyIndex, m_queue, &m_updateTemplates, &m_updateRegistry);
5172 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5174 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
5175 writeDescriptorSet(DE_NULL, setNdx);
5177 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder, m_descriptorsPerSet);
5182 compute.submitAndWait(m_queueFamilyIndex, m_queue);
5184 m_result.readResultContentsTo(&results);
5187 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5189 const tcu::Vec4 result = results[resultNdx];
5191 tcu::Vec4 reference = tcu::Vec4(0.0f);
5192 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
5193 reference += m_images.fetchImageValue(resultNdx, setNdx);
5195 if (getDescriptorSetCount(m_descriptorSetCount) > 1)
5196 reference = reference / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
5198 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
5200 if (result != tcu::Vec4(-1.0f))
5201 anyResultSet = true;
5203 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
5205 allResultsOk = false;
5207 m_context.getTestContext().getLog()
5208 << tcu::TestLog::Message
5209 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
5210 << tcu::TestLog::EndMessage;
5214 // read back and verify
5216 return tcu::TestStatus::pass("Pass");
5217 else if (anyResultSet)
5218 return tcu::TestStatus::fail("Invalid result values");
5221 m_context.getTestContext().getLog()
5222 << tcu::TestLog::Message
5223 << "Result buffer was not written to."
5224 << tcu::TestLog::EndMessage;
5225 return tcu::TestStatus::fail("Result buffer was not written to");
5229 class ImageSampleInstanceImages : private ImageInstanceImages
5232 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
5233 vk::VkDevice device,
5234 deUint32 queueFamilyIndex,
5236 vk::Allocator& allocator,
5237 vk::VkDescriptorType descriptorType,
5238 DescriptorSetCount descriptorSetCount,
5239 ShaderInputInterface shaderInterface,
5240 vk::VkImageViewType viewType,
5241 deUint32 baseMipLevel,
5242 deUint32 baseArraySlice,
5245 static std::vector<tcu::Sampler> getRefSamplers (DescriptorSetCount descriptorSetCount,
5246 ShaderInputInterface shaderInterface);
5248 static std::vector<SamplerHandleSp> getSamplers (const vk::DeviceInterface& vki,
5249 vk::VkDevice device,
5250 std::vector<tcu::Sampler>& refSamplers,
5251 const tcu::TextureFormat imageFormat);
5253 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
5254 tcu::Vec4 fetchSampleValue (int samplePosNdx, int setNdx) const;
5256 inline tcu::TextureLevelPyramid getSourceImage (int ndx) const { return m_sourceImage[ndx % m_sourceImage.size()]; }
5257 inline vk::VkImageView getImageView (int ndx) const { return **m_imageView[ndx % m_imageView.size()]; }
5258 inline tcu::Sampler getRefSampler (int ndx) const { return m_refSampler[ndx % m_refSampler.size()]; }
5259 inline vk::VkSampler getSampler (int ndx) const { return **m_sampler[ndx % m_sampler.size()]; }
5260 inline bool isImmutable (void) const { return m_isImmutable; }
5263 static int getNumImages (vk::VkDescriptorType descriptorType, DescriptorSetCount descriptorSetCount, ShaderInputInterface shaderInterface);
5264 static tcu::Sampler createRefSampler (int ndx);
5265 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
5267 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
5268 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
5269 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
5270 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
5272 const vk::VkDescriptorType m_descriptorType;
5273 const ShaderInputInterface m_shaderInterface;
5274 const bool m_isImmutable;
5276 std::vector<tcu::Sampler> m_refSampler;
5277 std::vector<SamplerHandleSp> m_sampler;
5280 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
5281 vk::VkDevice device,
5282 deUint32 queueFamilyIndex,
5284 vk::Allocator& allocator,
5285 vk::VkDescriptorType descriptorType,
5286 DescriptorSetCount descriptorSetCount,
5287 ShaderInputInterface shaderInterface,
5288 vk::VkImageViewType viewType,
5289 deUint32 baseMipLevel,
5290 deUint32 baseArraySlice,
5292 : ImageInstanceImages (vki,
5299 getNumImages(descriptorType, descriptorSetCount, shaderInterface),
5302 , m_descriptorType (descriptorType)
5303 , m_shaderInterface (shaderInterface)
5304 , m_isImmutable (immutable)
5305 , m_refSampler (getRefSamplers(descriptorSetCount, shaderInterface))
5306 , m_sampler (getSamplers(vki, device, m_refSampler, m_imageFormat))
5310 std::vector<tcu::Sampler> ImageSampleInstanceImages::getRefSamplers (DescriptorSetCount descriptorSetCount,
5311 ShaderInputInterface shaderInterface)
5313 std::vector<tcu::Sampler> refSamplers;
5314 for (deUint32 samplerNdx = 0; samplerNdx < getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface); samplerNdx++)
5315 refSamplers.push_back(createRefSampler(samplerNdx));
5320 std::vector<SamplerHandleSp> ImageSampleInstanceImages::getSamplers (const vk::DeviceInterface& vki,
5321 vk::VkDevice device,
5322 std::vector<tcu::Sampler>& refSamplers,
5323 const tcu::TextureFormat imageFormat)
5325 std::vector<SamplerHandleSp> samplers;
5326 for (deUint32 samplerNdx = 0; samplerNdx < (deUint32)refSamplers.size(); samplerNdx++)
5328 vk::Move<vk::VkSampler> sampler = createSampler(vki, device, refSamplers[samplerNdx], imageFormat);
5329 samplers.push_back(SamplerHandleSp(new SamplerHandleUp(sampler)));
5334 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
5336 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
5338 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
5339 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
5341 // choose arbitrary values that are not ambiguous with NEAREST filtering
5345 case vk::VK_IMAGE_VIEW_TYPE_1D:
5346 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
5347 case vk::VK_IMAGE_VIEW_TYPE_2D:
5348 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
5349 case vk::VK_IMAGE_VIEW_TYPE_3D:
5351 const tcu::Vec3 coords[4] =
5355 (float)(12u % imageSize) + 0.25f),
5357 tcu::Vec3((float)(23u % imageSize) + 0.25f,
5358 (float)(73u % imageSize) + 0.5f,
5359 (float)(16u % imageSize) + 0.5f + (float)imageSize),
5361 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
5362 (float)(84u % imageSize) + 0.5f + (float)imageSize,
5363 (float)(117u % imageSize) + 0.75f),
5365 tcu::Vec3((float)imageSize + 0.5f,
5366 (float)(75u % imageSize) + 0.25f,
5367 (float)(83u % imageSize) + 0.25f + (float)imageSize),
5369 const deUint32 slices[4] =
5379 case vk::VK_IMAGE_VIEW_TYPE_1D:
5380 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
5381 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
5382 (float)slices[samplePosNdx],
5385 case vk::VK_IMAGE_VIEW_TYPE_2D:
5386 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
5387 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
5388 coords[samplePosNdx].y() / (float)imageSize,
5389 (float)slices[samplePosNdx],
5391 case vk::VK_IMAGE_VIEW_TYPE_3D:
5392 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
5393 coords[samplePosNdx].y() / (float)imageSize,
5394 coords[samplePosNdx].z() / (float)imageSize,
5397 DE_FATAL("Impossible");
5402 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
5403 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
5405 // \note these values are in [0, texSize]*3 space for convenience
5406 const tcu::Vec3 coords[4] =
5412 tcu::Vec3((float)(13u % imageSize) + 0.25f,
5414 (float)(16u % imageSize) + 0.5f),
5417 (float)(84u % imageSize) + 0.5f,
5418 (float)(10u % imageSize) + 0.75f),
5420 tcu::Vec3((float)imageSize,
5421 (float)(75u % imageSize) + 0.25f,
5422 (float)(83u % imageSize) + 0.75f),
5424 const deUint32 slices[4] =
5432 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
5433 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
5434 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
5436 // map to [-1, 1]*3 space
5437 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
5438 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
5439 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
5440 (float)slices[samplePosNdx]);
5444 DE_FATAL("Impossible");
5449 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx, int setNdx) const
5451 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
5453 // texture order is ABAB
5454 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
5455 const deUint32 numImages = (isSamplerCase) ? 1 : getInterfaceNumResources(m_shaderInterface);
5456 const tcu::TextureLevelPyramid& sampleSrcA = getSourceImage(setNdx * numImages);
5457 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? sampleSrcA : getSourceImage(setNdx * numImages + 1);
5458 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
5460 // sampler order is ABAB
5461 const tcu::Sampler& samplerA = getRefSampler(setNdx * getInterfaceNumResources(m_shaderInterface));
5462 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (samplerA) : getRefSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1);
5463 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
5465 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5466 const float lod = 0.0f;
5467 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
5471 case vk::VK_IMAGE_VIEW_TYPE_1D:
5472 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
5473 case vk::VK_IMAGE_VIEW_TYPE_2D:
5474 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);
5475 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
5476 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
5477 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);
5481 DE_FATAL("Impossible");
5487 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, DescriptorSetCount descriptorSetCount, ShaderInputInterface shaderInterface)
5489 // If we are testing separate samplers, just one image is enough
5490 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5491 return getDescriptorSetCount(descriptorSetCount);
5492 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5494 // combined: numImages == numSamplers
5495 return getInterfaceNumResources(shaderInterface) * getDescriptorSetCount(descriptorSetCount);
5499 DE_FATAL("Impossible");
5504 tcu::Sampler ImageSampleInstanceImages::createRefSampler (int ndx)
5509 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR,
5510 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
5514 // nearest, clamping
5515 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST,
5516 0.0f, true, tcu::Sampler::COMPAREMODE_NONE, 0, tcu::Vec4(0.0f), true);
5520 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
5522 const vk::VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, format);
5524 return vk::createSampler(vki, device, &createInfo);
5527 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5529 DE_ASSERT(levelStorage->empty());
5531 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
5532 const deUint32 numLevels = (deUint32)source.getNumLevels();
5534 // cut pyramid from baseMipLevel
5535 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5537 // cut levels from baseArraySlice
5538 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
5539 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
5540 levelStorage->push_back(cutLevel);
5543 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
5546 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5548 DE_ASSERT(levelStorage->empty());
5550 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
5551 const deUint32 numLevels = (deUint32)source.getNumLevels();
5553 // cut pyramid from baseMipLevel
5554 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5556 // cut levels from baseArraySlice
5557 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
5558 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
5559 levelStorage->push_back(cutLevel);
5562 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
5565 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5567 DE_ASSERT(levelStorage->empty());
5568 DE_ASSERT(baseArraySlice == 0);
5569 DE_UNREF(baseArraySlice);
5571 const deUint32 numLevels = (deUint32)source.getNumLevels();
5573 // cut pyramid from baseMipLevel
5574 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5575 levelStorage->push_back(source.getLevel(level));
5577 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
5580 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5582 DE_ASSERT(levelStorage->empty());
5584 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
5585 const deUint32 numLevels = (deUint32)source.getNumLevels();
5587 // cut pyramid from baseMipLevel
5588 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5590 // cut levels from baseArraySlice
5591 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
5592 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
5593 levelStorage->push_back(cutLevel);
5596 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
5599 class ImageSampleRenderInstance : public SingleCmdRenderInstance
5602 ImageSampleRenderInstance (vkt::Context& context,
5603 DescriptorUpdateMethod updateMethod,
5604 bool isPrimaryCmdBuf,
5605 vk::VkDescriptorType descriptorType,
5606 DescriptorSetCount descriptorSetCount,
5607 vk::VkShaderStageFlags stageFlags,
5608 ShaderInputInterface shaderInterface,
5609 vk::VkImageViewType viewType,
5610 deUint32 baseMipLevel,
5611 deUint32 baseArraySlice,
5615 static std::vector<DescriptorSetLayoutHandleSp> createDescriptorSetLayouts (const vk::DeviceInterface& vki,
5616 vk::VkDevice device,
5617 vk::VkDescriptorType descriptorType,
5618 DescriptorSetCount descriptorSetCount,
5619 ShaderInputInterface shaderInterface,
5620 vk::VkShaderStageFlags stageFlags,
5621 const ImageSampleInstanceImages& images,
5622 DescriptorUpdateMethod updateMethod);
5624 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5625 vk::VkDevice device,
5626 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout);
5628 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5629 vk::VkDevice device,
5630 vk::VkDescriptorType descriptorType,
5631 DescriptorSetCount descriptorSetCount,
5632 ShaderInputInterface shaderInterface);
5634 static std::vector<DescriptorSetHandleSp> createDescriptorSets (const vk::DeviceInterface& vki,
5635 DescriptorUpdateMethod updateMethod,
5636 vk::VkDevice device,
5637 vk::VkDescriptorType descriptorType,
5638 DescriptorSetCount descriptorSetCount,
5639 ShaderInputInterface shaderInterface,
5640 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
5641 vk::VkDescriptorPool pool,
5643 const ImageSampleInstanceImages& images,
5644 vk::DescriptorSetUpdateBuilder& updateBuilder,
5645 #ifndef CTS_USES_VULKANSC
5646 std::vector<UpdateTemplateHandleSp>& updateTemplates,
5647 std::vector<RawUpdateRegistry>& updateRegistry,
5649 std::vector<deUint32>& descriptorsPerSet,
5650 vk::VkPipelineLayout pipelineLayout = DE_NULL);
5652 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
5653 vk::VkDevice device,
5654 ShaderInputInterface shaderInterface,
5656 const ImageSampleInstanceImages& images,
5657 vk::VkDescriptorSet descriptorSet,
5659 vk::DescriptorSetUpdateBuilder& updateBuilder,
5660 std::vector<deUint32>& descriptorsPerSet,
5661 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
5663 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
5664 vk::VkDevice device,
5665 ShaderInputInterface shaderInterface,
5667 const ImageSampleInstanceImages& images,
5668 vk::VkDescriptorSet descriptorSet,
5670 vk::DescriptorSetUpdateBuilder& updateBuilder,
5671 std::vector<deUint32>& descriptorsPerSet,
5672 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
5674 static void writeSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5675 vk::VkDevice device,
5676 DescriptorSetCount descriptorSetCount,
5677 ShaderInputInterface shaderInterface,
5679 const ImageSampleInstanceImages& images,
5680 vk::VkDescriptorSet descriptorSet,
5682 vk::VkDescriptorSetLayout layout,
5683 #ifndef CTS_USES_VULKANSC
5684 std::vector<UpdateTemplateHandleSp>& updateTemplates,
5685 std::vector<RawUpdateRegistry>& registry,
5687 bool withPush = false,
5688 vk::VkPipelineLayout pipelineLayout = 0);
5690 static void writeImageSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5691 vk::VkDevice device,
5692 DescriptorSetCount descriptorSetCount,
5693 ShaderInputInterface shaderInterface,
5695 const ImageSampleInstanceImages& images,
5696 vk::VkDescriptorSet descriptorSet,
5698 vk::VkDescriptorSetLayout layout,
5699 #ifndef CTS_USES_VULKANSC
5700 std::vector<UpdateTemplateHandleSp>& updateTemplates,
5701 std::vector<RawUpdateRegistry>& registry,
5703 bool withPush = false,
5704 vk::VkPipelineLayout pipelineLayout = 0);
5706 void logTestPlan (void) const;
5707 vk::VkPipelineLayout getPipelineLayout (void) const;
5708 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5709 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5716 const DescriptorUpdateMethod m_updateMethod;
5717 const vk::VkDescriptorType m_descriptorType;
5718 const DescriptorSetCount m_descriptorSetCount;
5719 const vk::VkShaderStageFlags m_stageFlags;
5720 const ShaderInputInterface m_shaderInterface;
5721 const vk::VkImageViewType m_viewType;
5722 const deUint32 m_baseMipLevel;
5723 const deUint32 m_baseArraySlice;
5725 #ifndef CTS_USES_VULKANSC
5726 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
5727 std::vector<RawUpdateRegistry> m_updateRegistry;
5729 vk::DescriptorSetUpdateBuilder m_updateBuilder;
5730 const ImageSampleInstanceImages m_images;
5731 std::vector<deUint32> m_descriptorsPerSet;
5732 const std::vector<DescriptorSetLayoutHandleSp> m_descriptorSetLayouts;
5733 const vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
5734 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5735 const std::vector<DescriptorSetHandleSp> m_descriptorSets;
5738 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
5739 DescriptorUpdateMethod updateMethod,
5740 bool isPrimaryCmdBuf,
5741 vk::VkDescriptorType descriptorType,
5742 DescriptorSetCount descriptorSetCount,
5743 vk::VkShaderStageFlags stageFlags,
5744 ShaderInputInterface shaderInterface,
5745 vk::VkImageViewType viewType,
5746 deUint32 baseMipLevel,
5747 deUint32 baseArraySlice,
5749 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5750 , m_updateMethod (updateMethod)
5751 , m_descriptorType (descriptorType)
5752 , m_descriptorSetCount (descriptorSetCount)
5753 , m_stageFlags (stageFlags)
5754 , m_shaderInterface (shaderInterface)
5755 , m_viewType (viewType)
5756 , m_baseMipLevel (baseMipLevel)
5757 , m_baseArraySlice (baseArraySlice)
5758 #ifndef CTS_USES_VULKANSC
5759 , m_updateTemplates ()
5760 , m_updateRegistry ()
5762 , m_updateBuilder ()
5763 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
5764 , m_descriptorSetLayouts (createDescriptorSetLayouts(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_stageFlags, m_images, m_updateMethod))
5765 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, m_descriptorSetLayouts))
5766 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface))
5767 , m_descriptorSets (createDescriptorSets(m_vki, m_updateMethod, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_descriptorSetLayouts, *m_descriptorPool, isImmutable, m_images, m_updateBuilder,
5768 #ifndef CTS_USES_VULKANSC
5772 m_descriptorsPerSet, *m_pipelineLayout))
5776 std::vector<DescriptorSetLayoutHandleSp> ImageSampleRenderInstance::createDescriptorSetLayouts (const vk::DeviceInterface& vki,
5777 vk::VkDevice device,
5778 vk::VkDescriptorType descriptorType,
5779 DescriptorSetCount descriptorSetCount,
5780 ShaderInputInterface shaderInterface,
5781 vk::VkShaderStageFlags stageFlags,
5782 const ImageSampleInstanceImages& images,
5783 DescriptorUpdateMethod updateMethod)
5785 #ifdef CTS_USES_VULKANSC
5786 DE_UNREF(updateMethod);
5788 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
5790 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
5792 const vk::VkSampler samplers[2] =
5794 images.getSampler(setNdx * getInterfaceNumResources(shaderInterface)),
5795 images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1),
5798 vk::DescriptorSetLayoutBuilder builder;
5799 const bool addSeparateImage = descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER;
5800 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
5802 #ifndef CTS_USES_VULKANSC
5803 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
5804 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5806 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
5810 // (combined)samplers follow
5811 switch (shaderInterface)
5813 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5814 if (addSeparateImage)
5815 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5816 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5819 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5820 if (addSeparateImage)
5821 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5822 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5823 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5826 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5827 builder.addSingleIndexedSamplerBinding(descriptorType, stageFlags, 0u, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5828 if (addSeparateImage)
5829 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags, 1u);
5830 builder.addSingleIndexedSamplerBinding(descriptorType, stageFlags, 2u, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5833 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
5834 if (addSeparateImage)
5835 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5836 builder.addSingleIndexedSamplerBinding(descriptorType, stageFlags, getArbitraryBindingIndex(0), (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5837 builder.addSingleIndexedSamplerBinding(descriptorType, stageFlags, getArbitraryBindingIndex(1), (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5840 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5841 if (addSeparateImage)
5842 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5843 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
5847 DE_FATAL("Impossible");
5850 vk::Move<vk::VkDescriptorSetLayout> layout = builder.build(vki, device, extraFlags);
5851 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
5853 // Add an empty descriptor set layout between sets 0 and 2
5854 if (setNdx == 0 && descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS)
5856 vk::DescriptorSetLayoutBuilder emptyBuilder;
5857 vk::Move<vk::VkDescriptorSetLayout> emptyLayout = emptyBuilder.build(vki, device, (vk::VkDescriptorSetLayoutCreateFlags)0);
5858 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(emptyLayout)));
5862 return descriptorSetLayouts;
5865 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5866 vk::VkDevice device,
5867 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout)
5869 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
5870 for (size_t setNdx = 0; setNdx < descriptorSetLayout.size(); setNdx++)
5871 layoutHandles.push_back(**descriptorSetLayout[setNdx]);
5873 const vk::VkPipelineLayoutCreateInfo createInfo =
5875 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5877 (vk::VkPipelineLayoutCreateFlags)0,
5878 (deUint32)layoutHandles.size(), // descriptorSetCount
5879 &layoutHandles.front(), // pSetLayouts
5880 0u, // pushConstantRangeCount
5881 DE_NULL, // pPushConstantRanges
5883 return vk::createPipelineLayout(vki, device, &createInfo);
5886 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5887 vk::VkDevice device,
5888 vk::VkDescriptorType descriptorType,
5889 DescriptorSetCount descriptorSetCount,
5890 ShaderInputInterface shaderInterface)
5892 vk::DescriptorPoolBuilder builder;
5894 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5896 // separate samplers need image to sample
5897 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, getDescriptorSetCount(descriptorSetCount));
5899 // also need sample to use, indifferent of whether immutable or not
5900 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface));
5902 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5904 // combined image samplers
5905 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface));
5908 DE_FATAL("Impossible");
5910 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(descriptorSetCount));
5913 std::vector<DescriptorSetHandleSp> ImageSampleRenderInstance::createDescriptorSets (const vk::DeviceInterface& vki,
5914 DescriptorUpdateMethod updateMethod,
5915 vk::VkDevice device,
5916 vk::VkDescriptorType descriptorType,
5917 DescriptorSetCount descriptorSetCount,
5918 ShaderInputInterface shaderInterface,
5919 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
5920 vk::VkDescriptorPool pool,
5922 const ImageSampleInstanceImages& images,
5923 vk::DescriptorSetUpdateBuilder& updateBuilder,
5924 #ifndef CTS_USES_VULKANSC
5925 std::vector<UpdateTemplateHandleSp>& updateTemplates,
5926 std::vector<RawUpdateRegistry>& updateRegistry,
5928 std::vector<deUint32>& descriptorsPerSet,
5929 vk::VkPipelineLayout pipelineLayout)
5931 #ifdef CTS_USES_VULKANSC
5932 DE_UNREF(pipelineLayout);
5934 std::vector<DescriptorSetHandleSp> descriptorSets;
5936 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
5938 vk::VkDescriptorSetLayout layout = **descriptorSetLayouts[getDescriptorSetNdx(descriptorSetCount, setNdx)];
5940 const vk::VkDescriptorSetAllocateInfo allocInfo =
5942 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5949 vk::Move<vk::VkDescriptorSet> descriptorSet;
5950 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5952 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5956 descriptorSet = vk::Move<vk::VkDescriptorSet>();
5959 #ifndef CTS_USES_VULKANSC
5960 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
5962 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5963 writeSamplerDescriptorSetWithTemplate(vki, device, descriptorSetCount, shaderInterface, isImmutable, images, *descriptorSet, setNdx, layout, updateTemplates, updateRegistry);
5964 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5965 writeImageSamplerDescriptorSetWithTemplate(vki, device, descriptorSetCount, shaderInterface, isImmutable, images, *descriptorSet, setNdx, layout, updateTemplates, updateRegistry);
5967 DE_FATAL("Impossible");
5969 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5971 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5972 writeSamplerDescriptorSetWithTemplate(vki, device, descriptorSetCount, shaderInterface, isImmutable, images, DE_NULL, setNdx, layout, updateTemplates, updateRegistry, true, pipelineLayout);
5973 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5974 writeImageSamplerDescriptorSetWithTemplate(vki, device, descriptorSetCount, shaderInterface, isImmutable, images, DE_NULL, setNdx, layout, updateTemplates, updateRegistry, true, pipelineLayout);
5976 DE_FATAL("Impossible");
5978 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5980 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5981 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, updateBuilder, descriptorsPerSet, updateMethod);
5982 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5983 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, updateBuilder, descriptorsPerSet, updateMethod);
5985 DE_FATAL("Impossible");
5987 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5990 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5991 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, updateBuilder, descriptorsPerSet);
5992 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5993 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, updateBuilder, descriptorsPerSet);
5995 DE_FATAL("Impossible");
5998 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(descriptorSet)));
6000 return descriptorSets;
6003 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
6004 vk::VkDevice device,
6005 ShaderInputInterface shaderInterface,
6007 const ImageSampleInstanceImages& images,
6008 vk::VkDescriptorSet descriptorSet,
6010 vk::DescriptorSetUpdateBuilder& updateBuilder,
6011 std::vector<deUint32>& descriptorsPerSet,
6012 DescriptorUpdateMethod updateMethod)
6014 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageView(setNdx), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
6015 const vk::VkDescriptorImageInfo samplersInfos[2] =
6017 makeDescriptorImageInfo(images.getSampler(setNdx * getInterfaceNumResources(shaderInterface))),
6018 makeDescriptorImageInfo(images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1)),
6021 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
6022 deUint32 numDescriptors = 1u;
6024 // stand alone texture
6025 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(samplerLocation), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
6028 if (!isImmutable || (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH))
6030 switch (shaderInterface)
6032 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6033 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6037 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6038 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6039 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
6040 numDescriptors += 2;
6043 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6044 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6045 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
6046 numDescriptors += 2;
6049 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
6050 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6051 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
6052 numDescriptors += 2;
6055 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6056 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
6061 DE_FATAL("Impossible");
6065 descriptorsPerSet.push_back(numDescriptors);
6067 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6069 updateBuilder.update(vki, device);
6070 updateBuilder.clear();
6074 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
6075 vk::VkDevice device,
6076 ShaderInputInterface shaderInterface,
6078 const ImageSampleInstanceImages& images,
6079 vk::VkDescriptorSet descriptorSet,
6081 vk::DescriptorSetUpdateBuilder& updateBuilder,
6082 std::vector<deUint32>& descriptorsPerSet,
6083 DescriptorUpdateMethod updateMethod)
6085 const vk::VkSampler samplers[2] =
6087 (isImmutable && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? (0) : (images.getSampler(setNdx * getInterfaceNumResources(shaderInterface))),
6088 (isImmutable && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? (0) : (images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1)),
6090 const vk::VkDescriptorImageInfo imageSamplers[2] =
6092 vk::makeDescriptorImageInfo(samplers[0], images.getImageView(setNdx * getInterfaceNumResources(shaderInterface)), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6093 vk::makeDescriptorImageInfo(samplers[1], images.getImageView(setNdx * getInterfaceNumResources(shaderInterface) + 1), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6095 deUint32 numDescriptors = 0u;
6097 // combined image samplers
6098 switch (shaderInterface)
6100 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6101 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6105 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6106 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6107 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6108 numDescriptors += 2;
6111 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6112 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6113 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6114 numDescriptors += 2;
6117 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
6118 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6119 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6120 numDescriptors += 2;
6123 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6124 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
6129 DE_FATAL("Impossible");
6132 descriptorsPerSet.push_back(numDescriptors);
6134 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6136 updateBuilder.update(vki, device);
6137 updateBuilder.clear();
6141 #ifndef CTS_USES_VULKANSC
6142 void ImageSampleRenderInstance::writeSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
6143 vk::VkDevice device,
6144 DescriptorSetCount descriptorSetCount,
6145 ShaderInputInterface shaderInterface,
6147 const ImageSampleInstanceImages& images,
6148 vk::VkDescriptorSet descriptorSet,
6150 vk::VkDescriptorSetLayout layout,
6151 std::vector<UpdateTemplateHandleSp>& updateTemplates,
6152 std::vector<RawUpdateRegistry>& registry,
6154 vk::VkPipelineLayout pipelineLayout)
6156 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageView(setNdx), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
6157 const vk::VkDescriptorImageInfo samplersInfos[2] =
6159 makeDescriptorImageInfo(images.getSampler(setNdx * getInterfaceNumResources(shaderInterface))),
6160 makeDescriptorImageInfo(images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1)),
6163 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
6165 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
6166 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
6168 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6172 DE_NULL, // pUpdates
6173 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
6175 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
6177 getDescriptorSetNdx(descriptorSetCount, setNdx)
6180 RawUpdateRegistry updateRegistry;
6182 updateRegistry.addWriteObject(imageInfo);
6183 updateRegistry.addWriteObject(samplersInfos[0]);
6184 updateRegistry.addWriteObject(samplersInfos[1]);
6186 // stand alone texture
6187 updateEntries.push_back(createTemplateBinding(samplerLocation, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, updateRegistry.getWriteObjectOffset(0), 0));
6190 if (!isImmutable || withPush)
6192 switch (shaderInterface)
6194 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6195 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6198 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6199 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6200 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
6203 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6204 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6205 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
6208 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
6209 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6210 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
6213 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6214 updateEntries.push_back(createTemplateBinding(1, 0, 2, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), sizeof(samplersInfos[0])));
6218 DE_FATAL("Impossible");
6222 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6223 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6225 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(vki, device, &templateCreateInfo);
6226 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
6227 registry.push_back(updateRegistry);
6231 vki.updateDescriptorSetWithTemplate(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
6236 void ImageSampleRenderInstance::writeImageSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
6237 vk::VkDevice device,
6238 DescriptorSetCount descriptorSetCount,
6239 ShaderInputInterface shaderInterface,
6241 const ImageSampleInstanceImages& images,
6242 vk::VkDescriptorSet descriptorSet,
6244 vk::VkDescriptorSetLayout layout,
6245 std::vector<UpdateTemplateHandleSp>& updateTemplates,
6246 std::vector<RawUpdateRegistry>& registry,
6248 vk::VkPipelineLayout pipelineLayout)
6250 const vk::VkSampler samplers[2] =
6252 (isImmutable && !withPush) ? (0) : (images.getSampler(setNdx * getInterfaceNumResources(shaderInterface))),
6253 (isImmutable && !withPush) ? (0) : (images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1)),
6255 const vk::VkDescriptorImageInfo imageSamplers[2] =
6257 vk::makeDescriptorImageInfo(samplers[0], images.getImageView(setNdx * getInterfaceNumResources(shaderInterface)), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6258 vk::makeDescriptorImageInfo(samplers[1], images.getImageView(setNdx * getInterfaceNumResources(shaderInterface) + 1), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6261 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
6262 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
6264 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6268 DE_NULL, // pUpdates
6269 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
6271 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
6273 getDescriptorSetNdx(descriptorSetCount, setNdx)
6276 RawUpdateRegistry updateRegistry;
6278 updateRegistry.addWriteObject(imageSamplers[0]);
6279 updateRegistry.addWriteObject(imageSamplers[1]);
6281 // combined image samplers
6282 switch (shaderInterface)
6284 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6285 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
6288 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6289 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
6290 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6293 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6294 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
6295 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6298 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
6299 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
6300 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6303 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6304 updateEntries.push_back(createTemplateBinding(0, 0, 2, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), sizeof(imageSamplers[0])));
6308 DE_FATAL("Impossible");
6311 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6312 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6314 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(vki, device, &templateCreateInfo);
6315 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
6316 registry.push_back(updateRegistry);
6320 vki.updateDescriptorSetWithTemplate(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
6325 void ImageSampleRenderInstance::logTestPlan (void) const
6327 std::ostringstream msg;
6329 msg << "Rendering 2x2 grid.\n";
6331 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6333 msg << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
6334 << "Each descriptor set contains "
6335 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6336 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6337 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
6338 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
6339 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6340 (const char*)DE_NULL)
6341 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
6343 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6345 msg << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
6346 << "Each descriptor set contains "
6347 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6348 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6349 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
6350 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
6351 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6352 (const char*)DE_NULL)
6353 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
6356 DE_FATAL("Impossible");
6358 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
6361 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
6362 if (m_baseArraySlice)
6363 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
6365 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
6366 msg << "Sampler mode is LINEAR, with WRAP\n";
6368 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
6370 if (m_stageFlags == 0u)
6372 msg << "Descriptors are not accessed in any shader stage.\n";
6376 msg << "Color in each cell is fetched using the descriptor(s):\n";
6378 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6380 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
6382 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
6384 const int srcResourceNdx = (resultNdx % 2); // ABAB source
6386 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6387 msg << " using sampler " << srcResourceNdx;
6388 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6389 msg << " from combined image sampler " << srcResourceNdx;
6391 DE_FATAL("Impossible");
6396 msg << "Descriptors are accessed in {"
6397 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
6398 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
6399 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
6400 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
6401 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
6405 m_context.getTestContext().getLog()
6406 << tcu::TestLog::Message
6408 << tcu::TestLog::EndMessage;
6411 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
6413 return *m_pipelineLayout;
6416 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
6418 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6420 std::vector<vk::VkDescriptorSet> setHandles;
6421 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6422 setHandles.push_back(**m_descriptorSets[setNdx]);
6424 switch (m_descriptorSetCount)
6426 case DESCRIPTOR_SET_COUNT_SINGLE:
6427 case DESCRIPTOR_SET_COUNT_MULTIPLE:
6429 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, (int)setHandles.size(), &setHandles.front(), 0u, DE_NULL);
6432 case DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS:
6434 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6436 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
6437 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), descriptorSetNdx, 1u, &setHandles[setNdx], 0u, DE_NULL);
6442 DE_FATAL("Impossible");
6445 #ifndef CTS_USES_VULKANSC
6446 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
6448 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6450 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
6451 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, **m_updateTemplates[setNdx], getPipelineLayout(), descriptorSetNdx, (const void*)m_updateRegistry[setNdx].getRawPointer());
6454 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6456 deUint32 descriptorNdx = 0u;
6457 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6459 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
6460 const deUint32 numDescriptors = m_descriptorsPerSet[setNdx];
6461 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, descriptorSetNdx, descriptorNdx, numDescriptors);
6462 descriptorNdx += numDescriptors;
6467 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
6470 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
6472 const deUint32 numDescriptorSets = getDescriptorSetCount(m_descriptorSetCount);
6473 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
6474 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
6475 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
6476 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
6478 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
6480 tcu::Vec4 sample0 = tcu::Vec4(0.0f);
6481 tcu::Vec4 sample1 = tcu::Vec4(0.0f);
6482 tcu::Vec4 sample2 = tcu::Vec4(0.0f);
6483 tcu::Vec4 sample3 = tcu::Vec4(0.0f);
6485 for (deUint32 setNdx = 0; setNdx < numDescriptorSets; setNdx++)
6487 sample0 += (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0, setNdx));
6488 sample1 += (!doFetch) ? (green) : (m_images.fetchSampleValue(1, setNdx));
6489 sample2 += (!doFetch) ? (green) : (m_images.fetchSampleValue(2, setNdx));
6490 sample3 += (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3, setNdx));
6493 if (numDescriptorSets > 1)
6495 sample0 = sample0 / tcu::Vec4(float(numDescriptorSets));
6496 sample1 = sample1 / tcu::Vec4(float(numDescriptorSets));
6497 sample2 = sample2 / tcu::Vec4(float(numDescriptorSets));
6498 sample3 = sample3 / tcu::Vec4(float(numDescriptorSets));
6501 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
6503 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
6504 return tcu::TestStatus::fail("Image verification failed");
6506 return tcu::TestStatus::pass("Pass");
6509 class ImageSampleComputeInstance : public vkt::TestInstance
6512 ImageSampleComputeInstance (vkt::Context& context,
6513 DescriptorUpdateMethod updateMethod,
6514 vk::VkDescriptorType descriptorType,
6515 DescriptorSetCount descriptorSetCount,
6516 ShaderInputInterface shaderInterface,
6517 vk::VkImageViewType viewType,
6518 deUint32 baseMipLevel,
6519 deUint32 baseArraySlice,
6520 bool isImmutableSampler);
6523 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (deUint32 setNdx) const;
6524 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
6525 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx);
6526 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, vk::VkPipelineLayout pipelineLayout = DE_NULL);
6527 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx);
6528 #ifndef CTS_USES_VULKANSC
6529 void writeImageSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
6531 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx);
6532 #ifndef CTS_USES_VULKANSC
6533 void writeSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
6536 tcu::TestStatus iterate (void);
6537 void logTestPlan (void) const;
6538 tcu::TestStatus testResourceAccess (void);
6540 const DescriptorUpdateMethod m_updateMethod;
6541 const vk::VkDescriptorType m_descriptorType;
6542 const DescriptorSetCount m_descriptorSetCount;
6543 const ShaderInputInterface m_shaderInterface;
6544 const vk::VkImageViewType m_viewType;
6545 const deUint32 m_baseMipLevel;
6546 const deUint32 m_baseArraySlice;
6547 const bool m_isImmutableSampler;
6548 #ifndef CTS_USES_VULKANSC
6549 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
6552 const vk::DeviceInterface& m_vki;
6553 const vk::VkDevice m_device;
6554 const vk::VkQueue m_queue;
6555 const deUint32 m_queueFamilyIndex;
6556 vk::Allocator& m_allocator;
6557 const ComputeInstanceResultBuffer m_result;
6558 const ImageSampleInstanceImages m_images;
6559 #ifndef CTS_USES_VULKANSC
6560 std::vector<RawUpdateRegistry> m_updateRegistry;
6562 vk::DescriptorSetUpdateBuilder m_updateBuilder;
6563 std::vector<deUint32> m_descriptorsPerSet;
6566 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
6567 DescriptorUpdateMethod updateMethod,
6568 vk::VkDescriptorType descriptorType,
6569 DescriptorSetCount descriptorSetCount,
6570 ShaderInputInterface shaderInterface,
6571 vk::VkImageViewType viewType,
6572 deUint32 baseMipLevel,
6573 deUint32 baseArraySlice,
6574 bool isImmutableSampler)
6575 : vkt::TestInstance (context)
6576 , m_updateMethod (updateMethod)
6577 , m_descriptorType (descriptorType)
6578 , m_descriptorSetCount (descriptorSetCount)
6579 , m_shaderInterface (shaderInterface)
6580 , m_viewType (viewType)
6581 , m_baseMipLevel (baseMipLevel)
6582 , m_baseArraySlice (baseArraySlice)
6583 , m_isImmutableSampler (isImmutableSampler)
6584 #ifndef CTS_USES_VULKANSC
6585 , m_updateTemplates ()
6587 , m_vki (context.getDeviceInterface())
6588 , m_device (context.getDevice())
6589 , m_queue (context.getUniversalQueue())
6590 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
6591 , m_allocator (context.getDefaultAllocator())
6592 , m_result (m_vki, m_device, m_allocator)
6593 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
6594 #ifndef CTS_USES_VULKANSC
6595 , m_updateRegistry ()
6597 , m_updateBuilder ()
6598 , m_descriptorsPerSet ()
6602 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (deUint32 setNdx) const
6604 const vk::VkSampler samplers[2] =
6606 m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface)),
6607 m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1),
6610 vk::DescriptorSetLayoutBuilder builder;
6611 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
6612 deUint32 binding = 0;
6614 #ifndef CTS_USES_VULKANSC
6615 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
6616 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6618 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
6624 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++);
6626 // (combined)samplers follow
6627 switch (m_shaderInterface)
6629 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6630 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6631 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++);
6632 builder.addSingleIndexedSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
6635 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6636 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6637 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++);
6638 builder.addSingleIndexedSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
6639 builder.addSingleIndexedSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
6642 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6643 builder.addSingleIndexedSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
6644 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6645 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding + 1u);
6646 builder.addSingleIndexedSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding + 2u, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
6649 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
6650 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6651 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++);
6652 builder.addSingleIndexedSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, getArbitraryBindingIndex(0), (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
6653 builder.addSingleIndexedSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, getArbitraryBindingIndex(1), (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
6656 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6657 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6658 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++);
6659 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
6663 DE_FATAL("Impossible");
6666 return builder.build(m_vki, m_device, extraFlags);
6669 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
6671 vk::DescriptorPoolBuilder builder;
6673 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
6674 builder.addType(m_descriptorType, getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface));
6676 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6677 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, getDescriptorSetCount(m_descriptorSetCount));
6679 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(m_descriptorSetCount));
6682 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx)
6684 const vk::VkDescriptorSetAllocateInfo allocInfo =
6686 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
6693 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6695 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
6696 writeDescriptorSet(*descriptorSet, layout, setNdx);
6698 return descriptorSet;
6701 return vk::Move<vk::VkDescriptorSet>();
6704 void ImageSampleComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, vk::VkPipelineLayout pipelineLayout)
6706 #ifdef CTS_USES_VULKANSC
6708 DE_UNREF(pipelineLayout);
6710 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
6712 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6713 writeSamplerDescriptorSetWithTemplate(descriptorSet, layout, setNdx);
6714 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6715 writeImageSamplerDescriptorSetWithTemplate(descriptorSet, layout, setNdx);
6717 DE_FATAL("Impossible");
6719 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
6721 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6722 writeSamplerDescriptorSetWithTemplate(descriptorSet, layout, setNdx, true, pipelineLayout);
6723 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6724 writeImageSamplerDescriptorSetWithTemplate(descriptorSet, layout, setNdx, true, pipelineLayout);
6726 DE_FATAL("Impossible");
6728 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6730 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6731 writeSamplerDescriptorSet(descriptorSet, setNdx);
6732 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6733 writeImageSamplerDescriptorSet(descriptorSet, setNdx);
6735 DE_FATAL("Impossible");
6737 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6740 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6741 writeSamplerDescriptorSet(descriptorSet, setNdx);
6742 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6743 writeImageSamplerDescriptorSet(descriptorSet, setNdx);
6745 DE_FATAL("Impossible");
6749 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx)
6751 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6752 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageView(setNdx), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
6753 const vk::VkDescriptorImageInfo samplersInfos[2] =
6755 makeDescriptorImageInfo(m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface))),
6756 makeDescriptorImageInfo(m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)),
6758 deUint32 binding = 0u;
6759 deUint32 numDescriptors = 0u;
6764 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
6768 // stand alone texture
6770 const deUint32 texutreBinding = (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? (binding + 1) : (binding++);
6771 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(texutreBinding), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
6776 if (!m_isImmutableSampler || (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH))
6778 switch (m_shaderInterface)
6780 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6781 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6785 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6786 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6787 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
6788 numDescriptors += 2;
6791 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6792 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6793 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding + 2), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
6794 numDescriptors += 2;
6797 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
6798 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6799 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
6800 numDescriptors += 2;
6803 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6804 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
6809 DE_FATAL("Impossible");
6813 m_descriptorsPerSet.push_back(numDescriptors);
6815 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6817 m_updateBuilder.update(m_vki, m_device);
6818 m_updateBuilder.clear();
6822 #ifndef CTS_USES_VULKANSC
6823 void ImageSampleComputeInstance::writeSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush, vk::VkPipelineLayout pipelineLayout)
6825 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
6826 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6827 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageView(setNdx), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
6828 const vk::VkDescriptorImageInfo samplersInfos[2] =
6830 makeDescriptorImageInfo(m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface))),
6831 makeDescriptorImageInfo(m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)),
6833 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
6835 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6839 DE_NULL, // pUpdates
6840 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
6842 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
6844 getDescriptorSetNdx(m_descriptorSetCount, setNdx)
6846 deUint32 binding = 0u;
6847 deUint32 offset = 0u;
6848 RawUpdateRegistry updateRegistry;
6851 updateRegistry.addWriteObject(resultInfo);
6853 updateRegistry.addWriteObject(imageInfo);
6854 updateRegistry.addWriteObject(samplersInfos[0]);
6855 updateRegistry.addWriteObject(samplersInfos[1]);
6859 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
6861 // stand alone texture
6863 const deUint32 textureBinding = (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? (binding + 1) : (binding++);
6864 updateEntries.push_back(createTemplateBinding(textureBinding, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, updateRegistry.getWriteObjectOffset(offset++), 0));
6868 if (!m_isImmutableSampler || withPush)
6870 switch (m_shaderInterface)
6872 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6873 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6876 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6877 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6878 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6881 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6882 updateEntries.push_back(createTemplateBinding(binding, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6883 updateEntries.push_back(createTemplateBinding(binding + 2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6886 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
6887 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6888 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6891 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6892 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), sizeof(samplersInfos[0])));
6896 DE_FATAL("Impossible");
6900 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6901 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6903 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(m_vki, m_device, &templateCreateInfo);
6904 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
6905 m_updateRegistry.push_back(updateRegistry);
6909 m_vki.updateDescriptorSetWithTemplate(m_device, descriptorSet, **m_updateTemplates.back(), m_updateRegistry.back().getRawPointer());
6914 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx)
6916 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6917 const vk::VkSampler samplers[2] =
6919 (m_isImmutableSampler && (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)) ? (0) : (m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface))),
6920 (m_isImmutableSampler && (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)) ? (0) : (m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)),
6922 const vk::VkDescriptorImageInfo imageSamplers[2] =
6924 makeDescriptorImageInfo(samplers[0], m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface)), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6925 makeDescriptorImageInfo(samplers[1], m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6927 deUint32 binding = 0u;
6928 deUint32 numDescriptors = 0u;
6933 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
6937 // combined image samplers
6938 switch (m_shaderInterface)
6940 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6941 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6945 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6946 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6947 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6948 numDescriptors += 2;
6951 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6952 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6953 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding + 2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6954 numDescriptors += 2;
6957 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
6958 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6959 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6960 numDescriptors += 2;
6963 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6964 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
6969 DE_FATAL("Impossible");
6972 m_descriptorsPerSet.push_back(numDescriptors);
6974 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6976 m_updateBuilder.update(m_vki, m_device);
6977 m_updateBuilder.clear();
6981 #ifndef CTS_USES_VULKANSC
6982 void ImageSampleComputeInstance::writeImageSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush, vk::VkPipelineLayout pipelineLayout)
6984 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
6985 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6986 const vk::VkSampler samplers[2] =
6988 (m_isImmutableSampler && !withPush) ? (0) : (m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface))),
6989 (m_isImmutableSampler && !withPush) ? (0) : (m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)),
6991 const vk::VkDescriptorImageInfo imageSamplers[2] =
6993 makeDescriptorImageInfo(samplers[0], m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface)), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6994 makeDescriptorImageInfo(samplers[1], m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6996 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
6998 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
7002 DE_NULL, // pUpdates
7003 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
7005 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
7007 getDescriptorSetNdx(m_descriptorSetCount, setNdx)
7010 deUint32 binding = 0u;
7011 deUint32 offset = 0u;
7012 RawUpdateRegistry updateRegistry;
7015 updateRegistry.addWriteObject(resultInfo);
7017 updateRegistry.addWriteObject(imageSamplers[0]);
7018 updateRegistry.addWriteObject(imageSamplers[1]);
7022 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
7024 // combined image samplers
7025 switch (m_shaderInterface)
7027 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7028 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
7031 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7032 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
7033 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
7036 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
7037 updateEntries.push_back(createTemplateBinding(binding, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
7038 updateEntries.push_back(createTemplateBinding(binding + 2, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
7041 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
7042 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
7043 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
7046 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7047 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), sizeof(imageSamplers[0])));
7051 DE_FATAL("Impossible");
7054 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
7055 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
7057 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(m_vki, m_device, &templateCreateInfo);
7058 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
7059 m_updateRegistry.push_back(updateRegistry);
7063 m_vki.updateDescriptorSetWithTemplate(m_device, descriptorSet, **m_updateTemplates.back(), m_updateRegistry.back().getRawPointer());
7068 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
7071 return testResourceAccess();
7074 void ImageSampleComputeInstance::logTestPlan (void) const
7076 std::ostringstream msg;
7078 msg << "Accessing resource in a compute program.\n";
7080 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
7082 msg << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
7083 << "Each descriptor set contains "
7084 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
7085 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
7086 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
7087 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
7088 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
7089 (const char*)DE_NULL)
7090 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
7092 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
7094 msg << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
7095 << "Each descriptor set contains "
7096 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
7097 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
7098 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
7099 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
7100 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
7101 (const char*)DE_NULL)
7102 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
7105 DE_FATAL("Impossible");
7107 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
7110 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
7111 if (m_baseArraySlice)
7112 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
7114 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
7115 msg << "Sampler mode is LINEAR, with WRAP\n";
7117 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
7119 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
7121 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
7123 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
7125 const int srcResourceNdx = (resultNdx % 2); // ABAB source
7127 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
7128 msg << " using sampler " << srcResourceNdx;
7129 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
7130 msg << " from combined image sampler " << srcResourceNdx;
7132 DE_FATAL("Impossible");
7137 m_context.getTestContext().getLog()
7138 << tcu::TestLog::Message
7140 << tcu::TestLog::EndMessage;
7143 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
7145 const vk::Unique<vk::VkDescriptorPool> descriptorPool(createDescriptorPool());
7146 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
7147 std::vector<DescriptorSetHandleSp> descriptorSets;
7148 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
7149 std::vector<vk::VkDescriptorSet> setHandles;
7151 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
7153 vk::Move<vk::VkDescriptorSetLayout> layout = createDescriptorSetLayout(setNdx);
7154 vk::Move<vk::VkDescriptorSet> set = createDescriptorSet(*descriptorPool, *layout, setNdx);
7156 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
7157 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(set)));
7159 layoutHandles.push_back(**descriptorSetLayouts.back());
7160 setHandles.push_back(**descriptorSets.back());
7162 // Add an empty descriptor set layout between sets 0 and 2
7163 if (setNdx == 0 && m_descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS)
7165 vk::DescriptorSetLayoutBuilder emptyBuilder;
7166 vk::Move<vk::VkDescriptorSetLayout> emptyLayout = emptyBuilder.build(m_vki, m_device, (vk::VkDescriptorSetLayoutCreateFlags)0);
7168 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(emptyLayout)));
7169 layoutHandles.push_back(**descriptorSetLayouts.back());
7173 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), (int)layoutHandles.size(), &layoutHandles.front());
7174 const deUint32* const dynamicOffsets = DE_NULL;
7175 const int numDynamicOffsets = 0;
7176 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
7177 const int numPreBarriers = 0;
7178 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
7179 const int numPostBarriers = 1;
7181 const ComputeCommand compute (m_vki,
7183 pipeline.getPipeline(),
7184 pipeline.getPipelineLayout(),
7185 tcu::UVec3(4, 1, 1),
7187 m_descriptorSetCount, &setHandles.front(),
7188 numDynamicOffsets, dynamicOffsets,
7189 numPreBarriers, preBarriers,
7190 numPostBarriers, postBarriers);
7192 tcu::Vec4 results[4];
7193 bool anyResultSet = false;
7194 bool allResultsOk = true;
7196 #ifndef CTS_USES_VULKANSC
7197 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7199 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
7200 writeDescriptorSet(DE_NULL, layoutHandles[getDescriptorSetNdx(m_descriptorSetCount, setNdx)], setNdx, pipeline.getPipelineLayout()); // descriptor set not applicable
7202 compute.submitAndWait(m_queueFamilyIndex, m_queue, &m_updateTemplates, &m_updateRegistry);
7204 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7206 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
7207 writeDescriptorSet(DE_NULL, layoutHandles[getDescriptorSetNdx(m_descriptorSetCount, setNdx)], setNdx, pipeline.getPipelineLayout()); // descriptor set not applicable
7209 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder, m_descriptorsPerSet);
7214 compute.submitAndWait(m_queueFamilyIndex, m_queue);
7216 m_result.readResultContentsTo(&results);
7219 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
7221 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
7222 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
7223 const tcu::Vec4 result = results[resultNdx];
7224 tcu::Vec4 reference = tcu::Vec4(0.0f);
7226 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
7227 reference += m_images.fetchSampleValue(resultNdx, setNdx);
7229 reference = reference / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
7231 if (result != tcu::Vec4(-1.0f))
7232 anyResultSet = true;
7234 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
7236 allResultsOk = false;
7238 m_context.getTestContext().getLog()
7239 << tcu::TestLog::Message
7240 << "Test sample " << resultNdx << ":\n"
7241 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
7242 << "\tError expected " << reference << ", got " << result
7243 << tcu::TestLog::EndMessage;
7247 // read back and verify
7249 return tcu::TestStatus::pass("Pass");
7250 else if (anyResultSet)
7251 return tcu::TestStatus::fail("Invalid result values");
7254 m_context.getTestContext().getLog()
7255 << tcu::TestLog::Message
7256 << "Result buffer was not written to."
7257 << tcu::TestLog::EndMessage;
7258 return tcu::TestStatus::fail("Result buffer was not written to");
7262 class ImageDescriptorCase : public QuadrantRendederCase
7267 FLAG_BASE_MIP = (1u << 1u),
7268 FLAG_BASE_SLICE = (1u << 2u),
7270 // enum continues where resource flags ends
7271 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
7273 ImageDescriptorCase (tcu::TestContext& testCtx,
7275 const char* description,
7276 bool isPrimaryCmdBuf,
7277 DescriptorUpdateMethod updateMethod,
7278 vk::VkDescriptorType descriptorType,
7279 vk::VkShaderStageFlags exitingStages,
7280 vk::VkShaderStageFlags activeStages,
7281 DescriptorSetCount descriptorSetCount,
7282 ShaderInputInterface shaderInterface,
7283 vk::VkImageViewType viewType,
7287 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
7288 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
7289 std::string genFetchCoordStr (int fetchPosNdx) const;
7290 std::string genSampleCoordStr (int samplePosNdx) const;
7291 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
7292 std::string genNoAccessSource (void) const;
7294 vkt::TestInstance* createInstance (vkt::Context& context) const;
7297 const bool m_isPrimaryCmdBuf;
7298 const DescriptorUpdateMethod m_updateMethod;
7299 const vk::VkDescriptorType m_descriptorType;
7300 const DescriptorSetCount m_descriptorSetCount;
7301 const ShaderInputInterface m_shaderInterface;
7302 const vk::VkImageViewType m_viewType;
7303 const deUint32 m_baseMipLevel;
7304 const deUint32 m_baseArraySlice;
7305 const bool m_isImmutableSampler;
7308 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
7310 const char* description,
7311 bool isPrimaryCmdBuf,
7312 DescriptorUpdateMethod updateMethod,
7313 vk::VkDescriptorType descriptorType,
7314 vk::VkShaderStageFlags exitingStages,
7315 vk::VkShaderStageFlags activeStages,
7316 DescriptorSetCount descriptorSetCount,
7317 ShaderInputInterface shaderInterface,
7318 vk::VkImageViewType viewType,
7320 : QuadrantRendederCase (testCtx, name, description,
7321 // \note 1D textures are not supported in ES
7322 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
7323 exitingStages, activeStages, descriptorSetCount)
7324 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
7325 , m_updateMethod (updateMethod)
7326 , m_descriptorType (descriptorType)
7327 , m_descriptorSetCount (descriptorSetCount)
7328 , m_shaderInterface (shaderInterface)
7329 , m_viewType (viewType)
7330 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
7331 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
7332 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
7336 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
7340 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
7341 return "#extension GL_OES_texture_cube_map_array : require\n";
7346 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
7350 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
7351 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
7352 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
7353 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
7354 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
7356 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
7357 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
7358 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
7359 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
7361 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
7362 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
7366 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
7368 // Result buffer is bound only to the first descriptor set in compute shader cases
7369 const int descBinding = numUsedBindings - ((m_activeStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) ? (setNdx == 0 ? 0 : 1) : 0);
7370 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
7371 const deUint32 descriptorSet = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
7373 switch (m_shaderInterface)
7375 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7377 switch (m_descriptorType)
7379 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7380 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7381 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + ";\n";
7383 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7384 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + ";\n";
7386 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7387 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + ";\n";
7389 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7390 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + ";\n";
7393 DE_FATAL("invalid descriptor");
7397 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7399 switch (m_descriptorType)
7401 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7402 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS)
7403 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7404 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "A;\n"
7405 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 2) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "B;\n";
7407 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "A;\n"
7408 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7409 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 2) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "B;\n";
7411 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7412 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "A;\n"
7413 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "B;\n";
7415 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7416 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "A;\n"
7417 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "B;\n";
7419 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7420 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "A;\n"
7421 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 1) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "B;\n";
7424 DE_FATAL("invalid descriptor");
7428 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
7430 switch (m_descriptorType)
7432 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7433 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "A;\n"
7434 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7435 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 2) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "B;\n";
7437 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7438 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "A;\n"
7439 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 2) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "B;\n";
7441 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7442 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "A;\n"
7443 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 2) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "B;\n";
7445 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7446 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "A;\n"
7447 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 2) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "B;\n";
7450 DE_FATAL("invalid descriptor");
7454 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
7456 switch (m_descriptorType)
7458 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7459 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7460 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(getArbitraryBindingIndex(0)) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "A;\n"
7461 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(getArbitraryBindingIndex(1)) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "B;\n";
7463 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7464 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(getArbitraryBindingIndex(0)) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "A;\n"
7465 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(getArbitraryBindingIndex(1)) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "B;\n";
7467 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7468 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(getArbitraryBindingIndex(0)) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "A;\n"
7469 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(getArbitraryBindingIndex(1)) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "B;\n";
7471 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7472 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(getArbitraryBindingIndex(0)) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "A;\n"
7473 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(getArbitraryBindingIndex(1)) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "B;\n";
7476 DE_FATAL("invalid descriptor");
7480 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7482 switch (m_descriptorType)
7484 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7485 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7486 "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "[2];\n";
7488 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7489 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "[2];\n";
7491 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7492 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "[2];\n";
7494 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7495 buf += "layout(set = " + de::toString(descriptorSet) + ", binding = " + de::toString(descBinding) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "[2];\n";
7498 DE_FATAL("invalid descriptor");
7503 DE_FATAL("Impossible");
7509 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
7511 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
7512 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
7514 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
7516 return de::toString(fetchPos.x());
7518 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
7520 std::ostringstream buf;
7521 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
7526 std::ostringstream buf;
7527 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
7532 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
7534 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
7535 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
7537 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
7539 std::ostringstream buf;
7540 buf << "float(" << fetchPos.x() << ")";
7543 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
7545 std::ostringstream buf;
7546 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
7549 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
7551 std::ostringstream buf;
7552 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
7557 std::ostringstream buf;
7558 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
7563 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
7567 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
7568 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
7569 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
7570 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
7571 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
7572 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
7573 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
7575 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
7576 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
7577 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("A")
7578 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? ("A")
7579 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
7581 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
7582 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
7583 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("B")
7584 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? ("B")
7585 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
7587 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
7589 std::ostringstream buf;
7591 buf << " result_color = vec4(0.0);\n";
7593 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
7595 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
7597 switch (m_descriptorType)
7599 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7600 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7602 const std::string coodStr[4] =
7604 genSampleCoordStr(0),
7605 genSampleCoordStr(1),
7606 genSampleCoordStr(2),
7607 genSampleCoordStr(3),
7610 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
7612 buf << " if (quadrant_id == 0)\n"
7613 << " result_color += textureLod(sampler" << dimension << "(u_separateTexture" << setNdxPostfix << ", u_separateSampler" << setNdxPostfix << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
7614 << " else if (quadrant_id == 1)\n"
7615 << " result_color += textureLod(sampler" << dimension << "(u_separateTexture" << setNdxPostfix << ", u_separateSampler" << setNdxPostfix << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
7616 << " else if (quadrant_id == 2)\n"
7617 << " result_color += textureLod(sampler" << dimension << "(u_separateTexture" << setNdxPostfix << ", u_separateSampler" << setNdxPostfix << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
7619 << " result_color += textureLod(sampler" << dimension << "(u_separateTexture" << setNdxPostfix << ", u_separateSampler" << setNdxPostfix << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
7623 buf << " if (quadrant_id == 0)\n"
7624 << " result_color += textureLod(u_combinedTextureSampler" << setNdxPostfix << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
7625 << " else if (quadrant_id == 1)\n"
7626 << " result_color += textureLod(u_combinedTextureSampler" << setNdxPostfix << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
7627 << " else if (quadrant_id == 2)\n"
7628 << " result_color += textureLod(u_combinedTextureSampler" << setNdxPostfix << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
7630 << " result_color += textureLod(u_combinedTextureSampler" << setNdxPostfix << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
7635 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7637 const std::string coodStr[4] =
7639 genFetchCoordStr(0),
7640 genFetchCoordStr(1),
7641 genFetchCoordStr(2),
7642 genFetchCoordStr(3),
7645 buf << " if (quadrant_id == 0)\n"
7646 << " result_color += imageLoad(u_image" << setNdxPostfix << accessPostfixA << ", " << coodStr[0] << ");\n"
7647 << " else if (quadrant_id == 1)\n"
7648 << " result_color += imageLoad(u_image" << setNdxPostfix << accessPostfixB << ", " << coodStr[1] << ");\n"
7649 << " else if (quadrant_id == 2)\n"
7650 << " result_color += imageLoad(u_image" << setNdxPostfix << accessPostfixA << ", " << coodStr[2] << ");\n"
7652 << " result_color += imageLoad(u_image" << setNdxPostfix << accessPostfixB << ", " << coodStr[3] << ");\n";
7657 DE_FATAL("invalid descriptor");
7661 if (getDescriptorSetCount(m_descriptorSetCount) > 1)
7662 buf << " result_color /= vec4(" << getDescriptorSetCount(m_descriptorSetCount) << ".0);\n";
7667 std::string ImageDescriptorCase::genNoAccessSource (void) const
7669 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
7670 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7672 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
7675 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
7677 verifyDriverSupport(context.getUsedApiVersion(), context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages, m_viewType);
7679 switch (m_descriptorType)
7681 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7682 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7683 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
7685 DE_ASSERT(m_isPrimaryCmdBuf);
7686 return new ImageSampleComputeInstance(context, m_updateMethod, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
7689 return new ImageSampleRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_descriptorSetCount, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
7691 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7692 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7693 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
7695 DE_ASSERT(m_isPrimaryCmdBuf);
7696 return new ImageFetchComputeInstance(context, m_updateMethod, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
7699 return new ImageFetchRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_descriptorSetCount, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
7702 DE_FATAL("Impossible");
7707 class TexelBufferInstanceBuffers
7710 TexelBufferInstanceBuffers (vkt::Context& context,
7711 const vk::DeviceInterface& vki,
7712 vk::VkDevice device,
7713 vk::Allocator& allocator,
7714 vk::VkDescriptorType descriptorType,
7715 DescriptorSetCount descriptorSetCount,
7716 ShaderInputInterface shaderInterface,
7717 bool hasViewOffset);
7720 static std::vector<de::ArrayBuffer<deUint8> > createSourceBuffers (tcu::TextureFormat imageFormat,
7721 deUint32 numTexelBuffers);
7723 static std::vector<tcu::ConstPixelBufferAccess> createSourceViews (const std::vector<de::ArrayBuffer<deUint8> >& sourceBuffers,
7724 tcu::TextureFormat imageFormat,
7725 deUint32 numTexelBuffers,
7726 deUint32 viewOffset);
7728 static std::vector<BufferHandleSp> createBuffers (const vk::DeviceInterface& vki,
7729 vk::VkDevice device,
7730 vk::Allocator& allocator,
7731 vk::VkDescriptorType descriptorType,
7732 const std::vector<de::ArrayBuffer<deUint8> >& sourceBuffers,
7733 std::vector<AllocationSp>& bufferMemory,
7734 tcu::TextureFormat imageFormat,
7735 deUint32 numTexelBuffers,
7736 deUint32 viewOffset);
7738 static std::vector<BufferViewHandleSp> createBufferViews (const vk::DeviceInterface& vki,
7739 vk::VkDevice device,
7740 const std::vector<BufferHandleSp>& buffers,
7741 tcu::TextureFormat imageFormat,
7742 deUint32 numTexelBuffers,
7743 deUint32 viewOffset);
7745 static std::vector<vk::VkBufferMemoryBarrier> createBufferBarriers (vk::VkDescriptorType descriptorType,
7746 const std::vector<BufferHandleSp>& buffers,
7747 deUint32 numTexelBuffers);
7750 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
7751 vk::VkDevice device,
7752 vk::Allocator& allocator,
7753 vk::VkDescriptorType descriptorType,
7754 de::MovePtr<vk::Allocation> *outAllocation);
7756 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
7757 vk::VkDevice device,
7758 const tcu::TextureFormat& textureFormat,
7760 vk::VkBuffer buffer);
7762 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType,
7763 vk::VkBuffer buffer);
7765 static void populateSourceBuffer (const tcu::PixelBufferAccess& access,
7766 deUint32 bufferNdx);
7768 static void uploadData (const vk::DeviceInterface& vki,
7769 vk::VkDevice device,
7770 const vk::Allocation& memory,
7771 const de::ArrayBuffer<deUint8>& data);
7773 deUint32 getViewOffset (vkt::Context& context,
7775 vk::VkDescriptorType descriptorType);
7778 static int getFetchPos (int fetchPosNdx);
7779 tcu::Vec4 fetchTexelValue (int fetchPosNdx, int setNdx) const;
7781 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
7782 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
7783 inline vk::VkBufferView getBufferView (int ndx) const { return **m_bufferView[ndx % m_bufferView.size()]; }
7784 inline tcu::ConstPixelBufferAccess getSourceView (int ndx) const { return m_sourceView[ndx % m_sourceView.size()]; }
7785 inline const vk::VkBufferMemoryBarrier* getBufferInitBarriers (void) const { return &m_bufferBarrier.front(); }
7791 VIEW_DATA_SIZE = 256, //!< size in bytes
7792 VIEW_WIDTH = 64, //!< size in pixels
7796 // some arbitrary points
7798 SAMPLE_POINT_1 = 51,
7799 SAMPLE_POINT_2 = 42,
7800 SAMPLE_POINT_3 = 25,
7803 const deUint32 m_numTexelBuffers;
7804 const tcu::TextureFormat m_imageFormat;
7805 const ShaderInputInterface m_shaderInterface;
7806 const deUint32 m_viewOffset;
7808 const std::vector<de::ArrayBuffer<deUint8> > m_sourceBuffer;
7809 const std::vector<tcu::ConstPixelBufferAccess> m_sourceView;
7811 std::vector<AllocationSp> m_bufferMemory;
7812 const std::vector<BufferHandleSp> m_buffer;
7813 const std::vector<BufferViewHandleSp> m_bufferView;
7814 const std::vector<vk::VkBufferMemoryBarrier> m_bufferBarrier;
7817 deUint32 TexelBufferInstanceBuffers::getViewOffset(vkt::Context& context,
7819 vk::VkDescriptorType descriptorType)
7824 if (!context.getTexelBufferAlignmentFeaturesEXT().texelBufferAlignment)
7825 return (deUint32)context.getDeviceProperties().limits.minTexelBufferOffsetAlignment;
7827 vk::VkPhysicalDeviceTexelBufferAlignmentPropertiesEXT alignmentProperties;
7828 deMemset(&alignmentProperties, 0, sizeof(alignmentProperties));
7829 alignmentProperties.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TEXEL_BUFFER_ALIGNMENT_PROPERTIES_EXT;
7831 vk::VkPhysicalDeviceProperties2 properties2;
7832 deMemset(&properties2, 0, sizeof(properties2));
7833 properties2.sType = vk::VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
7834 properties2.pNext = &alignmentProperties;
7836 context.getInstanceInterface().getPhysicalDeviceProperties2(context.getPhysicalDevice(), &properties2);
7838 vk::VkBool32 singleTexelAlignment = isUniformDescriptorType(descriptorType) ? alignmentProperties.uniformTexelBufferOffsetSingleTexelAlignment :
7839 alignmentProperties.storageTexelBufferOffsetSingleTexelAlignment;
7840 vk::VkDeviceSize align = isUniformDescriptorType(descriptorType) ? alignmentProperties.uniformTexelBufferOffsetAlignmentBytes :
7841 alignmentProperties.storageTexelBufferOffsetAlignmentBytes;
7844 if (singleTexelAlignment)
7845 return de::min(4u, (deUint32)align);
7847 return (deUint32)align;
7850 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (vkt::Context& context,
7851 const vk::DeviceInterface& vki,
7852 vk::VkDevice device,
7853 vk::Allocator& allocator,
7854 vk::VkDescriptorType descriptorType,
7855 DescriptorSetCount descriptorSetCount,
7856 ShaderInputInterface shaderInterface,
7858 : m_numTexelBuffers (getInterfaceNumResources(shaderInterface) * getDescriptorSetCount(descriptorSetCount))
7859 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
7860 , m_shaderInterface (shaderInterface)
7861 , m_viewOffset (getViewOffset(context, hasViewOffset, descriptorType))
7862 , m_sourceBuffer (createSourceBuffers(m_imageFormat, m_numTexelBuffers))
7863 , m_sourceView (createSourceViews(m_sourceBuffer, m_imageFormat, m_numTexelBuffers, m_viewOffset))
7865 , m_buffer (createBuffers(vki, device, allocator, descriptorType, m_sourceBuffer, m_bufferMemory, m_imageFormat, m_numTexelBuffers, m_viewOffset))
7866 , m_bufferView (createBufferViews(vki, device, m_buffer, m_imageFormat, m_numTexelBuffers, m_viewOffset))
7867 , m_bufferBarrier (createBufferBarriers(descriptorType, m_buffer, m_numTexelBuffers))
7871 std::vector<de::ArrayBuffer<deUint8> > TexelBufferInstanceBuffers::createSourceBuffers (tcu::TextureFormat imageFormat,
7872 deUint32 numTexelBuffers)
7874 DE_ASSERT(BUFFER_SIZE % imageFormat.getPixelSize() == 0);
7876 std::vector<de::ArrayBuffer<deUint8> > sourceBuffers(numTexelBuffers, BUFFER_SIZE);
7878 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7879 populateSourceBuffer(tcu::PixelBufferAccess(imageFormat, tcu::IVec3(BUFFER_SIZE / imageFormat.getPixelSize(), 1, 1), sourceBuffers[bufferNdx].getPtr()), bufferNdx);
7881 return sourceBuffers;
7884 std::vector<tcu::ConstPixelBufferAccess> TexelBufferInstanceBuffers::createSourceViews (const std::vector<de::ArrayBuffer<deUint8> >& sourceBuffers,
7885 tcu::TextureFormat imageFormat,
7886 deUint32 numTexelBuffers,
7887 deUint32 viewOffset)
7889 std::vector<tcu::ConstPixelBufferAccess> sourceViews;
7891 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7892 sourceViews.push_back(tcu::ConstPixelBufferAccess(imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), sourceBuffers[bufferNdx].getElementPtr(viewOffset)));
7897 std::vector<BufferHandleSp> TexelBufferInstanceBuffers::createBuffers (const vk::DeviceInterface& vki,
7898 vk::VkDevice device,
7899 vk::Allocator& allocator,
7900 vk::VkDescriptorType descriptorType,
7901 const std::vector<de::ArrayBuffer<deUint8> >& sourceBuffers,
7902 std::vector<AllocationSp>& bufferMemory,
7903 tcu::TextureFormat imageFormat,
7904 deUint32 numTexelBuffers,
7905 deUint32 viewOffset)
7907 std::vector<BufferHandleSp> buffers;
7909 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7911 de::MovePtr<vk::Allocation> memory;
7912 vk::Move<vk::VkBuffer> buffer = createBuffer(vki, device, allocator, descriptorType, &memory);
7913 vk::Move<vk::VkBufferView> bufferView = createBufferView(vki, device, imageFormat, viewOffset, *buffer);
7915 uploadData(vki, device, *memory, sourceBuffers[bufferNdx]);
7917 bufferMemory.push_back(AllocationSp(memory.release()));
7918 buffers.push_back(BufferHandleSp(new BufferHandleUp(buffer)));
7924 std::vector<BufferViewHandleSp> TexelBufferInstanceBuffers::createBufferViews (const vk::DeviceInterface& vki,
7925 vk::VkDevice device,
7926 const std::vector<BufferHandleSp>& buffers,
7927 tcu::TextureFormat imageFormat,
7928 deUint32 numTexelBuffers,
7929 deUint32 viewOffset)
7931 std::vector<BufferViewHandleSp> bufferViews;
7933 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7935 vk::Move<vk::VkBufferView> bufferView = createBufferView(vki, device, imageFormat, viewOffset, **buffers[bufferNdx]);
7936 bufferViews.push_back(BufferViewHandleSp(new BufferViewHandleUp(bufferView)));
7942 std::vector<vk::VkBufferMemoryBarrier> TexelBufferInstanceBuffers::createBufferBarriers (vk::VkDescriptorType descriptorType,
7943 const std::vector<BufferHandleSp>& buffers,
7944 deUint32 numTexelBuffers)
7946 std::vector<vk::VkBufferMemoryBarrier> bufferBarriers;
7948 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7949 bufferBarriers.push_back(createBarrier(descriptorType, **buffers[bufferNdx]));
7951 return bufferBarriers;
7954 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
7955 vk::VkDevice device,
7956 vk::Allocator& allocator,
7957 vk::VkDescriptorType descriptorType,
7958 de::MovePtr<vk::Allocation> *outAllocation)
7960 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
7961 const vk::VkBufferCreateInfo createInfo =
7963 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
7966 (vk::VkDeviceSize)BUFFER_SIZE, // size
7968 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
7969 0u, // queueFamilyCount
7970 DE_NULL, // pQueueFamilyIndices
7972 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
7973 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
7975 *outAllocation = allocation;
7979 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
7980 vk::VkDevice device,
7981 const tcu::TextureFormat& textureFormat,
7983 vk::VkBuffer buffer)
7985 const vk::VkBufferViewCreateInfo createInfo =
7987 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
7989 (vk::VkBufferViewCreateFlags)0,
7991 vk::mapTextureFormat(textureFormat), // format
7992 (vk::VkDeviceSize)offset, // offset
7993 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
7995 return vk::createBufferView(vki, device, &createInfo);
7998 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
8000 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
8001 const vk::VkBufferMemoryBarrier barrier =
8003 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
8005 vk::VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask
8006 inputBit, // dstAccessMask
8007 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
8008 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
8011 (vk::VkDeviceSize)BUFFER_SIZE // size
8016 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access, deUint32 bufferNdx)
8018 DE_ASSERT(access.getHeight() == 1);
8019 DE_ASSERT(access.getDepth() == 1);
8021 const deInt32 width = access.getWidth();
8023 for (int x = 0; x < width; ++x)
8025 int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
8026 int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
8027 int blue = 16 * (x % 16); //!< 16-long triangle wave
8029 DE_ASSERT(de::inRange(red, 0, 255));
8030 DE_ASSERT(de::inRange(green, 0, 255));
8031 DE_ASSERT(de::inRange(blue, 0, 255));
8033 if (bufferNdx % 2 == 0) red = 255 - red;
8034 if (bufferNdx % 3 == 0) green = 255 - green;
8035 if (bufferNdx % 4 == 0) blue = 255 - blue;
8037 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
8041 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
8043 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
8044 flushAlloc(vki, device, memory);
8047 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
8049 static const int fetchPositions[4] =
8056 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
8059 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx, int setNdx) const
8061 // source order is ABAB
8062 const tcu::ConstPixelBufferAccess& texelSrcA = getSourceView(setNdx * getInterfaceNumResources(m_shaderInterface));
8063 const tcu::ConstPixelBufferAccess& texelSrcB = getSourceView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1);
8064 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
8066 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
8069 class TexelBufferRenderInstance : public SingleCmdRenderInstance
8072 TexelBufferRenderInstance (vkt::Context& context,
8073 DescriptorUpdateMethod updateMethod,
8074 bool isPrimaryCmdBuf,
8075 vk::VkDescriptorType descriptorType,
8076 DescriptorSetCount descriptorSetCount,
8077 vk::VkShaderStageFlags stageFlags,
8078 ShaderInputInterface shaderInterface,
8079 bool nonzeroViewOffset);
8082 static std::vector<DescriptorSetLayoutHandleSp> createDescriptorSetLayouts (const vk::DeviceInterface& vki,
8083 vk::VkDevice device,
8084 vk::VkDescriptorType descriptorType,
8085 DescriptorSetCount descriptorSetCount,
8086 ShaderInputInterface shaderInterface,
8087 vk::VkShaderStageFlags stageFlags,
8088 DescriptorUpdateMethod updateMethod);
8090 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
8091 vk::VkDevice device,
8092 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout);
8094 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
8095 vk::VkDevice device,
8096 vk::VkDescriptorType descriptorType,
8097 DescriptorSetCount descriptorSetCount,
8098 ShaderInputInterface shaderInterface);
8100 static std::vector<DescriptorSetHandleSp> createDescriptorSets (const vk::DeviceInterface& vki,
8101 DescriptorUpdateMethod updateMethod,
8102 vk::VkDevice device,
8103 vk::VkDescriptorType descriptorType,
8104 DescriptorSetCount descriptorSetCount,
8105 ShaderInputInterface shaderInterface,
8106 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
8107 vk::VkDescriptorPool pool,
8108 const TexelBufferInstanceBuffers& buffers,
8109 vk::DescriptorSetUpdateBuilder& updateBuilder,
8110 #ifndef CTS_USES_VULKANSC
8111 std::vector<UpdateTemplateHandleSp>& updateTemplates,
8112 std::vector<RawUpdateRegistry>& updateRegistry,
8114 std::vector<deUint32>& descriptorsPerSet,
8115 vk::VkPipelineLayout pipelineLayout = DE_NULL);
8117 static void writeDescriptorSet (const vk::DeviceInterface& vki,
8118 vk::VkDevice device,
8119 vk::VkDescriptorType descriptorType,
8120 ShaderInputInterface shaderInterface,
8121 vk::VkDescriptorSetLayout layout,
8122 vk::VkDescriptorPool pool,
8123 vk::VkBufferView viewA,
8124 vk::VkBufferView viewB,
8125 vk::VkDescriptorSet descriptorSet,
8126 vk::DescriptorSetUpdateBuilder& updateBuilder,
8127 std::vector<deUint32>& descriptorsPerSet,
8128 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
8130 #ifndef CTS_USES_VULKANSC
8131 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
8132 vk::VkDevice device,
8133 vk::VkDescriptorType descriptorType,
8134 ShaderInputInterface shaderInterface,
8135 vk::VkDescriptorSetLayout layout,
8137 vk::VkDescriptorPool pool,
8138 vk::VkBufferView viewA,
8139 vk::VkBufferView viewB,
8140 vk::VkDescriptorSet descriptorSet,
8141 std::vector<UpdateTemplateHandleSp>& updateTemplates,
8142 std::vector<RawUpdateRegistry>& registry,
8143 bool withPush = false,
8144 vk::VkPipelineLayout pipelineLayout = 0);
8147 void logTestPlan (void) const;
8148 vk::VkPipelineLayout getPipelineLayout (void) const;
8149 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
8150 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
8157 const DescriptorUpdateMethod m_updateMethod;
8158 const vk::VkDescriptorType m_descriptorType;
8159 const DescriptorSetCount m_descriptorSetCount;
8160 const vk::VkShaderStageFlags m_stageFlags;
8161 const ShaderInputInterface m_shaderInterface;
8162 const bool m_nonzeroViewOffset;
8164 #ifndef CTS_USES_VULKANSC
8165 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
8166 std::vector<RawUpdateRegistry> m_updateRegistry;
8168 vk::DescriptorSetUpdateBuilder m_updateBuilder;
8169 const std::vector<DescriptorSetLayoutHandleSp> m_descriptorSetLayouts;
8170 const vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
8171 const TexelBufferInstanceBuffers m_texelBuffers;
8172 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
8173 std::vector<deUint32> m_descriptorsPerSet;
8174 const std::vector<DescriptorSetHandleSp> m_descriptorSets;
8177 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
8178 DescriptorUpdateMethod updateMethod,
8179 bool isPrimaryCmdBuf,
8180 vk::VkDescriptorType descriptorType,
8181 DescriptorSetCount descriptorSetCount,
8182 vk::VkShaderStageFlags stageFlags,
8183 ShaderInputInterface shaderInterface,
8184 bool nonzeroViewOffset)
8185 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
8186 , m_updateMethod (updateMethod)
8187 , m_descriptorType (descriptorType)
8188 , m_descriptorSetCount (descriptorSetCount)
8189 , m_stageFlags (stageFlags)
8190 , m_shaderInterface (shaderInterface)
8191 , m_nonzeroViewOffset (nonzeroViewOffset)
8192 #ifndef CTS_USES_VULKANSC
8193 , m_updateTemplates ()
8194 , m_updateRegistry ()
8196 , m_updateBuilder ()
8197 , m_descriptorSetLayouts (createDescriptorSetLayouts(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_stageFlags, m_updateMethod))
8198 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, m_descriptorSetLayouts))
8199 , m_texelBuffers (context, m_vki, m_device, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_nonzeroViewOffset)
8200 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface))
8201 , m_descriptorsPerSet ()
8202 , m_descriptorSets (createDescriptorSets(m_vki, m_updateMethod, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_descriptorSetLayouts, *m_descriptorPool, m_texelBuffers, m_updateBuilder,
8203 #ifndef CTS_USES_VULKANSC
8207 m_descriptorsPerSet, *m_pipelineLayout))
8211 std::vector<DescriptorSetLayoutHandleSp> TexelBufferRenderInstance::createDescriptorSetLayouts (const vk::DeviceInterface& vki,
8212 vk::VkDevice device,
8213 vk::VkDescriptorType descriptorType,
8214 DescriptorSetCount descriptorSetCount,
8215 ShaderInputInterface shaderInterface,
8216 vk::VkShaderStageFlags stageFlags,
8217 DescriptorUpdateMethod updateMethod)
8219 #ifdef CTS_USES_VULKANSC
8220 DE_UNREF(updateMethod);
8222 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
8224 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
8226 vk::DescriptorSetLayoutBuilder builder;
8227 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
8229 #ifndef CTS_USES_VULKANSC
8230 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
8231 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8233 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
8237 switch (shaderInterface)
8239 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8240 builder.addSingleBinding(descriptorType, stageFlags);
8243 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8244 builder.addSingleBinding(descriptorType, stageFlags);
8245 builder.addSingleBinding(descriptorType, stageFlags);
8248 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
8249 builder.addSingleIndexedBinding(descriptorType, stageFlags, 0);
8250 builder.addSingleIndexedBinding(descriptorType, stageFlags, 2);
8253 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
8254 builder.addSingleIndexedBinding(descriptorType, stageFlags, getArbitraryBindingIndex(0));
8255 builder.addSingleIndexedBinding(descriptorType, stageFlags, getArbitraryBindingIndex(1));
8258 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8259 builder.addArrayBinding(descriptorType, 2u, stageFlags);
8263 DE_FATAL("Impossible");
8266 vk::Move<vk::VkDescriptorSetLayout> layout = builder.build(vki, device, extraFlags);
8267 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
8269 // Add an empty descriptor set layout between sets 0 and 2
8270 if (setNdx == 0 && descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS)
8272 vk::DescriptorSetLayoutBuilder emptyBuilder;
8273 vk::Move<vk::VkDescriptorSetLayout> emptyLayout = emptyBuilder.build(vki, device, (vk::VkDescriptorSetLayoutCreateFlags)0);
8274 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(emptyLayout)));
8277 return descriptorSetLayouts;
8280 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
8281 vk::VkDevice device,
8282 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout)
8284 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
8285 for (size_t setNdx = 0; setNdx < descriptorSetLayout.size(); setNdx++)
8286 layoutHandles.push_back(**descriptorSetLayout[setNdx]);
8288 const vk::VkPipelineLayoutCreateInfo createInfo =
8290 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
8292 (vk::VkPipelineLayoutCreateFlags)0,
8293 (deUint32)layoutHandles.size(), // descriptorSetCount
8294 &layoutHandles.front(), // pSetLayouts
8295 0u, // pushConstantRangeCount
8296 DE_NULL, // pPushConstantRanges
8298 return vk::createPipelineLayout(vki, device, &createInfo);
8301 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
8302 vk::VkDevice device,
8303 vk::VkDescriptorType descriptorType,
8304 DescriptorSetCount descriptorSetCount,
8305 ShaderInputInterface shaderInterface)
8307 return vk::DescriptorPoolBuilder()
8308 .addType(descriptorType, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface))
8309 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(descriptorSetCount));
8312 std::vector<DescriptorSetHandleSp> TexelBufferRenderInstance::createDescriptorSets (const vk::DeviceInterface& vki,
8313 DescriptorUpdateMethod updateMethod,
8314 vk::VkDevice device,
8315 vk::VkDescriptorType descriptorType,
8316 DescriptorSetCount descriptorSetCount,
8317 ShaderInputInterface shaderInterface,
8318 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
8319 vk::VkDescriptorPool pool,
8320 const TexelBufferInstanceBuffers& buffers,
8321 vk::DescriptorSetUpdateBuilder& updateBuilder,
8322 #ifndef CTS_USES_VULKANSC
8323 std::vector<UpdateTemplateHandleSp>& updateTemplates,
8324 std::vector<RawUpdateRegistry>& updateRegistry,
8326 std::vector<deUint32>& descriptorsPerSet,
8327 vk::VkPipelineLayout pipelineLayout)
8329 #ifdef CTS_USES_VULKANSC
8330 DE_UNREF(pipelineLayout);
8332 std::vector<DescriptorSetHandleSp> descriptorSets;
8334 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
8336 vk::VkDescriptorSetLayout layout = **descriptorSetLayouts[getDescriptorSetNdx(descriptorSetCount, setNdx)];
8338 const vk::VkDescriptorSetAllocateInfo allocInfo =
8340 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
8347 vk::VkBufferView viewA = buffers.getBufferView(setNdx * getInterfaceNumResources(shaderInterface));
8348 vk::VkBufferView viewB = buffers.getBufferView(setNdx * getInterfaceNumResources(shaderInterface) + 1);
8350 vk::Move<vk::VkDescriptorSet> descriptorSet;
8352 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
8354 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
8358 descriptorSet = vk::Move<vk::VkDescriptorSet>();
8361 #ifndef CTS_USES_VULKANSC
8362 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
8364 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, setNdx, pool, viewA, viewB, *descriptorSet, updateTemplates, updateRegistry);
8366 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
8368 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, setNdx, pool, viewA, viewB, *descriptorSet, updateTemplates, updateRegistry, true, pipelineLayout);
8370 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8372 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, descriptorsPerSet, updateMethod);
8374 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
8377 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, descriptorsPerSet);
8380 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(descriptorSet)));
8383 return descriptorSets;
8386 void TexelBufferRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
8387 vk::VkDevice device,
8388 vk::VkDescriptorType descriptorType,
8389 ShaderInputInterface shaderInterface,
8390 vk::VkDescriptorSetLayout layout,
8391 vk::VkDescriptorPool pool,
8392 vk::VkBufferView viewA,
8393 vk::VkBufferView viewB,
8394 vk::VkDescriptorSet descriptorSet,
8395 vk::DescriptorSetUpdateBuilder& updateBuilder,
8396 std::vector<deUint32>& descriptorsPerSet,
8397 DescriptorUpdateMethod updateMethod)
8401 const vk::VkBufferView texelBufferInfos[2] =
8406 deUint32 numDescriptors = 0u;
8408 switch (shaderInterface)
8410 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8411 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
8415 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8416 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
8417 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
8418 numDescriptors += 2;
8421 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
8422 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
8423 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), descriptorType, &texelBufferInfos[1]);
8424 numDescriptors += 2;
8427 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
8428 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), descriptorType, &texelBufferInfos[0]);
8429 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), descriptorType, &texelBufferInfos[1]);
8430 numDescriptors += 2;
8433 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8434 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
8439 DE_FATAL("Impossible");
8442 descriptorsPerSet.push_back(numDescriptors);
8444 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
8446 updateBuilder.update(vki, device);
8447 updateBuilder.clear();
8451 #ifndef CTS_USES_VULKANSC
8452 void TexelBufferRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
8453 vk::VkDevice device,
8454 vk::VkDescriptorType descriptorType,
8455 ShaderInputInterface shaderInterface,
8456 vk::VkDescriptorSetLayout layout,
8458 vk::VkDescriptorPool pool,
8459 vk::VkBufferView viewA,
8460 vk::VkBufferView viewB,
8461 vk::VkDescriptorSet descriptorSet,
8462 std::vector<UpdateTemplateHandleSp>& updateTemplates,
8463 std::vector<RawUpdateRegistry>& registry,
8465 vk::VkPipelineLayout pipelineLayout)
8468 const vk::VkBufferView texelBufferInfos[2] =
8473 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
8474 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
8476 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
8480 DE_NULL, // pUpdates
8481 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
8483 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
8488 RawUpdateRegistry updateRegistry;
8490 updateRegistry.addWriteObject(texelBufferInfos[0]);
8491 updateRegistry.addWriteObject(texelBufferInfos[1]);
8493 switch (shaderInterface)
8495 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8496 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
8499 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8500 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
8501 updateEntries.push_back(createTemplateBinding(1, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
8504 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
8505 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
8506 updateEntries.push_back(createTemplateBinding(2, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
8509 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
8510 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
8511 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
8514 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8515 updateEntries.push_back(createTemplateBinding(0, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(texelBufferInfos[0])));
8519 DE_FATAL("Impossible");
8522 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
8523 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
8525 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(vki, device, &templateCreateInfo);
8526 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
8527 registry.push_back(updateRegistry);
8531 vki.updateDescriptorSetWithTemplate(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
8536 void TexelBufferRenderInstance::logTestPlan (void) const
8538 std::ostringstream msg;
8540 msg << "Rendering 2x2 grid.\n"
8541 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
8542 << "Each descriptor set contains "
8543 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
8544 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
8545 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
8546 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
8547 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
8548 (const char*)DE_NULL)
8549 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
8550 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
8551 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
8553 if (m_stageFlags == 0u)
8555 msg << "Descriptors are not accessed in any shader stage.\n";
8559 msg << "Color in each cell is fetched using the descriptor(s):\n";
8561 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
8563 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
8565 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
8567 const int srcResourceNdx = (resultNdx % 2); // ABAB source
8568 msg << " from texelBuffer " << srcResourceNdx;
8574 msg << "Descriptors are accessed in {"
8575 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
8576 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
8577 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
8578 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
8579 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
8583 m_context.getTestContext().getLog()
8584 << tcu::TestLog::Message
8586 << tcu::TestLog::EndMessage;
8589 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
8591 return *m_pipelineLayout;
8594 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
8596 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8598 std::vector<vk::VkDescriptorSet> sets;
8599 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8600 sets.push_back(**m_descriptorSets[setNdx]);
8602 switch (m_descriptorSetCount)
8604 case DESCRIPTOR_SET_COUNT_SINGLE:
8605 case DESCRIPTOR_SET_COUNT_MULTIPLE:
8607 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, (deUint32)sets.size(), &sets.front(), 0, DE_NULL);
8610 case DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS:
8612 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8614 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
8615 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), descriptorSetNdx, 1, &sets[setNdx], 0, DE_NULL);
8620 DE_FATAL("Impossible");
8623 #ifndef CTS_USES_VULKANSC
8624 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
8626 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8628 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
8629 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, **m_updateTemplates[setNdx], getPipelineLayout(), descriptorSetNdx, (const void*)m_updateRegistry[setNdx].getRawPointer());
8632 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8634 deUint32 descriptorNdx = 0u;
8635 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8637 const deUint32 numDescriptors = m_descriptorsPerSet[setNdx];
8638 const deUint32 descriptorSetNdx = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
8639 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, descriptorSetNdx, descriptorNdx, numDescriptors);
8640 descriptorNdx += numDescriptors;
8645 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
8648 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
8650 const deUint32 numDescriptorSets = getDescriptorSetCount(m_descriptorSetCount);
8651 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
8652 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
8653 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
8655 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
8657 tcu::Vec4 sample0 = tcu::Vec4(0.0f);
8658 tcu::Vec4 sample1 = tcu::Vec4(0.0f);
8659 tcu::Vec4 sample2 = tcu::Vec4(0.0f);
8660 tcu::Vec4 sample3 = tcu::Vec4(0.0f);
8664 for (deUint32 setNdx = 0u; setNdx < numDescriptorSets; setNdx++)
8666 sample0 += m_texelBuffers.fetchTexelValue(0, setNdx);
8667 sample1 += m_texelBuffers.fetchTexelValue(1, setNdx);
8668 sample2 += m_texelBuffers.fetchTexelValue(2, setNdx);
8669 sample3 += m_texelBuffers.fetchTexelValue(3, setNdx);
8672 if (numDescriptorSets > 1)
8674 sample0 = sample0 / tcu::Vec4(float(numDescriptorSets));
8675 sample1 = sample1 / tcu::Vec4(float(numDescriptorSets));
8676 sample2 = sample2 / tcu::Vec4(float(numDescriptorSets));
8677 sample3 = sample3 / tcu::Vec4(float(numDescriptorSets));
8688 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
8690 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
8691 return tcu::TestStatus::fail("Image verification failed");
8693 return tcu::TestStatus::pass("Pass");
8696 class TexelBufferComputeInstance : public vkt::TestInstance
8699 TexelBufferComputeInstance (vkt::Context& context,
8700 DescriptorUpdateMethod updateMethod,
8701 vk::VkDescriptorType descriptorType,
8702 DescriptorSetCount descriptorSetCount,
8703 ShaderInputInterface shaderInterface,
8704 bool nonzeroViewOffset);
8707 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (deUint32 setNdx) const;
8708 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
8709 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx);
8710 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx);
8711 #ifndef CTS_USES_VULKANSC
8712 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
8715 tcu::TestStatus iterate (void);
8716 void logTestPlan (void) const;
8717 tcu::TestStatus testResourceAccess (void);
8719 const DescriptorUpdateMethod m_updateMethod;
8720 const vk::VkDescriptorType m_descriptorType;
8721 const DescriptorSetCount m_descriptorSetCount;
8722 const ShaderInputInterface m_shaderInterface;
8723 const bool m_nonzeroViewOffset;
8725 const vk::DeviceInterface& m_vki;
8726 const vk::VkDevice m_device;
8727 const vk::VkQueue m_queue;
8728 const deUint32 m_queueFamilyIndex;
8729 vk::Allocator& m_allocator;
8730 #ifndef CTS_USES_VULKANSC
8731 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
8734 const ComputeInstanceResultBuffer m_result;
8735 const TexelBufferInstanceBuffers m_texelBuffers;
8737 #ifndef CTS_USES_VULKANSC
8738 std::vector<RawUpdateRegistry> m_updateRegistry;
8740 vk::DescriptorSetUpdateBuilder m_updateBuilder;
8741 std::vector<deUint32> m_descriptorsPerSet;
8744 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
8745 DescriptorUpdateMethod updateMethod,
8746 vk::VkDescriptorType descriptorType,
8747 DescriptorSetCount descriptorSetCount,
8748 ShaderInputInterface shaderInterface,
8749 bool nonzeroViewOffset)
8750 : vkt::TestInstance (context)
8751 , m_updateMethod (updateMethod)
8752 , m_descriptorType (descriptorType)
8753 , m_descriptorSetCount (descriptorSetCount)
8754 , m_shaderInterface (shaderInterface)
8755 , m_nonzeroViewOffset (nonzeroViewOffset)
8756 , m_vki (context.getDeviceInterface())
8757 , m_device (context.getDevice())
8758 , m_queue (context.getUniversalQueue())
8759 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
8760 , m_allocator (context.getDefaultAllocator())
8761 #ifndef CTS_USES_VULKANSC
8762 , m_updateTemplates ()
8764 , m_result (m_vki, m_device, m_allocator)
8765 , m_texelBuffers (context, m_vki, m_device, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_nonzeroViewOffset)
8766 #ifndef CTS_USES_VULKANSC
8767 , m_updateRegistry ()
8769 , m_updateBuilder ()
8770 , m_descriptorsPerSet ()
8774 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (deUint32 setNdx) const
8776 vk::DescriptorSetLayoutBuilder builder;
8777 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
8778 deUint32 binding = 0;
8780 #ifndef CTS_USES_VULKANSC
8781 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
8782 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8784 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
8789 builder.addSingleIndexedBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding++);
8791 switch (m_shaderInterface)
8793 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8794 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8797 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8798 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8799 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8802 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
8803 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding);
8804 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, binding + 2);
8807 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
8808 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, getArbitraryBindingIndex(0));
8809 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, getArbitraryBindingIndex(1));
8812 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8813 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8817 DE_FATAL("Impossible");
8820 return builder.build(m_vki, m_device, extraFlags);
8823 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
8825 return vk::DescriptorPoolBuilder()
8826 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
8827 .addType(m_descriptorType, getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface))
8828 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(m_descriptorSetCount));
8831 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx)
8833 const vk::VkDescriptorSetAllocateInfo allocInfo =
8835 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
8842 vk::Move<vk::VkDescriptorSet> descriptorSet;
8843 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
8845 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
8849 descriptorSet = vk::Move<vk::VkDescriptorSet>();
8853 #ifndef CTS_USES_VULKANSC
8854 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
8856 writeDescriptorSetWithTemplate(*descriptorSet, layout, setNdx);
8860 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
8862 writeDescriptorSet(*descriptorSet, setNdx);
8865 return descriptorSet;
8868 void TexelBufferComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx)
8870 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
8871 const vk::VkBufferView texelBufferInfos[2] =
8873 m_texelBuffers.getBufferView(setNdx * getInterfaceNumResources(m_shaderInterface)),
8874 m_texelBuffers.getBufferView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)
8876 deUint32 binding = 0u;
8877 deUint32 numDescriptors = 0u;
8882 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
8887 switch (m_shaderInterface)
8889 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8890 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &texelBufferInfos[0]);
8894 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8895 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &texelBufferInfos[0]);
8896 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &texelBufferInfos[1]);
8897 numDescriptors += 2;
8900 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
8901 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding), m_descriptorType, &texelBufferInfos[0]);
8902 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding + 2), m_descriptorType, &texelBufferInfos[1]);
8903 numDescriptors += 2;
8906 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
8907 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(0)), m_descriptorType, &texelBufferInfos[0]);
8908 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(getArbitraryBindingIndex(1)), m_descriptorType, &texelBufferInfos[1]);
8909 numDescriptors += 2;
8912 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8913 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, 2u, texelBufferInfos);
8918 DE_FATAL("Impossible");
8921 m_descriptorsPerSet.push_back(numDescriptors);
8923 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
8925 m_updateBuilder.update(m_vki, m_device);
8926 m_updateBuilder.clear();
8930 #ifndef CTS_USES_VULKANSC
8931 void TexelBufferComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush, vk::VkPipelineLayout pipelineLayout)
8933 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
8934 const vk::VkBufferView texelBufferInfos[2] =
8936 m_texelBuffers.getBufferView(setNdx * getInterfaceNumResources(m_shaderInterface)),
8937 m_texelBuffers.getBufferView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)
8939 std::vector<vk::VkDescriptorUpdateTemplateEntry> updateEntries;
8940 vk::VkDescriptorUpdateTemplateCreateInfo templateCreateInfo =
8942 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
8946 DE_NULL, // pUpdates
8947 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET,
8949 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
8953 deUint32 binding = 0u;
8954 deUint32 offset = 0u;
8955 RawUpdateRegistry updateRegistry;
8958 updateRegistry.addWriteObject(resultInfo);
8960 updateRegistry.addWriteObject(texelBufferInfos[0]);
8961 updateRegistry.addWriteObject(texelBufferInfos[1]);
8965 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
8968 switch (m_shaderInterface)
8970 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8971 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8974 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8975 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8976 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8979 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
8980 updateEntries.push_back(createTemplateBinding(binding, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8981 updateEntries.push_back(createTemplateBinding(binding + 2, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8984 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
8985 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(0), 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8986 updateEntries.push_back(createTemplateBinding(getArbitraryBindingIndex(1), 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8989 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8990 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), sizeof(texelBufferInfos[0])));
8994 DE_FATAL("Impossible");
8997 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
8998 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
9000 vk::Move<vk::VkDescriptorUpdateTemplate> updateTemplate = vk::createDescriptorUpdateTemplate(m_vki, m_device, &templateCreateInfo);
9001 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
9002 m_updateRegistry.push_back(updateRegistry);
9006 m_vki.updateDescriptorSetWithTemplate(m_device, descriptorSet, **m_updateTemplates[setNdx], m_updateRegistry.back().getRawPointer());
9011 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
9014 return testResourceAccess();
9017 void TexelBufferComputeInstance::logTestPlan (void) const
9019 std::ostringstream msg;
9021 msg << "Fetching 4 values from image in compute shader.\n"
9022 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
9023 << "Each descriptor set contains "
9024 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
9025 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
9026 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
9027 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
9028 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
9029 (const char*)DE_NULL)
9030 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
9031 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
9032 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
9034 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
9036 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
9038 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
9040 const int srcResourceNdx = (resultNdx % 2); // ABAB source
9041 msg << " from texelBuffer " << srcResourceNdx;
9047 m_context.getTestContext().getLog()
9048 << tcu::TestLog::Message
9050 << tcu::TestLog::EndMessage;
9053 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
9055 const vk::Unique<vk::VkDescriptorPool> descriptorPool(createDescriptorPool());
9056 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
9057 std::vector<DescriptorSetHandleSp> descriptorSets;
9058 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
9059 std::vector<vk::VkDescriptorSet> setHandles;
9061 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
9063 vk::Move<vk::VkDescriptorSetLayout> layout = createDescriptorSetLayout(setNdx);
9064 vk::Move<vk::VkDescriptorSet> set = createDescriptorSet(*descriptorPool, *layout, setNdx);
9066 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
9067 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(set)));
9069 layoutHandles.push_back(**descriptorSetLayouts.back());
9070 setHandles.push_back(**descriptorSets.back());
9072 // Add an empty descriptor set layout between sets 0 and 2
9073 if (setNdx == 0 && m_descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS)
9075 vk::DescriptorSetLayoutBuilder emptyBuilder;
9076 vk::Move<vk::VkDescriptorSetLayout> emptyLayout = emptyBuilder.build(m_vki, m_device, (vk::VkDescriptorSetLayoutCreateFlags)0);
9078 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(emptyLayout)));
9079 layoutHandles.push_back(**descriptorSetLayouts.back());
9083 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), (int)layoutHandles.size(), &layoutHandles.front());
9084 const deUint32* const dynamicOffsets = DE_NULL;
9085 const int numDynamicOffsets = 0;
9086 const vk::VkBufferMemoryBarrier* const preBarriers = m_texelBuffers.getBufferInitBarriers();
9087 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
9088 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
9089 const int numPostBarriers = 1;
9091 const ComputeCommand compute (m_vki,
9093 pipeline.getPipeline(),
9094 pipeline.getPipelineLayout(),
9095 tcu::UVec3(4, 1, 1),
9097 m_descriptorSetCount, &setHandles.front(),
9098 numDynamicOffsets, dynamicOffsets,
9099 numPreBarriers, preBarriers,
9100 numPostBarriers, postBarriers);
9102 tcu::Vec4 results[4];
9103 bool anyResultSet = false;
9104 bool allResultsOk = true;
9106 #ifndef CTS_USES_VULKANSC
9107 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
9109 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
9110 writeDescriptorSetWithTemplate(DE_NULL, layoutHandles[setNdx], setNdx, true, pipeline.getPipelineLayout());
9112 compute.submitAndWait(m_queueFamilyIndex, m_queue, &m_updateTemplates, &m_updateRegistry);
9114 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
9116 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
9117 writeDescriptorSet(DE_NULL, setNdx);
9119 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder, m_descriptorsPerSet);
9124 compute.submitAndWait(m_queueFamilyIndex, m_queue);
9126 m_result.readResultContentsTo(&results);
9129 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
9131 const tcu::Vec4 result = results[resultNdx];
9132 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
9134 tcu::Vec4 reference = tcu::Vec4(0.0f);
9135 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
9136 reference += m_texelBuffers.fetchTexelValue(resultNdx, setNdx);
9138 reference = reference / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
9140 if (result != tcu::Vec4(-1.0f))
9141 anyResultSet = true;
9143 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
9145 allResultsOk = false;
9147 m_context.getTestContext().getLog()
9148 << tcu::TestLog::Message
9149 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
9150 << tcu::TestLog::EndMessage;
9154 // read back and verify
9156 return tcu::TestStatus::pass("Pass");
9157 else if (anyResultSet)
9158 return tcu::TestStatus::fail("Invalid result values");
9161 m_context.getTestContext().getLog()
9162 << tcu::TestLog::Message
9163 << "Result buffer was not written to."
9164 << tcu::TestLog::EndMessage;
9165 return tcu::TestStatus::fail("Result buffer was not written to");
9169 class TexelBufferDescriptorCase : public QuadrantRendederCase
9174 FLAG_VIEW_OFFSET = (1u << 1u),
9176 // enum continues where resource flags ends
9177 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
9179 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
9180 DescriptorUpdateMethod updateMethod,
9182 const char* description,
9183 bool isPrimaryCmdBuf,
9184 vk::VkDescriptorType descriptorType,
9185 vk::VkShaderStageFlags exitingStages,
9186 vk::VkShaderStageFlags activeStages,
9187 DescriptorSetCount descriptorSetCount,
9188 ShaderInputInterface shaderInterface,
9192 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
9193 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
9194 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
9195 std::string genNoAccessSource (void) const;
9197 vkt::TestInstance* createInstance (vkt::Context& context) const;
9199 const DescriptorUpdateMethod m_updateMethod;
9200 const bool m_isPrimaryCmdBuf;
9201 const vk::VkDescriptorType m_descriptorType;
9202 const DescriptorSetCount m_descriptorSetCount;
9203 const ShaderInputInterface m_shaderInterface;
9204 const bool m_nonzeroViewOffset;
9207 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
9208 DescriptorUpdateMethod updateMethod,
9210 const char* description,
9211 bool isPrimaryCmdBuf,
9212 vk::VkDescriptorType descriptorType,
9213 vk::VkShaderStageFlags exitingStages,
9214 vk::VkShaderStageFlags activeStages,
9215 DescriptorSetCount descriptorSetCount,
9216 ShaderInputInterface shaderInterface,
9218 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages, descriptorSetCount)
9219 , m_updateMethod (updateMethod)
9220 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
9221 , m_descriptorType (descriptorType)
9222 , m_descriptorSetCount (descriptorSetCount)
9223 , m_shaderInterface (shaderInterface)
9224 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
9228 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
9231 return "#extension GL_EXT_texture_buffer : require\n";
9234 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
9238 const bool isUniform = isUniformDescriptorType(m_descriptorType);
9239 const char* const storageType = (isUniform) ? ("textureBuffer ") : ("readonly imageBuffer ");
9240 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
9241 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
9243 std::ostringstream buf;
9245 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
9247 // Result buffer is bound only to the first descriptor set in compute shader cases
9248 const int descBinding = numUsedBindings - ((m_activeStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) ? (setNdx == 0 ? 0 : 1) : 0);
9249 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
9250 const deUint32 descriptorSet = getDescriptorSetNdx(m_descriptorSetCount, setNdx);
9252 switch (m_shaderInterface)
9254 case SHADER_INPUT_SINGLE_DESCRIPTOR:
9255 buf << "layout(set = " << descriptorSet << ", binding = " + de::toString(descBinding) + formatQualifier + ") uniform highp " + storageType + "u_texelBuffer" << setNdxPostfix << ";\n";
9257 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
9258 buf << "layout(set = " << descriptorSet << ", binding = " + de::toString(descBinding) + formatQualifier + ") uniform highp " + storageType + "u_texelBuffer" << setNdxPostfix << "A;\n"
9259 "layout(set = " << descriptorSet << ", binding = " + de::toString(descBinding + 1) + formatQualifier + ") uniform highp " + storageType + "u_texelBuffer" << setNdxPostfix << "B;\n";
9261 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
9262 buf << "layout(set = " << descriptorSet << ", binding = " + de::toString(descBinding) + formatQualifier + ") uniform highp " + storageType + "u_texelBuffer" << setNdxPostfix << "A;\n"
9263 "layout(set = " << descriptorSet << ", binding = " + de::toString(descBinding + 2) + formatQualifier + ") uniform highp " + storageType + "u_texelBuffer" << setNdxPostfix << "B;\n";
9265 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
9266 buf << "layout(set = " << descriptorSet << ", binding = " + de::toString(getArbitraryBindingIndex(0)) + formatQualifier + ") uniform highp " + storageType + "u_texelBuffer" << setNdxPostfix << "A;\n"
9267 "layout(set = " << descriptorSet << ", binding = " + de::toString(getArbitraryBindingIndex(1)) + formatQualifier + ") uniform highp " + storageType + "u_texelBuffer" << setNdxPostfix << "B;\n";
9269 case SHADER_INPUT_DESCRIPTOR_ARRAY:
9270 buf << "layout(set = " << descriptorSet << ", binding = " + de::toString(descBinding) + formatQualifier + ") uniform highp " + storageType + "u_texelBuffer" << setNdxPostfix << "[2];\n";
9273 DE_FATAL("Impossible");
9280 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
9284 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
9285 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
9286 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("A")
9287 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? ("A")
9288 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
9290 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
9291 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
9292 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("B")
9293 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? ("B")
9294 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
9296 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
9297 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
9299 std::ostringstream buf;
9301 buf << " result_color = vec4(0.0);\n";
9303 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
9305 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
9307 buf << " if (quadrant_id == 0)\n"
9308 << " result_color += " << fetchFunc << "(u_texelBuffer" << setNdxPostfix << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
9309 << " else if (quadrant_id == 1)\n"
9310 << " result_color += " << fetchFunc << "(u_texelBuffer" << setNdxPostfix << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
9311 << " else if (quadrant_id == 2)\n"
9312 << " result_color += " << fetchFunc << "(u_texelBuffer" << setNdxPostfix << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
9314 << " result_color += " << fetchFunc << "(u_texelBuffer" << setNdxPostfix << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
9317 if (getDescriptorSetCount(m_descriptorSetCount) > 1)
9318 buf << " result_color /= vec4(" << getDescriptorSetCount(m_descriptorSetCount) << ".0);\n";
9323 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
9325 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
9326 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
9328 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
9331 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
9333 verifyDriverSupport(context.getUsedApiVersion(), context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
9335 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
9337 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
9338 return new TexelBufferComputeInstance(context, m_updateMethod, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_nonzeroViewOffset);
9341 return new TexelBufferRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_descriptorSetCount, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
9344 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
9345 bool isPrimaryCmdBuf,
9346 DescriptorUpdateMethod updateMethod,
9347 vk::VkDescriptorType descriptorType,
9348 vk::VkShaderStageFlags exitingStages,
9349 vk::VkShaderStageFlags activeStages,
9350 DescriptorSetCount descriptorSetCount,
9351 ShaderInputInterface dimension,
9352 deUint32 resourceFlags)
9356 vk::VkImageViewType viewType;
9358 const char* description;
9362 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
9363 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
9364 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
9366 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
9367 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
9368 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
9370 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
9371 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
9372 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
9374 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
9375 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
9376 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
9378 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
9379 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
9380 // no 3d array textures
9382 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
9383 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
9384 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
9386 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
9387 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
9388 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE }
9391 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
9394 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
9396 // skip some image view variations to avoid unnecessary bloating
9397 if ((descriptorType != vk::VK_DESCRIPTOR_TYPE_SAMPLER) && (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) && (s_imageTypes[ndx].viewType != vk::VK_IMAGE_VIEW_TYPE_2D))
9400 if ((dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) && (activeStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) && (s_imageTypes[ndx].viewType != vk::VK_IMAGE_VIEW_TYPE_2D))
9403 if ((dimension == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) && (s_imageTypes[ndx].viewType != vk::VK_IMAGE_VIEW_TYPE_2D))
9406 if ((descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS) && (s_imageTypes[ndx].viewType != vk::VK_IMAGE_VIEW_TYPE_2D))
9409 group->addChild(new ImageDescriptorCase(group->getTestContext(),
9410 s_imageTypes[ndx].name,
9411 s_imageTypes[ndx].description,
9419 s_imageTypes[ndx].viewType,
9420 s_imageTypes[ndx].flags | resourceFlags));
9424 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
9425 bool isPrimaryCmdBuf,
9426 DescriptorUpdateMethod updateMethod,
9427 vk::VkDescriptorType descriptorType,
9428 vk::VkShaderStageFlags exitingStages,
9429 vk::VkShaderStageFlags activeStages,
9430 DescriptorSetCount descriptorSetCount,
9431 ShaderInputInterface dimension,
9432 deUint32 resourceFlags)
9434 DE_ASSERT(resourceFlags == 0);
9435 DE_UNREF(resourceFlags);
9440 const char* description;
9442 } s_texelBufferTypes[] =
9444 { "offset_zero", "View offset is zero", 0u },
9445 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
9448 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
9450 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
9452 s_texelBufferTypes[ndx].name,
9453 s_texelBufferTypes[ndx].description,
9460 s_texelBufferTypes[ndx].flags));
9464 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
9465 bool isPrimaryCmdBuf,
9466 DescriptorUpdateMethod updateMethod,
9467 vk::VkDescriptorType descriptorType,
9468 vk::VkShaderStageFlags exitingStages,
9469 vk::VkShaderStageFlags activeStages,
9470 DescriptorSetCount descriptorSetCount,
9471 ShaderInputInterface dimension,
9472 deUint32 resourceFlags)
9474 DE_ASSERT(resourceFlags == 0u);
9475 DE_UNREF(resourceFlags);
9480 const char* description;
9481 bool isForDynamicCases;
9485 { "offset_view_zero", "View offset is zero", false, 0u },
9486 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
9488 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
9489 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
9490 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
9491 { "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 },
9494 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
9498 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH || updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
9500 // Can't support push descriptor sets with dynamic UBOs or SSBOs
9505 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
9507 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
9508 group->addChild(new BufferDescriptorCase(group->getTestContext(),
9510 s_bufferTypes[ndx].name,
9511 s_bufferTypes[ndx].description,
9518 s_bufferTypes[ndx].flags));
9524 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
9528 const bool isPrimary;
9530 const char* description;
9533 { true, "primary_cmd_buf", "Bind in primary command buffer" },
9534 { false, "secondary_cmd_buf", "Bind in secondary command buffer" },
9538 const DescriptorUpdateMethod method;
9540 const char* description;
9541 } s_updateMethods[] =
9543 { DESCRIPTOR_UPDATE_METHOD_NORMAL, "", "Use regular descriptor updates" },
9544 #ifndef CTS_USES_VULKANSC
9545 { DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE, "with_template", "Use descriptor update templates" },
9546 { DESCRIPTOR_UPDATE_METHOD_WITH_PUSH, "with_push", "Use push descriptor updates" },
9547 { DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE, "with_push_template", "Use push descriptor update templates" },
9552 const vk::VkDescriptorType descriptorType;
9554 const char* description;
9556 } s_descriptorTypes[] =
9558 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
9559 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
9560 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
9561 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
9562 // \note No way to access SAMPLED_IMAGE without a sampler
9563 //{ vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
9564 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
9565 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
9566 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
9567 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
9568 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
9569 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
9570 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
9575 const char* description;
9576 vk::VkShaderStageFlags existingStages; //!< stages that exists
9577 vk::VkShaderStageFlags activeStages; //!< stages that access resource
9578 bool supportsSecondaryCmdBufs;
9579 } s_shaderStages[] =
9583 "No accessing stages",
9584 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9591 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9592 vk::VK_SHADER_STAGE_VERTEX_BIT,
9597 "Tessellation control stage",
9598 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9599 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
9604 "Tessellation evaluation stage",
9605 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9606 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
9612 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9613 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
9619 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9620 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9626 vk::VK_SHADER_STAGE_COMPUTE_BIT,
9627 vk::VK_SHADER_STAGE_COMPUTE_BIT,
9632 "Vertex and fragment stages",
9633 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9634 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9640 ShaderInputInterface dimension;
9642 const char* description;
9643 } s_variableDimensions[] =
9645 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
9646 { SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, "multiple_contiguous_descriptors", "Multiple descriptors" },
9647 { SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, "multiple_discontiguous_descriptors", "Multiple descriptors" },
9648 { SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS, "multiple_arbitrary_descriptors", "Multiple descriptors" },
9649 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
9652 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
9654 // .primary_cmd_buf...
9655 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
9657 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
9659 for (int updateMethodNdx = 0; updateMethodNdx < DE_LENGTH_OF_ARRAY(s_updateMethods); ++updateMethodNdx)
9661 de::MovePtr<tcu::TestCaseGroup> updateMethodGroup(new tcu::TestCaseGroup(testCtx, s_updateMethods[updateMethodNdx].name, s_updateMethods[updateMethodNdx].description));
9663 // .sampler, .combined_image_sampler, other resource types ...
9664 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
9666 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
9668 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
9670 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
9672 de::MovePtr<tcu::TestCaseGroup> stageGroup (new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
9673 de::MovePtr<tcu::TestCaseGroup> multipleGroup (new tcu::TestCaseGroup(testCtx, "multiple_descriptor_sets", "Multiple descriptor sets"));
9674 de::MovePtr<tcu::TestCaseGroup> multipleDiscontiguousGroup (new tcu::TestCaseGroup(testCtx, "multiple_discontiguous_descriptor_sets", "Multiple discontiguous descriptor sets"));
9676 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
9678 de::MovePtr<tcu::TestCaseGroup> dimensionSingleDescriptorSetGroup (new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
9679 de::MovePtr<tcu::TestCaseGroup> dimensionMultipleDescriptorSetsGroup (new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
9680 de::MovePtr<tcu::TestCaseGroup> dimensionMultipleDiscontiguousDescriptorSetsGroup (new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
9681 void (*createTestsFunc)(tcu::TestCaseGroup* group,
9682 bool isPrimaryCmdBuf,
9683 DescriptorUpdateMethod updateMethod,
9684 vk::VkDescriptorType descriptorType,
9685 vk::VkShaderStageFlags existingStages,
9686 vk::VkShaderStageFlags activeStages,
9687 DescriptorSetCount descriptorSetCount,
9688 ShaderInputInterface dimension,
9689 deUint32 resourceFlags);
9691 switch (s_descriptorTypes[descriptorNdx].descriptorType)
9693 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
9694 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
9695 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
9696 createTestsFunc = createShaderAccessImageTests;
9699 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
9700 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
9701 createTestsFunc = createShaderAccessTexelBufferTests;
9704 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
9705 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
9706 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
9707 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
9708 createTestsFunc = createShaderAccessBufferTests;
9712 createTestsFunc = DE_NULL;
9713 DE_FATAL("Impossible");
9716 if (createTestsFunc)
9718 createTestsFunc(dimensionSingleDescriptorSetGroup.get(),
9719 s_bindTypes[bindTypeNdx].isPrimary,
9720 s_updateMethods[updateMethodNdx].method,
9721 s_descriptorTypes[descriptorNdx].descriptorType,
9722 s_shaderStages[stageNdx].existingStages,
9723 s_shaderStages[stageNdx].activeStages,
9724 DESCRIPTOR_SET_COUNT_SINGLE,
9725 s_variableDimensions[dimensionNdx].dimension,
9726 s_descriptorTypes[descriptorNdx].flags);
9728 createTestsFunc(dimensionMultipleDescriptorSetsGroup.get(),
9729 s_bindTypes[bindTypeNdx].isPrimary,
9730 s_updateMethods[updateMethodNdx].method,
9731 s_descriptorTypes[descriptorNdx].descriptorType,
9732 s_shaderStages[stageNdx].existingStages,
9733 s_shaderStages[stageNdx].activeStages,
9734 DESCRIPTOR_SET_COUNT_MULTIPLE,
9735 s_variableDimensions[dimensionNdx].dimension,
9736 s_descriptorTypes[descriptorNdx].flags);
9738 createTestsFunc(dimensionMultipleDiscontiguousDescriptorSetsGroup.get(),
9739 s_bindTypes[bindTypeNdx].isPrimary,
9740 s_updateMethods[updateMethodNdx].method,
9741 s_descriptorTypes[descriptorNdx].descriptorType,
9742 s_shaderStages[stageNdx].existingStages,
9743 s_shaderStages[stageNdx].activeStages,
9744 DESCRIPTOR_SET_COUNT_MULTIPLE_DISCONTIGUOUS,
9745 s_variableDimensions[dimensionNdx].dimension,
9746 s_descriptorTypes[descriptorNdx].flags);
9749 DE_FATAL("Impossible");
9751 stageGroup->addChild(dimensionSingleDescriptorSetGroup.release());
9753 // Only one descriptor set layout can be created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR set
9754 if (s_updateMethods[updateMethodNdx].method == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH || s_updateMethods[updateMethodNdx].method == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
9757 multipleGroup->addChild(dimensionMultipleDescriptorSetsGroup.release());
9758 multipleDiscontiguousGroup->addChild(dimensionMultipleDiscontiguousDescriptorSetsGroup.release());
9761 stageGroup->addChild(multipleGroup.release());
9762 stageGroup->addChild(multipleDiscontiguousGroup.release());
9763 typeGroup->addChild(stageGroup.release());
9767 if (s_updateMethods[updateMethodNdx].method != DESCRIPTOR_UPDATE_METHOD_NORMAL)
9769 updateMethodGroup->addChild(typeGroup.release());
9773 bindGroup->addChild(typeGroup.release());
9777 if (s_updateMethods[updateMethodNdx].method != DESCRIPTOR_UPDATE_METHOD_NORMAL)
9779 bindGroup->addChild(updateMethodGroup.release());
9783 group->addChild(bindGroup.release());
9786 return group.release();