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"
39 #include "tcuVector.hpp"
40 #include "tcuVectorUtil.hpp"
41 #include "tcuTexture.hpp"
42 #include "tcuTextureUtil.hpp"
43 #include "tcuResultCollector.hpp"
44 #include "tcuTestLog.hpp"
45 #include "tcuRGBA.hpp"
46 #include "tcuSurface.hpp"
47 #include "tcuImageCompare.hpp"
49 #include "deUniquePtr.hpp"
50 #include "deSharedPtr.hpp"
51 #include "deStringUtil.hpp"
52 #include "deArrayUtil.hpp"
59 namespace BindingModel
66 RESOURCE_FLAG_IMMUTABLE_SAMPLER = (1u << 0u),
68 RESOURCE_FLAG_LAST = (1u << 1u)
71 enum DescriptorUpdateMethod
73 DESCRIPTOR_UPDATE_METHOD_NORMAL = 0, //!< use vkUpdateDescriptorSets
74 DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE, //!< use descriptor update templates
75 DESCRIPTOR_UPDATE_METHOD_WITH_PUSH, //!< use push descriptor updates
76 DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE, //!< use push descriptor update templates
78 DESCRIPTOR_UPDATE_METHOD_LAST
81 std::string stringifyDescriptorUpdateMethod(DescriptorUpdateMethod method)
85 case DESCRIPTOR_UPDATE_METHOD_NORMAL:
89 case DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE:
90 return "with_template";
93 case DESCRIPTOR_UPDATE_METHOD_WITH_PUSH:
97 case DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE:
98 return "with_push_template";
107 static const char* const s_quadrantGenVertexPosSource = " highp int quadPhase = gl_VertexIndex % 6;\n"
108 " highp int quadXcoord = int(quadPhase == 1 || quadPhase == 4 || quadPhase == 5);\n"
109 " highp int quadYcoord = int(quadPhase == 2 || quadPhase == 3 || quadPhase == 5);\n"
110 " highp int quadOriginX = (gl_VertexIndex / 6) % 2;\n"
111 " highp int quadOriginY = (gl_VertexIndex / 6) / 2;\n"
112 " quadrant_id = gl_VertexIndex / 6;\n"
113 " result_position = vec4(float(quadOriginX + quadXcoord - 1), float(quadOriginY + quadYcoord - 1), 0.0, 1.0);\n";
115 std::string genPerVertexBlock (const vk::VkShaderStageFlagBits stage, const glu::GLSLVersion version)
117 static const char* const block = "gl_PerVertex {\n"
118 " vec4 gl_Position;\n"
119 " float gl_PointSize;\n" // not used, but for compatibility with how implicit block is declared in ES
121 std::ostringstream str;
123 if (!glu::glslVersionIsES(version))
126 case vk::VK_SHADER_STAGE_VERTEX_BIT:
127 str << "out " << block << ";\n";
130 case vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
131 str << "in " << block << " gl_in[gl_MaxPatchVertices];\n"
132 << "out " << block << " gl_out[];\n";
135 case vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
136 str << "in " << block << " gl_in[gl_MaxPatchVertices];\n"
137 << "out " << block << ";\n";
140 case vk::VK_SHADER_STAGE_GEOMETRY_BIT:
141 str << "in " << block << " gl_in[];\n"
142 << "out " << block << ";\n";
152 bool isUniformDescriptorType (vk::VkDescriptorType type)
154 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
155 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
156 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
159 bool isDynamicDescriptorType (vk::VkDescriptorType type)
161 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || type == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
164 void verifyDriverSupport(const vk::VkPhysicalDeviceFeatures& deviceFeatures,
165 const std::vector<std::string>& deviceExtensions,
166 DescriptorUpdateMethod updateMethod,
167 vk::VkDescriptorType descType,
168 vk::VkShaderStageFlags activeStages)
170 std::vector<std::string> extensionNames;
171 size_t numExtensionsNeeded = 0;
173 switch (updateMethod)
175 case DESCRIPTOR_UPDATE_METHOD_WITH_PUSH:
176 extensionNames.push_back("VK_KHR_push_descriptor");
180 case DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE:
181 extensionNames.push_back("VK_KHR_push_descriptor");
182 case DESCRIPTOR_UPDATE_METHOD_WITH_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");
255 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type)
259 case vk::VK_IMAGE_VIEW_TYPE_1D:
260 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return vk::VK_IMAGE_TYPE_1D;
261 case vk::VK_IMAGE_VIEW_TYPE_2D:
262 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return vk::VK_IMAGE_TYPE_2D;
263 case vk::VK_IMAGE_VIEW_TYPE_3D: return vk::VK_IMAGE_TYPE_3D;
264 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
265 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return vk::VK_IMAGE_TYPE_2D;
268 DE_FATAL("Impossible");
269 return (vk::VkImageType)0;
273 vk::VkImageLayout getImageLayoutForDescriptorType (vk::VkDescriptorType descType)
275 if (descType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
276 return vk::VK_IMAGE_LAYOUT_GENERAL;
278 return vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
281 deUint32 getTextureLevelPyramidDataSize (const tcu::TextureLevelPyramid& srcImage)
283 deUint32 dataSize = 0;
284 for (int level = 0; level < srcImage.getNumLevels(); ++level)
286 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
289 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
291 dataSize += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
296 void writeTextureLevelPyramidData (void* dst, deUint32 dstLen, const tcu::TextureLevelPyramid& srcImage, vk::VkImageViewType viewType, std::vector<vk::VkBufferImageCopy>* copySlices)
298 // \note cube is copied face-by-face
299 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (srcImage.getLevel(0).getHeight()) :
300 (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
301 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
302 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
304 deUint32 levelOffset = 0;
306 DE_ASSERT(arraySize != 0);
308 for (int level = 0; level < srcImage.getNumLevels(); ++level)
310 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
311 const tcu::PixelBufferAccess dstAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), (deUint8*)dst + levelOffset);
312 const deUint32 dataSize = srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
313 const deUint32 sliceDataSize = dataSize / arraySize;
314 const deInt32 sliceHeight = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (srcAccess.getHeight());
315 const deInt32 sliceDepth = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (srcAccess.getDepth()) : (1);
316 const tcu::IVec3 sliceSize (srcAccess.getWidth(), sliceHeight, sliceDepth);
319 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
321 for (int sliceNdx = 0; sliceNdx < (int)arraySize; ++sliceNdx)
323 const vk::VkBufferImageCopy copySlice =
325 (vk::VkDeviceSize)levelOffset + sliceNdx * sliceDataSize, // bufferOffset
326 (deUint32)sliceSize.x(), // bufferRowLength
327 (deUint32)sliceSize.y(), // bufferImageHeight
329 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
330 (deUint32)level, // mipLevel
331 (deUint32)sliceNdx, // arrayLayer
333 }, // imageSubresource
340 (deUint32)sliceSize.x(),
341 (deUint32)sliceSize.y(),
342 (deUint32)sliceSize.z(),
345 copySlices->push_back(copySlice);
348 DE_ASSERT(arraySize * sliceDataSize == dataSize);
350 tcu::copy(dstAccess, srcAccess);
351 levelOffset += dataSize;
354 DE_ASSERT(dstLen == levelOffset);
358 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement)
360 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer);
361 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
363 VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
367 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkImage image, vk::MemoryRequirement requirement)
369 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vki, device, image);
370 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
372 VK_CHECK(vki.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
376 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkSampler sampler)
378 return vk::makeDescriptorImageInfo(sampler, (vk::VkImageView)0, (vk::VkImageLayout)0);
381 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkImageView imageView, vk::VkImageLayout layout)
383 return vk::makeDescriptorImageInfo((vk::VkSampler)0, imageView, layout);
386 void drawQuadrantReferenceResult (const tcu::PixelBufferAccess& dst, const tcu::Vec4& c1, const tcu::Vec4& c2, const tcu::Vec4& c3, const tcu::Vec4& c4)
388 tcu::clear(tcu::getSubregion(dst, 0, 0, dst.getWidth() / 2, dst.getHeight() / 2), c1);
389 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, 0, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() / 2), c2);
390 tcu::clear(tcu::getSubregion(dst, 0, dst.getHeight() / 2, dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c3);
391 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, dst.getHeight() / 2, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c4);
394 static const vk::VkDescriptorUpdateTemplateEntryKHR createTemplateBinding (deUint32 binding, deUint32 arrayElement, deUint32 descriptorCount, vk::VkDescriptorType descriptorType, size_t offset, size_t stride)
396 const vk::VkDescriptorUpdateTemplateEntryKHR updateBinding =
406 return updateBinding;
409 class RawUpdateRegistry
412 RawUpdateRegistry (void);
414 template<typename Type>
415 void addWriteObject (const Type& updateObject);
416 size_t getWriteObjectOffset (const deUint32 objectId);
417 const deUint8* getRawPointer () const;
421 std::vector<deUint8> m_updateEntries;
422 std::vector<size_t> m_updateEntryOffsets;
426 RawUpdateRegistry::RawUpdateRegistry (void)
428 , m_updateEntryOffsets()
433 template<typename Type>
434 void RawUpdateRegistry::addWriteObject (const Type& updateObject)
436 m_updateEntryOffsets.push_back(m_nextOffset);
438 // in this case, elements <=> bytes
439 m_updateEntries.resize(m_nextOffset + sizeof(updateObject));
440 Type* t = reinterpret_cast<Type*>(m_updateEntries.data() + m_nextOffset);
442 m_nextOffset += sizeof(updateObject);
445 size_t RawUpdateRegistry::getWriteObjectOffset (const deUint32 objectId)
447 return m_updateEntryOffsets[objectId];
450 const deUint8* RawUpdateRegistry::getRawPointer () const
452 return m_updateEntries.data();
455 class SingleTargetRenderInstance : public vkt::TestInstance
458 SingleTargetRenderInstance (Context& context,
459 const tcu::UVec2& size);
462 static vk::Move<vk::VkImage> createColorAttachment (const vk::DeviceInterface& vki,
464 vk::Allocator& allocator,
465 const tcu::TextureFormat& format,
466 const tcu::UVec2& size,
467 de::MovePtr<vk::Allocation>* outAllocation);
469 static vk::Move<vk::VkImageView> createColorAttachmentView (const vk::DeviceInterface& vki,
471 const tcu::TextureFormat& format,
474 static vk::Move<vk::VkRenderPass> createRenderPass (const vk::DeviceInterface& vki,
476 const tcu::TextureFormat& format);
478 static vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vki,
480 vk::VkRenderPass renderpass,
481 vk::VkImageView colorAttachmentView,
482 const tcu::UVec2& size);
484 static vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vki,
486 deUint32 queueFamilyIndex);
488 virtual void logTestPlan (void) const = 0;
489 virtual void renderToTarget (void) = 0;
490 virtual tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const = 0;
492 void readRenderTarget (tcu::TextureLevel& dst);
493 tcu::TestStatus iterate (void);
496 const tcu::TextureFormat m_targetFormat;
497 const tcu::UVec2 m_targetSize;
499 const vk::DeviceInterface& m_vki;
500 const vk::VkDevice m_device;
501 const vk::VkQueue m_queue;
502 const deUint32 m_queueFamilyIndex;
503 vk::Allocator& m_allocator;
504 de::MovePtr<vk::Allocation> m_colorAttachmentMemory;
505 const vk::Unique<vk::VkImage> m_colorAttachmentImage;
506 const vk::Unique<vk::VkImageView> m_colorAttachmentView;
507 const vk::Unique<vk::VkRenderPass> m_renderPass;
508 const vk::Unique<vk::VkFramebuffer> m_framebuffer;
509 const vk::Unique<vk::VkCommandPool> m_cmdPool;
511 bool m_firstIteration;
514 SingleTargetRenderInstance::SingleTargetRenderInstance (Context& context,
515 const tcu::UVec2& size)
516 : vkt::TestInstance (context)
517 , m_targetFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
518 , m_targetSize (size)
519 , m_vki (context.getDeviceInterface())
520 , m_device (context.getDevice())
521 , m_queue (context.getUniversalQueue())
522 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
523 , m_allocator (context.getDefaultAllocator())
524 , m_colorAttachmentMemory (DE_NULL)
525 , m_colorAttachmentImage (createColorAttachment(m_vki, m_device, m_allocator, m_targetFormat, m_targetSize, &m_colorAttachmentMemory))
526 , m_colorAttachmentView (createColorAttachmentView(m_vki, m_device, m_targetFormat, *m_colorAttachmentImage))
527 , m_renderPass (createRenderPass(m_vki, m_device, m_targetFormat))
528 , m_framebuffer (createFramebuffer(m_vki, m_device, *m_renderPass, *m_colorAttachmentView, m_targetSize))
529 , m_cmdPool (createCommandPool(m_vki, m_device, context.getUniversalQueueFamilyIndex()))
530 , m_firstIteration (true)
534 vk::Move<vk::VkImage> SingleTargetRenderInstance::createColorAttachment (const vk::DeviceInterface& vki,
536 vk::Allocator& allocator,
537 const tcu::TextureFormat& format,
538 const tcu::UVec2& size,
539 de::MovePtr<vk::Allocation>* outAllocation)
541 const vk::VkImageCreateInfo imageInfo =
543 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
545 (vk::VkImageCreateFlags)0,
546 vk::VK_IMAGE_TYPE_2D, // imageType
547 vk::mapTextureFormat(format), // format
548 { size.x(), size.y(), 1u }, // extent
551 vk::VK_SAMPLE_COUNT_1_BIT, // samples
552 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
553 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
554 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
555 0u, // queueFamilyCount
556 DE_NULL, // pQueueFamilyIndices
557 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
560 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &imageInfo));
561 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any));
563 *outAllocation = allocation;
567 vk::Move<vk::VkImageView> SingleTargetRenderInstance::createColorAttachmentView (const vk::DeviceInterface& vki,
569 const tcu::TextureFormat& format,
572 const vk::VkImageViewCreateInfo createInfo =
574 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
576 (vk::VkImageViewCreateFlags)0,
578 vk::VK_IMAGE_VIEW_TYPE_2D, // viewType
579 vk::mapTextureFormat(format), // format
580 vk::makeComponentMappingRGBA(),
582 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
585 0u, // baseArrayLayer
590 return vk::createImageView(vki, device, &createInfo);
593 vk::Move<vk::VkRenderPass> SingleTargetRenderInstance::createRenderPass (const vk::DeviceInterface& vki,
595 const tcu::TextureFormat& format)
597 const vk::VkAttachmentDescription attachmentDescription =
599 (vk::VkAttachmentDescriptionFlags)0,
600 vk::mapTextureFormat(format), // format
601 vk::VK_SAMPLE_COUNT_1_BIT, // samples
602 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp
603 vk::VK_ATTACHMENT_STORE_OP_STORE, // storeOp
604 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
605 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
606 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
607 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout
609 const vk::VkAttachmentReference colorAttachment =
612 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
614 const vk::VkAttachmentReference depthStencilAttachment =
616 VK_ATTACHMENT_UNUSED, // attachment
617 vk::VK_IMAGE_LAYOUT_UNDEFINED // layout
619 const vk::VkSubpassDescription subpass =
621 (vk::VkSubpassDescriptionFlags)0,
622 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
623 0u, // inputAttachmentCount
624 DE_NULL, // pInputAttachments
625 1u, // colorAttachmentCount
626 &colorAttachment, // pColorAttachments
627 DE_NULL, // pResolveAttachments
628 &depthStencilAttachment, // pDepthStencilAttachment
629 0u, // preserveAttachmentCount
630 DE_NULL // pPreserveAttachments
632 const vk::VkRenderPassCreateInfo renderPassCreateInfo =
634 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
636 (vk::VkRenderPassCreateFlags)0,
637 1u, // attachmentCount
638 &attachmentDescription, // pAttachments
640 &subpass, // pSubpasses
641 0u, // dependencyCount
642 DE_NULL, // pDependencies
645 return vk::createRenderPass(vki, device, &renderPassCreateInfo);
648 vk::Move<vk::VkFramebuffer> SingleTargetRenderInstance::createFramebuffer (const vk::DeviceInterface& vki,
650 vk::VkRenderPass renderpass,
651 vk::VkImageView colorAttachmentView,
652 const tcu::UVec2& size)
654 const vk::VkFramebufferCreateInfo framebufferCreateInfo =
656 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
658 (vk::VkFramebufferCreateFlags)0,
659 renderpass, // renderPass
660 1u, // attachmentCount
661 &colorAttachmentView, // pAttachments
667 return vk::createFramebuffer(vki, device, &framebufferCreateInfo);
670 vk::Move<vk::VkCommandPool> SingleTargetRenderInstance::createCommandPool (const vk::DeviceInterface& vki,
672 deUint32 queueFamilyIndex)
674 return vk::createCommandPool(vki, device, vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
677 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
679 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
680 const vk::VkBufferCreateInfo bufferCreateInfo =
682 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
685 pixelDataSize, // size
686 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
687 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
688 0u, // queueFamilyCount
689 DE_NULL, // pQueueFamilyIndices
691 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
692 const vk::VkImageSubresourceRange fullSubrange =
694 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
697 0u, // baseArraySlice
700 const vk::VkImageMemoryBarrier imageBarrier =
702 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
704 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
705 vk::VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
706 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
707 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
708 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
709 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
710 *m_colorAttachmentImage, // image
711 fullSubrange, // subresourceRange
713 const vk::VkBufferMemoryBarrier memoryBarrier =
715 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
717 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
718 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
719 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
720 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
723 (vk::VkDeviceSize)pixelDataSize // size
725 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
727 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
729 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
730 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
732 const vk::VkImageSubresourceLayers firstSlice =
734 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspect
739 const vk::VkBufferImageCopy copyRegion =
742 m_targetSize.x(), // bufferRowLength
743 m_targetSize.y(), // bufferImageHeight
744 firstSlice, // imageSubresource
745 { 0, 0, 0 }, // imageOffset
746 { m_targetSize.x(), m_targetSize.y(), 1u } // imageExtent
749 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
751 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
752 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device));
753 const deUint64 infiniteTimeout = ~(deUint64)0u;
755 // copy content to buffer
756 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
757 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
758 0, (const vk::VkMemoryBarrier*)DE_NULL,
759 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
761 m_vki.cmdCopyImageToBuffer(*cmd, *m_colorAttachmentImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
762 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0,
763 0, (const vk::VkMemoryBarrier*)DE_NULL,
765 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
766 VK_CHECK(m_vki.endCommandBuffer(*cmd));
768 // wait for transfer to complete
770 const vk::VkSubmitInfo submitInfo =
772 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
775 (const vk::VkSemaphore*)0,
776 (const vk::VkPipelineStageFlags*)DE_NULL,
780 (const vk::VkSemaphore*)0,
783 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *cmdCompleteFence));
785 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
787 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
790 invalidateMappedMemoryRange(m_vki, m_device, bufferMemory->getMemory(), bufferMemory->getOffset(), pixelDataSize);
791 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
794 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
796 tcu::TextureLevel resultImage;
799 if (m_firstIteration)
802 m_firstIteration = false;
807 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
808 const vk::VkImageSubresourceRange fullSubrange =
810 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
813 0u, // baseArraySlice
816 const vk::VkImageMemoryBarrier imageBarrier =
818 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
821 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
822 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
823 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
824 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
825 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
826 *m_colorAttachmentImage, // image
827 fullSubrange, // subresourceRange
829 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
831 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
833 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
834 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
837 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
838 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device));
839 const deUint64 infiniteTimeout = ~(deUint64)0u;
841 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
842 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (vk::VkDependencyFlags)0,
843 0, (const vk::VkMemoryBarrier*)DE_NULL,
844 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
846 VK_CHECK(m_vki.endCommandBuffer(*cmd));
849 const vk::VkSubmitInfo submitInfo =
851 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
854 (const vk::VkSemaphore*)0,
855 (const vk::VkPipelineStageFlags*)DE_NULL,
859 (const vk::VkSemaphore*)0,
862 VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
864 VK_CHECK(m_vki.waitForFences(m_device, 1u, &fence.get(), VK_TRUE, infiniteTimeout));
866 // and then render to
871 readRenderTarget(resultImage);
872 return verifyResultImage(resultImage.getAccess());
875 class RenderInstanceShaders
878 RenderInstanceShaders (const vk::DeviceInterface& vki,
880 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
881 const vk::BinaryCollection& programCollection);
883 inline bool hasTessellationStage (void) const { return *m_tessCtrlShaderModule != 0 || *m_tessEvalShaderModule != 0; }
884 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
885 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
888 void addStage (const vk::DeviceInterface& vki,
890 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
891 const vk::BinaryCollection& programCollection,
893 vk::VkShaderStageFlagBits stage,
894 vk::Move<vk::VkShaderModule>* outModule);
896 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const;
898 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
899 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
900 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
901 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
902 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
903 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
906 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
908 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
909 const vk::BinaryCollection& programCollection)
911 addStage(vki, device, deviceFeatures, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX_BIT, &m_vertexShaderModule);
912 addStage(vki, device, deviceFeatures, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessCtrlShaderModule);
913 addStage(vki, device, deviceFeatures, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvalShaderModule);
914 addStage(vki, device, deviceFeatures, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule);
915 addStage(vki, device, deviceFeatures, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule);
917 DE_ASSERT(!m_stageInfos.empty());
920 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
922 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
923 const vk::BinaryCollection& programCollection,
925 vk::VkShaderStageFlagBits stage,
926 vk::Move<vk::VkShaderModule>* outModule)
928 if (programCollection.contains(name))
930 if (vk::isShaderStageSupported(deviceFeatures, stage))
932 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
934 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *module));
939 // Wait for the GPU to idle so that throwing the exception
940 // below doesn't free in-use GPU resource.
941 vki.deviceWaitIdle(device);
942 TCU_THROW(NotSupportedError, (de::toString(stage) + " is not supported").c_str());
947 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const
949 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
951 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
953 (vk::VkPipelineShaderStageCreateFlags)0,
957 DE_NULL, // pSpecializationInfo
959 return stageCreateInfo;
962 class SingleCmdRenderInstance : public SingleTargetRenderInstance
965 SingleCmdRenderInstance (Context& context,
966 bool isPrimaryCmdBuf,
967 const tcu::UVec2& renderSize);
970 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
972 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
973 virtual void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const = 0;
975 void renderToTarget (void);
977 const bool m_isPrimaryCmdBuf;
980 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
981 bool isPrimaryCmdBuf,
982 const tcu::UVec2& renderSize)
983 : SingleTargetRenderInstance (context, renderSize)
984 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
988 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
990 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getDeviceFeatures(), m_context.getBinaryCollection());
991 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
992 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
994 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
996 (vk::VkPipelineVertexInputStateCreateFlags)0,
998 DE_NULL, // pVertexBindingDescriptions
999 0u, // attributeCount
1000 DE_NULL, // pVertexAttributeDescriptions
1002 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
1004 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1006 (vk::VkPipelineInputAssemblyStateCreateFlags)0,
1007 topology, // topology
1008 VK_FALSE, // primitiveRestartEnable
1010 const vk::VkPipelineTessellationStateCreateInfo tessState =
1012 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
1014 (vk::VkPipelineTessellationStateCreateFlags)0,
1015 3u, // patchControlPoints
1017 const vk::VkViewport viewport =
1021 float(m_targetSize.x()), // width
1022 float(m_targetSize.y()), // height
1026 const vk::VkRect2D renderArea =
1029 { m_targetSize.x(), m_targetSize.y() }, // extent
1031 const vk::VkPipelineViewportStateCreateInfo vpState =
1033 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1035 (vk::VkPipelineViewportStateCreateFlags)0,
1036 1u, // viewportCount
1041 const vk::VkPipelineRasterizationStateCreateInfo rsState =
1043 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1045 (vk::VkPipelineRasterizationStateCreateFlags)0,
1046 VK_TRUE, // depthClipEnable
1047 VK_FALSE, // rasterizerDiscardEnable
1048 vk::VK_POLYGON_MODE_FILL, // fillMode
1049 vk::VK_CULL_MODE_NONE, // cullMode
1050 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1051 VK_FALSE, // depthBiasEnable
1053 0.0f, // depthBiasClamp
1054 0.0f, // slopeScaledDepthBias
1057 const vk::VkSampleMask sampleMask = 0x01u;
1058 const vk::VkPipelineMultisampleStateCreateInfo msState =
1060 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1062 (vk::VkPipelineMultisampleStateCreateFlags)0,
1063 vk::VK_SAMPLE_COUNT_1_BIT, // rasterSamples
1064 VK_FALSE, // sampleShadingEnable
1065 0.0f, // minSampleShading
1066 &sampleMask, // sampleMask
1067 VK_FALSE, // alphaToCoverageEnable
1068 VK_FALSE, // alphaToOneEnable
1070 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
1072 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1074 (vk::VkPipelineDepthStencilStateCreateFlags)0,
1075 VK_FALSE, // depthTestEnable
1076 VK_FALSE, // depthWriteEnable
1077 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
1078 VK_FALSE, // depthBoundsTestEnable
1079 VK_FALSE, // stencilTestEnable
1080 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
1081 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
1082 -1.0f, // minDepthBounds
1083 +1.0f, // maxDepthBounds
1085 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
1087 VK_FALSE, // blendEnable
1088 vk::VK_BLEND_FACTOR_ZERO, // srcBlendColor
1089 vk::VK_BLEND_FACTOR_ZERO, // destBlendColor
1090 vk::VK_BLEND_OP_ADD, // blendOpColor
1091 vk::VK_BLEND_FACTOR_ZERO, // srcBlendAlpha
1092 vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha
1093 vk::VK_BLEND_OP_ADD, // blendOpAlpha
1094 (vk::VK_COLOR_COMPONENT_R_BIT |
1095 vk::VK_COLOR_COMPONENT_G_BIT |
1096 vk::VK_COLOR_COMPONENT_B_BIT |
1097 vk::VK_COLOR_COMPONENT_A_BIT), // channelWriteMask
1099 const vk::VkPipelineColorBlendStateCreateInfo cbState =
1101 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1103 (vk::VkPipelineColorBlendStateCreateFlags)0,
1104 VK_FALSE, // logicOpEnable
1105 vk::VK_LOGIC_OP_CLEAR, // logicOp
1106 1u, // attachmentCount
1107 &cbAttachment, // pAttachments
1108 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
1110 const vk::VkGraphicsPipelineCreateInfo createInfo =
1112 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1114 (vk::VkPipelineCreateFlags)0,
1115 shaderStages.getNumStages(), // stageCount
1116 shaderStages.getStages(), // pStages
1117 &vertexInputState, // pVertexInputState
1118 &iaState, // pInputAssemblyState
1119 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
1120 &vpState, // pViewportState
1121 &rsState, // pRasterState
1122 &msState, // pMultisampleState
1123 &dsState, // pDepthStencilState
1124 &cbState, // pColorBlendState
1125 (const vk::VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
1126 pipelineLayout, // layout
1127 *m_renderPass, // renderPass
1129 (vk::VkPipeline)0, // basePipelineHandle
1130 0u, // basePipelineIndex
1132 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
1135 void SingleCmdRenderInstance::renderToTarget (void)
1137 const vk::VkRect2D renderArea =
1140 { m_targetSize.x(), m_targetSize.y() }, // extent
1142 const vk::VkCommandBufferBeginInfo mainCmdBufBeginInfo =
1144 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1146 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1147 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
1149 const vk::VkCommandBufferInheritanceInfo passCmdBufInheritInfo =
1151 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1153 (vk::VkRenderPass)*m_renderPass, // renderPass
1155 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
1156 VK_FALSE, // occlusionQueryEnable
1157 (vk::VkQueryControlFlags)0,
1158 (vk::VkQueryPipelineStatisticFlags)0,
1160 const vk::VkCommandBufferBeginInfo passCmdBufBeginInfo =
1162 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1164 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
1165 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // flags
1166 &passCmdBufInheritInfo,
1168 const vk::VkClearValue clearValue = vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
1169 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1171 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1173 *m_renderPass, // renderPass
1174 *m_framebuffer, // framebuffer
1175 renderArea, // renderArea
1176 1u, // clearValueCount
1177 &clearValue, // pClearValues
1180 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1181 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1182 const vk::Unique<vk::VkCommandBuffer> mainCmd (vk::allocateCommandBuffer(m_vki, m_device, *m_cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
1183 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)));
1184 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device));
1185 const deUint64 infiniteTimeout = ~(deUint64)0u;
1186 const vk::VkSubpassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_SUBPASS_CONTENTS_INLINE) : (vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1188 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1189 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1191 if (m_isPrimaryCmdBuf)
1193 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1194 writeDrawCmdBuffer(*mainCmd);
1198 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1199 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1200 writeDrawCmdBuffer(*passCmd);
1201 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1203 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1206 m_vki.cmdEndRenderPass(*mainCmd);
1207 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1209 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1211 const vk::VkSubmitInfo submitInfo =
1213 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1216 (const vk::VkSemaphore*)0,
1217 (const vk::VkPipelineStageFlags*)DE_NULL,
1221 (const vk::VkSemaphore*)0,
1223 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *fence));
1225 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1228 enum DescriptorSetCount
1230 DESCRIPTOR_SET_COUNT_SINGLE = 0, //!< single descriptor set
1231 DESCRIPTOR_SET_COUNT_MULTIPLE, //!< multiple descriptor sets
1233 DESCRIPTOR_SET_COUNT_LAST
1236 deUint32 getDescriptorSetCount (DescriptorSetCount count)
1240 case DESCRIPTOR_SET_COUNT_SINGLE:
1242 case DESCRIPTOR_SET_COUNT_MULTIPLE:
1245 DE_FATAL("Impossible");
1250 enum ShaderInputInterface
1252 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1253 SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with contiguous binding id's
1254 SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with discontiguous binding id's
1255 SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS, //!< multiple descriptors with large gaps between binding id's
1256 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1261 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1263 switch (shaderInterface)
1265 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1266 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS: return 2u;
1267 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS: return 2u;
1268 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS: return 2u;
1269 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1272 DE_FATAL("Impossible");
1277 typedef de::MovePtr<vk::Allocation> AllocationMp;
1278 typedef de::SharedPtr<vk::Allocation> AllocationSp;
1279 typedef vk::Unique<vk::VkBuffer> BufferHandleUp;
1280 typedef de::SharedPtr<BufferHandleUp> BufferHandleSp;
1281 typedef vk::Unique<vk::VkBufferView> BufferViewHandleUp;
1282 typedef de::SharedPtr<BufferViewHandleUp> BufferViewHandleSp;
1283 typedef vk::Unique<vk::VkSampler> SamplerHandleUp;
1284 typedef de::SharedPtr<SamplerHandleUp> SamplerHandleSp;
1285 typedef vk::Unique<vk::VkImage> ImageHandleUp;
1286 typedef de::SharedPtr<ImageHandleUp> ImageHandleSp;
1287 typedef vk::Unique<vk::VkImageView> ImageViewHandleUp;
1288 typedef de::SharedPtr<ImageViewHandleUp> ImageViewHandleSp;
1289 typedef vk::Unique<vk::VkDescriptorSet> DescriptorSetHandleUp;
1290 typedef de::SharedPtr<DescriptorSetHandleUp> DescriptorSetHandleSp;
1291 typedef vk::Unique<vk::VkDescriptorSetLayout> DescriptorSetLayoutHandleUp;
1292 typedef de::SharedPtr<DescriptorSetLayoutHandleUp> DescriptorSetLayoutHandleSp;
1293 typedef vk::Unique<vk::VkDescriptorUpdateTemplateKHR> UpdateTemplateHandleUp;
1294 typedef de::SharedPtr<UpdateTemplateHandleUp> UpdateTemplateHandleSp;
1296 class BufferRenderInstance : public SingleCmdRenderInstance
1299 BufferRenderInstance (Context& context,
1300 DescriptorUpdateMethod updateMethod,
1301 bool isPrimaryCmdBuf,
1302 vk::VkDescriptorType descriptorType,
1303 DescriptorSetCount descriptorSetCount,
1304 vk::VkShaderStageFlags stageFlags,
1305 ShaderInputInterface shaderInterface,
1308 bool dynamicOffsetNonZero);
1310 static std::vector<deUint32> getViewOffsets (DescriptorSetCount descriptorSetCount,
1311 ShaderInputInterface shaderInterface,
1312 bool setViewOffset);
1314 static std::vector<deUint32> getDynamicOffsets (DescriptorSetCount descriptorSetCount,
1315 ShaderInputInterface shaderInterface,
1316 bool dynamicOffsetNonZero);
1318 static std::vector<BufferHandleSp> createSourceBuffers (const vk::DeviceInterface& vki,
1319 vk::VkDevice device,
1320 vk::Allocator& allocator,
1321 vk::VkDescriptorType descriptorType,
1322 DescriptorSetCount descriptorSetCount,
1323 ShaderInputInterface shaderInterface,
1324 const std::vector<deUint32>& viewOffset,
1325 const std::vector<deUint32>& dynamicOffset,
1326 std::vector<AllocationSp>& bufferMemory);
1328 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1329 vk::VkDevice device,
1330 vk::Allocator& allocator,
1331 vk::VkDescriptorType descriptorType,
1334 deUint32 bufferSize,
1335 de::MovePtr<vk::Allocation>* outMemory);
1337 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1338 vk::VkDevice device,
1339 vk::VkDescriptorType descriptorType,
1340 DescriptorSetCount descriptorSetCount,
1341 ShaderInputInterface shaderInterface);
1343 static std::vector<DescriptorSetLayoutHandleSp> createDescriptorSetLayouts (const vk::DeviceInterface& vki,
1344 vk::VkDevice device,
1345 vk::VkDescriptorType descriptorType,
1346 DescriptorSetCount descriptorSetCount,
1347 ShaderInputInterface shaderInterface,
1348 vk::VkShaderStageFlags stageFlags,
1349 DescriptorUpdateMethod updateMethod);
1351 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1352 vk::VkDevice device,
1353 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout);
1355 static std::vector<DescriptorSetHandleSp> createDescriptorSets (const vk::DeviceInterface& vki,
1356 DescriptorUpdateMethod updateMethod,
1357 vk::VkDevice device,
1358 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
1359 vk::VkDescriptorPool descriptorPool,
1360 vk::VkDescriptorType descriptorType,
1361 ShaderInputInterface shaderInterface,
1362 const std::vector<BufferHandleSp>& buffers,
1363 const std::vector<deUint32>& offsets,
1364 vk::DescriptorSetUpdateBuilder& updateBuilder,
1365 std::vector<deUint32>& descriptorsPerSet,
1366 std::vector<UpdateTemplateHandleSp>& updateTemplates,
1367 std::vector<RawUpdateRegistry>& updateRegistry,
1368 vk::VkPipelineLayout pipelineLayout = DE_NULL);
1370 static void writeDescriptorSet (const vk::DeviceInterface& vki,
1371 vk::VkDevice device,
1372 vk::VkDescriptorType descriptorType,
1373 ShaderInputInterface shaderInterface,
1374 vk::VkBuffer sourceBufferA,
1375 const deUint32 viewOffsetA,
1376 vk::VkBuffer sourceBufferB,
1377 const deUint32 viewOffsetB,
1378 vk::VkDescriptorSet descriptorSet,
1379 vk::DescriptorSetUpdateBuilder& updateBuilder,
1380 std::vector<deUint32>& descriptorsPerSet,
1381 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
1383 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
1384 vk::VkDevice device,
1385 vk::VkDescriptorSetLayout descriptorSetLayout,
1387 vk::VkDescriptorPool descriptorPool,
1388 vk::VkDescriptorType descriptorType,
1389 ShaderInputInterface shaderInterface,
1390 vk::VkBuffer sourceBufferA,
1391 const deUint32 viewOffsetA,
1392 vk::VkBuffer sourceBufferB,
1393 const deUint32 viewOffsetB,
1394 vk::VkDescriptorSet descriptorSet,
1395 std::vector<UpdateTemplateHandleSp>& updateTemplates,
1396 std::vector<RawUpdateRegistry>& registry,
1397 bool withPush = false,
1398 vk::VkPipelineLayout pipelineLayout = 0);
1400 void logTestPlan (void) const;
1401 vk::VkPipelineLayout getPipelineLayout (void) const;
1402 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1403 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1408 BUFFER_DATA_SIZE = 8 * sizeof(float),
1409 BUFFER_SIZE_A = 2048, //!< a lot more than required
1410 BUFFER_SIZE_B = 2560, //!< a lot more than required
1411 BUFFER_SIZE_C = 2128, //!< a lot more than required
1412 BUFFER_SIZE_D = 2136, //!< a lot more than required
1414 STATIC_OFFSET_VALUE_A = 256,
1415 DYNAMIC_OFFSET_VALUE_A = 512,
1416 STATIC_OFFSET_VALUE_B = 1024,
1417 DYNAMIC_OFFSET_VALUE_B = 768,
1418 STATIC_OFFSET_VALUE_C = 512,
1419 DYNAMIC_OFFSET_VALUE_C = 512,
1420 STATIC_OFFSET_VALUE_D = 768,
1421 DYNAMIC_OFFSET_VALUE_D = 1024,
1424 const DescriptorUpdateMethod m_updateMethod;
1425 const vk::VkDescriptorType m_descriptorType;
1426 const DescriptorSetCount m_descriptorSetCount;
1427 const ShaderInputInterface m_shaderInterface;
1428 const bool m_setViewOffset;
1429 const bool m_setDynamicOffset;
1430 const bool m_dynamicOffsetNonZero;
1431 const vk::VkShaderStageFlags m_stageFlags;
1433 const std::vector<deUint32> m_viewOffset;
1434 const std::vector<deUint32> m_dynamicOffset;
1436 std::vector<AllocationSp> m_bufferMemory;
1437 const std::vector<BufferHandleSp> m_sourceBuffer;
1438 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1439 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
1440 std::vector<RawUpdateRegistry> m_updateRegistry;
1441 vk::DescriptorSetUpdateBuilder m_updateBuilder;
1442 const std::vector<DescriptorSetLayoutHandleSp> m_descriptorSetLayouts;
1443 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1444 std::vector<deUint32> m_descriptorsPerSet;
1445 const std::vector<DescriptorSetHandleSp> m_descriptorSets;
1448 BufferRenderInstance::BufferRenderInstance (Context& context,
1449 DescriptorUpdateMethod updateMethod,
1450 bool isPrimaryCmdBuf,
1451 vk::VkDescriptorType descriptorType,
1452 DescriptorSetCount descriptorSetCount,
1453 vk::VkShaderStageFlags stageFlags,
1454 ShaderInputInterface shaderInterface,
1457 bool dynamicOffsetNonZero)
1458 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1459 , m_updateMethod (updateMethod)
1460 , m_descriptorType (descriptorType)
1461 , m_descriptorSetCount (descriptorSetCount)
1462 , m_shaderInterface (shaderInterface)
1463 , m_setViewOffset (viewOffset)
1464 , m_setDynamicOffset (dynamicOffset)
1465 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1466 , m_stageFlags (stageFlags)
1467 , m_viewOffset (getViewOffsets(m_descriptorSetCount, m_shaderInterface, m_setViewOffset))
1468 , m_dynamicOffset (getDynamicOffsets(m_descriptorSetCount, m_shaderInterface, m_dynamicOffsetNonZero))
1470 , m_sourceBuffer (createSourceBuffers(m_vki, m_device, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewOffset, m_dynamicOffset, m_bufferMemory))
1471 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface))
1472 , m_updateTemplates ()
1473 , m_updateRegistry ()
1474 , m_updateBuilder ()
1475 , m_descriptorSetLayouts (createDescriptorSetLayouts(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_stageFlags, m_updateMethod))
1476 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, m_descriptorSetLayouts))
1477 , m_descriptorsPerSet ()
1478 , m_descriptorSets (createDescriptorSets(m_vki, m_updateMethod, m_device, m_descriptorSetLayouts, *m_descriptorPool, m_descriptorType, m_shaderInterface, m_sourceBuffer, m_viewOffset, m_updateBuilder, m_descriptorsPerSet, m_updateTemplates, m_updateRegistry, *m_pipelineLayout))
1480 if (m_setDynamicOffset)
1481 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1482 if (m_dynamicOffsetNonZero)
1483 DE_ASSERT(m_setDynamicOffset);
1486 std::vector<deUint32> BufferRenderInstance::getViewOffsets (DescriptorSetCount descriptorSetCount,
1487 ShaderInputInterface shaderInterface,
1490 const int numBuffers = getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface);
1491 std::vector<deUint32> viewOffset;
1493 for (int bufferNdx = 0; bufferNdx < numBuffers; bufferNdx++)
1495 const deUint32 staticOffsetValues[] =
1497 STATIC_OFFSET_VALUE_A,
1498 STATIC_OFFSET_VALUE_B,
1499 STATIC_OFFSET_VALUE_C,
1500 STATIC_OFFSET_VALUE_D
1503 viewOffset.push_back(setViewOffset ? (staticOffsetValues[bufferNdx % getInterfaceNumResources(shaderInterface)]) : (0u));
1509 std::vector<deUint32> BufferRenderInstance::getDynamicOffsets (DescriptorSetCount descriptorSetCount,
1510 ShaderInputInterface shaderInterface,
1511 bool dynamicOffsetNonZero)
1513 const int numBuffers = getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface);
1514 std::vector<deUint32> dynamicOffset;
1516 for (int bufferNdx = 0; bufferNdx < numBuffers; bufferNdx++)
1518 const deUint32 dynamicOffsetValues[] =
1520 DYNAMIC_OFFSET_VALUE_A,
1521 DYNAMIC_OFFSET_VALUE_B,
1522 DYNAMIC_OFFSET_VALUE_C,
1523 DYNAMIC_OFFSET_VALUE_D
1526 dynamicOffset.push_back(dynamicOffsetNonZero ? (dynamicOffsetValues[bufferNdx % getInterfaceNumResources(shaderInterface)]) : (0u));
1529 return dynamicOffset;
1532 std::vector<BufferHandleSp> BufferRenderInstance::createSourceBuffers (const vk::DeviceInterface& vki,
1533 vk::VkDevice device,
1534 vk::Allocator& allocator,
1535 vk::VkDescriptorType descriptorType,
1536 DescriptorSetCount descriptorSetCount,
1537 ShaderInputInterface shaderInterface,
1538 const std::vector<deUint32>& viewOffset,
1539 const std::vector<deUint32>& dynamicOffset,
1540 std::vector<AllocationSp>& bufferMemory)
1542 const int numBuffers = getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface);
1543 std::vector<deUint32> effectiveOffset;
1544 std::vector<deUint32> bufferSize;
1545 std::vector<BufferHandleSp> sourceBuffers;
1547 for (int bufferNdx = 0; bufferNdx < numBuffers; bufferNdx++)
1549 const deUint32 bufferSizeValues[] =
1557 effectiveOffset.push_back(isDynamicDescriptorType(descriptorType) ? (viewOffset[bufferNdx] + dynamicOffset[bufferNdx]) : (viewOffset[bufferNdx]));
1558 bufferSize.push_back(bufferSizeValues[bufferNdx % getInterfaceNumResources(shaderInterface)]);
1562 // Create source buffers
1563 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
1565 for (deUint32 bufferNdx = 0; bufferNdx < getInterfaceNumResources(shaderInterface); bufferNdx++)
1567 de::MovePtr<vk::Allocation> memory;
1568 vk::Move<vk::VkBuffer> buffer = createSourceBuffer(vki, device, allocator, descriptorType, setNdx, effectiveOffset[bufferNdx], bufferSize[bufferNdx], &memory);
1570 bufferMemory.push_back(AllocationSp(memory.release()));
1571 sourceBuffers.push_back(BufferHandleSp(new BufferHandleUp(buffer)));
1575 return sourceBuffers;
1578 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1579 vk::VkDevice device,
1580 vk::Allocator& allocator,
1581 vk::VkDescriptorType descriptorType,
1584 deUint32 bufferSize,
1585 de::MovePtr<vk::Allocation>* outMemory)
1587 static const float s_colors[] =
1589 0.0f, 1.0f, 0.0f, 1.0f, // green
1590 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1591 0.0f, 0.0f, 1.0f, 1.0f, // blue
1592 1.0f, 0.0f, 0.0f, 1.0f // red
1594 DE_STATIC_ASSERT(sizeof(s_colors) / 2 == BUFFER_DATA_SIZE);
1595 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1596 DE_ASSERT(offset % sizeof(float) == 0);
1597 DE_ASSERT(bufferSize % sizeof(float) == 0);
1599 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1600 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1601 const float preGuardValue = 0.5f;
1602 const float postGuardValue = 0.75f;
1603 const vk::VkBufferCreateInfo bufferCreateInfo =
1605 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1609 usageFlags, // usage
1610 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1611 0u, // queueFamilyCount
1612 DE_NULL, // pQueueFamilyIndices
1614 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1615 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1616 void* const mapPtr = bufferMemory->getHostPtr();
1618 // guard with interesting values
1619 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1620 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1622 deMemcpy((deUint8*)mapPtr + offset, &s_colors[8 * (setNdx % 2)], sizeof(s_colors) / 2);
1623 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors) / 2; postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1624 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1625 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
1627 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1629 // Flushed host-visible memory is automatically made available to the GPU, no barrier is needed.
1631 *outMemory = bufferMemory;
1635 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1636 vk::VkDevice device,
1637 vk::VkDescriptorType descriptorType,
1638 DescriptorSetCount descriptorSetCount,
1639 ShaderInputInterface shaderInterface)
1641 return vk::DescriptorPoolBuilder()
1642 .addType(descriptorType, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface))
1643 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(descriptorSetCount));
1646 std::vector<DescriptorSetLayoutHandleSp> BufferRenderInstance::createDescriptorSetLayouts (const vk::DeviceInterface& vki,
1647 vk::VkDevice device,
1648 vk::VkDescriptorType descriptorType,
1649 DescriptorSetCount descriptorSetCount,
1650 ShaderInputInterface shaderInterface,
1651 vk::VkShaderStageFlags stageFlags,
1652 DescriptorUpdateMethod updateMethod)
1654 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
1656 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
1657 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1659 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
1662 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
1664 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
1666 vk::DescriptorSetLayoutBuilder builder;
1667 switch (shaderInterface)
1669 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1670 builder.addSingleBinding(descriptorType, stageFlags);
1673 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1674 builder.addSingleBinding(descriptorType, stageFlags);
1675 builder.addSingleBinding(descriptorType, stageFlags);
1678 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
1679 builder.addSingleIndexedBinding(descriptorType, stageFlags, 0x7FFEu);
1680 builder.addSingleIndexedBinding(descriptorType, stageFlags, 0xFFFEu);
1683 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1684 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1688 DE_FATAL("Impossible");
1691 vk::Move<vk::VkDescriptorSetLayout> layout = builder.build(vki, device, extraFlags);
1692 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
1694 return descriptorSetLayouts;
1697 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1698 vk::VkDevice device,
1699 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout)
1701 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
1702 for (size_t setNdx = 0; setNdx < descriptorSetLayout.size(); setNdx++)
1703 layoutHandles.push_back(**descriptorSetLayout[setNdx]);
1705 const vk::VkPipelineLayoutCreateInfo createInfo =
1707 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1709 (vk::VkPipelineLayoutCreateFlags)0,
1710 (deUint32)layoutHandles.size(), // descriptorSetCount
1711 &layoutHandles.front(), // pSetLayouts
1712 0u, // pushConstantRangeCount
1713 DE_NULL, // pPushConstantRanges
1715 return vk::createPipelineLayout(vki, device, &createInfo);
1718 std::vector<DescriptorSetHandleSp> BufferRenderInstance::createDescriptorSets (const vk::DeviceInterface& vki,
1719 DescriptorUpdateMethod updateMethod,
1720 vk::VkDevice device,
1721 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
1722 vk::VkDescriptorPool descriptorPool,
1723 vk::VkDescriptorType descriptorType,
1724 ShaderInputInterface shaderInterface,
1725 const std::vector<BufferHandleSp>& buffers,
1726 const std::vector<deUint32>& offsets,
1727 vk::DescriptorSetUpdateBuilder& updateBuilder,
1728 std::vector<deUint32>& descriptorsPerSet,
1729 std::vector<UpdateTemplateHandleSp>& updateTemplates,
1730 std::vector<RawUpdateRegistry>& updateRegistry,
1731 vk::VkPipelineLayout pipelineLayout)
1733 std::vector<DescriptorSetHandleSp> descriptorSets;
1735 for (deUint32 setNdx = 0; setNdx < (deUint32)descriptorSetLayouts.size(); setNdx++)
1737 vk::VkDescriptorSetLayout layout = **descriptorSetLayouts[setNdx];
1738 const vk::VkDescriptorSetAllocateInfo allocInfo =
1740 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1747 vk::VkBuffer bufferA = **buffers[(setNdx * getInterfaceNumResources(shaderInterface)) % buffers.size()];
1748 vk::VkBuffer bufferB = **buffers[(setNdx * getInterfaceNumResources(shaderInterface) + 1) % buffers.size()];
1749 deUint32 offsetA = offsets[(setNdx * getInterfaceNumResources(shaderInterface)) % offsets.size()];
1750 deUint32 offsetB = offsets[(setNdx * getInterfaceNumResources(shaderInterface) + 1) % offsets.size()];
1752 vk::Move<vk::VkDescriptorSet> descriptorSet;
1754 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1756 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1760 descriptorSet = vk::Move<vk::VkDescriptorSet>();
1763 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
1765 writeDescriptorSetWithTemplate(vki, device, layout, setNdx, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateTemplates, updateRegistry);
1767 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1769 writeDescriptorSetWithTemplate(vki, device, layout, setNdx, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateTemplates, updateRegistry, true, pipelineLayout);
1771 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1773 writeDescriptorSet(vki, device, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateBuilder, descriptorsPerSet, updateMethod);
1775 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
1777 writeDescriptorSet(vki, device, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateBuilder, descriptorsPerSet);
1780 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(descriptorSet)));
1782 return descriptorSets;
1785 void BufferRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
1786 vk::VkDevice device,
1787 vk::VkDescriptorType descriptorType,
1788 ShaderInputInterface shaderInterface,
1789 vk::VkBuffer bufferA,
1790 const deUint32 offsetA,
1791 vk::VkBuffer bufferB,
1792 const deUint32 offsetB,
1793 vk::VkDescriptorSet descriptorSet,
1794 vk::DescriptorSetUpdateBuilder& updateBuilder,
1795 std::vector<deUint32>& descriptorsPerSet,
1796 DescriptorUpdateMethod updateMethod)
1798 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1800 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1801 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1803 deUint32 numBindings = 0u;
1805 switch (shaderInterface)
1807 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1808 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1812 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1813 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1814 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1818 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
1819 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0x7FFEu), descriptorType, &bufferInfos[0]);
1820 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0xFFFEu), descriptorType, &bufferInfos[1]);
1824 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1825 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1830 DE_FATAL("Impossible");
1833 descriptorsPerSet.push_back(numBindings);
1835 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
1837 updateBuilder.update(vki, device);
1838 updateBuilder.clear();
1842 void BufferRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
1843 vk::VkDevice device,
1844 vk::VkDescriptorSetLayout layout,
1846 vk::VkDescriptorPool descriptorPool,
1847 vk::VkDescriptorType descriptorType,
1848 ShaderInputInterface shaderInterface,
1849 vk::VkBuffer bufferA,
1850 const deUint32 offsetA,
1851 vk::VkBuffer bufferB,
1852 const deUint32 offsetB,
1853 vk::VkDescriptorSet descriptorSet,
1854 std::vector<UpdateTemplateHandleSp>& updateTemplates,
1855 std::vector<RawUpdateRegistry>& registry,
1857 vk::VkPipelineLayout pipelineLayout)
1859 DE_UNREF(descriptorPool);
1860 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1862 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1863 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1865 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
1866 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
1868 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
1871 0, // descriptorUpdateEntryCount
1872 DE_NULL, // pDescriptorUpdateEntries
1873 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
1875 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
1880 RawUpdateRegistry updateRegistry;
1882 updateRegistry.addWriteObject(bufferInfos[0]);
1883 updateRegistry.addWriteObject(bufferInfos[1]);
1885 switch (shaderInterface)
1887 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1888 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1891 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1892 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1893 updateEntries.push_back(createTemplateBinding(1u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
1896 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
1897 updateEntries.push_back(createTemplateBinding(0x7FFEu, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1898 updateEntries.push_back(createTemplateBinding(0xFFFEu, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
1901 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1902 updateEntries.push_back(createTemplateBinding(0u, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(bufferInfos[0])));
1906 DE_FATAL("Impossible");
1909 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
1910 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
1912 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
1913 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
1914 registry.push_back(updateRegistry);
1918 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
1922 void BufferRenderInstance::logTestPlan (void) const
1924 std::ostringstream msg;
1926 msg << "Rendering 2x2 yellow-green grid.\n"
1927 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
1928 << "Each descriptor set contains "
1929 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1930 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
1931 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
1932 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1933 (const char*)DE_NULL)
1934 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1935 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1937 if (isDynamicDescriptorType(m_descriptorType))
1939 if (m_setDynamicOffset)
1941 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1942 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1946 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1950 if (m_stageFlags == 0u)
1952 msg << "Descriptors are not accessed in any shader stage.\n";
1956 msg << "Descriptors are accessed in {"
1957 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1958 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1959 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1960 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1961 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1965 m_context.getTestContext().getLog()
1966 << tcu::TestLog::Message
1968 << tcu::TestLog::EndMessage;
1971 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1973 return *m_pipelineLayout;
1976 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1978 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1979 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : ((deUint32)m_dynamicOffset.size());
1980 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (&m_dynamicOffset.front());
1982 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1984 std::vector<vk::VkDescriptorSet> sets;
1985 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
1986 sets.push_back(**m_descriptorSets[setNdx]);
1988 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, (int)sets.size(), &sets.front(), numOffsets, dynamicOffsetPtr);
1990 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1992 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
1993 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, **m_updateTemplates[setNdx], getPipelineLayout(), setNdx, (const void*)m_updateRegistry[setNdx].getRawPointer());
1995 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1997 deUint32 descriptorNdx = 0u;
1998 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2000 const deUint32 numDescriptors = m_descriptorsPerSet[setNdx];
2001 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, setNdx, descriptorNdx, numDescriptors);
2002 descriptorNdx += numDescriptors;
2006 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
2009 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
2011 const deUint32 numDescriptorSets = getDescriptorSetCount(m_descriptorSetCount);
2012 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
2013 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
2014 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
2016 tcu::Vec4 sample0 = tcu::Vec4(0.0f);
2017 tcu::Vec4 sample1 = tcu::Vec4(0.0f);
2021 const tcu::Vec4 colors[] =
2023 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), // green
2024 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), // yellow
2025 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), // blue
2026 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), // red
2030 for (deUint32 setNdx = 0; setNdx < numDescriptorSets; setNdx++)
2032 sample0 += colors[2 * (setNdx % 2)];
2033 sample1 += colors[2 * (setNdx % 2) + 1];
2036 if (numDescriptorSets > 1)
2038 sample0 = sample0 / tcu::Vec4(float(numDescriptorSets));
2039 sample1 = sample1 / tcu::Vec4(float(numDescriptorSets));
2048 drawQuadrantReferenceResult(reference.getAccess(), sample1, sample0, sample0, sample1);
2050 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
2051 return tcu::TestStatus::fail("Image verification failed");
2053 return tcu::TestStatus::pass("Pass");
2056 class ComputeInstanceResultBuffer
2061 DATA_SIZE = sizeof(tcu::Vec4[4])
2064 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
2065 vk::VkDevice device,
2066 vk::Allocator& allocator);
2068 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
2070 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
2071 inline const vk::VkBufferMemoryBarrier* getResultReadBarrier (void) const { return &m_bufferBarrier; }
2074 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
2075 vk::VkDevice device,
2076 vk::Allocator& allocator,
2077 de::MovePtr<vk::Allocation>* outAllocation);
2079 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
2081 const vk::DeviceInterface& m_vki;
2082 const vk::VkDevice m_device;
2084 de::MovePtr<vk::Allocation> m_bufferMem;
2085 const vk::Unique<vk::VkBuffer> m_buffer;
2086 const vk::VkBufferMemoryBarrier m_bufferBarrier;
2089 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
2090 vk::VkDevice device,
2091 vk::Allocator& allocator)
2094 , m_bufferMem (DE_NULL)
2095 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
2096 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
2100 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
2102 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
2103 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
2106 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
2107 vk::VkDevice device,
2108 vk::Allocator& allocator,
2109 de::MovePtr<vk::Allocation>* outAllocation)
2111 const vk::VkBufferCreateInfo createInfo =
2113 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
2116 (vk::VkDeviceSize)DATA_SIZE, // size
2117 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
2118 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2119 0u, // queueFamilyCount
2120 DE_NULL, // pQueueFamilyIndices
2122 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
2123 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
2124 const float clearValue = -1.0f;
2125 void* mapPtr = allocation->getHostPtr();
2127 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
2128 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
2130 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
2132 *outAllocation = allocation;
2136 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
2138 const vk::VkBufferMemoryBarrier bufferBarrier =
2140 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2142 vk::VK_ACCESS_SHADER_WRITE_BIT, // srcAccessMask
2143 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
2144 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2145 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2147 (vk::VkDeviceSize)0u, // offset
2150 return bufferBarrier;
2153 class ComputePipeline
2156 ComputePipeline (const vk::DeviceInterface& vki,
2157 vk::VkDevice device,
2158 const vk::BinaryCollection& programCollection,
2159 deUint32 numDescriptorSets,
2160 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
2162 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
2163 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
2166 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
2167 vk::VkDevice device,
2168 deUint32 numDescriptorSets,
2169 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
2171 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
2172 vk::VkDevice device,
2173 const vk::BinaryCollection& programCollection,
2174 vk::VkPipelineLayout layout);
2176 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
2177 const vk::Unique<vk::VkPipeline> m_pipeline;
2180 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
2181 vk::VkDevice device,
2182 const vk::BinaryCollection& programCollection,
2183 deUint32 numDescriptorSets,
2184 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
2185 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
2186 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
2190 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
2191 vk::VkDevice device,
2192 deUint32 numDescriptorSets,
2193 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
2195 const vk::VkPipelineLayoutCreateInfo createInfo =
2197 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2199 (vk::VkPipelineLayoutCreateFlags)0,
2200 numDescriptorSets, // descriptorSetCount
2201 descriptorSetLayouts, // pSetLayouts
2202 0u, // pushConstantRangeCount
2203 DE_NULL, // pPushConstantRanges
2205 return vk::createPipelineLayout(vki, device, &createInfo);
2208 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
2209 vk::VkDevice device,
2210 const vk::BinaryCollection& programCollection,
2211 vk::VkPipelineLayout layout)
2213 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
2214 const vk::VkPipelineShaderStageCreateInfo cs =
2216 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2218 (vk::VkPipelineShaderStageCreateFlags)0,
2219 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
2220 *computeModule, // shader
2222 DE_NULL, // pSpecializationInfo
2224 const vk::VkComputePipelineCreateInfo createInfo =
2226 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2231 (vk::VkPipeline)0, // basePipelineHandle
2232 0u, // basePipelineIndex
2234 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
2237 class ComputeCommand
2240 ComputeCommand (const vk::DeviceInterface& vki,
2241 vk::VkDevice device,
2242 vk::VkPipeline pipeline,
2243 vk::VkPipelineLayout pipelineLayout,
2244 const tcu::UVec3& numWorkGroups,
2245 int numDescriptorSets,
2246 const vk::VkDescriptorSet* descriptorSets,
2247 int numDynamicOffsets,
2248 const deUint32* dynamicOffsets,
2250 const vk::VkBufferMemoryBarrier* preBarriers,
2251 int numPostBarriers,
2252 const vk::VkBufferMemoryBarrier* postBarriers);
2254 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, std::vector<UpdateTemplateHandleSp>* updateTemplates = DE_NULL, std::vector<RawUpdateRegistry>* updateRegistry = DE_NULL) const;
2255 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::DescriptorSetUpdateBuilder& updateBuilder, std::vector<deUint32>& descriptorsPerSet) const;
2258 const vk::DeviceInterface& m_vki;
2259 const vk::VkDevice m_device;
2260 const vk::VkPipeline m_pipeline;
2261 const vk::VkPipelineLayout m_pipelineLayout;
2262 const tcu::UVec3 m_numWorkGroups;
2263 const int m_numDescriptorSets;
2264 const vk::VkDescriptorSet* const m_descriptorSets;
2265 const int m_numDynamicOffsets;
2266 const deUint32* const m_dynamicOffsets;
2267 const int m_numPreBarriers;
2268 const vk::VkBufferMemoryBarrier* const m_preBarriers;
2269 const int m_numPostBarriers;
2270 const vk::VkBufferMemoryBarrier* const m_postBarriers;
2273 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
2274 vk::VkDevice device,
2275 vk::VkPipeline pipeline,
2276 vk::VkPipelineLayout pipelineLayout,
2277 const tcu::UVec3& numWorkGroups,
2278 int numDescriptorSets,
2279 const vk::VkDescriptorSet* descriptorSets,
2280 int numDynamicOffsets,
2281 const deUint32* dynamicOffsets,
2283 const vk::VkBufferMemoryBarrier* preBarriers,
2284 int numPostBarriers,
2285 const vk::VkBufferMemoryBarrier* postBarriers)
2288 , m_pipeline (pipeline)
2289 , m_pipelineLayout (pipelineLayout)
2290 , m_numWorkGroups (numWorkGroups)
2291 , m_numDescriptorSets (numDescriptorSets)
2292 , m_descriptorSets (descriptorSets)
2293 , m_numDynamicOffsets (numDynamicOffsets)
2294 , m_dynamicOffsets (dynamicOffsets)
2295 , m_numPreBarriers (numPreBarriers)
2296 , m_preBarriers (preBarriers)
2297 , m_numPostBarriers (numPostBarriers)
2298 , m_postBarriers (postBarriers)
2302 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, std::vector<UpdateTemplateHandleSp>* updateTemplates, std::vector<RawUpdateRegistry>* updateRegistry) const
2304 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
2306 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2308 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
2309 queueFamilyIndex, // queueFamilyIndex
2311 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
2313 const vk::VkFenceCreateInfo fenceCreateInfo =
2315 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2320 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
2322 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
2324 *cmdPool, // cmdPool
2325 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
2328 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
2330 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2332 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
2333 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
2336 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
2337 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
2338 const deUint64 infiniteTimeout = ~(deUint64)0u;
2340 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
2342 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
2344 if (m_numDescriptorSets)
2346 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
2349 if (updateTemplates != DE_NULL)
2351 // we need to update the push descriptors
2352 for (deUint32 setNdx = 0; setNdx < (deUint32)(*updateTemplates).size(); setNdx++)
2353 m_vki.cmdPushDescriptorSetWithTemplateKHR(*cmd, **(*updateTemplates)[setNdx], m_pipelineLayout, setNdx, (const void*)(*updateRegistry)[setNdx].getRawPointer());
2356 if (m_numPreBarriers)
2357 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
2358 0, (const vk::VkMemoryBarrier*)DE_NULL,
2359 m_numPreBarriers, m_preBarriers,
2360 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2362 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
2363 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0,
2364 0, (const vk::VkMemoryBarrier*)DE_NULL,
2365 m_numPostBarriers, m_postBarriers,
2366 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2367 VK_CHECK(m_vki.endCommandBuffer(*cmd));
2371 const vk::VkSubmitInfo submitInfo =
2373 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
2376 (const vk::VkSemaphore*)0,
2377 (const vk::VkPipelineStageFlags*)DE_NULL,
2381 (const vk::VkSemaphore*)0,
2383 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
2385 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
2388 //cmdPushDescriptorSet variant
2389 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::DescriptorSetUpdateBuilder& updateBuilder, std::vector<deUint32>& descriptorsPerSet) const
2391 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
2393 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2395 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
2396 queueFamilyIndex, // queueFamilyIndex
2398 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
2399 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
2401 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2403 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
2404 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
2407 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device));
2408 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2409 const deUint64 infiniteTimeout = ~(deUint64)0u;
2411 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
2413 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
2415 if (m_numDescriptorSets)
2417 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
2421 deUint32 descriptorNdx = 0u;
2422 for (deUint32 setNdx = 0; setNdx < (deUint32)descriptorsPerSet.size(); setNdx++)
2424 const deUint32 numDescriptors = descriptorsPerSet[setNdx];
2425 updateBuilder.updateWithPush(m_vki, *cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, setNdx, descriptorNdx, numDescriptors);
2426 descriptorNdx += numDescriptors;
2430 if (m_numPreBarriers)
2431 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
2432 0, (const vk::VkMemoryBarrier*)DE_NULL,
2433 m_numPreBarriers, m_preBarriers,
2434 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2436 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
2437 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_HOST_BIT, (vk::VkDependencyFlags)0,
2438 0, (const vk::VkMemoryBarrier*)DE_NULL,
2439 m_numPostBarriers, m_postBarriers,
2440 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2441 VK_CHECK(m_vki.endCommandBuffer(*cmd));
2445 const vk::VkSubmitInfo submitInfo =
2447 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
2450 (const vk::VkSemaphore*)0,
2451 (const vk::VkPipelineStageFlags*)DE_NULL,
2455 (const vk::VkSemaphore*)0,
2457 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
2459 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
2462 class BufferComputeInstance : public vkt::TestInstance
2465 BufferComputeInstance (Context& context,
2466 DescriptorUpdateMethod updateMethod,
2467 vk::VkDescriptorType descriptorType,
2468 DescriptorSetCount descriptorSetCount,
2469 ShaderInputInterface shaderInterface,
2472 bool dynamicOffsetNonZero);
2475 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
2476 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (deUint32 setNdx) const;
2477 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
2478 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);
2479 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf);
2480 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);
2482 tcu::TestStatus iterate (void);
2483 void logTestPlan (void) const;
2484 tcu::TestStatus testResourceAccess (void);
2488 STATIC_OFFSET_VALUE_A = 256,
2489 DYNAMIC_OFFSET_VALUE_A = 512,
2490 STATIC_OFFSET_VALUE_B = 1024,
2491 DYNAMIC_OFFSET_VALUE_B = 768,
2494 const DescriptorUpdateMethod m_updateMethod;
2495 const vk::VkDescriptorType m_descriptorType;
2496 const DescriptorSetCount m_descriptorSetCount;
2497 const ShaderInputInterface m_shaderInterface;
2498 const bool m_setViewOffset;
2499 const bool m_setDynamicOffset;
2500 const bool m_dynamicOffsetNonZero;
2502 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
2503 const vk::DeviceInterface& m_vki;
2504 const vk::VkDevice m_device;
2505 const vk::VkQueue m_queue;
2506 const deUint32 m_queueFamilyIndex;
2507 vk::Allocator& m_allocator;
2509 const ComputeInstanceResultBuffer m_result;
2511 std::vector<RawUpdateRegistry> m_updateRegistry;
2512 vk::DescriptorSetUpdateBuilder m_updateBuilder;
2513 std::vector<deUint32> m_descriptorsPerSet;
2516 BufferComputeInstance::BufferComputeInstance (Context& context,
2517 DescriptorUpdateMethod updateMethod,
2518 vk::VkDescriptorType descriptorType,
2519 DescriptorSetCount descriptorSetCount,
2520 ShaderInputInterface shaderInterface,
2523 bool dynamicOffsetNonZero)
2524 : vkt::TestInstance (context)
2525 , m_updateMethod (updateMethod)
2526 , m_descriptorType (descriptorType)
2527 , m_descriptorSetCount (descriptorSetCount)
2528 , m_shaderInterface (shaderInterface)
2529 , m_setViewOffset (viewOffset)
2530 , m_setDynamicOffset (dynamicOffset)
2531 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
2532 , m_updateTemplates ()
2533 , m_vki (context.getDeviceInterface())
2534 , m_device (context.getDevice())
2535 , m_queue (context.getUniversalQueue())
2536 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
2537 , m_allocator (context.getDefaultAllocator())
2538 , m_result (m_vki, m_device, m_allocator)
2539 , m_updateRegistry ()
2540 , m_updateBuilder ()
2541 , m_descriptorsPerSet ()
2543 if (m_dynamicOffsetNonZero)
2544 DE_ASSERT(m_setDynamicOffset);
2547 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
2549 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
2551 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2552 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2553 const vk::VkBufferCreateInfo createInfo =
2555 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
2558 (vk::VkDeviceSize)bufferSize, // size
2559 usageFlags, // usage
2560 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2561 0u, // queueFamilyCount
2562 DE_NULL, // pQueueFamilyIndices
2564 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
2565 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
2566 void* mapPtr = allocation->getHostPtr();
2569 deMemset(mapPtr, 0x5A, (size_t)offset);
2570 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
2571 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
2572 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
2574 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
2576 *outAllocation = allocation;
2580 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (deUint32 setNdx) const
2582 vk::DescriptorSetLayoutBuilder builder;
2583 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
2585 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
2586 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
2588 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
2592 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2594 switch (m_shaderInterface)
2596 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2597 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2600 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2601 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2602 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2605 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
2606 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, 0x7FFEu);
2607 builder.addSingleIndexedBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, 0xFFFEu);
2610 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2611 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2615 DE_FATAL("Impossible");
2618 return builder.build(m_vki, m_device, extraFlags);
2621 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
2623 return vk::DescriptorPoolBuilder()
2624 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2625 .addType(m_descriptorType, getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface))
2626 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(m_descriptorSetCount));
2629 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)
2631 const vk::VkDescriptorSetAllocateInfo allocInfo =
2633 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2640 vk::Move<vk::VkDescriptorSet> descriptorSet;
2641 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
2643 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
2647 descriptorSet = vk::Move<vk::VkDescriptorSet>();
2650 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
2652 writeDescriptorSetWithTemplate(*descriptorSet, layout, setNdx, viewA, offsetA, viewB, offsetB, resBuf);
2654 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
2656 writeDescriptorSet(*descriptorSet, setNdx, viewA, offsetA, viewB, offsetB, resBuf);
2659 return descriptorSet;
2662 void BufferComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf)
2664 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2665 const vk::VkDescriptorBufferInfo bufferInfos[2] =
2667 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2668 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2671 deUint32 numBindings = 0u;
2672 deUint32 binding = 0u;
2677 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
2682 switch (m_shaderInterface)
2684 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2685 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &bufferInfos[0]);
2689 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2690 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &bufferInfos[0]);
2691 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &bufferInfos[1]);
2695 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
2696 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0x7FFEu), m_descriptorType, &bufferInfos[0]);
2697 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0xFFFEu), m_descriptorType, &bufferInfos[1]);
2701 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2702 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, 2u, bufferInfos);
2707 DE_FATAL("Impossible");
2710 m_descriptorsPerSet.push_back(numBindings);
2712 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
2714 m_updateBuilder.update(m_vki, m_device);
2715 m_updateBuilder.clear();
2719 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)
2721 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2722 const vk::VkDescriptorBufferInfo bufferInfos[2] =
2724 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2725 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2727 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
2728 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
2730 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
2733 0, // descriptorUpdateEntryCount
2734 DE_NULL, // pDescriptorUpdateEntries
2735 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
2737 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
2741 deUint32 binding = 0u;
2742 deUint32 offset = 0u;
2743 RawUpdateRegistry updateRegistry;
2746 updateRegistry.addWriteObject(resultInfo);
2748 updateRegistry.addWriteObject(bufferInfos[0]);
2749 updateRegistry.addWriteObject(bufferInfos[1]);
2753 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
2756 switch (m_shaderInterface)
2758 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2759 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2762 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2763 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2764 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2767 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
2768 updateEntries.push_back(createTemplateBinding(0x7FFEu, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2769 updateEntries.push_back(createTemplateBinding(0xFFFEu, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
2772 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2773 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), sizeof(bufferInfos[0])));
2777 DE_FATAL("Impossible");
2780 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
2781 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
2783 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
2784 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
2785 m_updateRegistry.push_back(updateRegistry);
2789 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, **m_updateTemplates.back(), m_updateRegistry.back().getRawPointer());
2793 tcu::TestStatus BufferComputeInstance::iterate (void)
2796 return testResourceAccess();
2799 void BufferComputeInstance::logTestPlan (void) const
2801 std::ostringstream msg;
2803 msg << "Accessing resource in a compute program.\n"
2804 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
2805 << "Each descriptor set contains "
2806 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2807 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
2808 (m_shaderInterface == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS) ? "two" :
2809 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2810 (const char*)DE_NULL)
2811 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2812 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2813 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2815 if (isDynamicDescriptorType(m_descriptorType))
2817 if (m_setDynamicOffset)
2819 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2820 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2824 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2828 msg << "Destination buffer is pre-initialized to -1.\n";
2830 m_context.getTestContext().getLog()
2831 << tcu::TestLog::Message
2833 << tcu::TestLog::EndMessage;
2836 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2840 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2843 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2844 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2846 const tcu::Vec4 color[] =
2848 tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f), // green
2849 tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f), // yellow
2850 tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f), // blue
2851 tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f), // red
2854 std::vector<deUint32> bindTimeOffsets;
2855 std::vector<tcu::Vec4> colors;
2856 std::vector<deUint32> dataOffsets;
2857 std::vector<deUint32> viewOffsets;
2858 std::vector<deUint32> bufferSizes;
2859 std::vector<AllocationSp> bufferMems;
2860 std::vector<BufferHandleSp> buffers;
2862 for (deUint32 bufferNdx = 0; bufferNdx < getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface); bufferNdx++)
2864 const deUint32 staticOffsets[] =
2866 STATIC_OFFSET_VALUE_A,
2867 STATIC_OFFSET_VALUE_B
2870 const deUint32 dynamicOffset[] =
2872 DYNAMIC_OFFSET_VALUE_A,
2873 DYNAMIC_OFFSET_VALUE_B
2876 const deUint32 parity = bufferNdx % 2;
2877 bindTimeOffsets.push_back((m_dynamicOffsetNonZero) ? (dynamicOffset[parity]) : (0u));
2879 const deUint32 dataOffset = ((isDynamicCase) ? (bindTimeOffsets.back()) : 0) + ((m_setViewOffset) ? (staticOffsets[parity]) : (0u));
2880 const deUint32 viewOffset = ((m_setViewOffset) ? (staticOffsets[parity]) : (0u));
2882 colors.push_back(color[bufferNdx % DE_LENGTH_OF_ARRAY(color)]);
2883 dataOffsets.push_back(dataOffset);
2884 viewOffsets.push_back(viewOffset);
2885 bufferSizes.push_back(dataOffsets.back() + ADDRESSABLE_SIZE);
2887 de::MovePtr<vk::Allocation> bufferMem;
2888 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));
2890 bufferMems.push_back(AllocationSp(bufferMem.release()));
2891 buffers.push_back(BufferHandleSp(new BufferHandleUp(buffer)));
2894 const vk::Unique<vk::VkDescriptorPool> descriptorPool(createDescriptorPool());
2895 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
2896 std::vector<DescriptorSetHandleSp> descriptorSets;
2897 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
2898 std::vector<vk::VkDescriptorSet> setHandles;
2900 const deUint32 numSrcBuffers = getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface);
2902 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2904 const deUint32 ndx0 = (setNdx * getInterfaceNumResources(m_shaderInterface)) % numSrcBuffers;
2905 const deUint32 ndx1 = (setNdx * getInterfaceNumResources(m_shaderInterface) + 1) % numSrcBuffers;
2907 vk::Move<vk::VkDescriptorSetLayout> layout = createDescriptorSetLayout(setNdx);
2908 vk::Move<vk::VkDescriptorSet> set = createDescriptorSet(*descriptorPool, *layout, setNdx, **buffers[ndx0], viewOffsets[ndx0], **buffers[ndx1], viewOffsets[ndx1], m_result.getBuffer());
2910 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
2911 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(set)));
2913 layoutHandles.push_back(**descriptorSetLayouts.back());
2914 setHandles.push_back(**descriptorSets.back());
2917 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), (int)layoutHandles.size(), &layoutHandles.front());
2918 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2920 std::vector<vk::VkBufferMemoryBarrier> bufferBarriers;
2922 for (deUint32 bufferNdx = 0; bufferNdx < numSrcBuffers; bufferNdx++)
2924 const vk::VkBufferMemoryBarrier barrier =
2926 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2928 vk::VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask
2929 inputBit, // dstAccessMask
2930 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2931 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2932 **buffers[bufferNdx], // buffer
2933 (vk::VkDeviceSize)0u, // offset
2934 (vk::VkDeviceSize)bufferSizes[bufferNdx], // size
2937 bufferBarriers.push_back(barrier);
2940 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : getDescriptorSetCount(m_descriptorSetCount);
2941 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (&bindTimeOffsets.front()) : (DE_NULL);
2942 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2943 const vk::VkBufferMemoryBarrier* const preBarriers = &bufferBarriers.front();
2944 const int numPreBarriers = numSrcBuffers;
2945 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
2946 const int numPostBarriers = 1;
2948 const ComputeCommand compute (m_vki,
2950 pipeline.getPipeline(),
2951 pipeline.getPipelineLayout(),
2952 tcu::UVec3(4, 1, 1),
2953 numDescriptorSets, &setHandles.front(),
2954 numDynamicOffsets, dynamicOffsets,
2955 numPreBarriers, preBarriers,
2956 numPostBarriers, postBarriers);
2958 tcu::Vec4 refQuadrantValue14 = tcu::Vec4(0.0f);
2959 tcu::Vec4 refQuadrantValue23 = tcu::Vec4(0.0f);
2961 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2963 deUint32 offset = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? 1 : 3;
2964 refQuadrantValue14 += color[(2 * setNdx * getInterfaceNumResources(m_shaderInterface) + offset) % DE_LENGTH_OF_ARRAY(color)];
2965 refQuadrantValue23 += color[(2 * setNdx * getInterfaceNumResources(m_shaderInterface)) % DE_LENGTH_OF_ARRAY(color)];
2968 refQuadrantValue14 = refQuadrantValue14 / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
2969 refQuadrantValue23 = refQuadrantValue23 / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
2971 const tcu::Vec4 references[4] =
2978 tcu::Vec4 results[4];
2980 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
2982 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2984 const deUint32 ndx0 = (setNdx * getInterfaceNumResources(m_shaderInterface)) % numSrcBuffers;
2985 const deUint32 ndx1 = (setNdx * getInterfaceNumResources(m_shaderInterface) + 1) % numSrcBuffers;
2987 writeDescriptorSetWithTemplate(DE_NULL, layoutHandles[setNdx], setNdx, **buffers[ndx0], viewOffsets[ndx0], **buffers[ndx1], viewOffsets[ndx1], m_result.getBuffer(), true, pipeline.getPipelineLayout());
2989 compute.submitAndWait(m_queueFamilyIndex, m_queue, &m_updateTemplates, &m_updateRegistry);
2991 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
2993 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
2995 const deUint32 ndx0 = (setNdx * getInterfaceNumResources(m_shaderInterface)) % numSrcBuffers;
2996 const deUint32 ndx1 = (setNdx * getInterfaceNumResources(m_shaderInterface) + 1) % numSrcBuffers;
2998 writeDescriptorSet(DE_NULL, setNdx, **buffers[ndx0], viewOffsets[ndx0], **buffers[ndx1], viewOffsets[ndx1], m_result.getBuffer());
3001 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder, m_descriptorsPerSet);
3005 compute.submitAndWait(m_queueFamilyIndex, m_queue);
3007 m_result.readResultContentsTo(&results);
3010 if (results[0] == references[0] &&
3011 results[1] == references[1] &&
3012 results[2] == references[2] &&
3013 results[3] == references[3])
3015 return tcu::TestStatus::pass("Pass");
3017 else if (results[0] == tcu::Vec4(-1.0f) &&
3018 results[1] == tcu::Vec4(-1.0f) &&
3019 results[2] == tcu::Vec4(-1.0f) &&
3020 results[3] == tcu::Vec4(-1.0f))
3022 m_context.getTestContext().getLog()
3023 << tcu::TestLog::Message
3024 << "Result buffer was not written to."
3025 << tcu::TestLog::EndMessage;
3026 return tcu::TestStatus::fail("Result buffer was not written to");
3030 m_context.getTestContext().getLog()
3031 << tcu::TestLog::Message
3032 << "Error expected ["
3033 << references[0] << ", "
3034 << references[1] << ", "
3035 << references[2] << ", "
3036 << references[3] << "], got ["
3037 << results[0] << ", "
3038 << results[1] << ", "
3039 << results[2] << ", "
3040 << results[3] << "]"
3041 << tcu::TestLog::EndMessage;
3042 return tcu::TestStatus::fail("Invalid result values");
3046 class QuadrantRendederCase : public vkt::TestCase
3049 QuadrantRendederCase (tcu::TestContext& testCtx,
3051 const char* description,
3052 glu::GLSLVersion glslVersion,
3053 vk::VkShaderStageFlags exitingStages,
3054 vk::VkShaderStageFlags activeStages,
3055 DescriptorSetCount descriptorSetCount);
3057 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
3058 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
3059 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
3060 virtual std::string genNoAccessSource (void) const = 0;
3062 std::string genVertexSource (void) const;
3063 std::string genTessCtrlSource (void) const;
3064 std::string genTessEvalSource (void) const;
3065 std::string genGeometrySource (void) const;
3066 std::string genFragmentSource (void) const;
3067 std::string genComputeSource (void) const;
3069 void initPrograms (vk::SourceCollections& programCollection) const;
3072 const glu::GLSLVersion m_glslVersion;
3073 const vk::VkShaderStageFlags m_exitingStages;
3074 const vk::VkShaderStageFlags m_activeStages;
3075 const DescriptorSetCount m_descriptorSetCount;
3078 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
3080 const char* description,
3081 glu::GLSLVersion glslVersion,
3082 vk::VkShaderStageFlags exitingStages,
3083 vk::VkShaderStageFlags activeStages,
3084 DescriptorSetCount descriptorSetCount)
3085 : vkt::TestCase (testCtx, name, description)
3086 , m_glslVersion (glslVersion)
3087 , m_exitingStages (exitingStages)
3088 , m_activeStages (activeStages)
3089 , m_descriptorSetCount (descriptorSetCount)
3091 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
3094 std::string QuadrantRendederCase::genVertexSource (void) const
3096 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
3097 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
3098 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
3100 const char* const fragColorPrec = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? "highp" : "mediump";
3101 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3102 std::ostringstream buf;
3104 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
3106 const bool onlyVS = (m_activeStages == vk::VK_SHADER_STAGE_VERTEX_BIT);
3108 // active vertex shader
3109 buf << versionDecl << "\n"
3110 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT);
3111 buf << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0);
3112 buf << "layout(location = 0) out " << fragColorPrec << " vec4 " << nextStageName << "_color;\n"
3113 << (onlyVS ? "" : "layout(location = 1) flat out highp int " + de::toString(nextStageName) + "_quadrant_id;\n")
3114 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
3115 << "void main (void)\n"
3117 << " highp vec4 result_position;\n"
3118 << " highp int quadrant_id;\n"
3119 << s_quadrantGenVertexPosSource
3120 << " gl_Position = result_position;\n"
3121 << (onlyVS ? "" : "\t" + de::toString(nextStageName) + "_quadrant_id = quadrant_id;\n")
3123 << " highp vec4 result_color;\n"
3124 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
3125 << " " << nextStageName << "_color = result_color;\n"
3131 buf << versionDecl << "\n"
3132 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
3133 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
3134 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
3135 << "void main (void)\n"
3137 << " highp vec4 result_position;\n"
3138 << " highp int quadrant_id;\n"
3139 << s_quadrantGenVertexPosSource
3140 << " gl_Position = result_position;\n"
3141 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
3148 std::string QuadrantRendederCase::genTessCtrlSource (void) const
3150 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3151 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
3152 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
3153 std::ostringstream buf;
3155 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
3157 // contributing not implemented
3158 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
3161 buf << versionDecl << "\n"
3163 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3164 << "layout(vertices=3) out;\n"
3165 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
3166 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
3167 << "layout(location = 0) out highp vec4 tes_color[];\n"
3168 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
3169 << "void main (void)\n"
3171 << " highp vec4 result_color;\n"
3172 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
3173 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
3175 << " tes_color[gl_InvocationID] = result_color;\n"
3177 << " // no dynamic input block indexing\n"
3178 << " highp vec4 position;\n"
3179 << " if (gl_InvocationID == 0)\n"
3180 << " position = gl_in[0].gl_Position;\n"
3181 << " else if (gl_InvocationID == 1)\n"
3182 << " position = gl_in[1].gl_Position;\n"
3184 << " position = gl_in[2].gl_Position;\n"
3185 << " gl_out[gl_InvocationID].gl_Position = position;\n"
3186 << " gl_TessLevelInner[0] = 2.8;\n"
3187 << " gl_TessLevelInner[1] = 2.8;\n"
3188 << " gl_TessLevelOuter[0] = 2.8;\n"
3189 << " gl_TessLevelOuter[1] = 2.8;\n"
3190 << " gl_TessLevelOuter[2] = 2.8;\n"
3191 << " gl_TessLevelOuter[3] = 2.8;\n"
3194 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
3196 // active te shader, tc passthru
3197 buf << versionDecl << "\n"
3199 << "layout(vertices=3) out;\n"
3200 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
3201 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
3202 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
3203 << "void main (void)\n"
3205 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
3207 << " // no dynamic input block indexing\n"
3208 << " highp vec4 position;\n"
3209 << " if (gl_InvocationID == 0)\n"
3210 << " position = gl_in[0].gl_Position;\n"
3211 << " else if (gl_InvocationID == 1)\n"
3212 << " position = gl_in[1].gl_Position;\n"
3214 << " position = gl_in[2].gl_Position;\n"
3215 << " gl_out[gl_InvocationID].gl_Position = position;\n"
3216 << " gl_TessLevelInner[0] = 2.8;\n"
3217 << " gl_TessLevelInner[1] = 2.8;\n"
3218 << " gl_TessLevelOuter[0] = 2.8;\n"
3219 << " gl_TessLevelOuter[1] = 2.8;\n"
3220 << " gl_TessLevelOuter[2] = 2.8;\n"
3221 << " gl_TessLevelOuter[3] = 2.8;\n"
3226 // passthrough not implemented
3227 DE_FATAL("not implemented");
3233 std::string QuadrantRendederCase::genTessEvalSource (void) const
3235 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3236 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
3237 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
3238 std::ostringstream buf;
3240 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
3242 // contributing not implemented
3243 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
3246 buf << versionDecl << "\n"
3248 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3249 << "layout(triangles) in;\n"
3250 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
3251 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
3252 << "layout(location = 0) out mediump vec4 frag_color;\n"
3253 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
3254 << "void main (void)\n"
3256 << " highp vec4 result_color;\n"
3257 << " highp int quadrant_id = tes_quadrant_id[0];\n"
3258 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
3260 << " frag_color = result_color;\n"
3261 << " 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"
3264 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
3266 // contributing not implemented
3267 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
3269 // active tc shader, te is passthru
3270 buf << versionDecl << "\n"
3272 << "layout(triangles) in;\n"
3273 << "layout(location = 0) in highp vec4 tes_color[];\n"
3274 << "layout(location = 0) out mediump vec4 frag_color;\n"
3275 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
3276 << "void main (void)\n"
3278 << " frag_color = tes_color[0];\n"
3279 << " 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"
3284 // passthrough not implemented
3285 DE_FATAL("not implemented");
3291 std::string QuadrantRendederCase::genGeometrySource (void) const
3293 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3294 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
3295 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
3296 std::ostringstream buf;
3298 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
3300 // contributing not implemented
3301 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
3303 // active geometry shader
3304 buf << versionDecl << "\n"
3306 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3307 << "layout(triangles) in;\n"
3308 << "layout(triangle_strip, max_vertices=4) out;\n"
3309 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
3310 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
3311 << "layout(location = 0) out mediump vec4 frag_color;\n"
3312 << genPerVertexBlock(vk::VK_SHADER_STAGE_GEOMETRY_BIT, m_glslVersion)
3313 << "void main (void)\n"
3315 << " highp int quadrant_id;\n"
3316 << " highp vec4 result_color;\n"
3318 << " quadrant_id = geo_quadrant_id[0];\n"
3319 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3320 << " frag_color = result_color;\n"
3321 << " gl_Position = gl_in[0].gl_Position;\n"
3322 << " EmitVertex();\n"
3324 << " quadrant_id = geo_quadrant_id[1];\n"
3325 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3326 << " frag_color = result_color;\n"
3327 << " gl_Position = gl_in[1].gl_Position;\n"
3328 << " EmitVertex();\n"
3330 << " quadrant_id = geo_quadrant_id[2];\n"
3331 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3332 << " frag_color = result_color;\n"
3333 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
3334 << " EmitVertex();\n"
3336 << " quadrant_id = geo_quadrant_id[0];\n"
3337 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3338 << " frag_color = result_color;\n"
3339 << " gl_Position = gl_in[2].gl_Position;\n"
3340 << " EmitVertex();\n"
3345 // passthrough not implemented
3346 DE_FATAL("not implemented");
3352 std::string QuadrantRendederCase::genFragmentSource (void) const
3354 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3355 std::ostringstream buf;
3357 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
3359 buf << versionDecl << "\n"
3360 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3361 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
3363 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
3365 // there are other stages, this is just a contributor
3366 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
3369 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
3370 << "layout(location = 0) out mediump vec4 o_color;\n"
3371 << "void main (void)\n"
3373 << " highp int quadrant_id = frag_quadrant_id;\n"
3374 << " highp vec4 result_color;\n"
3375 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
3377 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
3380 buf << " if (frag_quadrant_id < 2)\n"
3381 << " o_color = result_color;\n"
3383 << " o_color = frag_color;\n";
3386 buf << " o_color = result_color;\n";
3390 else if (m_activeStages == 0u)
3392 // special case, no active stages
3393 buf << versionDecl << "\n"
3394 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
3395 << "layout(location = 0) out mediump vec4 o_color;\n"
3396 << "void main (void)\n"
3398 << " highp int quadrant_id = frag_quadrant_id;\n"
3399 << " highp vec4 result_color;\n"
3400 << genNoAccessSource()
3401 << " o_color = result_color;\n"
3407 buf << versionDecl << "\n"
3408 << "layout(location = 0) in mediump vec4 frag_color;\n"
3409 "layout(location = 0) out mediump vec4 o_color;\n"
3410 "void main (void)\n"
3412 " o_color = frag_color;\n"
3419 std::string QuadrantRendederCase::genComputeSource (void) const
3421 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3422 std::ostringstream buf;
3424 buf << versionDecl << "\n"
3425 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
3426 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3427 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
3428 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
3430 << " highp vec4 read_colors[4];\n"
3432 << "void main (void)\n"
3434 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
3435 << " highp vec4 result_color;\n"
3436 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
3437 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
3443 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
3445 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
3446 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
3448 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
3449 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
3451 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
3452 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
3454 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
3455 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
3457 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
3458 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
3460 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
3461 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
3464 class BufferDescriptorCase : public QuadrantRendederCase
3469 FLAG_VIEW_OFFSET = (1u << 1u),
3470 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
3471 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
3473 // enum continues where resource flags ends
3474 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
3476 BufferDescriptorCase (tcu::TestContext& testCtx,
3477 DescriptorUpdateMethod updateMethod,
3479 const char* description,
3480 bool isPrimaryCmdBuf,
3481 vk::VkDescriptorType descriptorType,
3482 vk::VkShaderStageFlags exitingStages,
3483 vk::VkShaderStageFlags activeStages,
3484 DescriptorSetCount descriptorSetCount,
3485 ShaderInputInterface shaderInterface,
3489 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
3490 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
3491 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
3492 std::string genNoAccessSource (void) const;
3494 vkt::TestInstance* createInstance (vkt::Context& context) const;
3496 const DescriptorUpdateMethod m_updateMethod;
3497 const bool m_viewOffset;
3498 const bool m_dynamicOffsetSet;
3499 const bool m_dynamicOffsetNonZero;
3500 const bool m_isPrimaryCmdBuf;
3501 const vk::VkDescriptorType m_descriptorType;
3502 const DescriptorSetCount m_descriptorSetCount;
3503 const ShaderInputInterface m_shaderInterface;
3506 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
3507 DescriptorUpdateMethod updateMethod,
3509 const char* description,
3510 bool isPrimaryCmdBuf,
3511 vk::VkDescriptorType descriptorType,
3512 vk::VkShaderStageFlags exitingStages,
3513 vk::VkShaderStageFlags activeStages,
3514 DescriptorSetCount descriptorSetCount,
3515 ShaderInputInterface shaderInterface,
3517 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages, descriptorSetCount)
3518 , m_updateMethod (updateMethod)
3519 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
3520 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
3521 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
3522 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
3523 , m_descriptorType (descriptorType)
3524 , m_descriptorSetCount (descriptorSetCount)
3525 , m_shaderInterface (shaderInterface)
3529 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
3535 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
3539 const bool isUniform = isUniformDescriptorType(m_descriptorType);
3540 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
3541 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
3543 std::ostringstream buf;
3545 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
3547 // Result buffer is bound only to the first descriptor set in compute shader cases
3548 const int descBinding = numUsedBindings - ((m_activeStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) ? (setNdx == 0 ? 0 : 1) : 0);
3549 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
3551 switch (m_shaderInterface)
3553 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3554 buf << "layout(set = " << setNdx << ", binding = " << (descBinding) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "\n"
3556 << " highp vec4 colorA;\n"
3557 << " highp vec4 colorB;\n"
3558 << "} b_instance" << setNdxPostfix << ";\n";
3561 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3562 buf << "layout(set = " << setNdx << ", binding = " << (descBinding) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "A\n"
3564 << " highp vec4 colorA;\n"
3565 << " highp vec4 colorB;\n"
3566 << "} b_instance" << setNdxPostfix << "A;\n"
3567 << "layout(set = " << setNdx << ", binding = " << (descBinding + 1) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "B\n"
3569 << " highp vec4 colorA;\n"
3570 << " highp vec4 colorB;\n"
3571 << "} b_instance" << setNdxPostfix << "B;\n";
3574 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
3575 buf << "layout(set = " << setNdx << ", binding = " << de::toString(0x7FFEu) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "A\n"
3577 << " highp vec4 colorA;\n"
3578 << " highp vec4 colorB;\n"
3579 << "} b_instance" << setNdxPostfix << "A;\n"
3580 << "layout(set = " << setNdx << ", binding = " << de::toString(0xFFFEu) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "B\n"
3582 << " highp vec4 colorA;\n"
3583 << " highp vec4 colorB;\n"
3584 << "} b_instance" << setNdxPostfix << "B;\n";
3587 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3588 buf << "layout(set = " << setNdx << ", binding = " << (descBinding) << ", std140) " << storageType << " BufferName" << setNdxPostfix << "\n"
3590 << " highp vec4 colorA;\n"
3591 << " highp vec4 colorB;\n"
3592 << "} b_instances" << setNdxPostfix << "[2];\n";
3596 DE_FATAL("Impossible");
3602 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
3606 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
3607 std::ostringstream buf;
3609 buf << " result_color = vec4(0.0);\n";
3611 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
3613 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
3615 switch (m_shaderInterface)
3617 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3618 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3619 << " result_color += b_instance" << setNdxPostfix << ".colorA;\n"
3621 << " result_color += b_instance" << setNdxPostfix << ".colorB;\n";
3624 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3625 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3626 << " result_color += b_instance" << setNdxPostfix << "A.colorA;\n"
3628 << " result_color += b_instance" << setNdxPostfix << "B.colorB;\n";
3631 case SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS:
3632 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3633 << " result_color += b_instance" << setNdxPostfix << "A.colorA;\n"
3635 << " result_color += b_instance" << setNdxPostfix << "B.colorB;\n";
3638 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3639 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3640 << " result_color += b_instances" << setNdxPostfix << "[0].colorA;\n"
3642 << " result_color += b_instances" << setNdxPostfix << "[1].colorB;\n";
3646 DE_FATAL("Impossible");
3650 if (m_descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE)
3651 buf << " result_color /= vec4(" << getDescriptorSetCount(m_descriptorSetCount) << ".0);\n";
3656 std::string BufferDescriptorCase::genNoAccessSource (void) const
3658 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
3659 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3661 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
3664 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
3666 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
3668 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
3670 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
3671 return new BufferComputeInstance(context, m_updateMethod, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
3674 return new BufferRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_descriptorSetCount, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
3677 class ImageInstanceImages
3680 ImageInstanceImages (const vk::DeviceInterface& vki,
3681 vk::VkDevice device,
3682 deUint32 queueFamilyIndex,
3684 vk::Allocator& allocator,
3685 vk::VkDescriptorType descriptorType,
3686 vk::VkImageViewType viewType,
3688 deUint32 baseMipLevel,
3689 deUint32 baseArraySlice);
3692 static std::vector<tcu::TextureLevelPyramid> createSourceImages (int numImages,
3693 vk::VkImageViewType viewType,
3694 tcu::TextureFormat imageFormat);
3696 static std::vector<ImageHandleSp> createImages (const vk::DeviceInterface& vki,
3697 vk::VkDevice device,
3698 vk::Allocator& allocator,
3699 deUint32 queueFamilyIndex,
3701 vk::VkDescriptorType descriptorType,
3702 vk::VkImageViewType viewType,
3703 std::vector<AllocationSp>& imageMemory,
3704 const std::vector<tcu::TextureLevelPyramid>& sourceImages);
3706 static std::vector<ImageViewHandleSp> createImageViews (const vk::DeviceInterface& vki,
3707 vk::VkDevice device,
3708 vk::VkImageViewType viewType,
3709 const std::vector<tcu::TextureLevelPyramid>& sourceImages,
3710 const std::vector<ImageHandleSp>& images,
3711 deUint32 baseMipLevel,
3712 deUint32 baseArraySlice);
3714 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
3715 vk::VkDevice device,
3716 vk::Allocator& allocator,
3717 vk::VkDescriptorType descriptorType,
3718 vk::VkImageViewType viewType,
3719 const tcu::TextureLevelPyramid& sourceImage,
3720 de::MovePtr<vk::Allocation>* outAllocation);
3722 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
3723 vk::VkDevice device,
3724 vk::VkImageViewType viewType,
3725 const tcu::TextureLevelPyramid& sourceImage,
3727 deUint32 baseMipLevel,
3728 deUint32 baseArraySlice);
3730 static void populateSourceImage (tcu::TextureLevelPyramid* dst,
3731 vk::VkImageViewType viewType,
3734 static void uploadImage (const vk::DeviceInterface& vki,
3735 vk::VkDevice device,
3736 deUint32 queueFamilyIndex,
3738 vk::Allocator& allocator,
3740 vk::VkImageLayout layout,
3741 vk::VkImageViewType viewType,
3742 const tcu::TextureLevelPyramid& data);
3752 const vk::VkImageViewType m_viewType;
3753 const deUint32 m_baseMipLevel;
3754 const deUint32 m_baseArraySlice;
3755 const tcu::TextureFormat m_imageFormat;
3756 const std::vector<tcu::TextureLevelPyramid> m_sourceImage;
3757 std::vector<AllocationSp> m_imageMemory;
3758 const std::vector<ImageHandleSp> m_image;
3759 const std::vector<ImageViewHandleSp> m_imageView;
3762 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
3763 vk::VkDevice device,
3764 deUint32 queueFamilyIndex,
3766 vk::Allocator& allocator,
3767 vk::VkDescriptorType descriptorType,
3768 vk::VkImageViewType viewType,
3770 deUint32 baseMipLevel,
3771 deUint32 baseArraySlice)
3772 : m_viewType (viewType)
3773 , m_baseMipLevel (baseMipLevel)
3774 , m_baseArraySlice (baseArraySlice)
3775 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
3776 , m_sourceImage (createSourceImages(numImages, viewType, m_imageFormat))
3778 , m_image (createImages(vki, device, allocator, queueFamilyIndex, queue, descriptorType, viewType, m_imageMemory, m_sourceImage))
3779 , m_imageView (createImageViews(vki, device, viewType, m_sourceImage, m_image, m_baseMipLevel, m_baseArraySlice))
3783 std::vector<tcu::TextureLevelPyramid> ImageInstanceImages::createSourceImages (int numImages,
3784 vk::VkImageViewType viewType,
3785 tcu::TextureFormat imageFormat)
3787 std::vector<tcu::TextureLevelPyramid> sourceImages(numImages, tcu::TextureLevelPyramid(imageFormat, NUM_MIP_LEVELS));
3789 for (int imageNdx = 0; imageNdx < numImages; imageNdx++)
3790 populateSourceImage(&sourceImages.at(imageNdx), viewType, imageNdx);
3792 return sourceImages;
3795 std::vector<ImageHandleSp> ImageInstanceImages::createImages (const vk::DeviceInterface& vki,
3796 vk::VkDevice device,
3797 vk::Allocator& allocator,
3798 deUint32 queueFamilyIndex,
3800 vk::VkDescriptorType descriptorType,
3801 vk::VkImageViewType viewType,
3802 std::vector<AllocationSp>& imageMemory,
3803 const std::vector<tcu::TextureLevelPyramid>& sourceImages)
3805 std::vector<ImageHandleSp> images;
3806 const vk::VkImageLayout layout = getImageLayoutForDescriptorType(descriptorType);
3808 for (int imageNdx = 0; imageNdx < (int)sourceImages.size(); imageNdx++)
3810 de::MovePtr<vk::Allocation> memory;
3811 vk::Move<vk::VkImage> image = createImage(vki, device, allocator, descriptorType, viewType, sourceImages[imageNdx], &memory);
3813 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *image, layout, viewType, sourceImages[imageNdx]);
3815 imageMemory.push_back(AllocationSp(memory.release()));
3816 images.push_back(ImageHandleSp(new ImageHandleUp(image)));
3821 std::vector<ImageViewHandleSp> ImageInstanceImages::createImageViews (const vk::DeviceInterface& vki,
3822 vk::VkDevice device,
3823 vk::VkImageViewType viewType,
3824 const std::vector<tcu::TextureLevelPyramid>& sourceImages,
3825 const std::vector<ImageHandleSp>& images,
3826 deUint32 baseMipLevel,
3827 deUint32 baseArraySlice)
3829 std::vector<ImageViewHandleSp> imageViews;
3830 for (int imageNdx = 0; imageNdx < (int)sourceImages.size(); imageNdx++)
3832 vk::Move<vk::VkImageView> imageView = createImageView(vki, device, viewType, sourceImages[imageNdx], **images[imageNdx], baseMipLevel, baseArraySlice);
3833 imageViews.push_back(ImageViewHandleSp(new ImageViewHandleUp(imageView)));
3838 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
3839 vk::VkDevice device,
3840 vk::Allocator& allocator,
3841 vk::VkDescriptorType descriptorType,
3842 vk::VkImageViewType viewType,
3843 const tcu::TextureLevelPyramid& sourceImage,
3844 de::MovePtr<vk::Allocation>* outAllocation)
3846 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3847 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
3848 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
3849 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
3850 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
3851 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
3852 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3853 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
3855 const vk::VkExtent3D extent =
3858 (deUint32)baseLevel.getWidth(),
3861 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1u) : (deUint32)baseLevel.getHeight(),
3864 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deUint32)baseLevel.getDepth()) : (1u),
3866 const vk::VkImageCreateInfo createInfo =
3868 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3870 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
3871 viewTypeToImageType(viewType), // imageType
3872 vk::mapTextureFormat(baseLevel.getFormat()), // format
3874 (deUint32)sourceImage.getNumLevels(), // mipLevels
3875 arraySize, // arraySize
3876 vk::VK_SAMPLE_COUNT_1_BIT, // samples
3877 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
3878 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
3879 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3880 0u, // queueFamilyCount
3881 DE_NULL, // pQueueFamilyIndices
3882 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
3884 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
3886 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
3890 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
3891 vk::VkDevice device,
3892 vk::VkImageViewType viewType,
3893 const tcu::TextureLevelPyramid& sourceImage,
3895 deUint32 baseMipLevel,
3896 deUint32 baseArraySlice)
3898 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3899 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
3900 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
3901 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
3902 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
3903 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
3904 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3905 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
3906 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
3909 DE_ASSERT(viewArraySize > 0);
3911 const vk::VkImageSubresourceRange resourceRange =
3913 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3914 baseMipLevel, // baseMipLevel
3915 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
3916 viewTypeBaseSlice, // baseArraySlice
3917 viewArraySize, // arraySize
3919 const vk::VkImageViewCreateInfo createInfo =
3921 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3923 (vk::VkImageViewCreateFlags)0,
3925 viewType, // viewType
3926 vk::mapTextureFormat(baseLevel.getFormat()), // format
3928 vk::VK_COMPONENT_SWIZZLE_R,
3929 vk::VK_COMPONENT_SWIZZLE_G,
3930 vk::VK_COMPONENT_SWIZZLE_B,
3931 vk::VK_COMPONENT_SWIZZLE_A
3933 resourceRange, // subresourceRange
3935 return vk::createImageView(vki, device, &createInfo);
3938 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, vk::VkImageViewType viewType, int imageNdx)
3940 const int numLevels = dst->getNumLevels();
3942 for (int level = 0; level < numLevels; ++level)
3944 const int width = IMAGE_SIZE >> level;
3945 const int height = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
3946 : (IMAGE_SIZE >> level);
3947 const int depth = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
3948 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
3949 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
3950 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
3953 dst->allocLevel(level, width, height, depth);
3956 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
3958 for (int z = 0; z < depth; ++z)
3959 for (int y = 0; y < height; ++y)
3960 for (int x = 0; x < width; ++x)
3962 const int gradPos = x + y + z;
3963 const int gradMax = width + height + depth - 3;
3965 int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
3966 int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
3967 int blue = (128 * level / numLevels) + ((imageNdx % 2 == 0) ? 127 : 0); //!< level and image index (detects incorrect lod / image)
3969 DE_ASSERT(de::inRange(red, 0, 255));
3970 DE_ASSERT(de::inRange(green, 0, 255));
3971 DE_ASSERT(de::inRange(blue, 0, 255));
3973 if (imageNdx % 3 == 0) red = 255 - red;
3974 if (imageNdx % 4 == 0) green = 255 - green;
3975 if (imageNdx % 5 == 0) blue = 255 - blue;
3977 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3983 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3984 vk::VkDevice device,
3985 deUint32 queueFamilyIndex,
3987 vk::Allocator& allocator,
3989 vk::VkImageLayout layout,
3990 vk::VkImageViewType viewType,
3991 const tcu::TextureLevelPyramid& data)
3993 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3994 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3995 ((deUint32)ARRAY_SIZE);
3996 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3997 const vk::VkBufferCreateInfo bufferCreateInfo =
3999 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
4002 dataBufferSize, // size
4003 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
4004 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
4005 0u, // queueFamilyCount
4006 DE_NULL, // pQueueFamilyIndices
4008 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
4009 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
4010 const vk::VkBufferMemoryBarrier preMemoryBarrier =
4012 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
4014 vk::VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask
4015 vk::VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
4016 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
4017 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
4018 *dataBuffer, // buffer
4020 dataBufferSize, // size
4022 const vk::VkImageSubresourceRange fullSubrange =
4024 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
4026 (deUint32)data.getNumLevels(), // mipLevels
4027 0u, // baseArraySlice
4028 arraySize, // arraySize
4030 const vk::VkImageMemoryBarrier preImageBarrier =
4032 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
4034 0u, // srcAccessMask
4035 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // dstAccessMask
4036 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
4037 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout
4038 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
4039 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
4041 fullSubrange // subresourceRange
4043 const vk::VkImageMemoryBarrier postImageBarrier =
4045 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
4047 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
4048 vk::VK_ACCESS_SHADER_READ_BIT, // dstAccessMask
4049 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout
4050 layout, // newLayout
4051 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
4052 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
4054 fullSubrange // subresourceRange
4056 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
4058 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
4060 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
4061 queueFamilyIndex, // queueFamilyIndex
4063 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
4064 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
4066 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
4068 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
4069 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
4072 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(vki, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
4073 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device));
4074 const deUint64 infiniteTimeout = ~(deUint64)0u;
4075 std::vector<vk::VkBufferImageCopy> copySlices;
4077 // copy data to buffer
4078 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, viewType , ©Slices);
4079 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
4081 // record command buffer
4082 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
4083 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_HOST_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
4084 0, (const vk::VkMemoryBarrier*)DE_NULL,
4085 1, &preMemoryBarrier,
4086 1, &preImageBarrier);
4087 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
4088 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (vk::VkDependencyFlags)0,
4089 0, (const vk::VkMemoryBarrier*)DE_NULL,
4090 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
4091 1, &postImageBarrier);
4092 VK_CHECK(vki.endCommandBuffer(*cmd));
4094 // submit and wait for command buffer to complete before killing it
4096 const vk::VkSubmitInfo submitInfo =
4098 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
4101 (const vk::VkSemaphore*)0,
4102 (const vk::VkPipelineStageFlags*)DE_NULL,
4106 (const vk::VkSemaphore*)0,
4108 VK_CHECK(vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
4110 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
4113 class ImageFetchInstanceImages : private ImageInstanceImages
4116 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
4117 vk::VkDevice device,
4118 deUint32 queueFamilyIndex,
4120 vk::Allocator& allocator,
4121 vk::VkDescriptorType descriptorType,
4122 DescriptorSetCount descriptorSetCount,
4123 ShaderInputInterface shaderInterface,
4124 vk::VkImageViewType viewType,
4125 deUint32 baseMipLevel,
4126 deUint32 baseArraySlice);
4128 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType,
4129 deUint32 baseMipLevel,
4130 deUint32 baseArraySlice,
4133 tcu::Vec4 fetchImageValue (int fetchPosNdx, int setNdx) const;
4135 inline tcu::TextureLevelPyramid getSourceImage (int ndx) const { return m_sourceImage[ndx]; }
4136 inline vk::VkImageView getImageView (int ndx) const { return **m_imageView[ndx % m_imageView.size()]; }
4141 // some arbitrary sample points for all four quadrants
4142 SAMPLE_POINT_0_X = 6,
4143 SAMPLE_POINT_0_Y = 13,
4144 SAMPLE_POINT_0_Z = 49,
4146 SAMPLE_POINT_1_X = 51,
4147 SAMPLE_POINT_1_Y = 40,
4148 SAMPLE_POINT_1_Z = 44,
4150 SAMPLE_POINT_2_X = 42,
4151 SAMPLE_POINT_2_Y = 26,
4152 SAMPLE_POINT_2_Z = 19,
4154 SAMPLE_POINT_3_X = 25,
4155 SAMPLE_POINT_3_Y = 25,
4156 SAMPLE_POINT_3_Z = 18,
4159 const ShaderInputInterface m_shaderInterface;
4162 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
4163 vk::VkDevice device,
4164 deUint32 queueFamilyIndex,
4166 vk::Allocator& allocator,
4167 vk::VkDescriptorType descriptorType,
4168 DescriptorSetCount descriptorSetCount,
4169 ShaderInputInterface shaderInterface,
4170 vk::VkImageViewType viewType,
4171 deUint32 baseMipLevel,
4172 deUint32 baseArraySlice)
4173 : ImageInstanceImages (vki,
4180 getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface), // numImages
4183 , m_shaderInterface (shaderInterface)
4187 bool isImageViewTypeArray (vk::VkImageViewType type)
4189 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;
4192 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
4194 const tcu::IVec3 fetchPositions[4] =
4196 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
4197 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
4198 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
4199 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
4201 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
4202 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
4203 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
4207 case vk::VK_IMAGE_VIEW_TYPE_1D:
4208 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
4209 case vk::VK_IMAGE_VIEW_TYPE_2D:
4210 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
4211 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4212 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
4213 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
4215 DE_FATAL("Impossible");
4216 return tcu::IVec3();
4220 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx, int setNdx) const
4222 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
4224 const tcu::TextureLevelPyramid& fetchSrcA = getSourceImage(setNdx * getInterfaceNumResources(m_shaderInterface));
4225 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? fetchSrcA : getSourceImage(setNdx * getInterfaceNumResources(m_shaderInterface) + 1);
4226 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
4227 tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
4229 // add base array layer into the appropriate coordinate, based on the view type
4230 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
4231 fetchPos.z() += 6 * m_baseArraySlice;
4232 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
4233 fetchPos.y() += m_baseArraySlice;
4235 fetchPos.z() += m_baseArraySlice;
4237 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
4240 class ImageFetchRenderInstance : public SingleCmdRenderInstance
4243 ImageFetchRenderInstance (vkt::Context& context,
4244 DescriptorUpdateMethod updateMethod,
4245 bool isPrimaryCmdBuf,
4246 vk::VkDescriptorType descriptorType,
4247 DescriptorSetCount descriptorSetCount,
4248 vk::VkShaderStageFlags stageFlags,
4249 ShaderInputInterface shaderInterface,
4250 vk::VkImageViewType viewType,
4251 deUint32 baseMipLevel,
4252 deUint32 baseArraySlice);
4255 static std::vector<DescriptorSetLayoutHandleSp> createDescriptorSetLayouts (const vk::DeviceInterface& vki,
4256 vk::VkDevice device,
4257 vk::VkDescriptorType descriptorType,
4258 DescriptorSetCount descriptorSetCount,
4259 ShaderInputInterface shaderInterface,
4260 vk::VkShaderStageFlags stageFlags,
4261 DescriptorUpdateMethod updateMethod);
4263 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4264 vk::VkDevice device,
4265 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout);
4267 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4268 vk::VkDevice device,
4269 vk::VkDescriptorType descriptorType,
4270 DescriptorSetCount descriptorSetCount,
4271 ShaderInputInterface shaderInterface);
4273 static std::vector<DescriptorSetHandleSp> createDescriptorSets (const vk::DeviceInterface& vki,
4274 DescriptorUpdateMethod updateMethod,
4275 vk::VkDevice device,
4276 vk::VkDescriptorType descriptorType,
4277 ShaderInputInterface shaderInterface,
4278 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
4279 vk::VkDescriptorPool pool,
4280 const ImageFetchInstanceImages& images,
4281 vk::DescriptorSetUpdateBuilder& updateBuilder,
4282 std::vector<UpdateTemplateHandleSp>& updateTemplates,
4283 std::vector<RawUpdateRegistry>& updateRegistry,
4284 std::vector<deUint32>& descriptorsPerSet,
4285 vk::VkPipelineLayout pipelineLayout = DE_NULL);
4287 static void writeDescriptorSet (const vk::DeviceInterface& vki,
4288 vk::VkDevice device,
4289 vk::VkDescriptorType descriptorType,
4290 ShaderInputInterface shaderInterface,
4291 vk::VkDescriptorSetLayout layout,
4292 vk::VkDescriptorPool pool,
4293 vk::VkImageView viewA,
4294 vk::VkImageView viewB,
4295 vk::VkDescriptorSet descriptorSet,
4296 vk::DescriptorSetUpdateBuilder& updateBuilder,
4297 std::vector<deUint32>& descriptorsPerSet,
4298 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
4300 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
4301 vk::VkDevice device,
4302 vk::VkDescriptorType descriptorType,
4303 ShaderInputInterface shaderInterface,
4304 vk::VkDescriptorSetLayout layout,
4305 vk::VkDescriptorPool pool,
4306 vk::VkImageView viewA,
4307 vk::VkImageView viewB,
4308 vk::VkDescriptorSet descriptorSet,
4309 std::vector<UpdateTemplateHandleSp>& updateTemplates,
4310 std::vector<RawUpdateRegistry>& registry,
4311 bool withPush = false,
4312 vk::VkPipelineLayout pipelineLayout = 0);
4314 void logTestPlan (void) const;
4315 vk::VkPipelineLayout getPipelineLayout (void) const;
4316 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
4317 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4324 const DescriptorUpdateMethod m_updateMethod;
4325 const vk::VkDescriptorType m_descriptorType;
4326 const DescriptorSetCount m_descriptorSetCount;
4327 const vk::VkShaderStageFlags m_stageFlags;
4328 const ShaderInputInterface m_shaderInterface;
4329 const vk::VkImageViewType m_viewType;
4330 const deUint32 m_baseMipLevel;
4331 const deUint32 m_baseArraySlice;
4333 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
4334 std::vector<RawUpdateRegistry> m_updateRegistry;
4335 vk::DescriptorSetUpdateBuilder m_updateBuilder;
4336 const std::vector<DescriptorSetLayoutHandleSp> m_descriptorSetLayouts;
4337 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4338 const ImageFetchInstanceImages m_images;
4339 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4340 std::vector<deUint32> m_descriptorsPerSet;
4341 const std::vector<DescriptorSetHandleSp> m_descriptorSets;
4344 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
4345 DescriptorUpdateMethod updateMethod,
4346 bool isPrimaryCmdBuf,
4347 vk::VkDescriptorType descriptorType,
4348 DescriptorSetCount descriptorSetCount,
4349 vk::VkShaderStageFlags stageFlags,
4350 ShaderInputInterface shaderInterface,
4351 vk::VkImageViewType viewType,
4352 deUint32 baseMipLevel,
4353 deUint32 baseArraySlice)
4354 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4355 , m_updateMethod (updateMethod)
4356 , m_descriptorType (descriptorType)
4357 , m_descriptorSetCount (descriptorSetCount)
4358 , m_stageFlags (stageFlags)
4359 , m_shaderInterface (shaderInterface)
4360 , m_viewType (viewType)
4361 , m_baseMipLevel (baseMipLevel)
4362 , m_baseArraySlice (baseArraySlice)
4363 , m_updateTemplates ()
4364 , m_updateRegistry ()
4365 , m_updateBuilder ()
4366 , m_descriptorSetLayouts (createDescriptorSetLayouts(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_stageFlags, m_updateMethod))
4367 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, m_descriptorSetLayouts))
4368 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
4369 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface))
4370 , m_descriptorsPerSet ()
4371 , m_descriptorSets (createDescriptorSets(m_vki, m_updateMethod, m_device, m_descriptorType, m_shaderInterface, m_descriptorSetLayouts, *m_descriptorPool, m_images, m_updateBuilder, m_updateTemplates, m_updateRegistry, m_descriptorsPerSet, *m_pipelineLayout))
4375 std::vector<DescriptorSetLayoutHandleSp> ImageFetchRenderInstance::createDescriptorSetLayouts (const vk::DeviceInterface& vki,
4376 vk::VkDevice device,
4377 vk::VkDescriptorType descriptorType,
4378 DescriptorSetCount descriptorSetCount,
4379 ShaderInputInterface shaderInterface,
4380 vk::VkShaderStageFlags stageFlags,
4381 DescriptorUpdateMethod updateMethod)
4383 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
4384 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
4386 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
4387 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4389 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
4392 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
4394 vk::DescriptorSetLayoutBuilder builder;
4396 switch (shaderInterface)
4398 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4399 builder.addSingleBinding(descriptorType, stageFlags);
4402 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4403 builder.addSingleBinding(descriptorType, stageFlags);
4404 builder.addSingleBinding(descriptorType, stageFlags);
4407 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4408 builder.addArrayBinding(descriptorType, 2u, stageFlags);
4412 DE_FATAL("Impossible");
4415 vk::Move<vk::VkDescriptorSetLayout> layout = builder.build(vki, device, extraFlags);
4416 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
4418 return descriptorSetLayouts;
4421 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4422 vk::VkDevice device,
4423 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout)
4425 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
4426 for (size_t setNdx = 0; setNdx < descriptorSetLayout.size(); setNdx++)
4427 layoutHandles.push_back(**descriptorSetLayout[setNdx]);
4429 const vk::VkPipelineLayoutCreateInfo createInfo =
4431 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4433 (vk::VkPipelineLayoutCreateFlags)0,
4434 (deUint32)layoutHandles.size(), // descriptorSetCount
4435 &layoutHandles.front(), // pSetLayouts
4436 0u, // pushConstantRangeCount
4437 DE_NULL, // pPushConstantRanges
4439 return vk::createPipelineLayout(vki, device, &createInfo);
4442 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4443 vk::VkDevice device,
4444 vk::VkDescriptorType descriptorType,
4445 DescriptorSetCount descriptorSetCount,
4446 ShaderInputInterface shaderInterface)
4448 return vk::DescriptorPoolBuilder()
4449 .addType(descriptorType, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface))
4450 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(descriptorSetCount));
4453 std::vector<DescriptorSetHandleSp> ImageFetchRenderInstance::createDescriptorSets (const vk::DeviceInterface& vki,
4454 DescriptorUpdateMethod updateMethod,
4455 vk::VkDevice device,
4456 vk::VkDescriptorType descriptorType,
4457 ShaderInputInterface shaderInterface,
4458 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
4459 vk::VkDescriptorPool pool,
4460 const ImageFetchInstanceImages& images,
4461 vk::DescriptorSetUpdateBuilder& updateBuilder,
4462 std::vector<UpdateTemplateHandleSp>& updateTemplates,
4463 std::vector<RawUpdateRegistry>& updateRegistry,
4464 std::vector<deUint32>& descriptorsPerSet,
4465 vk::VkPipelineLayout pipelineLayout)
4467 std::vector<DescriptorSetHandleSp> descriptorSets;
4469 for (deUint32 setNdx = 0; setNdx < (deUint32)descriptorSetLayouts.size(); setNdx++)
4471 vk::VkDescriptorSetLayout layout = **descriptorSetLayouts[setNdx];
4473 const vk::VkDescriptorSetAllocateInfo allocInfo =
4475 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4482 vk::VkImageView viewA = images.getImageView(setNdx * getInterfaceNumResources(shaderInterface));
4483 vk::VkImageView viewB = images.getImageView(setNdx * getInterfaceNumResources(shaderInterface) + 1);
4485 vk::Move<vk::VkDescriptorSet> descriptorSet;
4486 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4488 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4492 descriptorSet = vk::Move<vk::VkDescriptorSet>();
4495 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
4497 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplates, updateRegistry);
4499 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4501 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplates, updateRegistry, true, pipelineLayout);
4503 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4505 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, descriptorsPerSet, updateMethod);
4507 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4509 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, descriptorsPerSet);
4512 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(descriptorSet)));
4514 return descriptorSets;
4517 void ImageFetchRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
4518 vk::VkDevice device,
4519 vk::VkDescriptorType descriptorType,
4520 ShaderInputInterface shaderInterface,
4521 vk::VkDescriptorSetLayout layout,
4522 vk::VkDescriptorPool pool,
4523 vk::VkImageView viewA,
4524 vk::VkImageView viewB,
4525 vk::VkDescriptorSet descriptorSet,
4526 vk::DescriptorSetUpdateBuilder& updateBuilder,
4527 std::vector<deUint32>& descriptorsPerSet,
4528 DescriptorUpdateMethod updateMethod)
4532 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
4533 const vk::VkDescriptorImageInfo imageInfos[2] =
4535 makeDescriptorImageInfo(viewA, imageLayout),
4536 makeDescriptorImageInfo(viewB, imageLayout),
4538 deUint32 numBindings = 0u;
4540 switch (shaderInterface)
4542 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4543 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4547 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4548 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4549 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
4553 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4554 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
4559 DE_FATAL("Impossible");
4562 descriptorsPerSet.push_back(numBindings);
4564 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4566 updateBuilder.update(vki, device);
4567 updateBuilder.clear();
4571 void ImageFetchRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
4572 vk::VkDevice device,
4573 vk::VkDescriptorType descriptorType,
4574 ShaderInputInterface shaderInterface,
4575 vk::VkDescriptorSetLayout layout,
4576 vk::VkDescriptorPool pool,
4577 vk::VkImageView viewA,
4578 vk::VkImageView viewB,
4579 vk::VkDescriptorSet descriptorSet,
4580 std::vector<UpdateTemplateHandleSp>& updateTemplates,
4581 std::vector<RawUpdateRegistry>& registry,
4583 vk::VkPipelineLayout pipelineLayout)
4586 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
4587 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
4589 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
4593 DE_NULL, // pUpdates
4594 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
4596 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
4600 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
4601 const vk::VkDescriptorImageInfo imageInfos[2] =
4603 makeDescriptorImageInfo(viewA, imageLayout),
4604 makeDescriptorImageInfo(viewB, imageLayout),
4607 RawUpdateRegistry updateRegistry;
4609 updateRegistry.addWriteObject(imageInfos[0]);
4610 updateRegistry.addWriteObject(imageInfos[1]);
4612 switch (shaderInterface)
4614 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4615 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4618 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4619 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4620 updateEntries.push_back(createTemplateBinding(1, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
4623 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4624 updateEntries.push_back(createTemplateBinding(0, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(imageInfos[0])));
4628 DE_FATAL("Impossible");
4631 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
4632 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
4634 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
4635 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
4636 registry.push_back(updateRegistry);
4640 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
4644 void ImageFetchRenderInstance::logTestPlan (void) const
4646 std::ostringstream msg;
4648 msg << "Rendering 2x2 grid.\n"
4649 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
4650 << "Each descriptor set contains "
4651 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4652 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4653 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4654 (const char*)DE_NULL)
4655 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
4656 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4659 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4660 if (m_baseArraySlice)
4661 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4663 if (m_stageFlags == 0u)
4665 msg << "Descriptors are not accessed in any shader stage.\n";
4669 msg << "Color in each cell is fetched using the descriptor(s):\n";
4671 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4673 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4675 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4677 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4678 msg << " from descriptor " << srcResourceNdx;
4684 msg << "Descriptors are accessed in {"
4685 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4686 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4687 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4688 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4689 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4693 m_context.getTestContext().getLog()
4694 << tcu::TestLog::Message
4696 << tcu::TestLog::EndMessage;
4699 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
4701 return *m_pipelineLayout;
4704 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4706 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4708 std::vector<vk::VkDescriptorSet> sets;
4709 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
4710 sets.push_back(**m_descriptorSets[setNdx]);
4712 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, (int)sets.size(), &sets.front(), 0, DE_NULL);
4714 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4716 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
4717 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, **m_updateTemplates[setNdx], getPipelineLayout(), setNdx, (const void*)m_updateRegistry[setNdx].getRawPointer());
4719 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4721 deUint32 descriptorNdx = 0u;
4722 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
4724 const deUint32 numDescriptors = m_descriptorsPerSet[setNdx];
4725 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, setNdx, descriptorNdx, numDescriptors);
4726 descriptorNdx += numDescriptors;
4730 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
4733 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4735 const deUint32 numDescriptorSets = getDescriptorSetCount(m_descriptorSetCount);
4736 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4737 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4738 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4740 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4742 tcu::Vec4 sample0 = tcu::Vec4(0.0f);
4743 tcu::Vec4 sample1 = tcu::Vec4(0.0f);
4744 tcu::Vec4 sample2 = tcu::Vec4(0.0f);
4745 tcu::Vec4 sample3 = tcu::Vec4(0.0f);
4747 for (deUint32 setNdx = 0; setNdx < numDescriptorSets; setNdx++)
4749 sample0 += (!doFetch) ? (yellow) : (m_images.fetchImageValue(0, setNdx));
4750 sample1 += (!doFetch) ? (green) : (m_images.fetchImageValue(1, setNdx));
4751 sample2 += (!doFetch) ? (green) : (m_images.fetchImageValue(2, setNdx));
4752 sample3 += (!doFetch) ? (yellow) : (m_images.fetchImageValue(3, setNdx));
4755 if (numDescriptorSets > 1)
4757 sample0 = sample0 / tcu::Vec4(float(numDescriptorSets));
4758 sample1 = sample1 / tcu::Vec4(float(numDescriptorSets));
4759 sample2 = sample2 / tcu::Vec4(float(numDescriptorSets));
4760 sample3 = sample3 / tcu::Vec4(float(numDescriptorSets));
4763 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4765 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
4766 return tcu::TestStatus::fail("Image verification failed");
4768 return tcu::TestStatus::pass("Pass");
4771 class ImageFetchComputeInstance : public vkt::TestInstance
4774 ImageFetchComputeInstance (vkt::Context& context,
4775 DescriptorUpdateMethod updateMethod,
4776 vk::VkDescriptorType descriptorType,
4777 DescriptorSetCount descriptorSetCount,
4778 ShaderInputInterface shaderInterface,
4779 vk::VkImageViewType viewType,
4780 deUint32 baseMipLevel,
4781 deUint32 baseArraySlice);
4784 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (deUint32 setNdx) const;
4785 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4786 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx);
4787 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx);
4788 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
4791 tcu::TestStatus iterate (void);
4792 void logTestPlan (void) const;
4793 tcu::TestStatus testResourceAccess (void);
4795 const DescriptorUpdateMethod m_updateMethod;
4796 const vk::VkDescriptorType m_descriptorType;
4797 const DescriptorSetCount m_descriptorSetCount;
4798 const ShaderInputInterface m_shaderInterface;
4799 const vk::VkImageViewType m_viewType;
4800 const deUint32 m_baseMipLevel;
4801 const deUint32 m_baseArraySlice;
4802 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
4803 const vk::DeviceInterface& m_vki;
4804 const vk::VkDevice m_device;
4805 const vk::VkQueue m_queue;
4806 const deUint32 m_queueFamilyIndex;
4807 vk::Allocator& m_allocator;
4808 const ComputeInstanceResultBuffer m_result;
4809 const ImageFetchInstanceImages m_images;
4810 std::vector<RawUpdateRegistry> m_updateRegistry;
4811 vk::DescriptorSetUpdateBuilder m_updateBuilder;
4812 std::vector<deUint32> m_descriptorsPerSet;
4815 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
4816 DescriptorUpdateMethod updateMethod,
4817 vk::VkDescriptorType descriptorType,
4818 DescriptorSetCount descriptorSetCount,
4819 ShaderInputInterface shaderInterface,
4820 vk::VkImageViewType viewType,
4821 deUint32 baseMipLevel,
4822 deUint32 baseArraySlice)
4823 : vkt::TestInstance (context)
4824 , m_updateMethod (updateMethod)
4825 , m_descriptorType (descriptorType)
4826 , m_descriptorSetCount (descriptorSetCount)
4827 , m_shaderInterface (shaderInterface)
4828 , m_viewType (viewType)
4829 , m_baseMipLevel (baseMipLevel)
4830 , m_baseArraySlice (baseArraySlice)
4831 , m_updateTemplates ()
4832 , m_vki (context.getDeviceInterface())
4833 , m_device (context.getDevice())
4834 , m_queue (context.getUniversalQueue())
4835 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4836 , m_allocator (context.getDefaultAllocator())
4837 , m_result (m_vki, m_device, m_allocator)
4838 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
4839 , m_updateRegistry ()
4840 , m_updateBuilder ()
4841 , m_descriptorsPerSet ()
4845 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (deUint32 setNdx) const
4847 vk::DescriptorSetLayoutBuilder builder;
4848 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
4850 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
4851 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4853 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
4857 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4859 switch (m_shaderInterface)
4861 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4862 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4865 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4866 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4867 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4870 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4871 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4875 DE_FATAL("Impossible");
4878 return builder.build(m_vki, m_device, extraFlags);
4881 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
4883 return vk::DescriptorPoolBuilder()
4884 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
4885 .addType(m_descriptorType, getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface))
4886 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(m_descriptorSetCount));
4889 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx)
4891 const vk::VkDescriptorSetAllocateInfo allocInfo =
4893 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4900 vk::Move<vk::VkDescriptorSet> descriptorSet;
4901 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4903 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4907 descriptorSet = vk::Move<vk::VkDescriptorSet>();
4910 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
4912 writeDescriptorSetWithTemplate(*descriptorSet, layout, setNdx);
4914 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4916 writeDescriptorSet(*descriptorSet, setNdx);
4919 return descriptorSet;
4922 void ImageFetchComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx)
4924 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4925 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
4926 const vk::VkDescriptorImageInfo imageInfos[2] =
4928 makeDescriptorImageInfo(m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface)), imageLayout),
4929 makeDescriptorImageInfo(m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1), imageLayout),
4932 deUint32 binding = 0u;
4936 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]);
4945 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4946 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &imageInfos[0]);
4947 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &imageInfos[1]);
4950 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4951 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, 2u, imageInfos);
4955 DE_FATAL("Impossible");
4958 m_descriptorsPerSet.push_back(binding);
4960 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4962 m_updateBuilder.update(m_vki, m_device);
4963 m_updateBuilder.clear();
4967 void ImageFetchComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush, vk::VkPipelineLayout pipelineLayout)
4969 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4970 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
4971 const vk::VkDescriptorImageInfo imageInfos[2] =
4973 makeDescriptorImageInfo(m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface)), imageLayout),
4974 makeDescriptorImageInfo(m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1), imageLayout),
4976 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
4977 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
4979 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
4983 DE_NULL, // pUpdates
4984 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
4986 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
4991 deUint32 binding = 0u;
4992 deUint32 offset = 0u;
4993 RawUpdateRegistry updateRegistry;
4996 updateRegistry.addWriteObject(resultInfo);
4998 updateRegistry.addWriteObject(imageInfos[0]);
4999 updateRegistry.addWriteObject(imageInfos[1]);
5003 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
5006 switch (m_shaderInterface)
5008 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5009 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5012 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5013 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5014 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
5017 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5018 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), sizeof(imageInfos[0])));
5022 DE_FATAL("Impossible");
5025 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
5026 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
5028 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
5029 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
5030 m_updateRegistry.push_back(updateRegistry);
5034 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, **m_updateTemplates.back(), m_updateRegistry.back().getRawPointer());
5038 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
5041 return testResourceAccess();
5044 void ImageFetchComputeInstance::logTestPlan (void) const
5046 std::ostringstream msg;
5048 msg << "Fetching 4 values from image in compute shader.\n"
5049 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
5050 << "Each descriptor set contains "
5051 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5052 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5053 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5054 (const char*)DE_NULL)
5055 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5056 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
5059 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
5060 if (m_baseArraySlice)
5061 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
5063 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5065 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
5067 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5069 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5070 msg << " from descriptor " << srcResourceNdx;
5076 m_context.getTestContext().getLog()
5077 << tcu::TestLog::Message
5079 << tcu::TestLog::EndMessage;
5082 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
5084 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5085 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
5086 std::vector<DescriptorSetHandleSp> descriptorSets;
5087 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
5088 std::vector<vk::VkDescriptorSet> setHandles;
5090 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
5092 vk::Move<vk::VkDescriptorSetLayout> layout = createDescriptorSetLayout(setNdx);
5093 vk::Move<vk::VkDescriptorSet> set = createDescriptorSet(*descriptorPool, *layout, setNdx);
5095 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
5096 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(set)));
5098 layoutHandles.push_back(**descriptorSetLayouts.back());
5099 setHandles.push_back(**descriptorSets.back());
5102 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), (int)layoutHandles.size(), &layoutHandles.front());
5103 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : getDescriptorSetCount(m_descriptorSetCount);
5104 const deUint32* const dynamicOffsets = DE_NULL;
5105 const int numDynamicOffsets = 0;
5106 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
5107 const int numPreBarriers = 0;
5108 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
5109 const int numPostBarriers = 1;
5111 const ComputeCommand compute (m_vki,
5113 pipeline.getPipeline(),
5114 pipeline.getPipelineLayout(),
5115 tcu::UVec3(4, 1, 1),
5116 numDescriptorSets, &setHandles.front(),
5117 numDynamicOffsets, dynamicOffsets,
5118 numPreBarriers, preBarriers,
5119 numPostBarriers, postBarriers);
5121 tcu::Vec4 results[4];
5122 bool anyResultSet = false;
5123 bool allResultsOk = true;
5125 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5127 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
5128 writeDescriptorSetWithTemplate(DE_NULL, layoutHandles[setNdx], setNdx, true, pipeline.getPipelineLayout());
5130 compute.submitAndWait(m_queueFamilyIndex, m_queue, &m_updateTemplates, &m_updateRegistry);
5132 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5134 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
5135 writeDescriptorSet(DE_NULL, setNdx);
5137 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder, m_descriptorsPerSet);
5141 compute.submitAndWait(m_queueFamilyIndex, m_queue);
5143 m_result.readResultContentsTo(&results);
5146 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5148 const tcu::Vec4 result = results[resultNdx];
5150 tcu::Vec4 reference = tcu::Vec4(0.0f);
5151 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
5152 reference += m_images.fetchImageValue(resultNdx, setNdx);
5154 if (m_descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE)
5155 reference = reference / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
5157 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
5159 if (result != tcu::Vec4(-1.0f))
5160 anyResultSet = true;
5162 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
5164 allResultsOk = false;
5166 m_context.getTestContext().getLog()
5167 << tcu::TestLog::Message
5168 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
5169 << tcu::TestLog::EndMessage;
5173 // read back and verify
5175 return tcu::TestStatus::pass("Pass");
5176 else if (anyResultSet)
5177 return tcu::TestStatus::fail("Invalid result values");
5180 m_context.getTestContext().getLog()
5181 << tcu::TestLog::Message
5182 << "Result buffer was not written to."
5183 << tcu::TestLog::EndMessage;
5184 return tcu::TestStatus::fail("Result buffer was not written to");
5188 class ImageSampleInstanceImages : private ImageInstanceImages
5191 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
5192 vk::VkDevice device,
5193 deUint32 queueFamilyIndex,
5195 vk::Allocator& allocator,
5196 vk::VkDescriptorType descriptorType,
5197 DescriptorSetCount descriptorSetCount,
5198 ShaderInputInterface shaderInterface,
5199 vk::VkImageViewType viewType,
5200 deUint32 baseMipLevel,
5201 deUint32 baseArraySlice,
5204 static std::vector<tcu::Sampler> getRefSamplers (DescriptorSetCount descriptorSetCount,
5205 ShaderInputInterface shaderInterface);
5207 static std::vector<SamplerHandleSp> getSamplers (const vk::DeviceInterface& vki,
5208 vk::VkDevice device,
5209 std::vector<tcu::Sampler>& refSamplers,
5210 const tcu::TextureFormat imageFormat);
5212 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
5213 tcu::Vec4 fetchSampleValue (int samplePosNdx, int setNdx) const;
5215 inline tcu::TextureLevelPyramid getSourceImage (int ndx) const { return m_sourceImage[ndx % m_sourceImage.size()]; }
5216 inline vk::VkImageView getImageView (int ndx) const { return **m_imageView[ndx % m_imageView.size()]; }
5217 inline tcu::Sampler getRefSampler (int ndx) const { return m_refSampler[ndx % m_refSampler.size()]; }
5218 inline vk::VkSampler getSampler (int ndx) const { return **m_sampler[ndx % m_sampler.size()]; }
5219 inline bool isImmutable (void) const { return m_isImmutable; }
5222 static int getNumImages (vk::VkDescriptorType descriptorType, DescriptorSetCount descriptorSetCount, ShaderInputInterface shaderInterface);
5223 static tcu::Sampler createRefSampler (int ndx);
5224 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
5226 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
5227 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
5228 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
5229 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
5231 const vk::VkDescriptorType m_descriptorType;
5232 const ShaderInputInterface m_shaderInterface;
5233 const bool m_isImmutable;
5235 std::vector<tcu::Sampler> m_refSampler;
5236 std::vector<SamplerHandleSp> m_sampler;
5239 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
5240 vk::VkDevice device,
5241 deUint32 queueFamilyIndex,
5243 vk::Allocator& allocator,
5244 vk::VkDescriptorType descriptorType,
5245 DescriptorSetCount descriptorSetCount,
5246 ShaderInputInterface shaderInterface,
5247 vk::VkImageViewType viewType,
5248 deUint32 baseMipLevel,
5249 deUint32 baseArraySlice,
5251 : ImageInstanceImages (vki,
5258 getNumImages(descriptorType, descriptorSetCount, shaderInterface),
5261 , m_descriptorType (descriptorType)
5262 , m_shaderInterface (shaderInterface)
5263 , m_isImmutable (immutable)
5264 , m_refSampler (getRefSamplers(descriptorSetCount, shaderInterface))
5265 , m_sampler (getSamplers(vki, device, m_refSampler, m_imageFormat))
5269 std::vector<tcu::Sampler> ImageSampleInstanceImages::getRefSamplers (DescriptorSetCount descriptorSetCount,
5270 ShaderInputInterface shaderInterface)
5272 std::vector<tcu::Sampler> refSamplers;
5273 for (deUint32 samplerNdx = 0; samplerNdx < getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface); samplerNdx++)
5274 refSamplers.push_back(createRefSampler(samplerNdx));
5279 std::vector<SamplerHandleSp> ImageSampleInstanceImages::getSamplers (const vk::DeviceInterface& vki,
5280 vk::VkDevice device,
5281 std::vector<tcu::Sampler>& refSamplers,
5282 const tcu::TextureFormat imageFormat)
5284 std::vector<SamplerHandleSp> samplers;
5285 for (deUint32 samplerNdx = 0; samplerNdx < (deUint32)refSamplers.size(); samplerNdx++)
5287 vk::Move<vk::VkSampler> sampler = createSampler(vki, device, refSamplers[samplerNdx], imageFormat);
5288 samplers.push_back(SamplerHandleSp(new SamplerHandleUp(sampler)));
5293 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
5295 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
5297 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
5298 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
5300 // choose arbitrary values that are not ambiguous with NEAREST filtering
5304 case vk::VK_IMAGE_VIEW_TYPE_1D:
5305 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
5306 case vk::VK_IMAGE_VIEW_TYPE_2D:
5307 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
5308 case vk::VK_IMAGE_VIEW_TYPE_3D:
5310 const tcu::Vec3 coords[4] =
5314 (float)(12u % imageSize) + 0.25f),
5316 tcu::Vec3((float)(23u % imageSize) + 0.25f,
5317 (float)(73u % imageSize) + 0.5f,
5318 (float)(16u % imageSize) + 0.5f + (float)imageSize),
5320 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
5321 (float)(84u % imageSize) + 0.5f + (float)imageSize,
5322 (float)(117u % imageSize) + 0.75f),
5324 tcu::Vec3((float)imageSize + 0.5f,
5325 (float)(75u % imageSize) + 0.25f,
5326 (float)(83u % imageSize) + 0.25f + (float)imageSize),
5328 const deUint32 slices[4] =
5336 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
5337 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
5338 (float)slices[samplePosNdx],
5341 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
5342 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
5343 coords[samplePosNdx].y() / (float)imageSize,
5344 (float)slices[samplePosNdx],
5346 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
5347 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
5348 coords[samplePosNdx].y() / (float)imageSize,
5349 coords[samplePosNdx].z() / (float)imageSize,
5353 DE_FATAL("Impossible");
5358 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
5359 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
5361 // \note these values are in [0, texSize]*3 space for convenience
5362 const tcu::Vec3 coords[4] =
5368 tcu::Vec3((float)(13u % imageSize) + 0.25f,
5370 (float)(16u % imageSize) + 0.5f),
5373 (float)(84u % imageSize) + 0.5f,
5374 (float)(10u % imageSize) + 0.75f),
5376 tcu::Vec3((float)imageSize,
5377 (float)(75u % imageSize) + 0.25f,
5378 (float)(83u % imageSize) + 0.75f),
5380 const deUint32 slices[4] =
5388 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
5389 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
5390 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
5392 // map to [-1, 1]*3 space
5393 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
5394 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
5395 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
5396 (float)slices[samplePosNdx]);
5400 DE_FATAL("Impossible");
5405 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx, int setNdx) const
5407 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
5409 // texture order is ABAB
5410 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
5411 const deUint32 numImages = (isSamplerCase) ? 1 : getInterfaceNumResources(m_shaderInterface);
5412 const tcu::TextureLevelPyramid& sampleSrcA = getSourceImage(setNdx * numImages);
5413 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? sampleSrcA : getSourceImage(setNdx * numImages + 1);
5414 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
5416 // sampler order is ABAB
5417 const tcu::Sampler& samplerA = getRefSampler(setNdx * getInterfaceNumResources(m_shaderInterface));
5418 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (samplerA) : getRefSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1);
5419 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
5421 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5422 const float lod = 0.0f;
5423 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
5427 case vk::VK_IMAGE_VIEW_TYPE_1D:
5428 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
5429 case vk::VK_IMAGE_VIEW_TYPE_2D:
5430 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);
5431 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
5432 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
5433 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);
5437 DE_FATAL("Impossible");
5443 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, DescriptorSetCount descriptorSetCount, ShaderInputInterface shaderInterface)
5445 // If we are testing separate samplers, just one image is enough
5446 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5447 return getDescriptorSetCount(descriptorSetCount);
5448 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5450 // combined: numImages == numSamplers
5451 return getInterfaceNumResources(shaderInterface) * getDescriptorSetCount(descriptorSetCount);
5455 DE_FATAL("Impossible");
5460 tcu::Sampler ImageSampleInstanceImages::createRefSampler (int ndx)
5465 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
5469 // nearest, clamping
5470 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
5474 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
5476 const vk::VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, format);
5478 return vk::createSampler(vki, device, &createInfo);
5481 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5483 DE_ASSERT(levelStorage->empty());
5485 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
5486 const deUint32 numLevels = (deUint32)source.getNumLevels();
5488 // cut pyramid from baseMipLevel
5489 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5491 // cut levels from baseArraySlice
5492 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
5493 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
5494 levelStorage->push_back(cutLevel);
5497 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
5500 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5502 DE_ASSERT(levelStorage->empty());
5504 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
5505 const deUint32 numLevels = (deUint32)source.getNumLevels();
5507 // cut pyramid from baseMipLevel
5508 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5510 // cut levels from baseArraySlice
5511 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
5512 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
5513 levelStorage->push_back(cutLevel);
5516 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
5519 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5521 DE_ASSERT(levelStorage->empty());
5522 DE_ASSERT(baseArraySlice == 0);
5523 DE_UNREF(baseArraySlice);
5525 const deUint32 numLevels = (deUint32)source.getNumLevels();
5527 // cut pyramid from baseMipLevel
5528 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5529 levelStorage->push_back(source.getLevel(level));
5531 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
5534 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5536 DE_ASSERT(levelStorage->empty());
5538 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
5539 const deUint32 numLevels = (deUint32)source.getNumLevels();
5541 // cut pyramid from baseMipLevel
5542 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5544 // cut levels from baseArraySlice
5545 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
5546 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
5547 levelStorage->push_back(cutLevel);
5550 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
5553 class ImageSampleRenderInstance : public SingleCmdRenderInstance
5556 ImageSampleRenderInstance (vkt::Context& context,
5557 DescriptorUpdateMethod updateMethod,
5558 bool isPrimaryCmdBuf,
5559 vk::VkDescriptorType descriptorType,
5560 DescriptorSetCount descriptorSetCount,
5561 vk::VkShaderStageFlags stageFlags,
5562 ShaderInputInterface shaderInterface,
5563 vk::VkImageViewType viewType,
5564 deUint32 baseMipLevel,
5565 deUint32 baseArraySlice,
5569 static std::vector<DescriptorSetLayoutHandleSp> createDescriptorSetLayouts (const vk::DeviceInterface& vki,
5570 vk::VkDevice device,
5571 vk::VkDescriptorType descriptorType,
5572 DescriptorSetCount descriptorSetCount,
5573 ShaderInputInterface shaderInterface,
5574 vk::VkShaderStageFlags stageFlags,
5575 const ImageSampleInstanceImages& images,
5576 DescriptorUpdateMethod updateMethod);
5578 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5579 vk::VkDevice device,
5580 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout);
5582 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5583 vk::VkDevice device,
5584 vk::VkDescriptorType descriptorType,
5585 DescriptorSetCount descriptorSetCount,
5586 ShaderInputInterface shaderInterface);
5588 static std::vector<DescriptorSetHandleSp> createDescriptorSets (const vk::DeviceInterface& vki,
5589 DescriptorUpdateMethod updateMethod,
5590 vk::VkDevice device,
5591 vk::VkDescriptorType descriptorType,
5592 ShaderInputInterface shaderInterface,
5593 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
5594 vk::VkDescriptorPool pool,
5596 const ImageSampleInstanceImages& images,
5597 vk::DescriptorSetUpdateBuilder& updateBuilder,
5598 std::vector<UpdateTemplateHandleSp>& updateTemplates,
5599 std::vector<RawUpdateRegistry>& updateRegistry,
5600 std::vector<deUint32>& descriptorsPerSet,
5601 vk::VkPipelineLayout pipelineLayout = DE_NULL);
5603 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
5604 vk::VkDevice device,
5605 ShaderInputInterface shaderInterface,
5607 const ImageSampleInstanceImages& images,
5608 vk::VkDescriptorSet descriptorSet,
5610 vk::DescriptorSetUpdateBuilder& updateBuilder,
5611 std::vector<deUint32>& descriptorsPerSet,
5612 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
5614 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
5615 vk::VkDevice device,
5616 ShaderInputInterface shaderInterface,
5618 const ImageSampleInstanceImages& images,
5619 vk::VkDescriptorSet descriptorSet,
5621 vk::DescriptorSetUpdateBuilder& updateBuilder,
5622 std::vector<deUint32>& descriptorsPerSet,
5623 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
5625 static void writeSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5626 vk::VkDevice device,
5627 ShaderInputInterface shaderInterface,
5629 const ImageSampleInstanceImages& images,
5630 vk::VkDescriptorSet descriptorSet,
5632 vk::VkDescriptorSetLayout layout,
5633 std::vector<UpdateTemplateHandleSp>& updateTemplates,
5634 std::vector<RawUpdateRegistry>& registry,
5635 bool withPush = false,
5636 vk::VkPipelineLayout pipelineLayout = 0);
5638 static void writeImageSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5639 vk::VkDevice device,
5640 ShaderInputInterface shaderInterface,
5642 const ImageSampleInstanceImages& images,
5643 vk::VkDescriptorSet descriptorSet,
5645 vk::VkDescriptorSetLayout layout,
5646 std::vector<UpdateTemplateHandleSp>& updateTemplates,
5647 std::vector<RawUpdateRegistry>& registry,
5648 bool withPush = false,
5649 vk::VkPipelineLayout pipelineLayout = 0);
5651 void logTestPlan (void) const;
5652 vk::VkPipelineLayout getPipelineLayout (void) const;
5653 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5654 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5661 const DescriptorUpdateMethod m_updateMethod;
5662 const vk::VkDescriptorType m_descriptorType;
5663 const DescriptorSetCount m_descriptorSetCount;
5664 const vk::VkShaderStageFlags m_stageFlags;
5665 const ShaderInputInterface m_shaderInterface;
5666 const vk::VkImageViewType m_viewType;
5667 const deUint32 m_baseMipLevel;
5668 const deUint32 m_baseArraySlice;
5670 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
5671 std::vector<RawUpdateRegistry> m_updateRegistry;
5672 vk::DescriptorSetUpdateBuilder m_updateBuilder;
5673 const ImageSampleInstanceImages m_images;
5674 std::vector<deUint32> m_descriptorsPerSet;
5675 const std::vector<DescriptorSetLayoutHandleSp> m_descriptorSetLayouts;
5676 const vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
5677 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5678 const std::vector<DescriptorSetHandleSp> m_descriptorSets;
5681 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
5682 DescriptorUpdateMethod updateMethod,
5683 bool isPrimaryCmdBuf,
5684 vk::VkDescriptorType descriptorType,
5685 DescriptorSetCount descriptorSetCount,
5686 vk::VkShaderStageFlags stageFlags,
5687 ShaderInputInterface shaderInterface,
5688 vk::VkImageViewType viewType,
5689 deUint32 baseMipLevel,
5690 deUint32 baseArraySlice,
5692 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5693 , m_updateMethod (updateMethod)
5694 , m_descriptorType (descriptorType)
5695 , m_descriptorSetCount (descriptorSetCount)
5696 , m_stageFlags (stageFlags)
5697 , m_shaderInterface (shaderInterface)
5698 , m_viewType (viewType)
5699 , m_baseMipLevel (baseMipLevel)
5700 , m_baseArraySlice (baseArraySlice)
5701 , m_updateTemplates ()
5702 , m_updateRegistry ()
5703 , m_updateBuilder ()
5704 , 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)
5705 , m_descriptorSetLayouts (createDescriptorSetLayouts(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_stageFlags, m_images, m_updateMethod))
5706 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, m_descriptorSetLayouts))
5707 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface))
5708 , m_descriptorSets (createDescriptorSets(m_vki, m_updateMethod, m_device, m_descriptorType, m_shaderInterface, m_descriptorSetLayouts, *m_descriptorPool, isImmutable, m_images, m_updateBuilder, m_updateTemplates, m_updateRegistry, m_descriptorsPerSet, *m_pipelineLayout))
5712 std::vector<DescriptorSetLayoutHandleSp> ImageSampleRenderInstance::createDescriptorSetLayouts (const vk::DeviceInterface& vki,
5713 vk::VkDevice device,
5714 vk::VkDescriptorType descriptorType,
5715 DescriptorSetCount descriptorSetCount,
5716 ShaderInputInterface shaderInterface,
5717 vk::VkShaderStageFlags stageFlags,
5718 const ImageSampleInstanceImages& images,
5719 DescriptorUpdateMethod updateMethod)
5721 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
5723 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
5725 const vk::VkSampler samplers[2] =
5727 images.getSampler(setNdx * getInterfaceNumResources(shaderInterface)),
5728 images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1),
5731 vk::DescriptorSetLayoutBuilder builder;
5732 const bool addSeparateImage = descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER;
5733 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
5735 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
5736 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5738 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
5741 // (combined)samplers follow
5742 switch (shaderInterface)
5744 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5745 if (addSeparateImage)
5746 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5747 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5750 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5751 if (addSeparateImage)
5752 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5753 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5754 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5757 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5758 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5759 if (addSeparateImage)
5760 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5761 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5764 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5765 if (addSeparateImage)
5766 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5767 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
5771 DE_FATAL("Impossible");
5774 vk::Move<vk::VkDescriptorSetLayout> layout = builder.build(vki, device, extraFlags);
5775 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
5777 return descriptorSetLayouts;
5780 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5781 vk::VkDevice device,
5782 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout)
5784 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
5785 for (size_t setNdx = 0; setNdx < descriptorSetLayout.size(); setNdx++)
5786 layoutHandles.push_back(**descriptorSetLayout[setNdx]);
5788 const vk::VkPipelineLayoutCreateInfo createInfo =
5790 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5792 (vk::VkPipelineLayoutCreateFlags)0,
5793 (deUint32)layoutHandles.size(), // descriptorSetCount
5794 &layoutHandles.front(), // pSetLayouts
5795 0u, // pushConstantRangeCount
5796 DE_NULL, // pPushConstantRanges
5798 return vk::createPipelineLayout(vki, device, &createInfo);
5801 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5802 vk::VkDevice device,
5803 vk::VkDescriptorType descriptorType,
5804 DescriptorSetCount descriptorSetCount,
5805 ShaderInputInterface shaderInterface)
5807 vk::DescriptorPoolBuilder builder;
5809 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5811 // separate samplers need image to sample
5812 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, getDescriptorSetCount(descriptorSetCount));
5814 // also need sample to use, indifferent of whether immutable or not
5815 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface));
5817 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5819 // combined image samplers
5820 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface));
5823 DE_FATAL("Impossible");
5825 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(descriptorSetCount));
5828 std::vector<DescriptorSetHandleSp> ImageSampleRenderInstance::createDescriptorSets (const vk::DeviceInterface& vki,
5829 DescriptorUpdateMethod updateMethod,
5830 vk::VkDevice device,
5831 vk::VkDescriptorType descriptorType,
5832 ShaderInputInterface shaderInterface,
5833 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
5834 vk::VkDescriptorPool pool,
5836 const ImageSampleInstanceImages& images,
5837 vk::DescriptorSetUpdateBuilder& updateBuilder,
5838 std::vector<UpdateTemplateHandleSp>& updateTemplates,
5839 std::vector<RawUpdateRegistry>& updateRegistry,
5840 std::vector<deUint32>& descriptorsPerSet,
5841 vk::VkPipelineLayout pipelineLayout)
5843 std::vector<DescriptorSetHandleSp> descriptorSets;
5845 for (deUint32 setNdx = 0; setNdx < (deUint32)descriptorSetLayouts.size(); setNdx++)
5847 vk::VkDescriptorSetLayout layout = **descriptorSetLayouts[setNdx];
5849 const vk::VkDescriptorSetAllocateInfo allocInfo =
5851 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5858 vk::Move<vk::VkDescriptorSet> descriptorSet;
5859 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5861 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5865 descriptorSet = vk::Move<vk::VkDescriptorSet>();
5868 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
5870 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5871 writeSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, layout, updateTemplates, updateRegistry);
5872 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5873 writeImageSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, layout, updateTemplates, updateRegistry);
5875 DE_FATAL("Impossible");
5877 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5879 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5880 writeSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, DE_NULL, setNdx, layout, updateTemplates, updateRegistry, true, pipelineLayout);
5881 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5882 writeImageSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, DE_NULL, setNdx, layout, updateTemplates, updateRegistry, true, pipelineLayout);
5884 DE_FATAL("Impossible");
5886 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5888 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5889 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, updateBuilder, descriptorsPerSet, updateMethod);
5890 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5891 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, updateBuilder, descriptorsPerSet, updateMethod);
5893 DE_FATAL("Impossible");
5895 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5897 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5898 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, updateBuilder, descriptorsPerSet);
5899 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5900 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, setNdx, updateBuilder, descriptorsPerSet);
5902 DE_FATAL("Impossible");
5905 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(descriptorSet)));
5907 return descriptorSets;
5910 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
5911 vk::VkDevice device,
5912 ShaderInputInterface shaderInterface,
5914 const ImageSampleInstanceImages& images,
5915 vk::VkDescriptorSet descriptorSet,
5917 vk::DescriptorSetUpdateBuilder& updateBuilder,
5918 std::vector<deUint32>& descriptorsPerSet,
5919 DescriptorUpdateMethod updateMethod)
5921 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageView(setNdx), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5922 const vk::VkDescriptorImageInfo samplersInfos[2] =
5924 makeDescriptorImageInfo(images.getSampler(setNdx * getInterfaceNumResources(shaderInterface))),
5925 makeDescriptorImageInfo(images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1)),
5928 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
5929 deUint32 numBindings = 1u;
5931 // stand alone texture
5932 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(samplerLocation), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
5935 if (!isImmutable || (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH))
5937 switch (shaderInterface)
5939 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5940 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5944 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5945 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5946 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
5950 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5951 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5952 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
5956 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5957 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
5962 DE_FATAL("Impossible");
5966 descriptorsPerSet.push_back(numBindings);
5968 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5970 updateBuilder.update(vki, device);
5971 updateBuilder.clear();
5975 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
5976 vk::VkDevice device,
5977 ShaderInputInterface shaderInterface,
5979 const ImageSampleInstanceImages& images,
5980 vk::VkDescriptorSet descriptorSet,
5982 vk::DescriptorSetUpdateBuilder& updateBuilder,
5983 std::vector<deUint32>& descriptorsPerSet,
5984 DescriptorUpdateMethod updateMethod)
5986 const vk::VkSampler samplers[2] =
5988 (isImmutable && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? (0) : (images.getSampler(setNdx * getInterfaceNumResources(shaderInterface))),
5989 (isImmutable && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? (0) : (images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1)),
5991 const vk::VkDescriptorImageInfo imageSamplers[2] =
5993 vk::makeDescriptorImageInfo(samplers[0], images.getImageView(setNdx * getInterfaceNumResources(shaderInterface)), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5994 vk::makeDescriptorImageInfo(samplers[1], images.getImageView(setNdx * getInterfaceNumResources(shaderInterface) + 1), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5996 deUint32 numBindings = 0u;
5998 // combined image samplers
5999 switch (shaderInterface)
6001 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6002 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6006 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6007 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6008 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6012 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6013 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
6018 DE_FATAL("Impossible");
6021 descriptorsPerSet.push_back(numBindings);
6023 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6025 updateBuilder.update(vki, device);
6026 updateBuilder.clear();
6030 void ImageSampleRenderInstance::writeSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
6031 vk::VkDevice device,
6032 ShaderInputInterface shaderInterface,
6034 const ImageSampleInstanceImages& images,
6035 vk::VkDescriptorSet descriptorSet,
6037 vk::VkDescriptorSetLayout layout,
6038 std::vector<UpdateTemplateHandleSp>& updateTemplates,
6039 std::vector<RawUpdateRegistry>& registry,
6041 vk::VkPipelineLayout pipelineLayout)
6043 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageView(setNdx), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
6044 const vk::VkDescriptorImageInfo samplersInfos[2] =
6046 makeDescriptorImageInfo(images.getSampler(setNdx * getInterfaceNumResources(shaderInterface))),
6047 makeDescriptorImageInfo(images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1)),
6050 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
6052 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
6053 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
6055 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6059 DE_NULL, // pUpdates
6060 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
6062 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
6067 RawUpdateRegistry updateRegistry;
6069 updateRegistry.addWriteObject(imageInfo);
6070 updateRegistry.addWriteObject(samplersInfos[0]);
6071 updateRegistry.addWriteObject(samplersInfos[1]);
6073 // stand alone texture
6074 updateEntries.push_back(createTemplateBinding(samplerLocation, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, updateRegistry.getWriteObjectOffset(0), 0));
6077 if (!isImmutable || withPush)
6079 switch (shaderInterface)
6081 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6082 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6085 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6086 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6087 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
6090 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6091 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6092 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
6095 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6096 updateEntries.push_back(createTemplateBinding(1, 0, 2, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), sizeof(samplersInfos[0])));
6100 DE_FATAL("Impossible");
6104 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6105 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6107 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
6108 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
6109 registry.push_back(updateRegistry);
6113 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
6118 void ImageSampleRenderInstance::writeImageSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
6119 vk::VkDevice device,
6120 ShaderInputInterface shaderInterface,
6122 const ImageSampleInstanceImages& images,
6123 vk::VkDescriptorSet descriptorSet,
6125 vk::VkDescriptorSetLayout layout,
6126 std::vector<UpdateTemplateHandleSp>& updateTemplates,
6127 std::vector<RawUpdateRegistry>& registry,
6129 vk::VkPipelineLayout pipelineLayout)
6131 const vk::VkSampler samplers[2] =
6133 (isImmutable && !withPush) ? (0) : (images.getSampler(setNdx * getInterfaceNumResources(shaderInterface))),
6134 (isImmutable && !withPush) ? (0) : (images.getSampler(setNdx * getInterfaceNumResources(shaderInterface) + 1)),
6136 const vk::VkDescriptorImageInfo imageSamplers[2] =
6138 vk::makeDescriptorImageInfo(samplers[0], images.getImageView(setNdx * getInterfaceNumResources(shaderInterface)), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6139 vk::makeDescriptorImageInfo(samplers[1], images.getImageView(setNdx * getInterfaceNumResources(shaderInterface) + 1), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6142 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
6143 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
6145 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6149 DE_NULL, // pUpdates
6150 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
6152 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
6157 RawUpdateRegistry updateRegistry;
6159 updateRegistry.addWriteObject(imageSamplers[0]);
6160 updateRegistry.addWriteObject(imageSamplers[1]);
6162 // combined image samplers
6163 switch (shaderInterface)
6165 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6166 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
6169 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6170 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
6171 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
6174 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6175 updateEntries.push_back(createTemplateBinding(0, 0, 2, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), sizeof(imageSamplers[0])));
6179 DE_FATAL("Impossible");
6182 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6183 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6185 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
6186 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
6187 registry.push_back(updateRegistry);
6191 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
6195 void ImageSampleRenderInstance::logTestPlan (void) const
6197 std::ostringstream msg;
6199 msg << "Rendering 2x2 grid.\n";
6201 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6203 msg << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
6204 << "Each descriptor set contains "
6205 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6206 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6207 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
6208 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6209 (const char*)DE_NULL)
6210 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
6212 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6214 msg << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
6215 << "Each descriptor set contains "
6216 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6217 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6218 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
6219 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6220 (const char*)DE_NULL)
6221 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
6224 DE_FATAL("Impossible");
6226 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
6229 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
6230 if (m_baseArraySlice)
6231 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
6233 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
6234 msg << "Sampler mode is LINEAR, with WRAP\n";
6236 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
6238 if (m_stageFlags == 0u)
6240 msg << "Descriptors are not accessed in any shader stage.\n";
6244 msg << "Color in each cell is fetched using the descriptor(s):\n";
6246 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6248 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
6250 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
6252 const int srcResourceNdx = (resultNdx % 2); // ABAB source
6254 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6255 msg << " using sampler " << srcResourceNdx;
6256 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6257 msg << " from combined image sampler " << srcResourceNdx;
6259 DE_FATAL("Impossible");
6264 msg << "Descriptors are accessed in {"
6265 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
6266 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
6267 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
6268 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
6269 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
6273 m_context.getTestContext().getLog()
6274 << tcu::TestLog::Message
6276 << tcu::TestLog::EndMessage;
6279 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
6281 return *m_pipelineLayout;
6284 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
6286 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6288 std::vector<vk::VkDescriptorSet> setHandles;
6289 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6290 setHandles.push_back(**m_descriptorSets[setNdx]);
6292 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, (int)setHandles.size(), &setHandles.front(), 0u, DE_NULL);
6294 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
6296 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6297 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, **m_updateTemplates[setNdx], getPipelineLayout(), setNdx, (const void*)m_updateRegistry[setNdx].getRawPointer());
6299 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6301 deUint32 descriptorNdx = 0u;
6302 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6304 const deUint32 numDescriptors = m_descriptorsPerSet[setNdx];
6305 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, setNdx, descriptorNdx, numDescriptors);
6306 descriptorNdx += numDescriptors;
6310 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
6313 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
6315 const deUint32 numDescriptorSets = getDescriptorSetCount(m_descriptorSetCount);
6316 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
6317 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
6318 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
6319 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
6321 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
6323 tcu::Vec4 sample0 = tcu::Vec4(0.0f);
6324 tcu::Vec4 sample1 = tcu::Vec4(0.0f);
6325 tcu::Vec4 sample2 = tcu::Vec4(0.0f);
6326 tcu::Vec4 sample3 = tcu::Vec4(0.0f);
6328 for (deUint32 setNdx = 0; setNdx < numDescriptorSets; setNdx++)
6330 sample0 += (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0, setNdx));
6331 sample1 += (!doFetch) ? (green) : (m_images.fetchSampleValue(1, setNdx));
6332 sample2 += (!doFetch) ? (green) : (m_images.fetchSampleValue(2, setNdx));
6333 sample3 += (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3, setNdx));
6336 if (numDescriptorSets > 1)
6338 sample0 = sample0 / tcu::Vec4(float(numDescriptorSets));
6339 sample1 = sample1 / tcu::Vec4(float(numDescriptorSets));
6340 sample2 = sample2 / tcu::Vec4(float(numDescriptorSets));
6341 sample3 = sample3 / tcu::Vec4(float(numDescriptorSets));
6344 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
6346 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
6347 return tcu::TestStatus::fail("Image verification failed");
6349 return tcu::TestStatus::pass("Pass");
6352 class ImageSampleComputeInstance : public vkt::TestInstance
6355 ImageSampleComputeInstance (vkt::Context& context,
6356 DescriptorUpdateMethod updateMethod,
6357 vk::VkDescriptorType descriptorType,
6358 DescriptorSetCount descriptorSetCount,
6359 ShaderInputInterface shaderInterface,
6360 vk::VkImageViewType viewType,
6361 deUint32 baseMipLevel,
6362 deUint32 baseArraySlice,
6363 bool isImmutableSampler);
6366 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (deUint32 setNdx) const;
6367 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
6368 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx);
6369 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, vk::VkPipelineLayout pipelineLayout = DE_NULL);
6370 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx);
6371 void writeImageSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
6372 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx);
6373 void writeSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
6375 tcu::TestStatus iterate (void);
6376 void logTestPlan (void) const;
6377 tcu::TestStatus testResourceAccess (void);
6379 const DescriptorUpdateMethod m_updateMethod;
6380 const vk::VkDescriptorType m_descriptorType;
6381 const DescriptorSetCount m_descriptorSetCount;
6382 const ShaderInputInterface m_shaderInterface;
6383 const vk::VkImageViewType m_viewType;
6384 const deUint32 m_baseMipLevel;
6385 const deUint32 m_baseArraySlice;
6386 const bool m_isImmutableSampler;
6387 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
6389 const vk::DeviceInterface& m_vki;
6390 const vk::VkDevice m_device;
6391 const vk::VkQueue m_queue;
6392 const deUint32 m_queueFamilyIndex;
6393 vk::Allocator& m_allocator;
6394 const ComputeInstanceResultBuffer m_result;
6395 const ImageSampleInstanceImages m_images;
6396 std::vector<RawUpdateRegistry> m_updateRegistry;
6397 vk::DescriptorSetUpdateBuilder m_updateBuilder;
6398 std::vector<deUint32> m_descriptorsPerSet;
6401 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
6402 DescriptorUpdateMethod updateMethod,
6403 vk::VkDescriptorType descriptorType,
6404 DescriptorSetCount descriptorSetCount,
6405 ShaderInputInterface shaderInterface,
6406 vk::VkImageViewType viewType,
6407 deUint32 baseMipLevel,
6408 deUint32 baseArraySlice,
6409 bool isImmutableSampler)
6410 : vkt::TestInstance (context)
6411 , m_updateMethod (updateMethod)
6412 , m_descriptorType (descriptorType)
6413 , m_descriptorSetCount (descriptorSetCount)
6414 , m_shaderInterface (shaderInterface)
6415 , m_viewType (viewType)
6416 , m_baseMipLevel (baseMipLevel)
6417 , m_baseArraySlice (baseArraySlice)
6418 , m_isImmutableSampler (isImmutableSampler)
6419 , m_updateTemplates ()
6420 , m_vki (context.getDeviceInterface())
6421 , m_device (context.getDevice())
6422 , m_queue (context.getUniversalQueue())
6423 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
6424 , m_allocator (context.getDefaultAllocator())
6425 , m_result (m_vki, m_device, m_allocator)
6426 , 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)
6427 , m_updateRegistry ()
6428 , m_updateBuilder ()
6429 , m_descriptorsPerSet ()
6433 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (deUint32 setNdx) const
6435 const vk::VkSampler samplers[2] =
6437 m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface)),
6438 m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1),
6441 vk::DescriptorSetLayoutBuilder builder;
6442 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
6444 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
6445 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6447 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
6452 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
6454 // with samplers, separate texture at binding 0
6455 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6456 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
6458 // (combined)samplers follow
6459 switch (m_shaderInterface)
6461 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6462 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
6465 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6466 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
6467 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
6470 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6471 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
6475 DE_FATAL("Impossible");
6478 return builder.build(m_vki, m_device, extraFlags);
6481 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
6483 vk::DescriptorPoolBuilder builder;
6485 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
6486 builder.addType(m_descriptorType, getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface));
6488 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6489 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, getDescriptorSetCount(m_descriptorSetCount));
6491 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(m_descriptorSetCount));
6494 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx)
6496 const vk::VkDescriptorSetAllocateInfo allocInfo =
6498 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
6505 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6507 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
6508 writeDescriptorSet(*descriptorSet, layout, setNdx);
6510 return descriptorSet;
6513 return vk::Move<vk::VkDescriptorSet>();
6516 void ImageSampleComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, vk::VkPipelineLayout pipelineLayout)
6518 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
6520 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6521 writeSamplerDescriptorSetWithTemplate(descriptorSet, layout, setNdx);
6522 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6523 writeImageSamplerDescriptorSetWithTemplate(descriptorSet, layout, setNdx);
6525 DE_FATAL("Impossible");
6527 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
6529 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6530 writeSamplerDescriptorSetWithTemplate(descriptorSet, layout, setNdx, true, pipelineLayout);
6531 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6532 writeImageSamplerDescriptorSetWithTemplate(descriptorSet, layout, setNdx, true, pipelineLayout);
6534 DE_FATAL("Impossible");
6536 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6538 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6539 writeSamplerDescriptorSet(descriptorSet, setNdx);
6540 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6541 writeImageSamplerDescriptorSet(descriptorSet, setNdx);
6543 DE_FATAL("Impossible");
6545 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6547 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6548 writeSamplerDescriptorSet(descriptorSet, setNdx);
6549 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6550 writeImageSamplerDescriptorSet(descriptorSet, setNdx);
6552 DE_FATAL("Impossible");
6556 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx)
6558 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6559 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageView(setNdx), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
6560 const vk::VkDescriptorImageInfo samplersInfos[2] =
6562 makeDescriptorImageInfo(m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface))),
6563 makeDescriptorImageInfo(m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)),
6565 deUint32 binding = 0u;
6569 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
6571 // stand alone texture
6572 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
6575 if (!m_isImmutableSampler || (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH))
6577 switch (m_shaderInterface)
6579 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6580 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6583 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6584 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
6585 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
6588 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6589 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
6593 DE_FATAL("Impossible");
6597 m_descriptorsPerSet.push_back(binding);
6599 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6601 m_updateBuilder.update(m_vki, m_device);
6602 m_updateBuilder.clear();
6606 void ImageSampleComputeInstance::writeSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush, vk::VkPipelineLayout pipelineLayout)
6608 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
6609 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6610 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageView(setNdx), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
6611 const vk::VkDescriptorImageInfo samplersInfos[2] =
6613 makeDescriptorImageInfo(m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface))),
6614 makeDescriptorImageInfo(m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)),
6616 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
6618 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6622 DE_NULL, // pUpdates
6623 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
6625 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
6629 deUint32 binding = 0u;
6630 deUint32 offset = 0u;
6631 RawUpdateRegistry updateRegistry;
6634 updateRegistry.addWriteObject(resultInfo);
6636 updateRegistry.addWriteObject(imageInfo);
6637 updateRegistry.addWriteObject(samplersInfos[0]);
6638 updateRegistry.addWriteObject(samplersInfos[1]);
6642 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
6644 // stand alone texture
6645 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, updateRegistry.getWriteObjectOffset(offset++), 0));
6648 if (!m_isImmutableSampler || withPush)
6650 switch (m_shaderInterface)
6652 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6653 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6656 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6657 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6658 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6661 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6662 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), sizeof(samplersInfos[0])));
6666 DE_FATAL("Impossible");
6670 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6671 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6673 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
6674 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
6675 m_updateRegistry.push_back(updateRegistry);
6679 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, **m_updateTemplates.back(), m_updateRegistry.back().getRawPointer());
6683 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx)
6685 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6686 const vk::VkSampler samplers[2] =
6688 (m_isImmutableSampler && (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)) ? (0) : (m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface))),
6689 (m_isImmutableSampler && (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)) ? (0) : (m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)),
6691 const vk::VkDescriptorImageInfo imageSamplers[2] =
6693 makeDescriptorImageInfo(samplers[0], m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface)), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6694 makeDescriptorImageInfo(samplers[1], m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6696 deUint32 binding = 0u;
6700 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
6702 // combined image samplers
6703 switch (m_shaderInterface)
6705 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6706 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6709 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6710 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6711 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6714 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6715 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
6719 DE_FATAL("Impossible");
6722 m_descriptorsPerSet.push_back(binding);
6724 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6726 m_updateBuilder.update(m_vki, m_device);
6727 m_updateBuilder.clear();
6731 void ImageSampleComputeInstance::writeImageSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush, vk::VkPipelineLayout pipelineLayout)
6733 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
6734 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6735 const vk::VkSampler samplers[2] =
6737 (m_isImmutableSampler && !withPush) ? (0) : (m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface))),
6738 (m_isImmutableSampler && !withPush) ? (0) : (m_images.getSampler(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)),
6740 const vk::VkDescriptorImageInfo imageSamplers[2] =
6742 makeDescriptorImageInfo(samplers[0], m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface)), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6743 makeDescriptorImageInfo(samplers[1], m_images.getImageView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6745 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
6747 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6751 DE_NULL, // pUpdates
6752 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
6754 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
6759 deUint32 binding = 0u;
6760 deUint32 offset = 0u;
6761 RawUpdateRegistry updateRegistry;
6764 updateRegistry.addWriteObject(resultInfo);
6766 updateRegistry.addWriteObject(imageSamplers[0]);
6767 updateRegistry.addWriteObject(imageSamplers[1]);
6771 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
6773 // combined image samplers
6774 switch (m_shaderInterface)
6776 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6777 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6780 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6781 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6782 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), 0));
6785 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6786 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(offset++), sizeof(imageSamplers[0])));
6790 DE_FATAL("Impossible");
6793 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6794 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6796 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
6797 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
6798 m_updateRegistry.push_back(updateRegistry);
6802 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, **m_updateTemplates.back(), m_updateRegistry.back().getRawPointer());
6806 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
6809 return testResourceAccess();
6812 void ImageSampleComputeInstance::logTestPlan (void) const
6814 std::ostringstream msg;
6816 msg << "Accessing resource in a compute program.\n";
6818 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6820 msg << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
6821 << "Each descriptor set contains "
6822 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6823 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6824 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6825 (const char*)DE_NULL)
6826 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
6828 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6830 msg << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
6831 << "Each descriptor set contains "
6832 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6833 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6834 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6835 (const char*)DE_NULL)
6836 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
6839 DE_FATAL("Impossible");
6841 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
6844 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
6845 if (m_baseArraySlice)
6846 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
6848 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
6849 msg << "Sampler mode is LINEAR, with WRAP\n";
6851 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
6853 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6855 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
6857 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
6859 const int srcResourceNdx = (resultNdx % 2); // ABAB source
6861 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6862 msg << " using sampler " << srcResourceNdx;
6863 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6864 msg << " from combined image sampler " << srcResourceNdx;
6866 DE_FATAL("Impossible");
6871 m_context.getTestContext().getLog()
6872 << tcu::TestLog::Message
6874 << tcu::TestLog::EndMessage;
6877 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
6879 const vk::Unique<vk::VkDescriptorPool> descriptorPool(createDescriptorPool());
6880 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
6881 std::vector<DescriptorSetHandleSp> descriptorSets;
6882 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
6883 std::vector<vk::VkDescriptorSet> setHandles;
6885 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6887 vk::Move<vk::VkDescriptorSetLayout> layout = createDescriptorSetLayout(setNdx);
6888 vk::Move<vk::VkDescriptorSet> set = createDescriptorSet(*descriptorPool, *layout, setNdx);
6890 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
6891 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(set)));
6893 layoutHandles.push_back(**descriptorSetLayouts.back());
6894 setHandles.push_back(**descriptorSets.back());
6897 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), (int)layoutHandles.size(), &layoutHandles.front());
6898 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : getDescriptorSetCount(m_descriptorSetCount);
6899 const deUint32* const dynamicOffsets = DE_NULL;
6900 const int numDynamicOffsets = 0;
6901 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
6902 const int numPreBarriers = 0;
6903 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
6904 const int numPostBarriers = 1;
6906 const ComputeCommand compute (m_vki,
6908 pipeline.getPipeline(),
6909 pipeline.getPipelineLayout(),
6910 tcu::UVec3(4, 1, 1),
6911 numDescriptorSets, &setHandles.front(),
6912 numDynamicOffsets, dynamicOffsets,
6913 numPreBarriers, preBarriers,
6914 numPostBarriers, postBarriers);
6916 tcu::Vec4 results[4];
6917 bool anyResultSet = false;
6918 bool allResultsOk = true;
6920 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
6922 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6923 writeDescriptorSet(DE_NULL, layoutHandles[setNdx], setNdx, pipeline.getPipelineLayout()); // descriptor set not applicable
6925 compute.submitAndWait(m_queueFamilyIndex, m_queue, &m_updateTemplates, &m_updateRegistry);
6927 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6929 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6930 writeDescriptorSet(DE_NULL, layoutHandles[setNdx], setNdx, pipeline.getPipelineLayout()); // descriptor set not applicable
6932 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder, m_descriptorsPerSet);
6936 compute.submitAndWait(m_queueFamilyIndex, m_queue);
6938 m_result.readResultContentsTo(&results);
6941 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6943 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
6944 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
6945 const tcu::Vec4 result = results[resultNdx];
6946 tcu::Vec4 reference = tcu::Vec4(0.0f);
6948 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
6949 reference += m_images.fetchSampleValue(resultNdx, setNdx);
6951 reference = reference / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
6953 if (result != tcu::Vec4(-1.0f))
6954 anyResultSet = true;
6956 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
6958 allResultsOk = false;
6960 m_context.getTestContext().getLog()
6961 << tcu::TestLog::Message
6962 << "Test sample " << resultNdx << ":\n"
6963 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
6964 << "\tError expected " << reference << ", got " << result
6965 << tcu::TestLog::EndMessage;
6969 // read back and verify
6971 return tcu::TestStatus::pass("Pass");
6972 else if (anyResultSet)
6973 return tcu::TestStatus::fail("Invalid result values");
6976 m_context.getTestContext().getLog()
6977 << tcu::TestLog::Message
6978 << "Result buffer was not written to."
6979 << tcu::TestLog::EndMessage;
6980 return tcu::TestStatus::fail("Result buffer was not written to");
6984 class ImageDescriptorCase : public QuadrantRendederCase
6989 FLAG_BASE_MIP = (1u << 1u),
6990 FLAG_BASE_SLICE = (1u << 2u),
6992 // enum continues where resource flags ends
6993 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
6995 ImageDescriptorCase (tcu::TestContext& testCtx,
6997 const char* description,
6998 bool isPrimaryCmdBuf,
6999 DescriptorUpdateMethod updateMethod,
7000 vk::VkDescriptorType descriptorType,
7001 vk::VkShaderStageFlags exitingStages,
7002 vk::VkShaderStageFlags activeStages,
7003 DescriptorSetCount descriptorSetCount,
7004 ShaderInputInterface shaderInterface,
7005 vk::VkImageViewType viewType,
7009 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
7010 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
7011 std::string genFetchCoordStr (int fetchPosNdx) const;
7012 std::string genSampleCoordStr (int samplePosNdx) const;
7013 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
7014 std::string genNoAccessSource (void) const;
7016 vkt::TestInstance* createInstance (vkt::Context& context) const;
7019 const bool m_isPrimaryCmdBuf;
7020 const DescriptorUpdateMethod m_updateMethod;
7021 const vk::VkDescriptorType m_descriptorType;
7022 const DescriptorSetCount m_descriptorSetCount;
7023 const ShaderInputInterface m_shaderInterface;
7024 const vk::VkImageViewType m_viewType;
7025 const deUint32 m_baseMipLevel;
7026 const deUint32 m_baseArraySlice;
7027 const bool m_isImmutableSampler;
7030 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
7032 const char* description,
7033 bool isPrimaryCmdBuf,
7034 DescriptorUpdateMethod updateMethod,
7035 vk::VkDescriptorType descriptorType,
7036 vk::VkShaderStageFlags exitingStages,
7037 vk::VkShaderStageFlags activeStages,
7038 DescriptorSetCount descriptorSetCount,
7039 ShaderInputInterface shaderInterface,
7040 vk::VkImageViewType viewType,
7042 : QuadrantRendederCase (testCtx, name, description,
7043 // \note 1D textures are not supported in ES
7044 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
7045 exitingStages, activeStages, descriptorSetCount)
7046 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
7047 , m_updateMethod (updateMethod)
7048 , m_descriptorType (descriptorType)
7049 , m_descriptorSetCount (descriptorSetCount)
7050 , m_shaderInterface (shaderInterface)
7051 , m_viewType (viewType)
7052 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
7053 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
7054 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
7058 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
7062 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
7063 return "#extension GL_OES_texture_cube_map_array : require\n";
7068 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
7072 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
7073 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
7074 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
7075 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
7076 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
7078 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
7079 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
7080 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
7081 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
7083 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
7084 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
7086 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
7087 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
7091 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
7093 // Result buffer is bound only to the first descriptor set in compute shader cases
7094 const int descBinding = numUsedBindings - ((m_activeStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) ? (setNdx == 0 ? 0 : 1) : 0);
7095 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
7097 switch (m_shaderInterface)
7099 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7101 switch (m_descriptorType)
7103 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7104 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7105 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + ";\n";
7107 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7108 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + ";\n";
7110 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7111 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + ";\n";
7113 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7114 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + ";\n";
7117 DE_FATAL("invalid descriptor");
7122 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7123 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
7125 switch (m_descriptorType)
7127 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7128 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS)
7129 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7130 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "A;\n"
7131 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 2) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "B;\n";
7133 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "A;\n"
7134 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7135 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 2) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "B;\n";
7137 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7138 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "A;\n"
7139 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "B;\n";
7141 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7142 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "A;\n"
7143 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "B;\n";
7145 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7146 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "A;\n"
7147 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 1) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "B;\n";
7150 DE_FATAL("invalid descriptor");
7154 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7156 switch (m_descriptorType)
7158 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7159 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimension + " u_separateTexture" + setNdxPostfix + ";\n"
7160 "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding + 1) + ") uniform highp sampler u_separateSampler" + setNdxPostfix + "[2];\n";
7162 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7163 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler" + setNdxPostfix + "[2];\n";
7165 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7166 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ") uniform highp texture" + dimensionBase + " u_separateTexture" + setNdxPostfix + "[2];\n";
7168 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7169 buf += "layout(set = " + de::toString(setNdx) + ", binding = " + de::toString(descBinding) + ", rgba8) readonly uniform highp image" + dimension + " u_image" + setNdxPostfix + "[2];\n";
7172 DE_FATAL("invalid descriptor");
7177 DE_FATAL("Impossible");
7183 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
7185 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
7186 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
7188 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
7190 return de::toString(fetchPos.x());
7192 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
7194 std::ostringstream buf;
7195 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
7200 std::ostringstream buf;
7201 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
7206 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
7208 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
7209 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
7211 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
7213 std::ostringstream buf;
7214 buf << "float(" << fetchPos.x() << ")";
7217 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
7219 std::ostringstream buf;
7220 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
7223 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
7225 std::ostringstream buf;
7226 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
7231 std::ostringstream buf;
7232 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
7237 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
7241 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
7242 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
7243 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
7244 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
7245 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
7246 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
7247 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
7249 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
7250 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
7251 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("A")
7252 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
7254 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
7255 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
7256 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("B")
7257 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
7259 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
7261 std::ostringstream buf;
7263 buf << " result_color = vec4(0.0);\n";
7265 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
7267 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
7269 switch (m_descriptorType)
7271 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7272 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7274 const std::string coodStr[4] =
7276 genSampleCoordStr(0),
7277 genSampleCoordStr(1),
7278 genSampleCoordStr(2),
7279 genSampleCoordStr(3),
7282 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
7284 buf << " if (quadrant_id == 0)\n"
7285 << " result_color += textureLod(sampler" << dimension << "(u_separateTexture" << setNdxPostfix << ", u_separateSampler" << setNdxPostfix << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
7286 << " else if (quadrant_id == 1)\n"
7287 << " result_color += textureLod(sampler" << dimension << "(u_separateTexture" << setNdxPostfix << ", u_separateSampler" << setNdxPostfix << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
7288 << " else if (quadrant_id == 2)\n"
7289 << " result_color += textureLod(sampler" << dimension << "(u_separateTexture" << setNdxPostfix << ", u_separateSampler" << setNdxPostfix << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
7291 << " result_color += textureLod(sampler" << dimension << "(u_separateTexture" << setNdxPostfix << ", u_separateSampler" << setNdxPostfix << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
7295 buf << " if (quadrant_id == 0)\n"
7296 << " result_color += textureLod(u_combinedTextureSampler" << setNdxPostfix << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
7297 << " else if (quadrant_id == 1)\n"
7298 << " result_color += textureLod(u_combinedTextureSampler" << setNdxPostfix << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
7299 << " else if (quadrant_id == 2)\n"
7300 << " result_color += textureLod(u_combinedTextureSampler" << setNdxPostfix << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
7302 << " result_color += textureLod(u_combinedTextureSampler" << setNdxPostfix << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
7307 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7309 const std::string coodStr[4] =
7311 genFetchCoordStr(0),
7312 genFetchCoordStr(1),
7313 genFetchCoordStr(2),
7314 genFetchCoordStr(3),
7317 buf << " if (quadrant_id == 0)\n"
7318 << " result_color += imageLoad(u_image" << setNdxPostfix << accessPostfixA << ", " << coodStr[0] << ");\n"
7319 << " else if (quadrant_id == 1)\n"
7320 << " result_color += imageLoad(u_image" << setNdxPostfix << accessPostfixB << ", " << coodStr[1] << ");\n"
7321 << " else if (quadrant_id == 2)\n"
7322 << " result_color += imageLoad(u_image" << setNdxPostfix << accessPostfixA << ", " << coodStr[2] << ");\n"
7324 << " result_color += imageLoad(u_image" << setNdxPostfix << accessPostfixB << ", " << coodStr[3] << ");\n";
7329 DE_FATAL("invalid descriptor");
7333 if (m_descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE)
7334 buf << " result_color /= vec4(" << getDescriptorSetCount(m_descriptorSetCount) << ".0);\n";
7339 std::string ImageDescriptorCase::genNoAccessSource (void) const
7341 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
7342 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7344 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
7347 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
7349 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
7351 switch (m_descriptorType)
7353 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
7354 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
7355 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
7357 DE_ASSERT(m_isPrimaryCmdBuf);
7358 return new ImageSampleComputeInstance(context, m_updateMethod, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
7361 return new ImageSampleRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_descriptorSetCount, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
7363 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
7364 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
7365 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
7367 DE_ASSERT(m_isPrimaryCmdBuf);
7368 return new ImageFetchComputeInstance(context, m_updateMethod, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
7371 return new ImageFetchRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_descriptorSetCount, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
7374 DE_FATAL("Impossible");
7379 class TexelBufferInstanceBuffers
7382 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
7383 vk::VkDevice device,
7384 vk::Allocator& allocator,
7385 vk::VkDescriptorType descriptorType,
7386 DescriptorSetCount descriptorSetCount,
7387 ShaderInputInterface shaderInterface,
7388 bool hasViewOffset);
7391 static std::vector<de::ArrayBuffer<deUint8> > createSourceBuffers (tcu::TextureFormat imageFormat,
7392 deUint32 numTexelBuffers);
7394 static std::vector<tcu::ConstPixelBufferAccess> createSourceViews (const std::vector<de::ArrayBuffer<deUint8> >& sourceBuffers,
7395 tcu::TextureFormat imageFormat,
7396 deUint32 numTexelBuffers,
7397 deUint32 viewOffset);
7399 static std::vector<BufferHandleSp> createBuffers (const vk::DeviceInterface& vki,
7400 vk::VkDevice device,
7401 vk::Allocator& allocator,
7402 vk::VkDescriptorType descriptorType,
7403 const std::vector<de::ArrayBuffer<deUint8> >& sourceBuffers,
7404 std::vector<AllocationSp>& bufferMemory,
7405 tcu::TextureFormat imageFormat,
7406 deUint32 numTexelBuffers,
7407 deUint32 viewOffset);
7409 static std::vector<BufferViewHandleSp> createBufferViews (const vk::DeviceInterface& vki,
7410 vk::VkDevice device,
7411 const std::vector<BufferHandleSp>& buffers,
7412 tcu::TextureFormat imageFormat,
7413 deUint32 numTexelBuffers,
7414 deUint32 viewOffset);
7416 static std::vector<vk::VkBufferMemoryBarrier> createBufferBarriers (vk::VkDescriptorType descriptorType,
7417 const std::vector<BufferHandleSp>& buffers,
7418 deUint32 numTexelBuffers);
7421 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
7422 vk::VkDevice device,
7423 vk::Allocator& allocator,
7424 vk::VkDescriptorType descriptorType,
7425 de::MovePtr<vk::Allocation> *outAllocation);
7427 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
7428 vk::VkDevice device,
7429 const tcu::TextureFormat& textureFormat,
7431 vk::VkBuffer buffer);
7433 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType,
7434 vk::VkBuffer buffer);
7436 static void populateSourceBuffer (const tcu::PixelBufferAccess& access,
7437 deUint32 bufferNdx);
7439 static void uploadData (const vk::DeviceInterface& vki,
7440 vk::VkDevice device,
7441 const vk::Allocation& memory,
7442 const de::ArrayBuffer<deUint8>& data);
7445 static int getFetchPos (int fetchPosNdx);
7446 tcu::Vec4 fetchTexelValue (int fetchPosNdx, int setNdx) const;
7448 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
7449 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
7450 inline vk::VkBufferView getBufferView (int ndx) const { return **m_bufferView[ndx % m_bufferView.size()]; }
7451 inline tcu::ConstPixelBufferAccess getSourceView (int ndx) const { return m_sourceView[ndx % m_sourceView.size()]; }
7452 inline const vk::VkBufferMemoryBarrier* getBufferInitBarriers (void) const { return &m_bufferBarrier.front(); }
7458 VIEW_OFFSET_VALUE = 256,
7459 VIEW_DATA_SIZE = 256, //!< size in bytes
7460 VIEW_WIDTH = 64, //!< size in pixels
7464 // some arbitrary points
7466 SAMPLE_POINT_1 = 51,
7467 SAMPLE_POINT_2 = 42,
7468 SAMPLE_POINT_3 = 25,
7471 const deUint32 m_numTexelBuffers;
7472 const tcu::TextureFormat m_imageFormat;
7473 const ShaderInputInterface m_shaderInterface;
7474 const deUint32 m_viewOffset;
7476 const std::vector<de::ArrayBuffer<deUint8> > m_sourceBuffer;
7477 const std::vector<tcu::ConstPixelBufferAccess> m_sourceView;
7479 std::vector<AllocationSp> m_bufferMemory;
7480 const std::vector<BufferHandleSp> m_buffer;
7481 const std::vector<BufferViewHandleSp> m_bufferView;
7482 const std::vector<vk::VkBufferMemoryBarrier> m_bufferBarrier;
7485 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
7486 vk::VkDevice device,
7487 vk::Allocator& allocator,
7488 vk::VkDescriptorType descriptorType,
7489 DescriptorSetCount descriptorSetCount,
7490 ShaderInputInterface shaderInterface,
7492 : m_numTexelBuffers (getInterfaceNumResources(shaderInterface) * getDescriptorSetCount(descriptorSetCount))
7493 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
7494 , m_shaderInterface (shaderInterface)
7495 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
7496 , m_sourceBuffer (createSourceBuffers(m_imageFormat, m_numTexelBuffers))
7497 , m_sourceView (createSourceViews(m_sourceBuffer, m_imageFormat, m_numTexelBuffers, m_viewOffset))
7499 , m_buffer (createBuffers(vki, device, allocator, descriptorType, m_sourceBuffer, m_bufferMemory, m_imageFormat, m_numTexelBuffers, m_viewOffset))
7500 , m_bufferView (createBufferViews(vki, device, m_buffer, m_imageFormat, m_numTexelBuffers, m_viewOffset))
7501 , m_bufferBarrier (createBufferBarriers(descriptorType, m_buffer, m_numTexelBuffers))
7505 std::vector<de::ArrayBuffer<deUint8> > TexelBufferInstanceBuffers::createSourceBuffers (tcu::TextureFormat imageFormat,
7506 deUint32 numTexelBuffers)
7508 DE_ASSERT(BUFFER_SIZE % imageFormat.getPixelSize() == 0);
7510 std::vector<de::ArrayBuffer<deUint8> > sourceBuffers(numTexelBuffers, BUFFER_SIZE);
7512 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7513 populateSourceBuffer(tcu::PixelBufferAccess(imageFormat, tcu::IVec3(BUFFER_SIZE / imageFormat.getPixelSize(), 1, 1), sourceBuffers[bufferNdx].getPtr()), bufferNdx);
7515 return sourceBuffers;
7518 std::vector<tcu::ConstPixelBufferAccess> TexelBufferInstanceBuffers::createSourceViews (const std::vector<de::ArrayBuffer<deUint8> >& sourceBuffers,
7519 tcu::TextureFormat imageFormat,
7520 deUint32 numTexelBuffers,
7521 deUint32 viewOffset)
7523 std::vector<tcu::ConstPixelBufferAccess> sourceViews;
7525 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7526 sourceViews.push_back(tcu::ConstPixelBufferAccess(imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), sourceBuffers[bufferNdx].getElementPtr(viewOffset)));
7531 std::vector<BufferHandleSp> TexelBufferInstanceBuffers::createBuffers (const vk::DeviceInterface& vki,
7532 vk::VkDevice device,
7533 vk::Allocator& allocator,
7534 vk::VkDescriptorType descriptorType,
7535 const std::vector<de::ArrayBuffer<deUint8> >& sourceBuffers,
7536 std::vector<AllocationSp>& bufferMemory,
7537 tcu::TextureFormat imageFormat,
7538 deUint32 numTexelBuffers,
7539 deUint32 viewOffset)
7541 std::vector<BufferHandleSp> buffers;
7543 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7545 de::MovePtr<vk::Allocation> memory;
7546 vk::Move<vk::VkBuffer> buffer = createBuffer(vki, device, allocator, descriptorType, &memory);
7547 vk::Move<vk::VkBufferView> bufferView = createBufferView(vki, device, imageFormat, viewOffset, *buffer);
7549 uploadData(vki, device, *memory, sourceBuffers[bufferNdx]);
7551 bufferMemory.push_back(AllocationSp(memory.release()));
7552 buffers.push_back(BufferHandleSp(new BufferHandleUp(buffer)));
7558 std::vector<BufferViewHandleSp> TexelBufferInstanceBuffers::createBufferViews (const vk::DeviceInterface& vki,
7559 vk::VkDevice device,
7560 const std::vector<BufferHandleSp>& buffers,
7561 tcu::TextureFormat imageFormat,
7562 deUint32 numTexelBuffers,
7563 deUint32 viewOffset)
7565 std::vector<BufferViewHandleSp> bufferViews;
7567 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7569 vk::Move<vk::VkBufferView> bufferView = createBufferView(vki, device, imageFormat, viewOffset, **buffers[bufferNdx]);
7570 bufferViews.push_back(BufferViewHandleSp(new BufferViewHandleUp(bufferView)));
7576 std::vector<vk::VkBufferMemoryBarrier> TexelBufferInstanceBuffers::createBufferBarriers (vk::VkDescriptorType descriptorType,
7577 const std::vector<BufferHandleSp>& buffers,
7578 deUint32 numTexelBuffers)
7580 std::vector<vk::VkBufferMemoryBarrier> bufferBarriers;
7582 for (deUint32 bufferNdx = 0; bufferNdx < numTexelBuffers; bufferNdx++)
7583 bufferBarriers.push_back(createBarrier(descriptorType, **buffers[bufferNdx]));
7585 return bufferBarriers;
7588 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
7589 vk::VkDevice device,
7590 vk::Allocator& allocator,
7591 vk::VkDescriptorType descriptorType,
7592 de::MovePtr<vk::Allocation> *outAllocation)
7594 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
7595 const vk::VkBufferCreateInfo createInfo =
7597 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
7600 (vk::VkDeviceSize)BUFFER_SIZE, // size
7602 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
7603 0u, // queueFamilyCount
7604 DE_NULL, // pQueueFamilyIndices
7606 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
7607 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
7609 *outAllocation = allocation;
7613 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
7614 vk::VkDevice device,
7615 const tcu::TextureFormat& textureFormat,
7617 vk::VkBuffer buffer)
7619 const vk::VkBufferViewCreateInfo createInfo =
7621 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
7623 (vk::VkBufferViewCreateFlags)0,
7625 vk::mapTextureFormat(textureFormat), // format
7626 (vk::VkDeviceSize)offset, // offset
7627 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
7629 return vk::createBufferView(vki, device, &createInfo);
7632 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
7634 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
7635 const vk::VkBufferMemoryBarrier barrier =
7637 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
7639 vk::VK_ACCESS_HOST_WRITE_BIT, // srcAccessMask
7640 inputBit, // dstAccessMask
7641 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
7642 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
7645 (vk::VkDeviceSize)BUFFER_SIZE // size
7650 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access, deUint32 bufferNdx)
7652 DE_ASSERT(access.getHeight() == 1);
7653 DE_ASSERT(access.getDepth() == 1);
7655 const deInt32 width = access.getWidth();
7657 for (int x = 0; x < width; ++x)
7659 int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
7660 int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
7661 int blue = 16 * (x % 16); //!< 16-long triangle wave
7663 DE_ASSERT(de::inRange(red, 0, 255));
7664 DE_ASSERT(de::inRange(green, 0, 255));
7665 DE_ASSERT(de::inRange(blue, 0, 255));
7667 if (bufferNdx % 2 == 0) red = 255 - red;
7668 if (bufferNdx % 3 == 0) green = 255 - green;
7669 if (bufferNdx % 4 == 0) blue = 255 - blue;
7671 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
7675 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
7677 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
7678 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
7681 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
7683 static const int fetchPositions[4] =
7690 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
7693 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx, int setNdx) const
7695 // source order is ABAB
7696 const tcu::ConstPixelBufferAccess& texelSrcA = getSourceView(setNdx * getInterfaceNumResources(m_shaderInterface));
7697 const tcu::ConstPixelBufferAccess& texelSrcB = getSourceView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1);
7698 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
7700 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
7703 class TexelBufferRenderInstance : public SingleCmdRenderInstance
7706 TexelBufferRenderInstance (vkt::Context& context,
7707 DescriptorUpdateMethod updateMethod,
7708 bool isPrimaryCmdBuf,
7709 vk::VkDescriptorType descriptorType,
7710 DescriptorSetCount descriptorSetCount,
7711 vk::VkShaderStageFlags stageFlags,
7712 ShaderInputInterface shaderInterface,
7713 bool nonzeroViewOffset);
7716 static std::vector<DescriptorSetLayoutHandleSp> createDescriptorSetLayouts (const vk::DeviceInterface& vki,
7717 vk::VkDevice device,
7718 vk::VkDescriptorType descriptorType,
7719 DescriptorSetCount descriptorSetCount,
7720 ShaderInputInterface shaderInterface,
7721 vk::VkShaderStageFlags stageFlags,
7722 DescriptorUpdateMethod updateMethod);
7724 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
7725 vk::VkDevice device,
7726 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout);
7728 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
7729 vk::VkDevice device,
7730 vk::VkDescriptorType descriptorType,
7731 DescriptorSetCount descriptorSetCount,
7732 ShaderInputInterface shaderInterface);
7734 static std::vector<DescriptorSetHandleSp> createDescriptorSets (const vk::DeviceInterface& vki,
7735 DescriptorUpdateMethod updateMethod,
7736 vk::VkDevice device,
7737 vk::VkDescriptorType descriptorType,
7738 ShaderInputInterface shaderInterface,
7739 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
7740 vk::VkDescriptorPool pool,
7741 const TexelBufferInstanceBuffers& buffers,
7742 vk::DescriptorSetUpdateBuilder& updateBuilder,
7743 std::vector<UpdateTemplateHandleSp>& updateTemplates,
7744 std::vector<RawUpdateRegistry>& updateRegistry,
7745 std::vector<deUint32>& descriptorsPerSet,
7746 vk::VkPipelineLayout pipelineLayout = DE_NULL);
7748 static void writeDescriptorSet (const vk::DeviceInterface& vki,
7749 vk::VkDevice device,
7750 vk::VkDescriptorType descriptorType,
7751 ShaderInputInterface shaderInterface,
7752 vk::VkDescriptorSetLayout layout,
7753 vk::VkDescriptorPool pool,
7754 vk::VkBufferView viewA,
7755 vk::VkBufferView viewB,
7756 vk::VkDescriptorSet descriptorSet,
7757 vk::DescriptorSetUpdateBuilder& updateBuilder,
7758 std::vector<deUint32>& descriptorsPerSet,
7759 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
7761 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
7762 vk::VkDevice device,
7763 vk::VkDescriptorType descriptorType,
7764 ShaderInputInterface shaderInterface,
7765 vk::VkDescriptorSetLayout layout,
7767 vk::VkDescriptorPool pool,
7768 vk::VkBufferView viewA,
7769 vk::VkBufferView viewB,
7770 vk::VkDescriptorSet descriptorSet,
7771 std::vector<UpdateTemplateHandleSp>& updateTemplates,
7772 std::vector<RawUpdateRegistry>& registry,
7773 bool withPush = false,
7774 vk::VkPipelineLayout pipelineLayout = 0);
7776 void logTestPlan (void) const;
7777 vk::VkPipelineLayout getPipelineLayout (void) const;
7778 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
7779 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
7786 const DescriptorUpdateMethod m_updateMethod;
7787 const vk::VkDescriptorType m_descriptorType;
7788 const DescriptorSetCount m_descriptorSetCount;
7789 const vk::VkShaderStageFlags m_stageFlags;
7790 const ShaderInputInterface m_shaderInterface;
7791 const bool m_nonzeroViewOffset;
7793 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
7794 std::vector<RawUpdateRegistry> m_updateRegistry;
7795 vk::DescriptorSetUpdateBuilder m_updateBuilder;
7796 const std::vector<DescriptorSetLayoutHandleSp> m_descriptorSetLayouts;
7797 const vk::Move<vk::VkPipelineLayout> m_pipelineLayout;
7798 const TexelBufferInstanceBuffers m_texelBuffers;
7799 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
7800 std::vector<deUint32> m_descriptorsPerSet;
7801 const std::vector<DescriptorSetHandleSp> m_descriptorSets;
7804 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
7805 DescriptorUpdateMethod updateMethod,
7806 bool isPrimaryCmdBuf,
7807 vk::VkDescriptorType descriptorType,
7808 DescriptorSetCount descriptorSetCount,
7809 vk::VkShaderStageFlags stageFlags,
7810 ShaderInputInterface shaderInterface,
7811 bool nonzeroViewOffset)
7812 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
7813 , m_updateMethod (updateMethod)
7814 , m_descriptorType (descriptorType)
7815 , m_descriptorSetCount (descriptorSetCount)
7816 , m_stageFlags (stageFlags)
7817 , m_shaderInterface (shaderInterface)
7818 , m_nonzeroViewOffset (nonzeroViewOffset)
7819 , m_updateTemplates ()
7820 , m_updateRegistry ()
7821 , m_updateBuilder ()
7822 , m_descriptorSetLayouts (createDescriptorSetLayouts(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_stageFlags, m_updateMethod))
7823 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, m_descriptorSetLayouts))
7824 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_nonzeroViewOffset)
7825 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_descriptorSetCount, m_shaderInterface))
7826 , m_descriptorsPerSet ()
7827 , m_descriptorSets (createDescriptorSets(m_vki, m_updateMethod, m_device, m_descriptorType, m_shaderInterface, m_descriptorSetLayouts, *m_descriptorPool, m_texelBuffers, m_updateBuilder, m_updateTemplates, m_updateRegistry, m_descriptorsPerSet, *m_pipelineLayout))
7831 std::vector<DescriptorSetLayoutHandleSp> TexelBufferRenderInstance::createDescriptorSetLayouts (const vk::DeviceInterface& vki,
7832 vk::VkDevice device,
7833 vk::VkDescriptorType descriptorType,
7834 DescriptorSetCount descriptorSetCount,
7835 ShaderInputInterface shaderInterface,
7836 vk::VkShaderStageFlags stageFlags,
7837 DescriptorUpdateMethod updateMethod)
7839 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
7841 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(descriptorSetCount); setNdx++)
7843 vk::DescriptorSetLayoutBuilder builder;
7844 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
7846 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
7847 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7849 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
7852 switch (shaderInterface)
7854 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7855 builder.addSingleBinding(descriptorType, stageFlags);
7858 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7859 builder.addSingleBinding(descriptorType, stageFlags);
7860 builder.addSingleBinding(descriptorType, stageFlags);
7863 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7864 builder.addArrayBinding(descriptorType, 2u, stageFlags);
7868 DE_FATAL("Impossible");
7871 vk::Move<vk::VkDescriptorSetLayout> layout = builder.build(vki, device, extraFlags);
7872 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
7874 return descriptorSetLayouts;
7877 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
7878 vk::VkDevice device,
7879 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayout)
7881 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
7882 for (size_t setNdx = 0; setNdx < descriptorSetLayout.size(); setNdx++)
7883 layoutHandles.push_back(**descriptorSetLayout[setNdx]);
7885 const vk::VkPipelineLayoutCreateInfo createInfo =
7887 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
7889 (vk::VkPipelineLayoutCreateFlags)0,
7890 (deUint32)layoutHandles.size(), // descriptorSetCount
7891 &layoutHandles.front(), // pSetLayouts
7892 0u, // pushConstantRangeCount
7893 DE_NULL, // pPushConstantRanges
7895 return vk::createPipelineLayout(vki, device, &createInfo);
7898 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
7899 vk::VkDevice device,
7900 vk::VkDescriptorType descriptorType,
7901 DescriptorSetCount descriptorSetCount,
7902 ShaderInputInterface shaderInterface)
7904 return vk::DescriptorPoolBuilder()
7905 .addType(descriptorType, getDescriptorSetCount(descriptorSetCount) * getInterfaceNumResources(shaderInterface))
7906 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(descriptorSetCount));
7909 std::vector<DescriptorSetHandleSp> TexelBufferRenderInstance::createDescriptorSets (const vk::DeviceInterface& vki,
7910 DescriptorUpdateMethod updateMethod,
7911 vk::VkDevice device,
7912 vk::VkDescriptorType descriptorType,
7913 ShaderInputInterface shaderInterface,
7914 const std::vector<DescriptorSetLayoutHandleSp>& descriptorSetLayouts,
7915 vk::VkDescriptorPool pool,
7916 const TexelBufferInstanceBuffers& buffers,
7917 vk::DescriptorSetUpdateBuilder& updateBuilder,
7918 std::vector<UpdateTemplateHandleSp>& updateTemplates,
7919 std::vector<RawUpdateRegistry>& updateRegistry,
7920 std::vector<deUint32>& descriptorsPerSet,
7921 vk::VkPipelineLayout pipelineLayout)
7923 std::vector<DescriptorSetHandleSp> descriptorSets;
7925 for (deUint32 setNdx = 0; setNdx < (deUint32)descriptorSetLayouts.size(); setNdx++)
7927 vk::VkDescriptorSetLayout layout = **descriptorSetLayouts[setNdx];
7929 const vk::VkDescriptorSetAllocateInfo allocInfo =
7931 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
7938 vk::VkBufferView viewA = buffers.getBufferView(setNdx * getInterfaceNumResources(shaderInterface));
7939 vk::VkBufferView viewB = buffers.getBufferView(setNdx * getInterfaceNumResources(shaderInterface) + 1);
7941 vk::Move<vk::VkDescriptorSet> descriptorSet;
7943 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7945 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
7949 descriptorSet = vk::Move<vk::VkDescriptorSet>();
7952 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
7954 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, setNdx, pool, viewA, viewB, *descriptorSet, updateTemplates, updateRegistry);
7956 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7958 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, setNdx, pool, viewA, viewB, *descriptorSet, updateTemplates, updateRegistry, true, pipelineLayout);
7960 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7962 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, descriptorsPerSet, updateMethod);
7964 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7966 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, descriptorsPerSet);
7969 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(descriptorSet)));
7972 return descriptorSets;
7975 void TexelBufferRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
7976 vk::VkDevice device,
7977 vk::VkDescriptorType descriptorType,
7978 ShaderInputInterface shaderInterface,
7979 vk::VkDescriptorSetLayout layout,
7980 vk::VkDescriptorPool pool,
7981 vk::VkBufferView viewA,
7982 vk::VkBufferView viewB,
7983 vk::VkDescriptorSet descriptorSet,
7984 vk::DescriptorSetUpdateBuilder& updateBuilder,
7985 std::vector<deUint32>& descriptorsPerSet,
7986 DescriptorUpdateMethod updateMethod)
7990 const vk::VkBufferView texelBufferInfos[2] =
7995 deUint32 numBindings = 0u;
7997 switch (shaderInterface)
7999 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8000 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
8004 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8005 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
8006 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
8010 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8011 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
8016 DE_FATAL("Impossible");
8019 descriptorsPerSet.push_back(numBindings);
8021 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
8023 updateBuilder.update(vki, device);
8024 updateBuilder.clear();
8028 void TexelBufferRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
8029 vk::VkDevice device,
8030 vk::VkDescriptorType descriptorType,
8031 ShaderInputInterface shaderInterface,
8032 vk::VkDescriptorSetLayout layout,
8034 vk::VkDescriptorPool pool,
8035 vk::VkBufferView viewA,
8036 vk::VkBufferView viewB,
8037 vk::VkDescriptorSet descriptorSet,
8038 std::vector<UpdateTemplateHandleSp>& updateTemplates,
8039 std::vector<RawUpdateRegistry>& registry,
8041 vk::VkPipelineLayout pipelineLayout)
8044 const vk::VkBufferView texelBufferInfos[2] =
8049 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
8050 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
8052 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
8056 DE_NULL, // pUpdates
8057 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
8059 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
8064 RawUpdateRegistry updateRegistry;
8066 updateRegistry.addWriteObject(texelBufferInfos[0]);
8067 updateRegistry.addWriteObject(texelBufferInfos[1]);
8069 switch (shaderInterface)
8071 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8072 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
8075 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8076 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
8077 updateEntries.push_back(createTemplateBinding(1, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
8080 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8081 updateEntries.push_back(createTemplateBinding(0, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(texelBufferInfos[0])));
8085 DE_FATAL("Impossible");
8088 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
8089 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
8091 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
8092 updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
8093 registry.push_back(updateRegistry);
8097 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, **updateTemplates.back(), registry.back().getRawPointer());
8101 void TexelBufferRenderInstance::logTestPlan (void) const
8103 std::ostringstream msg;
8105 msg << "Rendering 2x2 grid.\n"
8106 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
8107 << "Each descriptor set contains "
8108 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
8109 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
8110 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
8111 (const char*)DE_NULL)
8112 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
8113 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
8114 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
8116 if (m_stageFlags == 0u)
8118 msg << "Descriptors are not accessed in any shader stage.\n";
8122 msg << "Color in each cell is fetched using the descriptor(s):\n";
8124 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
8126 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
8128 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
8130 const int srcResourceNdx = (resultNdx % 2); // ABAB source
8131 msg << " from texelBuffer " << srcResourceNdx;
8137 msg << "Descriptors are accessed in {"
8138 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
8139 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
8140 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
8141 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
8142 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
8146 m_context.getTestContext().getLog()
8147 << tcu::TestLog::Message
8149 << tcu::TestLog::EndMessage;
8152 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
8154 return *m_pipelineLayout;
8157 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
8159 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8161 std::vector<vk::VkDescriptorSet> sets;
8162 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8163 sets.push_back(**m_descriptorSets[setNdx]);
8165 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, (deUint32)sets.size(), &sets.front(), 0, DE_NULL);
8167 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
8169 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8170 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, **m_updateTemplates[setNdx], getPipelineLayout(), setNdx, (const void*)m_updateRegistry[setNdx].getRawPointer());
8172 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8174 deUint32 descriptorNdx = 0u;
8175 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8177 const deUint32 numDescriptors = m_descriptorsPerSet[setNdx];
8178 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, setNdx, descriptorNdx, numDescriptors);
8179 descriptorNdx += numDescriptors;
8183 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
8186 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
8188 const deUint32 numDescriptorSets = getDescriptorSetCount(m_descriptorSetCount);
8189 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
8190 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
8191 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
8193 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
8195 tcu::Vec4 sample0 = tcu::Vec4(0.0f);
8196 tcu::Vec4 sample1 = tcu::Vec4(0.0f);
8197 tcu::Vec4 sample2 = tcu::Vec4(0.0f);
8198 tcu::Vec4 sample3 = tcu::Vec4(0.0f);
8202 for (deUint32 setNdx = 0u; setNdx < numDescriptorSets; setNdx++)
8204 sample0 += m_texelBuffers.fetchTexelValue(0, setNdx);
8205 sample1 += m_texelBuffers.fetchTexelValue(1, setNdx);
8206 sample2 += m_texelBuffers.fetchTexelValue(2, setNdx);
8207 sample3 += m_texelBuffers.fetchTexelValue(3, setNdx);
8210 if (numDescriptorSets > 1)
8212 sample0 = sample0 / tcu::Vec4(float(numDescriptorSets));
8213 sample1 = sample1 / tcu::Vec4(float(numDescriptorSets));
8214 sample2 = sample2 / tcu::Vec4(float(numDescriptorSets));
8215 sample3 = sample3 / tcu::Vec4(float(numDescriptorSets));
8226 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
8228 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
8229 return tcu::TestStatus::fail("Image verification failed");
8231 return tcu::TestStatus::pass("Pass");
8234 class TexelBufferComputeInstance : public vkt::TestInstance
8237 TexelBufferComputeInstance (vkt::Context& context,
8238 DescriptorUpdateMethod updateMethod,
8239 vk::VkDescriptorType descriptorType,
8240 DescriptorSetCount descriptorSetCount,
8241 ShaderInputInterface shaderInterface,
8242 bool nonzeroViewOffset);
8245 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (deUint32 setNdx) const;
8246 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
8247 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx);
8248 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx);
8249 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
8251 tcu::TestStatus iterate (void);
8252 void logTestPlan (void) const;
8253 tcu::TestStatus testResourceAccess (void);
8255 const DescriptorUpdateMethod m_updateMethod;
8256 const vk::VkDescriptorType m_descriptorType;
8257 const DescriptorSetCount m_descriptorSetCount;
8258 const ShaderInputInterface m_shaderInterface;
8259 const bool m_nonzeroViewOffset;
8261 const vk::DeviceInterface& m_vki;
8262 const vk::VkDevice m_device;
8263 const vk::VkQueue m_queue;
8264 const deUint32 m_queueFamilyIndex;
8265 vk::Allocator& m_allocator;
8266 std::vector<UpdateTemplateHandleSp> m_updateTemplates;
8268 const ComputeInstanceResultBuffer m_result;
8269 const TexelBufferInstanceBuffers m_texelBuffers;
8271 std::vector<RawUpdateRegistry> m_updateRegistry;
8272 vk::DescriptorSetUpdateBuilder m_updateBuilder;
8273 std::vector<deUint32> m_descriptorsPerSet;
8276 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
8277 DescriptorUpdateMethod updateMethod,
8278 vk::VkDescriptorType descriptorType,
8279 DescriptorSetCount descriptorSetCount,
8280 ShaderInputInterface shaderInterface,
8281 bool nonzeroViewOffset)
8282 : vkt::TestInstance (context)
8283 , m_updateMethod (updateMethod)
8284 , m_descriptorType (descriptorType)
8285 , m_descriptorSetCount (descriptorSetCount)
8286 , m_shaderInterface (shaderInterface)
8287 , m_nonzeroViewOffset (nonzeroViewOffset)
8288 , m_vki (context.getDeviceInterface())
8289 , m_device (context.getDevice())
8290 , m_queue (context.getUniversalQueue())
8291 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
8292 , m_allocator (context.getDefaultAllocator())
8293 , m_updateTemplates ()
8294 , m_result (m_vki, m_device, m_allocator)
8295 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_nonzeroViewOffset)
8296 , m_updateRegistry ()
8297 , m_updateBuilder ()
8298 , m_descriptorsPerSet ()
8302 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (deUint32 setNdx) const
8304 vk::DescriptorSetLayoutBuilder builder;
8305 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
8307 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
8308 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8310 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
8314 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8316 switch (m_shaderInterface)
8318 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8319 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8322 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8323 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8324 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8327 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8328 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
8332 DE_FATAL("Impossible");
8335 return builder.build(m_vki, m_device, extraFlags);
8338 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
8340 return vk::DescriptorPoolBuilder()
8341 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
8342 .addType(m_descriptorType, getDescriptorSetCount(m_descriptorSetCount) * getInterfaceNumResources(m_shaderInterface))
8343 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, getDescriptorSetCount(m_descriptorSetCount));
8346 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, deUint32 setNdx)
8348 const vk::VkDescriptorSetAllocateInfo allocInfo =
8350 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
8357 vk::Move<vk::VkDescriptorSet> descriptorSet;
8358 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
8360 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
8364 descriptorSet = vk::Move<vk::VkDescriptorSet>();
8368 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
8370 writeDescriptorSetWithTemplate(*descriptorSet, layout, setNdx);
8372 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
8374 writeDescriptorSet(*descriptorSet, setNdx);
8377 return descriptorSet;
8380 void TexelBufferComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, deUint32 setNdx)
8382 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
8383 const vk::VkBufferView texelBufferInfos[2] =
8385 m_texelBuffers.getBufferView(setNdx * getInterfaceNumResources(m_shaderInterface)),
8386 m_texelBuffers.getBufferView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)
8388 deUint32 binding = 0u;
8392 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
8395 switch (m_shaderInterface)
8397 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8398 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &texelBufferInfos[0]);
8401 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8402 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &texelBufferInfos[0]);
8403 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, &texelBufferInfos[1]);
8406 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8407 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(binding++), m_descriptorType, 2u, texelBufferInfos);
8411 DE_FATAL("Impossible");
8414 m_descriptorsPerSet.push_back(binding);
8416 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
8418 m_updateBuilder.update(m_vki, m_device);
8419 m_updateBuilder.clear();
8423 void TexelBufferComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, deUint32 setNdx, bool withPush, vk::VkPipelineLayout pipelineLayout)
8425 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
8426 const vk::VkBufferView texelBufferInfos[2] =
8428 m_texelBuffers.getBufferView(setNdx * getInterfaceNumResources(m_shaderInterface)),
8429 m_texelBuffers.getBufferView(setNdx * getInterfaceNumResources(m_shaderInterface) + 1)
8431 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
8432 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
8434 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
8438 DE_NULL, // pUpdates
8439 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
8441 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
8445 deUint32 binding = 0u;
8446 deUint32 offset = 0u;
8447 RawUpdateRegistry updateRegistry;
8450 updateRegistry.addWriteObject(resultInfo);
8452 updateRegistry.addWriteObject(texelBufferInfos[0]);
8453 updateRegistry.addWriteObject(texelBufferInfos[1]);
8457 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, updateRegistry.getWriteObjectOffset(offset++), 0));
8460 switch (m_shaderInterface)
8462 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8463 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8466 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8467 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8468 updateEntries.push_back(createTemplateBinding(binding++, 0, 1, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), 0));
8471 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8472 updateEntries.push_back(createTemplateBinding(binding++, 0, 2, m_descriptorType, updateRegistry.getWriteObjectOffset(offset++), sizeof(texelBufferInfos[0])));
8476 DE_FATAL("Impossible");
8479 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
8480 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
8482 vk::Move<vk::VkDescriptorUpdateTemplateKHR> updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
8483 m_updateTemplates.push_back(UpdateTemplateHandleSp(new UpdateTemplateHandleUp(updateTemplate)));
8484 m_updateRegistry.push_back(updateRegistry);
8488 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, **m_updateTemplates[setNdx], m_updateRegistry.back().getRawPointer());
8492 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
8495 return testResourceAccess();
8498 void TexelBufferComputeInstance::logTestPlan (void) const
8500 std::ostringstream msg;
8502 msg << "Fetching 4 values from image in compute shader.\n"
8503 << ((m_descriptorSetCount == DESCRIPTOR_SET_COUNT_SINGLE) ? "Single descriptor set. " : "Multiple descriptor sets. ")
8504 << "Each descriptor set contains "
8505 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
8506 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
8507 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
8508 (const char*)DE_NULL)
8509 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
8510 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
8511 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
8513 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
8515 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
8517 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
8519 const int srcResourceNdx = (resultNdx % 2); // ABAB source
8520 msg << " from texelBuffer " << srcResourceNdx;
8526 m_context.getTestContext().getLog()
8527 << tcu::TestLog::Message
8529 << tcu::TestLog::EndMessage;
8532 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
8534 const vk::Unique<vk::VkDescriptorPool> descriptorPool(createDescriptorPool());
8535 std::vector<DescriptorSetLayoutHandleSp> descriptorSetLayouts;
8536 std::vector<DescriptorSetHandleSp> descriptorSets;
8537 std::vector<vk::VkDescriptorSetLayout> layoutHandles;
8538 std::vector<vk::VkDescriptorSet> setHandles;
8540 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8542 vk::Move<vk::VkDescriptorSetLayout> layout = createDescriptorSetLayout(setNdx);
8543 vk::Move<vk::VkDescriptorSet> set = createDescriptorSet(*descriptorPool, *layout, setNdx);
8545 descriptorSetLayouts.push_back(DescriptorSetLayoutHandleSp(new DescriptorSetLayoutHandleUp(layout)));
8546 descriptorSets.push_back(DescriptorSetHandleSp(new DescriptorSetHandleUp(set)));
8548 layoutHandles.push_back(**descriptorSetLayouts.back());
8549 setHandles.push_back(**descriptorSets.back());
8552 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), (int)layoutHandles.size(), &layoutHandles.front());
8553 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : getDescriptorSetCount(m_descriptorSetCount);
8554 const deUint32* const dynamicOffsets = DE_NULL;
8555 const int numDynamicOffsets = 0;
8556 const vk::VkBufferMemoryBarrier* const preBarriers = m_texelBuffers.getBufferInitBarriers();
8557 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
8558 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
8559 const int numPostBarriers = 1;
8561 const ComputeCommand compute (m_vki,
8563 pipeline.getPipeline(),
8564 pipeline.getPipelineLayout(),
8565 tcu::UVec3(4, 1, 1),
8566 numDescriptorSets, &setHandles.front(),
8567 numDynamicOffsets, dynamicOffsets,
8568 numPreBarriers, preBarriers,
8569 numPostBarriers, postBarriers);
8571 tcu::Vec4 results[4];
8572 bool anyResultSet = false;
8573 bool allResultsOk = true;
8575 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
8577 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8578 writeDescriptorSetWithTemplate(DE_NULL, layoutHandles[setNdx], setNdx, true, pipeline.getPipelineLayout());
8580 compute.submitAndWait(m_queueFamilyIndex, m_queue, &m_updateTemplates, &m_updateRegistry);
8582 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
8584 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8585 writeDescriptorSet(DE_NULL, setNdx);
8587 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder, m_descriptorsPerSet);
8591 compute.submitAndWait(m_queueFamilyIndex, m_queue);
8593 m_result.readResultContentsTo(&results);
8596 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
8598 const tcu::Vec4 result = results[resultNdx];
8599 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
8601 tcu::Vec4 reference = tcu::Vec4(0.0f);
8602 for (deUint32 setNdx = 0; setNdx < getDescriptorSetCount(m_descriptorSetCount); setNdx++)
8603 reference += m_texelBuffers.fetchTexelValue(resultNdx, setNdx);
8605 reference = reference / tcu::Vec4((float)getDescriptorSetCount(m_descriptorSetCount));
8607 if (result != tcu::Vec4(-1.0f))
8608 anyResultSet = true;
8610 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
8612 allResultsOk = false;
8614 m_context.getTestContext().getLog()
8615 << tcu::TestLog::Message
8616 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
8617 << tcu::TestLog::EndMessage;
8621 // read back and verify
8623 return tcu::TestStatus::pass("Pass");
8624 else if (anyResultSet)
8625 return tcu::TestStatus::fail("Invalid result values");
8628 m_context.getTestContext().getLog()
8629 << tcu::TestLog::Message
8630 << "Result buffer was not written to."
8631 << tcu::TestLog::EndMessage;
8632 return tcu::TestStatus::fail("Result buffer was not written to");
8636 class TexelBufferDescriptorCase : public QuadrantRendederCase
8641 FLAG_VIEW_OFFSET = (1u << 1u),
8643 // enum continues where resource flags ends
8644 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
8646 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
8647 DescriptorUpdateMethod updateMethod,
8649 const char* description,
8650 bool isPrimaryCmdBuf,
8651 vk::VkDescriptorType descriptorType,
8652 vk::VkShaderStageFlags exitingStages,
8653 vk::VkShaderStageFlags activeStages,
8654 DescriptorSetCount descriptorSetCount,
8655 ShaderInputInterface shaderInterface,
8659 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
8660 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
8661 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
8662 std::string genNoAccessSource (void) const;
8664 vkt::TestInstance* createInstance (vkt::Context& context) const;
8666 const DescriptorUpdateMethod m_updateMethod;
8667 const bool m_isPrimaryCmdBuf;
8668 const vk::VkDescriptorType m_descriptorType;
8669 const DescriptorSetCount m_descriptorSetCount;
8670 const ShaderInputInterface m_shaderInterface;
8671 const bool m_nonzeroViewOffset;
8674 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
8675 DescriptorUpdateMethod updateMethod,
8677 const char* description,
8678 bool isPrimaryCmdBuf,
8679 vk::VkDescriptorType descriptorType,
8680 vk::VkShaderStageFlags exitingStages,
8681 vk::VkShaderStageFlags activeStages,
8682 DescriptorSetCount descriptorSetCount,
8683 ShaderInputInterface shaderInterface,
8685 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages, descriptorSetCount)
8686 , m_updateMethod (updateMethod)
8687 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
8688 , m_descriptorType (descriptorType)
8689 , m_descriptorSetCount (descriptorSetCount)
8690 , m_shaderInterface (shaderInterface)
8691 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
8695 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
8698 return "#extension GL_EXT_texture_buffer : require\n";
8701 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
8705 const bool isUniform = isUniformDescriptorType(m_descriptorType);
8706 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
8707 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
8708 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
8710 std::ostringstream buf;
8712 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
8714 // Result buffer is bound only to the first descriptor set in compute shader cases
8715 const int descBinding = numUsedBindings - ((m_activeStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) ? (setNdx == 0 ? 0 : 1) : 0);
8716 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
8718 switch (m_shaderInterface)
8720 case SHADER_INPUT_SINGLE_DESCRIPTOR:
8721 buf << "layout(set = " << setNdx << ", binding = " + de::toString(descBinding) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer" << setNdxPostfix << ";\n";
8723 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
8724 buf << "layout(set = " << setNdx << ", binding = " + de::toString(descBinding) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer" << setNdxPostfix << "A;\n"
8725 "layout(set = " << setNdx << ", binding = " + de::toString(descBinding + 1) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer" << setNdxPostfix << "B;\n";
8727 case SHADER_INPUT_DESCRIPTOR_ARRAY:
8728 buf << "layout(set = " << setNdx << ", binding = " + de::toString(descBinding) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer" << setNdxPostfix << "[2];\n";
8731 DE_FATAL("Impossible");
8738 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
8742 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
8743 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
8744 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
8746 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
8747 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
8748 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
8750 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
8751 const deUint32 numSets = getDescriptorSetCount(m_descriptorSetCount);
8753 std::ostringstream buf;
8755 buf << " result_color = vec4(0.0);\n";
8757 for (deUint32 setNdx = 0; setNdx < numSets; setNdx++)
8759 const std::string setNdxPostfix = (numSets == 1) ? "" : de::toString(setNdx);
8761 buf << " if (quadrant_id == 0)\n"
8762 << " result_color += " << fetchFunc << "(u_texelBuffer" << setNdxPostfix << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
8763 << " else if (quadrant_id == 1)\n"
8764 << " result_color += " << fetchFunc << "(u_texelBuffer" << setNdxPostfix << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
8765 << " else if (quadrant_id == 2)\n"
8766 << " result_color += " << fetchFunc << "(u_texelBuffer" << setNdxPostfix << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
8768 << " result_color += " << fetchFunc << "(u_texelBuffer" << setNdxPostfix << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
8771 if (m_descriptorSetCount == DESCRIPTOR_SET_COUNT_MULTIPLE)
8772 buf << " result_color /= vec4(" << getDescriptorSetCount(m_descriptorSetCount) << ".0);\n";
8777 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
8779 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
8780 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
8782 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
8785 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
8787 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
8789 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
8791 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
8792 return new TexelBufferComputeInstance(context, m_updateMethod, m_descriptorType, m_descriptorSetCount, m_shaderInterface, m_nonzeroViewOffset);
8795 return new TexelBufferRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_descriptorSetCount, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
8798 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
8799 bool isPrimaryCmdBuf,
8800 DescriptorUpdateMethod updateMethod,
8801 vk::VkDescriptorType descriptorType,
8802 vk::VkShaderStageFlags exitingStages,
8803 vk::VkShaderStageFlags activeStages,
8804 DescriptorSetCount descriptorSetCount,
8805 ShaderInputInterface dimension,
8806 deUint32 resourceFlags)
8810 vk::VkImageViewType viewType;
8812 const char* description;
8816 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
8817 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
8818 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
8820 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
8821 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
8822 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
8824 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
8825 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
8826 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
8828 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
8829 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
8830 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
8832 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
8833 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
8834 // no 3d array textures
8836 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
8837 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
8838 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
8840 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
8841 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
8842 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
8845 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
8848 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
8851 if (dimension == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS)
8854 // SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS only supported in VK_DESCRIPTOR_TYPE_SAMPLER on graphics shaders for now
8855 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS &&
8856 (descriptorType != vk::VK_DESCRIPTOR_TYPE_SAMPLER || activeStages == vk::VK_SHADER_STAGE_COMPUTE_BIT))
8859 group->addChild(new ImageDescriptorCase(group->getTestContext(),
8860 s_imageTypes[ndx].name,
8861 s_imageTypes[ndx].description,
8869 s_imageTypes[ndx].viewType,
8870 s_imageTypes[ndx].flags | resourceFlags));
8874 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
8875 bool isPrimaryCmdBuf,
8876 DescriptorUpdateMethod updateMethod,
8877 vk::VkDescriptorType descriptorType,
8878 vk::VkShaderStageFlags exitingStages,
8879 vk::VkShaderStageFlags activeStages,
8880 DescriptorSetCount descriptorSetCount,
8881 ShaderInputInterface dimension,
8882 deUint32 resourceFlags)
8884 DE_ASSERT(resourceFlags == 0);
8885 DE_UNREF(resourceFlags);
8890 const char* description;
8892 } s_texelBufferTypes[] =
8894 { "offset_zero", "View offset is zero", 0u },
8895 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
8898 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
8900 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS || dimension == SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS)
8903 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
8905 s_texelBufferTypes[ndx].name,
8906 s_texelBufferTypes[ndx].description,
8913 s_texelBufferTypes[ndx].flags));
8917 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
8918 bool isPrimaryCmdBuf,
8919 DescriptorUpdateMethod updateMethod,
8920 vk::VkDescriptorType descriptorType,
8921 vk::VkShaderStageFlags exitingStages,
8922 vk::VkShaderStageFlags activeStages,
8923 DescriptorSetCount descriptorSetCount,
8924 ShaderInputInterface dimension,
8925 deUint32 resourceFlags)
8927 DE_ASSERT(resourceFlags == 0u);
8928 DE_UNREF(resourceFlags);
8933 const char* description;
8934 bool isForDynamicCases;
8938 { "offset_view_zero", "View offset is zero", false, 0u },
8939 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
8941 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
8942 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
8943 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
8944 { "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 },
8947 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
8951 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH || updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
8953 // Can't support push descriptor sets with dynamic UBOs or SSBOs
8958 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
8960 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
8963 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
8964 group->addChild(new BufferDescriptorCase(group->getTestContext(),
8966 s_bufferTypes[ndx].name,
8967 s_bufferTypes[ndx].description,
8974 s_bufferTypes[ndx].flags));
8980 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
8984 const bool isPrimary;
8986 const char* description;
8989 { true, "primary_cmd_buf", "Bind in primary command buffer" },
8990 { false, "secondary_cmd_buf", "Bind in secondary command buffer" },
8994 const DescriptorUpdateMethod method;
8996 const char* description;
8997 } s_updateMethods[] =
8999 { DESCRIPTOR_UPDATE_METHOD_NORMAL, "", "Use regular descriptor updates" },
9000 { DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE, "with_template", "Use descriptor update templates" },
9001 { DESCRIPTOR_UPDATE_METHOD_WITH_PUSH, "with_push", "Use push descriptor updates" },
9002 { DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE, "with_push_template", "Use push descriptor update templates" },
9006 const vk::VkDescriptorType descriptorType;
9008 const char* description;
9010 } s_descriptorTypes[] =
9012 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
9013 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
9014 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
9015 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
9016 // \note No way to access SAMPLED_IMAGE without a sampler
9017 //{ vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
9018 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
9019 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
9020 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
9021 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
9022 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
9023 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
9024 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
9029 const char* description;
9030 vk::VkShaderStageFlags existingStages; //!< stages that exists
9031 vk::VkShaderStageFlags activeStages; //!< stages that access resource
9032 bool supportsSecondaryCmdBufs;
9033 } s_shaderStages[] =
9037 "No accessing stages",
9038 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9045 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9046 vk::VK_SHADER_STAGE_VERTEX_BIT,
9051 "Tessellation control stage",
9052 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,
9053 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
9058 "Tessellation evaluation stage",
9059 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,
9060 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
9066 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9067 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
9073 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9074 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9080 vk::VK_SHADER_STAGE_COMPUTE_BIT,
9081 vk::VK_SHADER_STAGE_COMPUTE_BIT,
9086 "Vertex and fragment stages",
9087 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9088 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
9094 ShaderInputInterface dimension;
9096 const char* description;
9097 } s_variableDimensions[] =
9099 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
9100 { SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, "multiple_contiguous_descriptors", "Multiple descriptors" },
9101 { SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, "multiple_discontiguous_descriptors", "Multiple descriptors" },
9102 { SHADER_INPUT_MULTIPLE_ARBITRARY_DESCRIPTORS, "multiple_arbitrary_descriptors", "Multiple descriptors" },
9103 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
9106 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
9108 // .primary_cmd_buf...
9109 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
9111 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
9113 for (int updateMethodNdx = 0; updateMethodNdx < DE_LENGTH_OF_ARRAY(s_updateMethods); ++updateMethodNdx)
9115 de::MovePtr<tcu::TestCaseGroup> updateMethodGroup(new tcu::TestCaseGroup(testCtx, s_updateMethods[updateMethodNdx].name, s_updateMethods[updateMethodNdx].description));
9117 // .sampler, .combined_image_sampler, other resource types ...
9118 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
9120 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
9122 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
9124 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
9126 de::MovePtr<tcu::TestCaseGroup> stageGroup (new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
9127 de::MovePtr<tcu::TestCaseGroup> multipleGroup (new tcu::TestCaseGroup(testCtx, "multiple_descriptor_sets", "Multiple descriptor sets"));
9129 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
9131 de::MovePtr<tcu::TestCaseGroup> dimensionSingleDescriptorSetGroup (new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
9132 de::MovePtr<tcu::TestCaseGroup> dimensionMultipleDescriptorSetsGroup (new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
9133 void (*createTestsFunc)(tcu::TestCaseGroup* group,
9134 bool isPrimaryCmdBuf,
9135 DescriptorUpdateMethod updateMethod,
9136 vk::VkDescriptorType descriptorType,
9137 vk::VkShaderStageFlags existingStages,
9138 vk::VkShaderStageFlags activeStages,
9139 DescriptorSetCount descriptorSetCount,
9140 ShaderInputInterface dimension,
9141 deUint32 resourceFlags);
9143 switch (s_descriptorTypes[descriptorNdx].descriptorType)
9145 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
9146 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
9147 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
9148 createTestsFunc = createShaderAccessImageTests;
9151 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
9152 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
9153 createTestsFunc = createShaderAccessTexelBufferTests;
9156 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
9157 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
9158 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
9159 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
9160 createTestsFunc = createShaderAccessBufferTests;
9164 createTestsFunc = DE_NULL;
9165 DE_FATAL("Impossible");
9168 if (createTestsFunc)
9170 createTestsFunc(dimensionSingleDescriptorSetGroup.get(),
9171 s_bindTypes[bindTypeNdx].isPrimary,
9172 s_updateMethods[updateMethodNdx].method,
9173 s_descriptorTypes[descriptorNdx].descriptorType,
9174 s_shaderStages[stageNdx].existingStages,
9175 s_shaderStages[stageNdx].activeStages,
9176 DESCRIPTOR_SET_COUNT_SINGLE,
9177 s_variableDimensions[dimensionNdx].dimension,
9178 s_descriptorTypes[descriptorNdx].flags);
9180 createTestsFunc(dimensionMultipleDescriptorSetsGroup.get(),
9181 s_bindTypes[bindTypeNdx].isPrimary,
9182 s_updateMethods[updateMethodNdx].method,
9183 s_descriptorTypes[descriptorNdx].descriptorType,
9184 s_shaderStages[stageNdx].existingStages,
9185 s_shaderStages[stageNdx].activeStages,
9186 DESCRIPTOR_SET_COUNT_MULTIPLE,
9187 s_variableDimensions[dimensionNdx].dimension,
9188 s_descriptorTypes[descriptorNdx].flags);
9191 DE_FATAL("Impossible");
9193 stageGroup->addChild(dimensionSingleDescriptorSetGroup.release());
9195 // Only one descriptor set layout can be created with VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR set
9196 if (s_updateMethods[updateMethodNdx].method == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH || s_updateMethods[updateMethodNdx].method == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
9199 multipleGroup->addChild(dimensionMultipleDescriptorSetsGroup.release());
9202 stageGroup->addChild(multipleGroup.release());
9203 typeGroup->addChild(stageGroup.release());
9207 if (s_updateMethods[updateMethodNdx].method != DESCRIPTOR_UPDATE_METHOD_NORMAL)
9209 updateMethodGroup->addChild(typeGroup.release());
9213 bindGroup->addChild(typeGroup.release());
9217 if (s_updateMethods[updateMethodNdx].method != DESCRIPTOR_UPDATE_METHOD_NORMAL)
9219 bindGroup->addChild(updateMethodGroup.release());
9223 group->addChild(bindGroup.release());
9226 return group.release();