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_TOP_OF_PIPE_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_TOP_OF_PIPE_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 ShaderInputInterface
1230 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1231 SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with contiguous binding id's
1232 SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with discontiguous binding id's
1233 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1238 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1240 switch (shaderInterface)
1242 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1243 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS: return 2u;
1244 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS: return 2u;
1245 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1248 DE_FATAL("Impossible");
1253 class BufferRenderInstance : public SingleCmdRenderInstance
1256 BufferRenderInstance (Context& context,
1257 DescriptorUpdateMethod updateMethod,
1258 bool isPrimaryCmdBuf,
1259 vk::VkDescriptorType descriptorType,
1260 vk::VkShaderStageFlags stageFlags,
1261 ShaderInputInterface shaderInterface,
1264 bool dynamicOffsetNonZero);
1266 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1267 vk::VkDevice device,
1268 vk::Allocator& allocator,
1269 vk::VkDescriptorType descriptorType,
1271 deUint32 bufferSize,
1272 de::MovePtr<vk::Allocation>* outMemory);
1274 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1275 vk::VkDevice device,
1276 vk::VkDescriptorType descriptorType,
1277 ShaderInputInterface shaderInterface);
1279 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1280 vk::VkDevice device,
1281 vk::VkDescriptorType descriptorType,
1282 ShaderInputInterface shaderInterface,
1283 vk::VkShaderStageFlags stageFlags,
1284 DescriptorUpdateMethod updateMethod);
1286 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1287 DescriptorUpdateMethod updateMethod,
1288 vk::VkDevice device,
1289 vk::VkDescriptorSetLayout descriptorSetLayout,
1290 vk::VkDescriptorPool descriptorPool,
1291 vk::VkDescriptorType descriptorType,
1292 ShaderInputInterface shaderInterface,
1293 vk::VkBuffer sourceBufferA,
1294 const deUint32 viewOffsetA,
1295 vk::VkBuffer sourceBufferB,
1296 const deUint32 viewOffsetB,
1297 vk::DescriptorSetUpdateBuilder& updateBuilder,
1298 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
1299 RawUpdateRegistry& updateRegistry,
1300 vk::VkPipelineLayout pipelineLayout = DE_NULL);
1302 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1303 vk::VkDevice device,
1304 vk::VkDescriptorSetLayout descriptorSetLayout);
1306 static void writeDescriptorSet (const vk::DeviceInterface& vki,
1307 vk::VkDevice device,
1308 vk::VkDescriptorSetLayout descriptorSetLayout,
1309 vk::VkDescriptorPool descriptorPool,
1310 vk::VkDescriptorType descriptorType,
1311 ShaderInputInterface shaderInterface,
1312 vk::VkBuffer sourceBufferA,
1313 const deUint32 viewOffsetA,
1314 vk::VkBuffer sourceBufferB,
1315 const deUint32 viewOffsetB,
1316 vk::VkDescriptorSet descriptorSet,
1317 vk::DescriptorSetUpdateBuilder& updateBuilder,
1318 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
1320 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
1321 vk::VkDevice device,
1322 vk::VkDescriptorSetLayout descriptorSetLayout,
1323 vk::VkDescriptorPool descriptorPool,
1324 vk::VkDescriptorType descriptorType,
1325 ShaderInputInterface shaderInterface,
1326 vk::VkBuffer sourceBufferA,
1327 const deUint32 viewOffsetA,
1328 vk::VkBuffer sourceBufferB,
1329 const deUint32 viewOffsetB,
1330 vk::VkDescriptorSet descriptorSet,
1331 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
1332 RawUpdateRegistry& updateRegistry,
1333 bool withPush = false,
1334 vk::VkPipelineLayout pipelineLayout = 0);
1336 void logTestPlan (void) const;
1337 vk::VkPipelineLayout getPipelineLayout (void) const;
1338 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1339 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1344 BUFFER_DATA_SIZE = 8 * sizeof(float),
1345 BUFFER_SIZE_A = 2048, //!< a lot more than required
1346 BUFFER_SIZE_B = 2560, //!< a lot more than required
1348 STATIC_OFFSET_VALUE_A = 256,
1349 DYNAMIC_OFFSET_VALUE_A = 512,
1350 STATIC_OFFSET_VALUE_B = 1024,
1351 DYNAMIC_OFFSET_VALUE_B = 768,
1354 const DescriptorUpdateMethod m_updateMethod;
1355 const vk::VkDescriptorType m_descriptorType;
1356 const ShaderInputInterface m_shaderInterface;
1357 const bool m_setViewOffset;
1358 const bool m_setDynamicOffset;
1359 const bool m_dynamicOffsetNonZero;
1360 const vk::VkShaderStageFlags m_stageFlags;
1362 const deUint32 m_viewOffsetA;
1363 const deUint32 m_viewOffsetB;
1364 const deUint32 m_dynamicOffsetA;
1365 const deUint32 m_dynamicOffsetB;
1366 const deUint32 m_effectiveOffsetA;
1367 const deUint32 m_effectiveOffsetB;
1368 const deUint32 m_bufferSizeA;
1369 const deUint32 m_bufferSizeB;
1371 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1372 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1373 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1374 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1375 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1376 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
1377 RawUpdateRegistry m_updateRegistry;
1378 vk::DescriptorSetUpdateBuilder m_updateBuilder;
1379 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1380 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1381 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1384 BufferRenderInstance::BufferRenderInstance (Context& context,
1385 DescriptorUpdateMethod updateMethod,
1386 bool isPrimaryCmdBuf,
1387 vk::VkDescriptorType descriptorType,
1388 vk::VkShaderStageFlags stageFlags,
1389 ShaderInputInterface shaderInterface,
1392 bool dynamicOffsetNonZero)
1393 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1394 , m_updateMethod (updateMethod)
1395 , m_descriptorType (descriptorType)
1396 , m_shaderInterface (shaderInterface)
1397 , m_setViewOffset (viewOffset)
1398 , m_setDynamicOffset (dynamicOffset)
1399 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1400 , m_stageFlags (stageFlags)
1401 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1402 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1403 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1404 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1405 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetA + m_dynamicOffsetA) : (m_viewOffsetA))
1406 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetB + m_dynamicOffsetB) : (m_viewOffsetB))
1407 , m_bufferSizeA (BUFFER_SIZE_A)
1408 , m_bufferSizeB (BUFFER_SIZE_B)
1409 , m_bufferMemoryA (DE_NULL)
1410 , m_bufferMemoryB (DE_NULL)
1411 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1412 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1413 ? vk::Move<vk::VkBuffer>()
1414 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1415 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1416 , m_updateTemplate ()
1417 , m_updateRegistry ()
1418 , m_updateBuilder ()
1419 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_updateMethod))
1420 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1421 , m_descriptorSet (createDescriptorSet(m_vki, m_updateMethod, m_device, *m_descriptorSetLayout, *m_descriptorPool, m_descriptorType, m_shaderInterface, *m_sourceBufferA, m_viewOffsetA, *m_sourceBufferB, m_viewOffsetB, m_updateBuilder, m_updateTemplate, m_updateRegistry, *m_pipelineLayout))
1423 if (m_setDynamicOffset)
1424 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1425 if (m_dynamicOffsetNonZero)
1426 DE_ASSERT(m_setDynamicOffset);
1429 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1430 vk::VkDevice device,
1431 vk::Allocator& allocator,
1432 vk::VkDescriptorType descriptorType,
1434 deUint32 bufferSize,
1435 de::MovePtr<vk::Allocation>* outMemory)
1437 static const float s_colors[] =
1439 0.0f, 1.0f, 0.0f, 1.0f, // green
1440 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1442 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1443 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1444 DE_ASSERT(offset % sizeof(float) == 0);
1445 DE_ASSERT(bufferSize % sizeof(float) == 0);
1447 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1448 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1449 const float preGuardValue = 0.5f;
1450 const float postGuardValue = 0.75f;
1451 const vk::VkBufferCreateInfo bufferCreateInfo =
1453 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1457 usageFlags, // usage
1458 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1459 0u, // queueFamilyCount
1460 DE_NULL, // pQueueFamilyIndices
1462 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1463 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1464 void* const mapPtr = bufferMemory->getHostPtr();
1466 // guard with interesting values
1467 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1468 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1470 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1471 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1472 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1473 deMemset((deUint8*)mapPtr + offset + sizeof(s_colors), 0x5A, (size_t)bufferSize - (size_t)offset - sizeof(s_colors)); // fill with interesting pattern that produces valid floats
1475 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1477 // Flushed host-visible memory is automatically made available to the GPU, no barrier is needed.
1479 *outMemory = bufferMemory;
1483 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1484 vk::VkDevice device,
1485 vk::VkDescriptorType descriptorType,
1486 ShaderInputInterface shaderInterface)
1488 return vk::DescriptorPoolBuilder()
1489 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1490 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1493 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1494 vk::VkDevice device,
1495 vk::VkDescriptorType descriptorType,
1496 ShaderInputInterface shaderInterface,
1497 vk::VkShaderStageFlags stageFlags,
1498 DescriptorUpdateMethod updateMethod)
1500 vk::DescriptorSetLayoutBuilder builder;
1501 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
1503 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
1504 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1506 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
1509 switch (shaderInterface)
1511 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1512 builder.addSingleBinding(descriptorType, stageFlags);
1515 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1516 builder.addSingleBinding(descriptorType, stageFlags);
1517 builder.addSingleBinding(descriptorType, stageFlags);
1520 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1521 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1525 DE_FATAL("Impossible");
1528 return builder.build(vki, device, extraFlags);
1531 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1532 DescriptorUpdateMethod updateMethod,
1533 vk::VkDevice device,
1534 vk::VkDescriptorSetLayout descriptorSetLayout,
1535 vk::VkDescriptorPool descriptorPool,
1536 vk::VkDescriptorType descriptorType,
1537 ShaderInputInterface shaderInterface,
1538 vk::VkBuffer bufferA,
1540 vk::VkBuffer bufferB,
1542 vk::DescriptorSetUpdateBuilder& updateBuilder,
1543 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
1544 RawUpdateRegistry& updateRegistry,
1545 vk::VkPipelineLayout pipelineLayout)
1547 const vk::VkDescriptorSetAllocateInfo allocInfo =
1549 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1553 &descriptorSetLayout
1556 vk::Move<vk::VkDescriptorSet> descriptorSet;
1557 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1559 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1563 descriptorSet = vk::Move<vk::VkDescriptorSet>();
1566 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
1568 writeDescriptorSetWithTemplate(vki, device, descriptorSetLayout, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateTemplate, updateRegistry);
1570 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1572 writeDescriptorSetWithTemplate(vki, device, descriptorSetLayout, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateTemplate, updateRegistry, true, pipelineLayout);
1574 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1576 writeDescriptorSet(vki, device, descriptorSetLayout, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateBuilder, updateMethod);
1578 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
1580 writeDescriptorSet(vki, device, descriptorSetLayout, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateBuilder);
1583 return descriptorSet;
1586 void BufferRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
1587 vk::VkDevice device,
1588 vk::VkDescriptorSetLayout descriptorSetLayout,
1589 vk::VkDescriptorPool descriptorPool,
1590 vk::VkDescriptorType descriptorType,
1591 ShaderInputInterface shaderInterface,
1592 vk::VkBuffer bufferA,
1593 const deUint32 offsetA,
1594 vk::VkBuffer bufferB,
1595 const deUint32 offsetB,
1596 vk::VkDescriptorSet descriptorSet,
1597 vk::DescriptorSetUpdateBuilder& updateBuilder,
1598 DescriptorUpdateMethod updateMethod)
1600 DE_UNREF(descriptorSetLayout);
1601 DE_UNREF(descriptorPool);
1602 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1604 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1605 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1608 switch (shaderInterface)
1610 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1611 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1614 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1615 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1616 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1619 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1620 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1624 DE_FATAL("Impossible");
1627 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
1629 updateBuilder.update(vki, device);
1633 void BufferRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
1634 vk::VkDevice device,
1635 vk::VkDescriptorSetLayout layout,
1636 vk::VkDescriptorPool descriptorPool,
1637 vk::VkDescriptorType descriptorType,
1638 ShaderInputInterface shaderInterface,
1639 vk::VkBuffer bufferA,
1640 const deUint32 offsetA,
1641 vk::VkBuffer bufferB,
1642 const deUint32 offsetB,
1643 vk::VkDescriptorSet descriptorSet,
1644 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
1645 RawUpdateRegistry& updateRegistry,
1647 vk::VkPipelineLayout pipelineLayout)
1649 DE_UNREF(descriptorPool);
1650 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1652 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1653 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1655 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
1656 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
1658 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
1661 0, // descriptorUpdateEntryCount
1662 DE_NULL, // pDescriptorUpdateEntries
1663 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
1665 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
1669 updateRegistry.addWriteObject(bufferInfos[0]);
1670 updateRegistry.addWriteObject(bufferInfos[1]);
1672 switch (shaderInterface)
1674 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1675 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1678 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1679 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1680 updateEntries.push_back(createTemplateBinding(1u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
1683 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1684 updateEntries.push_back(createTemplateBinding(0u, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(bufferInfos[0])));
1688 DE_FATAL("Impossible");
1691 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
1692 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
1694 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
1698 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
1702 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1703 vk::VkDevice device,
1704 vk::VkDescriptorSetLayout descriptorSetLayout)
1706 const vk::VkPipelineLayoutCreateInfo createInfo =
1708 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1710 (vk::VkPipelineLayoutCreateFlags)0,
1711 1, // descriptorSetCount
1712 &descriptorSetLayout, // pSetLayouts
1713 0u, // pushConstantRangeCount
1714 DE_NULL, // pPushConstantRanges
1717 return vk::createPipelineLayout(vki, device, &createInfo);
1720 void BufferRenderInstance::logTestPlan (void) const
1722 std::ostringstream msg;
1724 msg << "Rendering 2x2 yellow-green grid.\n"
1725 << "Single descriptor set. Descriptor set contains "
1726 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1727 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
1728 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1729 (const char*)DE_NULL)
1730 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1731 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1733 if (isDynamicDescriptorType(m_descriptorType))
1735 if (m_setDynamicOffset)
1737 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1738 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1742 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1746 if (m_stageFlags == 0u)
1748 msg << "Descriptors are not accessed in any shader stage.\n";
1752 msg << "Descriptors are accessed in {"
1753 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1754 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1755 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1756 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1757 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1761 m_context.getTestContext().getLog()
1762 << tcu::TestLog::Message
1764 << tcu::TestLog::EndMessage;
1767 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1769 return *m_pipelineLayout;
1772 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1774 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1775 const deUint32 dynamicOffsets[] =
1780 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1781 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1783 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1785 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1787 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1789 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, *m_updateTemplate, getPipelineLayout(), 0, (const void*)m_updateRegistry.getRawPointer());
1791 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1793 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0);
1796 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1799 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1801 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1802 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1803 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1805 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1807 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1808 return tcu::TestStatus::fail("Image verification failed");
1810 return tcu::TestStatus::pass("Pass");
1813 class ComputeInstanceResultBuffer
1818 DATA_SIZE = sizeof(tcu::Vec4[4])
1821 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1822 vk::VkDevice device,
1823 vk::Allocator& allocator);
1825 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1827 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1828 inline const vk::VkBufferMemoryBarrier* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1831 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1832 vk::VkDevice device,
1833 vk::Allocator& allocator,
1834 de::MovePtr<vk::Allocation>* outAllocation);
1836 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1838 const vk::DeviceInterface& m_vki;
1839 const vk::VkDevice m_device;
1841 de::MovePtr<vk::Allocation> m_bufferMem;
1842 const vk::Unique<vk::VkBuffer> m_buffer;
1843 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1846 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1847 vk::VkDevice device,
1848 vk::Allocator& allocator)
1851 , m_bufferMem (DE_NULL)
1852 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1853 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1857 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1859 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1860 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1863 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1864 vk::VkDevice device,
1865 vk::Allocator& allocator,
1866 de::MovePtr<vk::Allocation>* outAllocation)
1868 const vk::VkBufferCreateInfo createInfo =
1870 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1873 (vk::VkDeviceSize)DATA_SIZE, // size
1874 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1875 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1876 0u, // queueFamilyCount
1877 DE_NULL, // pQueueFamilyIndices
1879 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1880 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1881 const float clearValue = -1.0f;
1882 void* mapPtr = allocation->getHostPtr();
1884 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1885 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1887 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1889 *outAllocation = allocation;
1893 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1895 const vk::VkBufferMemoryBarrier bufferBarrier =
1897 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1899 vk::VK_ACCESS_SHADER_WRITE_BIT, // outputMask
1900 vk::VK_ACCESS_HOST_READ_BIT, // inputMask
1901 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1902 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1904 (vk::VkDeviceSize)0u, // offset
1907 return bufferBarrier;
1910 class ComputePipeline
1913 ComputePipeline (const vk::DeviceInterface& vki,
1914 vk::VkDevice device,
1915 const vk::BinaryCollection& programCollection,
1916 deUint32 numDescriptorSets,
1917 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1919 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1920 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1923 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1924 vk::VkDevice device,
1925 deUint32 numDescriptorSets,
1926 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1928 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1929 vk::VkDevice device,
1930 const vk::BinaryCollection& programCollection,
1931 vk::VkPipelineLayout layout);
1933 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1934 const vk::Unique<vk::VkPipeline> m_pipeline;
1937 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1938 vk::VkDevice device,
1939 const vk::BinaryCollection& programCollection,
1940 deUint32 numDescriptorSets,
1941 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1942 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
1943 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
1947 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
1948 vk::VkDevice device,
1949 deUint32 numDescriptorSets,
1950 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1952 const vk::VkPipelineLayoutCreateInfo createInfo =
1954 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1956 (vk::VkPipelineLayoutCreateFlags)0,
1957 numDescriptorSets, // descriptorSetCount
1958 descriptorSetLayouts, // pSetLayouts
1959 0u, // pushConstantRangeCount
1960 DE_NULL, // pPushConstantRanges
1962 return vk::createPipelineLayout(vki, device, &createInfo);
1965 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
1966 vk::VkDevice device,
1967 const vk::BinaryCollection& programCollection,
1968 vk::VkPipelineLayout layout)
1970 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
1971 const vk::VkPipelineShaderStageCreateInfo cs =
1973 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1975 (vk::VkPipelineShaderStageCreateFlags)0,
1976 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
1977 *computeModule, // shader
1979 DE_NULL, // pSpecializationInfo
1981 const vk::VkComputePipelineCreateInfo createInfo =
1983 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1988 (vk::VkPipeline)0, // basePipelineHandle
1989 0u, // basePipelineIndex
1991 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
1994 class ComputeCommand
1997 ComputeCommand (const vk::DeviceInterface& vki,
1998 vk::VkDevice device,
1999 vk::VkPipeline pipeline,
2000 vk::VkPipelineLayout pipelineLayout,
2001 const tcu::UVec3& numWorkGroups,
2002 int numDescriptorSets,
2003 const vk::VkDescriptorSet* descriptorSets,
2004 int numDynamicOffsets,
2005 const deUint32* dynamicOffsets,
2007 const vk::VkBufferMemoryBarrier* preBarriers,
2008 int numPostBarriers,
2009 const vk::VkBufferMemoryBarrier* postBarriers);
2011 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::VkDescriptorUpdateTemplateKHR updateTemplate = DE_NULL, const void *rawUpdateData = 0) const;
2012 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::DescriptorSetUpdateBuilder& updateBuilder) const;
2015 const vk::DeviceInterface& m_vki;
2016 const vk::VkDevice m_device;
2017 const vk::VkPipeline m_pipeline;
2018 const vk::VkPipelineLayout m_pipelineLayout;
2019 const tcu::UVec3 m_numWorkGroups;
2020 const int m_numDescriptorSets;
2021 const vk::VkDescriptorSet* const m_descriptorSets;
2022 const int m_numDynamicOffsets;
2023 const deUint32* const m_dynamicOffsets;
2024 const int m_numPreBarriers;
2025 const vk::VkBufferMemoryBarrier* const m_preBarriers;
2026 const int m_numPostBarriers;
2027 const vk::VkBufferMemoryBarrier* const m_postBarriers;
2030 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
2031 vk::VkDevice device,
2032 vk::VkPipeline pipeline,
2033 vk::VkPipelineLayout pipelineLayout,
2034 const tcu::UVec3& numWorkGroups,
2035 int numDescriptorSets,
2036 const vk::VkDescriptorSet* descriptorSets,
2037 int numDynamicOffsets,
2038 const deUint32* dynamicOffsets,
2040 const vk::VkBufferMemoryBarrier* preBarriers,
2041 int numPostBarriers,
2042 const vk::VkBufferMemoryBarrier* postBarriers)
2045 , m_pipeline (pipeline)
2046 , m_pipelineLayout (pipelineLayout)
2047 , m_numWorkGroups (numWorkGroups)
2048 , m_numDescriptorSets (numDescriptorSets)
2049 , m_descriptorSets (descriptorSets)
2050 , m_numDynamicOffsets (numDynamicOffsets)
2051 , m_dynamicOffsets (dynamicOffsets)
2052 , m_numPreBarriers (numPreBarriers)
2053 , m_preBarriers (preBarriers)
2054 , m_numPostBarriers (numPostBarriers)
2055 , m_postBarriers (postBarriers)
2059 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::VkDescriptorUpdateTemplateKHR updateTemplate, const void *rawUpdateData) const
2061 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
2063 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2065 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
2066 queueFamilyIndex, // queueFamilyIndex
2068 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
2070 const vk::VkFenceCreateInfo fenceCreateInfo =
2072 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2077 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
2079 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
2081 *cmdPool, // cmdPool
2082 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
2085 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
2087 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2089 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
2090 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
2093 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
2094 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
2095 const deUint64 infiniteTimeout = ~(deUint64)0u;
2097 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
2099 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
2101 if (m_numDescriptorSets)
2103 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
2106 if (updateTemplate != DE_NULL)
2108 // we need to update the push descriptors
2109 m_vki.cmdPushDescriptorSetWithTemplateKHR(*cmd, updateTemplate, m_pipelineLayout, 0, rawUpdateData);
2112 if (m_numPreBarriers)
2113 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
2114 0, (const vk::VkMemoryBarrier*)DE_NULL,
2115 m_numPreBarriers, m_preBarriers,
2116 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2118 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
2119 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
2120 0, (const vk::VkMemoryBarrier*)DE_NULL,
2121 m_numPostBarriers, m_postBarriers,
2122 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2123 VK_CHECK(m_vki.endCommandBuffer(*cmd));
2127 const vk::VkSubmitInfo submitInfo =
2129 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
2132 (const vk::VkSemaphore*)0,
2133 (const vk::VkPipelineStageFlags*)DE_NULL,
2137 (const vk::VkSemaphore*)0,
2139 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
2141 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
2144 //cmdPushDescriptorSet variant
2145 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::DescriptorSetUpdateBuilder& updateBuilder) const
2147 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
2149 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2151 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
2152 queueFamilyIndex, // queueFamilyIndex
2154 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
2155 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
2157 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2159 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
2160 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
2163 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device));
2164 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
2165 const deUint64 infiniteTimeout = ~(deUint64)0u;
2167 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
2169 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
2171 if (m_numDescriptorSets)
2173 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
2176 updateBuilder.updateWithPush(m_vki, *cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0);
2178 if (m_numPreBarriers)
2179 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
2180 0, (const vk::VkMemoryBarrier*)DE_NULL,
2181 m_numPreBarriers, m_preBarriers,
2182 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2184 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
2185 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
2186 0, (const vk::VkMemoryBarrier*)DE_NULL,
2187 m_numPostBarriers, m_postBarriers,
2188 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2189 VK_CHECK(m_vki.endCommandBuffer(*cmd));
2193 const vk::VkSubmitInfo submitInfo =
2195 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
2198 (const vk::VkSemaphore*)0,
2199 (const vk::VkPipelineStageFlags*)DE_NULL,
2203 (const vk::VkSemaphore*)0,
2205 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
2207 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
2210 class BufferComputeInstance : public vkt::TestInstance
2213 BufferComputeInstance (Context& context,
2214 DescriptorUpdateMethod updateMethod,
2215 vk::VkDescriptorType descriptorType,
2216 ShaderInputInterface shaderInterface,
2219 bool dynamicOffsetNonZero);
2222 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
2223 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
2224 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
2225 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
2226 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf);
2227 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf);
2228 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
2230 tcu::TestStatus iterate (void);
2231 void logTestPlan (void) const;
2232 tcu::TestStatus testResourceAccess (void);
2236 STATIC_OFFSET_VALUE_A = 256,
2237 DYNAMIC_OFFSET_VALUE_A = 512,
2238 STATIC_OFFSET_VALUE_B = 1024,
2239 DYNAMIC_OFFSET_VALUE_B = 768,
2242 const DescriptorUpdateMethod m_updateMethod;
2243 const vk::VkDescriptorType m_descriptorType;
2244 const ShaderInputInterface m_shaderInterface;
2245 const bool m_setViewOffset;
2246 const bool m_setDynamicOffset;
2247 const bool m_dynamicOffsetNonZero;
2249 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
2250 const vk::DeviceInterface& m_vki;
2251 const vk::VkDevice m_device;
2252 const vk::VkQueue m_queue;
2253 const deUint32 m_queueFamilyIndex;
2254 vk::Allocator& m_allocator;
2256 const ComputeInstanceResultBuffer m_result;
2258 RawUpdateRegistry m_updateRegistry;
2259 vk::DescriptorSetUpdateBuilder m_updateBuilder;
2262 BufferComputeInstance::BufferComputeInstance (Context& context,
2263 DescriptorUpdateMethod updateMethod,
2264 vk::VkDescriptorType descriptorType,
2265 ShaderInputInterface shaderInterface,
2268 bool dynamicOffsetNonZero)
2269 : vkt::TestInstance (context)
2270 , m_updateMethod (updateMethod)
2271 , m_descriptorType (descriptorType)
2272 , m_shaderInterface (shaderInterface)
2273 , m_setViewOffset (viewOffset)
2274 , m_setDynamicOffset (dynamicOffset)
2275 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
2276 , m_updateTemplate ()
2277 , m_vki (context.getDeviceInterface())
2278 , m_device (context.getDevice())
2279 , m_queue (context.getUniversalQueue())
2280 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
2281 , m_allocator (context.getDefaultAllocator())
2282 , m_result (m_vki, m_device, m_allocator)
2283 , m_updateRegistry ()
2284 , m_updateBuilder ()
2286 if (m_dynamicOffsetNonZero)
2287 DE_ASSERT(m_setDynamicOffset);
2290 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
2292 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
2294 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2295 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2296 const vk::VkBufferCreateInfo createInfo =
2298 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
2301 (vk::VkDeviceSize)bufferSize, // size
2302 usageFlags, // usage
2303 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2304 0u, // queueFamilyCount
2305 DE_NULL, // pQueueFamilyIndices
2307 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
2308 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
2309 void* mapPtr = allocation->getHostPtr();
2312 deMemset(mapPtr, 0x5A, (size_t)offset);
2313 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
2314 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
2315 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
2317 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
2319 *outAllocation = allocation;
2323 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
2325 vk::DescriptorSetLayoutBuilder builder;
2326 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
2328 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
2329 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
2331 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
2334 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2336 switch (m_shaderInterface)
2338 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2339 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2342 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2343 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2344 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2347 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2348 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2352 DE_FATAL("Impossible");
2355 return builder.build(m_vki, m_device, extraFlags);
2358 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
2360 return vk::DescriptorPoolBuilder()
2361 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2362 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
2363 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
2366 vk::Move<vk::VkDescriptorSet> BufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf)
2368 const vk::VkDescriptorSetAllocateInfo allocInfo =
2370 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2377 vk::Move<vk::VkDescriptorSet> descriptorSet;
2378 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
2380 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
2384 descriptorSet = vk::Move<vk::VkDescriptorSet>();
2387 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
2389 writeDescriptorSetWithTemplate(*descriptorSet, layout, viewA, offsetA, viewB, offsetB, resBuf);
2391 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
2393 writeDescriptorSet(*descriptorSet, viewA, offsetA, viewB, offsetB, resBuf);
2396 return descriptorSet;
2399 void BufferComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf)
2401 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2402 const vk::VkDescriptorBufferInfo bufferInfos[2] =
2404 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2405 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2409 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
2412 switch (m_shaderInterface)
2414 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2415 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2418 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2419 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2420 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
2423 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2424 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
2428 DE_FATAL("Impossible");
2431 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
2433 m_updateBuilder.update(m_vki, m_device);
2437 void BufferComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf, bool withPush, vk::VkPipelineLayout pipelineLayout)
2439 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2440 const vk::VkDescriptorBufferInfo bufferInfos[2] =
2442 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2443 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2445 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
2446 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
2448 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
2451 0, // descriptorUpdateEntryCount
2452 DE_NULL, // pDescriptorUpdateEntries
2453 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
2455 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
2459 m_updateRegistry.addWriteObject(resultInfo);
2460 m_updateRegistry.addWriteObject(bufferInfos[0]);
2461 m_updateRegistry.addWriteObject(bufferInfos[1]);
2464 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
2467 switch (m_shaderInterface)
2469 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2470 updateEntries.push_back(createTemplateBinding(1, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
2473 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2474 updateEntries.push_back(createTemplateBinding(1, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
2475 updateEntries.push_back(createTemplateBinding(2, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(2), 0));
2478 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2479 updateEntries.push_back(createTemplateBinding(1, 0, 2, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), sizeof(bufferInfos[0])));
2483 DE_FATAL("Impossible");
2486 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
2487 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
2489 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
2493 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
2497 tcu::TestStatus BufferComputeInstance::iterate (void)
2500 return testResourceAccess();
2503 void BufferComputeInstance::logTestPlan (void) const
2505 std::ostringstream msg;
2507 msg << "Accessing resource in a compute program.\n"
2508 << "Single descriptor set. Descriptor set contains "
2509 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2510 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
2511 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2512 (const char*)DE_NULL)
2513 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2514 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2515 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2517 if (isDynamicDescriptorType(m_descriptorType))
2519 if (m_setDynamicOffset)
2521 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2522 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2526 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2530 msg << "Destination buffer is pre-initialized to -1.\n";
2532 m_context.getTestContext().getLog()
2533 << tcu::TestLog::Message
2535 << tcu::TestLog::EndMessage;
2538 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2542 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2545 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2546 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2547 const deUint32 bindTimeOffsets[] =
2549 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2550 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2553 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2554 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2555 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2556 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2558 const deUint32 dataOffsetA = ((isDynamicCase) ? (bindTimeOffsets[0]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u));
2559 const deUint32 dataOffsetB = ((isDynamicCase) ? (bindTimeOffsets[1]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u));
2560 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2561 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2562 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2563 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2565 de::MovePtr<vk::Allocation> bufferMemA;
2566 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2568 de::MovePtr<vk::Allocation> bufferMemB;
2569 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2570 ? (vk::Move<vk::VkBuffer>())
2571 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2573 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2574 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2575 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer()));
2576 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2578 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2579 const vk::VkBufferMemoryBarrier bufferBarriers[] =
2582 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2584 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2585 inputBit, // inputMask
2586 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2587 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2589 (vk::VkDeviceSize)0u, // offset
2590 (vk::VkDeviceSize)bufferSizeA, // size
2593 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2595 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2596 inputBit, // inputMask
2597 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2598 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2600 (vk::VkDeviceSize)0u, // offset
2601 (vk::VkDeviceSize)bufferSizeB, // size
2605 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2607 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2608 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : DE_LENGTH_OF_ARRAY(descriptorSets);
2609 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2610 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2611 const vk::VkBufferMemoryBarrier* const preBarriers = bufferBarriers;
2612 const int numPreBarriers = numSrcBuffers;
2613 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
2614 const int numPostBarriers = 1;
2616 const ComputeCommand compute (m_vki,
2618 pipeline.getPipeline(),
2619 pipeline.getPipelineLayout(),
2620 tcu::UVec3(4, 1, 1),
2621 numDescriptorSets, descriptorSets,
2622 numDynamicOffsets, dynamicOffsets,
2623 numPreBarriers, preBarriers,
2624 numPostBarriers, postBarriers);
2626 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2627 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? (colorB2) :
2628 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2630 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2631 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? (colorA1) :
2632 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2634 const tcu::Vec4 references[4] =
2641 tcu::Vec4 results[4];
2643 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
2645 writeDescriptorSetWithTemplate(DE_NULL, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer(), true, pipeline.getPipelineLayout());
2646 compute.submitAndWait(m_queueFamilyIndex, m_queue, *m_updateTemplate, (const void*) m_updateRegistry.getRawPointer());
2648 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
2650 writeDescriptorSet(DE_NULL, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer());
2651 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder);
2655 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2657 m_result.readResultContentsTo(&results);
2660 if (results[0] == references[0] &&
2661 results[1] == references[1] &&
2662 results[2] == references[2] &&
2663 results[3] == references[3])
2665 return tcu::TestStatus::pass("Pass");
2667 else if (results[0] == tcu::Vec4(-1.0f) &&
2668 results[1] == tcu::Vec4(-1.0f) &&
2669 results[2] == tcu::Vec4(-1.0f) &&
2670 results[3] == tcu::Vec4(-1.0f))
2672 m_context.getTestContext().getLog()
2673 << tcu::TestLog::Message
2674 << "Result buffer was not written to."
2675 << tcu::TestLog::EndMessage;
2676 return tcu::TestStatus::fail("Result buffer was not written to");
2680 m_context.getTestContext().getLog()
2681 << tcu::TestLog::Message
2682 << "Error expected ["
2683 << references[0] << ", "
2684 << references[1] << ", "
2685 << references[2] << ", "
2686 << references[3] << "], got ["
2687 << results[0] << ", "
2688 << results[1] << ", "
2689 << results[2] << ", "
2690 << results[3] << "]"
2691 << tcu::TestLog::EndMessage;
2692 return tcu::TestStatus::fail("Invalid result values");
2696 class QuadrantRendederCase : public vkt::TestCase
2699 QuadrantRendederCase (tcu::TestContext& testCtx,
2701 const char* description,
2702 glu::GLSLVersion glslVersion,
2703 vk::VkShaderStageFlags exitingStages,
2704 vk::VkShaderStageFlags activeStages);
2706 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
2707 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
2708 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
2709 virtual std::string genNoAccessSource (void) const = 0;
2711 std::string genVertexSource (void) const;
2712 std::string genTessCtrlSource (void) const;
2713 std::string genTessEvalSource (void) const;
2714 std::string genGeometrySource (void) const;
2715 std::string genFragmentSource (void) const;
2716 std::string genComputeSource (void) const;
2718 void initPrograms (vk::SourceCollections& programCollection) const;
2721 const glu::GLSLVersion m_glslVersion;
2722 const vk::VkShaderStageFlags m_exitingStages;
2723 const vk::VkShaderStageFlags m_activeStages;
2726 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2728 const char* description,
2729 glu::GLSLVersion glslVersion,
2730 vk::VkShaderStageFlags exitingStages,
2731 vk::VkShaderStageFlags activeStages)
2732 : vkt::TestCase (testCtx, name, description)
2733 , m_glslVersion (glslVersion)
2734 , m_exitingStages (exitingStages)
2735 , m_activeStages (activeStages)
2737 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2740 std::string QuadrantRendederCase::genVertexSource (void) const
2742 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
2743 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2744 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2746 const char* const fragColorPrec = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? "highp" : "mediump";
2747 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2748 std::ostringstream buf;
2750 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2752 const bool onlyVS = (m_activeStages == vk::VK_SHADER_STAGE_VERTEX_BIT);
2754 // active vertex shader
2755 buf << versionDecl << "\n"
2756 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2757 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0)
2758 << "layout(location = 0) out " << fragColorPrec << " vec4 " << nextStageName << "_color;\n"
2759 << (onlyVS ? "" : "layout(location = 1) flat out highp int " + de::toString(nextStageName) + "_quadrant_id;\n")
2760 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
2761 << "void main (void)\n"
2763 << " highp vec4 result_position;\n"
2764 << " highp int quadrant_id;\n"
2765 << s_quadrantGenVertexPosSource
2766 << " gl_Position = result_position;\n"
2767 << (onlyVS ? "" : "\t" + de::toString(nextStageName) + "_quadrant_id = quadrant_id;\n")
2769 << " highp vec4 result_color;\n"
2770 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
2771 << " " << nextStageName << "_color = result_color;\n"
2777 buf << versionDecl << "\n"
2778 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2779 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2780 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
2781 << "void main (void)\n"
2783 << " highp vec4 result_position;\n"
2784 << " highp int quadrant_id;\n"
2785 << s_quadrantGenVertexPosSource
2786 << " gl_Position = result_position;\n"
2787 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2794 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2796 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2797 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2798 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2799 std::ostringstream buf;
2801 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2803 // contributing not implemented
2804 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2807 buf << versionDecl << "\n"
2809 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2810 << "layout(vertices=3) out;\n"
2811 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
2812 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2813 << "layout(location = 0) out highp vec4 tes_color[];\n"
2814 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
2815 << "void main (void)\n"
2817 << " highp vec4 result_color;\n"
2818 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2819 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2821 << " tes_color[gl_InvocationID] = result_color;\n"
2823 << " // no dynamic input block indexing\n"
2824 << " highp vec4 position;\n"
2825 << " if (gl_InvocationID == 0)\n"
2826 << " position = gl_in[0].gl_Position;\n"
2827 << " else if (gl_InvocationID == 1)\n"
2828 << " position = gl_in[1].gl_Position;\n"
2830 << " position = gl_in[2].gl_Position;\n"
2831 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2832 << " gl_TessLevelInner[0] = 2.8;\n"
2833 << " gl_TessLevelInner[1] = 2.8;\n"
2834 << " gl_TessLevelOuter[0] = 2.8;\n"
2835 << " gl_TessLevelOuter[1] = 2.8;\n"
2836 << " gl_TessLevelOuter[2] = 2.8;\n"
2837 << " gl_TessLevelOuter[3] = 2.8;\n"
2840 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2842 // active te shader, tc passthru
2843 buf << versionDecl << "\n"
2845 << "layout(vertices=3) out;\n"
2846 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2847 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2848 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
2849 << "void main (void)\n"
2851 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2853 << " // no dynamic input block indexing\n"
2854 << " highp vec4 position;\n"
2855 << " if (gl_InvocationID == 0)\n"
2856 << " position = gl_in[0].gl_Position;\n"
2857 << " else if (gl_InvocationID == 1)\n"
2858 << " position = gl_in[1].gl_Position;\n"
2860 << " position = gl_in[2].gl_Position;\n"
2861 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2862 << " gl_TessLevelInner[0] = 2.8;\n"
2863 << " gl_TessLevelInner[1] = 2.8;\n"
2864 << " gl_TessLevelOuter[0] = 2.8;\n"
2865 << " gl_TessLevelOuter[1] = 2.8;\n"
2866 << " gl_TessLevelOuter[2] = 2.8;\n"
2867 << " gl_TessLevelOuter[3] = 2.8;\n"
2872 // passthrough not implemented
2873 DE_FATAL("not implemented");
2879 std::string QuadrantRendederCase::genTessEvalSource (void) const
2881 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2882 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2883 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2884 std::ostringstream buf;
2886 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2888 // contributing not implemented
2889 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
2892 buf << versionDecl << "\n"
2894 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2895 << "layout(triangles) in;\n"
2896 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
2897 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2898 << "layout(location = 0) out mediump vec4 frag_color;\n"
2899 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
2900 << "void main (void)\n"
2902 << " highp vec4 result_color;\n"
2903 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2904 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2906 << " frag_color = result_color;\n"
2907 << " 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"
2910 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2912 // contributing not implemented
2913 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2915 // active tc shader, te is passthru
2916 buf << versionDecl << "\n"
2918 << "layout(triangles) in;\n"
2919 << "layout(location = 0) in highp vec4 tes_color[];\n"
2920 << "layout(location = 0) out mediump vec4 frag_color;\n"
2921 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
2922 << "void main (void)\n"
2924 << " frag_color = tes_color[0];\n"
2925 << " 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"
2930 // passthrough not implemented
2931 DE_FATAL("not implemented");
2937 std::string QuadrantRendederCase::genGeometrySource (void) const
2939 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2940 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2941 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
2942 std::ostringstream buf;
2944 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2946 // contributing not implemented
2947 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
2949 // active geometry shader
2950 buf << versionDecl << "\n"
2952 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2953 << "layout(triangles) in;\n"
2954 << "layout(triangle_strip, max_vertices=4) out;\n"
2955 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
2956 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
2957 << "layout(location = 0) out mediump vec4 frag_color;\n"
2958 << genPerVertexBlock(vk::VK_SHADER_STAGE_GEOMETRY_BIT, m_glslVersion)
2959 << "void main (void)\n"
2961 << " highp int quadrant_id;\n"
2962 << " highp vec4 result_color;\n"
2964 << " quadrant_id = geo_quadrant_id[0];\n"
2965 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2966 << " frag_color = result_color;\n"
2967 << " gl_Position = gl_in[0].gl_Position;\n"
2968 << " EmitVertex();\n"
2970 << " quadrant_id = geo_quadrant_id[1];\n"
2971 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2972 << " frag_color = result_color;\n"
2973 << " gl_Position = gl_in[1].gl_Position;\n"
2974 << " EmitVertex();\n"
2976 << " quadrant_id = geo_quadrant_id[2];\n"
2977 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2978 << " frag_color = result_color;\n"
2979 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
2980 << " EmitVertex();\n"
2982 << " quadrant_id = geo_quadrant_id[0];\n"
2983 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2984 << " frag_color = result_color;\n"
2985 << " gl_Position = gl_in[2].gl_Position;\n"
2986 << " EmitVertex();\n"
2991 // passthrough not implemented
2992 DE_FATAL("not implemented");
2998 std::string QuadrantRendederCase::genFragmentSource (void) const
3000 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3001 std::ostringstream buf;
3003 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
3005 buf << versionDecl << "\n"
3006 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3007 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
3009 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
3011 // there are other stages, this is just a contributor
3012 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
3015 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
3016 << "layout(location = 0) out mediump vec4 o_color;\n"
3017 << "void main (void)\n"
3019 << " highp int quadrant_id = frag_quadrant_id;\n"
3020 << " highp vec4 result_color;\n"
3021 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
3023 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
3026 buf << " if (frag_quadrant_id < 2)\n"
3027 << " o_color = result_color;\n"
3029 << " o_color = frag_color;\n";
3032 buf << " o_color = result_color;\n";
3036 else if (m_activeStages == 0u)
3038 // special case, no active stages
3039 buf << versionDecl << "\n"
3040 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
3041 << "layout(location = 0) out mediump vec4 o_color;\n"
3042 << "void main (void)\n"
3044 << " highp int quadrant_id = frag_quadrant_id;\n"
3045 << " highp vec4 result_color;\n"
3046 << genNoAccessSource()
3047 << " o_color = result_color;\n"
3053 buf << versionDecl << "\n"
3054 << "layout(location = 0) in mediump vec4 frag_color;\n"
3055 "layout(location = 0) out mediump vec4 o_color;\n"
3056 "void main (void)\n"
3058 " o_color = frag_color;\n"
3065 std::string QuadrantRendederCase::genComputeSource (void) const
3067 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3068 std::ostringstream buf;
3070 buf << versionDecl << "\n"
3071 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
3072 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3073 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
3074 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
3076 << " highp vec4 read_colors[4];\n"
3078 << "void main (void)\n"
3080 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
3081 << " highp vec4 result_color;\n"
3082 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
3083 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
3089 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
3091 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
3092 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
3094 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
3095 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
3097 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
3098 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
3100 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
3101 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
3103 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
3104 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
3106 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
3107 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
3110 class BufferDescriptorCase : public QuadrantRendederCase
3115 FLAG_VIEW_OFFSET = (1u << 1u),
3116 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
3117 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
3119 // enum continues where resource flags ends
3120 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
3122 BufferDescriptorCase (tcu::TestContext& testCtx,
3123 DescriptorUpdateMethod updateMethod,
3125 const char* description,
3126 bool isPrimaryCmdBuf,
3127 vk::VkDescriptorType descriptorType,
3128 vk::VkShaderStageFlags exitingStages,
3129 vk::VkShaderStageFlags activeStages,
3130 ShaderInputInterface shaderInterface,
3134 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
3135 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
3136 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
3137 std::string genNoAccessSource (void) const;
3139 vkt::TestInstance* createInstance (vkt::Context& context) const;
3141 const DescriptorUpdateMethod m_updateMethod;
3142 const bool m_viewOffset;
3143 const bool m_dynamicOffsetSet;
3144 const bool m_dynamicOffsetNonZero;
3145 const bool m_isPrimaryCmdBuf;
3146 const vk::VkDescriptorType m_descriptorType;
3147 const ShaderInputInterface m_shaderInterface;
3150 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
3151 DescriptorUpdateMethod updateMethod,
3153 const char* description,
3154 bool isPrimaryCmdBuf,
3155 vk::VkDescriptorType descriptorType,
3156 vk::VkShaderStageFlags exitingStages,
3157 vk::VkShaderStageFlags activeStages,
3158 ShaderInputInterface shaderInterface,
3160 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
3161 , m_updateMethod (updateMethod)
3162 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
3163 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
3164 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
3165 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
3166 , m_descriptorType (descriptorType)
3167 , m_shaderInterface (shaderInterface)
3171 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
3177 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
3181 const bool isUniform = isUniformDescriptorType(m_descriptorType);
3182 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
3183 std::ostringstream buf;
3185 switch (m_shaderInterface)
3187 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3188 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
3190 << " highp vec4 colorA;\n"
3191 << " highp vec4 colorB;\n"
3192 << "} b_instance;\n";
3195 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3196 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
3198 << " highp vec4 colorA;\n"
3199 << " highp vec4 colorB;\n"
3200 << "} b_instanceA;\n"
3201 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
3203 << " highp vec4 colorA;\n"
3204 << " highp vec4 colorB;\n"
3205 << "} b_instanceB;\n";
3208 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3209 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
3211 << " highp vec4 colorA;\n"
3212 << " highp vec4 colorB;\n"
3213 << "} b_instances[2];\n";
3217 DE_FATAL("Impossible");
3223 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
3227 std::ostringstream buf;
3229 switch (m_shaderInterface)
3231 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3232 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3233 << " result_color = b_instance.colorA;\n"
3235 << " result_color = b_instance.colorB;\n";
3238 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3239 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3240 << " result_color = b_instanceA.colorA;\n"
3242 << " result_color = b_instanceB.colorB;\n";
3245 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3246 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3247 << " result_color = b_instances[0].colorA;\n"
3249 << " result_color = b_instances[1].colorB;\n";
3253 DE_FATAL("Impossible");
3259 std::string BufferDescriptorCase::genNoAccessSource (void) const
3261 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
3262 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3264 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
3267 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
3269 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
3271 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
3273 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
3274 return new BufferComputeInstance(context, m_updateMethod, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
3277 return new BufferRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
3280 class ImageInstanceImages
3283 ImageInstanceImages (const vk::DeviceInterface& vki,
3284 vk::VkDevice device,
3285 deUint32 queueFamilyIndex,
3287 vk::Allocator& allocator,
3288 vk::VkDescriptorType descriptorType,
3289 vk::VkImageViewType viewType,
3291 deUint32 baseMipLevel,
3292 deUint32 baseArraySlice);
3295 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
3296 vk::VkDevice device,
3297 vk::Allocator& allocator,
3298 vk::VkDescriptorType descriptorType,
3299 vk::VkImageViewType viewType,
3300 const tcu::TextureLevelPyramid& sourceImage,
3301 de::MovePtr<vk::Allocation>* outAllocation);
3303 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
3304 vk::VkDevice device,
3305 vk::VkImageViewType viewType,
3306 const tcu::TextureLevelPyramid& sourceImage,
3308 deUint32 baseMipLevel,
3309 deUint32 baseArraySlice);
3311 void populateSourceImage (tcu::TextureLevelPyramid* dst,
3312 bool isFirst) const;
3314 void uploadImage (const vk::DeviceInterface& vki,
3315 vk::VkDevice device,
3316 deUint32 queueFamilyIndex,
3318 vk::Allocator& allocator,
3320 vk::VkImageLayout layout,
3321 const tcu::TextureLevelPyramid& data);
3331 const vk::VkImageViewType m_viewType;
3332 const deUint32 m_baseMipLevel;
3333 const deUint32 m_baseArraySlice;
3335 const tcu::TextureFormat m_imageFormat;
3336 tcu::TextureLevelPyramid m_sourceImageA;
3337 tcu::TextureLevelPyramid m_sourceImageB;
3339 de::MovePtr<vk::Allocation> m_imageMemoryA;
3340 de::MovePtr<vk::Allocation> m_imageMemoryB;
3341 vk::Move<vk::VkImage> m_imageA;
3342 vk::Move<vk::VkImage> m_imageB;
3343 vk::Move<vk::VkImageView> m_imageViewA;
3344 vk::Move<vk::VkImageView> m_imageViewB;
3347 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
3348 vk::VkDevice device,
3349 deUint32 queueFamilyIndex,
3351 vk::Allocator& allocator,
3352 vk::VkDescriptorType descriptorType,
3353 vk::VkImageViewType viewType,
3355 deUint32 baseMipLevel,
3356 deUint32 baseArraySlice)
3357 : m_viewType (viewType)
3358 , m_baseMipLevel (baseMipLevel)
3359 , m_baseArraySlice (baseArraySlice)
3360 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
3361 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
3362 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
3363 , m_imageMemoryA (DE_NULL)
3364 , m_imageMemoryB (DE_NULL)
3365 , m_imageA (vk::Move<vk::VkImage>())
3366 , m_imageB (vk::Move<vk::VkImage>())
3367 , m_imageViewA (vk::Move<vk::VkImageView>())
3368 , m_imageViewB (vk::Move<vk::VkImageView>())
3370 const vk::VkImageLayout layout = getImageLayoutForDescriptorType(descriptorType);
3372 DE_ASSERT(numImages == 1 || numImages == 2);
3374 populateSourceImage(&m_sourceImageA, true);
3375 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
3376 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
3377 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, layout, m_sourceImageA);
3381 populateSourceImage(&m_sourceImageB, false);
3382 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
3383 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
3384 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, layout, m_sourceImageB);
3388 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
3389 vk::VkDevice device,
3390 vk::Allocator& allocator,
3391 vk::VkDescriptorType descriptorType,
3392 vk::VkImageViewType viewType,
3393 const tcu::TextureLevelPyramid& sourceImage,
3394 de::MovePtr<vk::Allocation>* outAllocation)
3396 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3397 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
3398 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
3399 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
3400 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
3401 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
3402 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3403 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
3405 const vk::VkExtent3D extent =
3408 (deUint32)baseLevel.getWidth(),
3411 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1u) : (deUint32)baseLevel.getHeight(),
3414 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deUint32)baseLevel.getDepth()) : (1u),
3416 const vk::VkImageCreateInfo createInfo =
3418 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3420 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
3421 viewTypeToImageType(viewType), // imageType
3422 vk::mapTextureFormat(baseLevel.getFormat()), // format
3424 (deUint32)sourceImage.getNumLevels(), // mipLevels
3425 arraySize, // arraySize
3426 vk::VK_SAMPLE_COUNT_1_BIT, // samples
3427 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
3428 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
3429 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3430 0u, // queueFamilyCount
3431 DE_NULL, // pQueueFamilyIndices
3432 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
3434 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
3436 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
3440 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
3441 vk::VkDevice device,
3442 vk::VkImageViewType viewType,
3443 const tcu::TextureLevelPyramid& sourceImage,
3445 deUint32 baseMipLevel,
3446 deUint32 baseArraySlice)
3448 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3449 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
3450 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
3451 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
3452 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
3453 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
3454 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3455 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
3456 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
3459 DE_ASSERT(viewArraySize > 0);
3461 const vk::VkImageSubresourceRange resourceRange =
3463 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3464 baseMipLevel, // baseMipLevel
3465 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
3466 viewTypeBaseSlice, // baseArraySlice
3467 viewArraySize, // arraySize
3469 const vk::VkImageViewCreateInfo createInfo =
3471 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3473 (vk::VkImageViewCreateFlags)0,
3475 viewType, // viewType
3476 vk::mapTextureFormat(baseLevel.getFormat()), // format
3478 vk::VK_COMPONENT_SWIZZLE_R,
3479 vk::VK_COMPONENT_SWIZZLE_G,
3480 vk::VK_COMPONENT_SWIZZLE_B,
3481 vk::VK_COMPONENT_SWIZZLE_A
3483 resourceRange, // subresourceRange
3485 return vk::createImageView(vki, device, &createInfo);
3488 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
3490 const int numLevels = dst->getNumLevels();
3492 for (int level = 0; level < numLevels; ++level)
3494 const int width = IMAGE_SIZE >> level;
3495 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
3496 : (IMAGE_SIZE >> level);
3497 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
3498 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
3499 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
3500 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
3503 dst->allocLevel(level, width, height, depth);
3506 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
3508 for (int z = 0; z < depth; ++z)
3509 for (int y = 0; y < height; ++y)
3510 for (int x = 0; x < width; ++x)
3512 const int gradPos = x + y + z;
3513 const int gradMax = width + height + depth - 3;
3515 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
3516 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
3517 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
3519 DE_ASSERT(de::inRange(red, 0, 255));
3520 DE_ASSERT(de::inRange(green, 0, 255));
3521 DE_ASSERT(de::inRange(blue, 0, 255));
3523 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3529 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3530 vk::VkDevice device,
3531 deUint32 queueFamilyIndex,
3533 vk::Allocator& allocator,
3535 vk::VkImageLayout layout,
3536 const tcu::TextureLevelPyramid& data)
3538 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3539 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3540 ((deUint32)ARRAY_SIZE);
3541 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3542 const vk::VkBufferCreateInfo bufferCreateInfo =
3544 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3547 dataBufferSize, // size
3548 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
3549 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3550 0u, // queueFamilyCount
3551 DE_NULL, // pQueueFamilyIndices
3553 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3554 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3555 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3557 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3559 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
3560 vk::VK_ACCESS_TRANSFER_READ_BIT, // inputMask
3561 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3562 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3563 *dataBuffer, // buffer
3565 dataBufferSize, // size
3567 const vk::VkImageSubresourceRange fullSubrange =
3569 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3571 (deUint32)data.getNumLevels(), // mipLevels
3572 0u, // baseArraySlice
3573 arraySize, // arraySize
3575 const vk::VkImageMemoryBarrier preImageBarrier =
3577 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3580 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // inputMask
3581 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3582 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout
3583 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3584 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3586 fullSubrange // subresourceRange
3588 const vk::VkImageMemoryBarrier postImageBarrier =
3590 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3592 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask
3593 vk::VK_ACCESS_SHADER_READ_BIT, // inputMask
3594 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout
3595 layout, // newLayout
3596 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3597 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3599 fullSubrange // subresourceRange
3601 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
3603 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
3605 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
3606 queueFamilyIndex, // queueFamilyIndex
3608 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3609 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
3611 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3613 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
3614 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
3617 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(vki, device, *cmdPool, vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY));
3618 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device));
3619 const deUint64 infiniteTimeout = ~(deUint64)0u;
3620 std::vector<vk::VkBufferImageCopy> copySlices;
3622 // copy data to buffer
3623 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3624 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3626 // record command buffer
3627 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3628 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
3629 0, (const vk::VkMemoryBarrier*)DE_NULL,
3630 1, &preMemoryBarrier,
3631 1, &preImageBarrier);
3632 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3633 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
3634 0, (const vk::VkMemoryBarrier*)DE_NULL,
3635 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
3636 1, &postImageBarrier);
3637 VK_CHECK(vki.endCommandBuffer(*cmd));
3639 // submit and wait for command buffer to complete before killing it
3641 const vk::VkSubmitInfo submitInfo =
3643 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
3646 (const vk::VkSemaphore*)0,
3647 (const vk::VkPipelineStageFlags*)DE_NULL,
3651 (const vk::VkSemaphore*)0,
3653 VK_CHECK(vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
3655 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3658 class ImageFetchInstanceImages : private ImageInstanceImages
3661 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3662 vk::VkDevice device,
3663 deUint32 queueFamilyIndex,
3665 vk::Allocator& allocator,
3666 vk::VkDescriptorType descriptorType,
3667 ShaderInputInterface shaderInterface,
3668 vk::VkImageViewType viewType,
3669 deUint32 baseMipLevel,
3670 deUint32 baseArraySlice);
3672 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3673 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3675 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3676 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3681 // some arbitrary sample points for all four quadrants
3682 SAMPLE_POINT_0_X = 6,
3683 SAMPLE_POINT_0_Y = 13,
3684 SAMPLE_POINT_0_Z = 49,
3686 SAMPLE_POINT_1_X = 51,
3687 SAMPLE_POINT_1_Y = 40,
3688 SAMPLE_POINT_1_Z = 44,
3690 SAMPLE_POINT_2_X = 42,
3691 SAMPLE_POINT_2_Y = 26,
3692 SAMPLE_POINT_2_Z = 19,
3694 SAMPLE_POINT_3_X = 25,
3695 SAMPLE_POINT_3_Y = 25,
3696 SAMPLE_POINT_3_Z = 18,
3699 const ShaderInputInterface m_shaderInterface;
3702 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3703 vk::VkDevice device,
3704 deUint32 queueFamilyIndex,
3706 vk::Allocator& allocator,
3707 vk::VkDescriptorType descriptorType,
3708 ShaderInputInterface shaderInterface,
3709 vk::VkImageViewType viewType,
3710 deUint32 baseMipLevel,
3711 deUint32 baseArraySlice)
3712 : ImageInstanceImages (vki,
3719 getInterfaceNumResources(shaderInterface), // numImages
3722 , m_shaderInterface (shaderInterface)
3726 bool isImageViewTypeArray (vk::VkImageViewType type)
3728 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;
3731 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3733 const tcu::IVec3 fetchPositions[4] =
3735 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3736 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3737 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3738 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3740 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3741 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3742 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3746 case vk::VK_IMAGE_VIEW_TYPE_1D:
3747 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3748 case vk::VK_IMAGE_VIEW_TYPE_2D:
3749 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3750 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3751 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3752 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3754 DE_FATAL("Impossible");
3755 return tcu::IVec3();
3759 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3761 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3763 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3764 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3765 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3766 tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3768 // add base array layer into the appropriate coordinate, based on the view type
3769 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
3770 fetchPos.z() += 6 * m_baseArraySlice;
3771 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3772 fetchPos.y() += m_baseArraySlice;
3774 fetchPos.z() += m_baseArraySlice;
3776 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3779 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3782 ImageFetchRenderInstance (vkt::Context& context,
3783 DescriptorUpdateMethod updateMethod,
3784 bool isPrimaryCmdBuf,
3785 vk::VkDescriptorType descriptorType,
3786 vk::VkShaderStageFlags stageFlags,
3787 ShaderInputInterface shaderInterface,
3788 vk::VkImageViewType viewType,
3789 deUint32 baseMipLevel,
3790 deUint32 baseArraySlice);
3793 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3794 vk::VkDevice device,
3795 vk::VkDescriptorType descriptorType,
3796 ShaderInputInterface shaderInterface,
3797 vk::VkShaderStageFlags stageFlags,
3798 DescriptorUpdateMethod updateMethod);
3800 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3801 vk::VkDevice device,
3802 vk::VkDescriptorSetLayout descriptorSetLayout);
3804 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3805 vk::VkDevice device,
3806 vk::VkDescriptorType descriptorType,
3807 ShaderInputInterface shaderInterface);
3809 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3810 DescriptorUpdateMethod updateMethod,
3811 vk::VkDevice device,
3812 vk::VkDescriptorType descriptorType,
3813 ShaderInputInterface shaderInterface,
3814 vk::VkDescriptorSetLayout layout,
3815 vk::VkDescriptorPool pool,
3816 vk::VkImageView viewA,
3817 vk::VkImageView viewB,
3818 vk::DescriptorSetUpdateBuilder& updateBuilder,
3819 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
3820 RawUpdateRegistry& updateRegistry,
3821 vk::VkPipelineLayout pipelineLayout = DE_NULL);
3823 static void writeDescriptorSet (const vk::DeviceInterface& vki,
3824 vk::VkDevice device,
3825 vk::VkDescriptorType descriptorType,
3826 ShaderInputInterface shaderInterface,
3827 vk::VkDescriptorSetLayout layout,
3828 vk::VkDescriptorPool pool,
3829 vk::VkImageView viewA,
3830 vk::VkImageView viewB,
3831 vk::VkDescriptorSet descriptorSet,
3832 vk::DescriptorSetUpdateBuilder& updateBuilder,
3833 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
3835 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
3836 vk::VkDevice device,
3837 vk::VkDescriptorType descriptorType,
3838 ShaderInputInterface shaderInterface,
3839 vk::VkDescriptorSetLayout layout,
3840 vk::VkDescriptorPool pool,
3841 vk::VkImageView viewA,
3842 vk::VkImageView viewB,
3843 vk::VkDescriptorSet descriptorSet,
3844 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
3845 RawUpdateRegistry& updateRegistry,
3846 bool withPush = false,
3847 vk::VkPipelineLayout pipelineLayout = 0);
3849 void logTestPlan (void) const;
3850 vk::VkPipelineLayout getPipelineLayout (void) const;
3851 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
3852 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3859 const DescriptorUpdateMethod m_updateMethod;
3860 const vk::VkDescriptorType m_descriptorType;
3861 const vk::VkShaderStageFlags m_stageFlags;
3862 const ShaderInputInterface m_shaderInterface;
3863 const vk::VkImageViewType m_viewType;
3864 const deUint32 m_baseMipLevel;
3865 const deUint32 m_baseArraySlice;
3867 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
3868 RawUpdateRegistry m_updateRegistry;
3869 vk::DescriptorSetUpdateBuilder m_updateBuilder;
3870 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3871 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3872 const ImageFetchInstanceImages m_images;
3873 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3874 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3877 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3878 DescriptorUpdateMethod updateMethod,
3879 bool isPrimaryCmdBuf,
3880 vk::VkDescriptorType descriptorType,
3881 vk::VkShaderStageFlags stageFlags,
3882 ShaderInputInterface shaderInterface,
3883 vk::VkImageViewType viewType,
3884 deUint32 baseMipLevel,
3885 deUint32 baseArraySlice)
3886 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3887 , m_updateMethod (updateMethod)
3888 , m_descriptorType (descriptorType)
3889 , m_stageFlags (stageFlags)
3890 , m_shaderInterface (shaderInterface)
3891 , m_viewType (viewType)
3892 , m_baseMipLevel (baseMipLevel)
3893 , m_baseArraySlice (baseArraySlice)
3894 , m_updateTemplate ()
3895 , m_updateRegistry ()
3896 , m_updateBuilder ()
3897 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_updateMethod))
3898 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3899 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3900 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3901 , m_descriptorSet (createDescriptorSet(m_vki, m_updateMethod, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_images.getImageViewA(), m_images.getImageViewB(), m_updateBuilder, m_updateTemplate, m_updateRegistry, *m_pipelineLayout))
3905 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3906 vk::VkDevice device,
3907 vk::VkDescriptorType descriptorType,
3908 ShaderInputInterface shaderInterface,
3909 vk::VkShaderStageFlags stageFlags,
3910 DescriptorUpdateMethod updateMethod)
3912 vk::DescriptorSetLayoutBuilder builder;
3913 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
3915 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
3916 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
3918 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
3921 switch (shaderInterface)
3923 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3924 builder.addSingleBinding(descriptorType, stageFlags);
3927 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3928 builder.addSingleBinding(descriptorType, stageFlags);
3929 builder.addSingleBinding(descriptorType, stageFlags);
3932 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3933 builder.addArrayBinding(descriptorType, 2u, stageFlags);
3937 DE_FATAL("Impossible");
3940 return builder.build(vki, device, extraFlags);
3943 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
3944 vk::VkDevice device,
3945 vk::VkDescriptorSetLayout descriptorSetLayout)
3947 const vk::VkPipelineLayoutCreateInfo createInfo =
3949 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3951 (vk::VkPipelineLayoutCreateFlags)0,
3952 1, // descriptorSetCount
3953 &descriptorSetLayout, // pSetLayouts
3954 0u, // pushConstantRangeCount
3955 DE_NULL, // pPushConstantRanges
3957 return vk::createPipelineLayout(vki, device, &createInfo);
3960 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
3961 vk::VkDevice device,
3962 vk::VkDescriptorType descriptorType,
3963 ShaderInputInterface shaderInterface)
3965 return vk::DescriptorPoolBuilder()
3966 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
3967 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3970 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
3971 DescriptorUpdateMethod updateMethod,
3972 vk::VkDevice device,
3973 vk::VkDescriptorType descriptorType,
3974 ShaderInputInterface shaderInterface,
3975 vk::VkDescriptorSetLayout layout,
3976 vk::VkDescriptorPool pool,
3977 vk::VkImageView viewA,
3978 vk::VkImageView viewB,
3979 vk::DescriptorSetUpdateBuilder& updateBuilder,
3980 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
3981 RawUpdateRegistry& updateRegistry,
3982 vk::VkPipelineLayout pipelineLayout)
3984 const vk::VkDescriptorSetAllocateInfo allocInfo =
3986 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3993 vk::Move<vk::VkDescriptorSet> descriptorSet;
3994 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
3996 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4000 descriptorSet = vk::Move<vk::VkDescriptorSet>();
4003 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
4005 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplate, updateRegistry);
4007 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4009 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplate, updateRegistry, true, pipelineLayout);
4011 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4013 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, updateMethod);
4015 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4017 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder);
4019 return descriptorSet;
4022 void ImageFetchRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
4023 vk::VkDevice device,
4024 vk::VkDescriptorType descriptorType,
4025 ShaderInputInterface shaderInterface,
4026 vk::VkDescriptorSetLayout layout,
4027 vk::VkDescriptorPool pool,
4028 vk::VkImageView viewA,
4029 vk::VkImageView viewB,
4030 vk::VkDescriptorSet descriptorSet,
4031 vk::DescriptorSetUpdateBuilder& updateBuilder,
4032 DescriptorUpdateMethod updateMethod)
4036 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
4037 const vk::VkDescriptorImageInfo imageInfos[2] =
4039 makeDescriptorImageInfo(viewA, imageLayout),
4040 makeDescriptorImageInfo(viewB, imageLayout),
4043 switch (shaderInterface)
4045 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4046 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4049 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4050 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4051 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
4054 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4055 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
4059 DE_FATAL("Impossible");
4062 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4064 updateBuilder.update(vki, device);
4068 void ImageFetchRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
4069 vk::VkDevice device,
4070 vk::VkDescriptorType descriptorType,
4071 ShaderInputInterface shaderInterface,
4072 vk::VkDescriptorSetLayout layout,
4073 vk::VkDescriptorPool pool,
4074 vk::VkImageView viewA,
4075 vk::VkImageView viewB,
4076 vk::VkDescriptorSet descriptorSet,
4077 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
4078 RawUpdateRegistry& updateRegistry,
4080 vk::VkPipelineLayout pipelineLayout)
4083 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
4084 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
4086 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
4090 DE_NULL, // pUpdates
4091 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
4093 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
4097 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
4098 const vk::VkDescriptorImageInfo imageInfos[2] =
4100 makeDescriptorImageInfo(viewA, imageLayout),
4101 makeDescriptorImageInfo(viewB, imageLayout),
4103 updateRegistry.addWriteObject(imageInfos[0]);
4104 updateRegistry.addWriteObject(imageInfos[1]);
4106 switch (shaderInterface)
4108 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4109 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4112 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4113 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4114 updateEntries.push_back(createTemplateBinding(1, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
4117 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4118 updateEntries.push_back(createTemplateBinding(0, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(imageInfos[0])));
4122 DE_FATAL("Impossible");
4125 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
4126 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
4128 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
4132 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
4136 void ImageFetchRenderInstance::logTestPlan (void) const
4138 std::ostringstream msg;
4140 msg << "Rendering 2x2 grid.\n"
4141 << "Single descriptor set. Descriptor set contains "
4142 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4143 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4144 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4145 (const char*)DE_NULL)
4146 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
4147 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4150 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4151 if (m_baseArraySlice)
4152 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4154 if (m_stageFlags == 0u)
4156 msg << "Descriptors are not accessed in any shader stage.\n";
4160 msg << "Color in each cell is fetched using the descriptor(s):\n";
4162 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4164 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4166 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4168 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4169 msg << " from descriptor " << srcResourceNdx;
4175 msg << "Descriptors are accessed in {"
4176 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4177 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4178 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4179 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4180 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4184 m_context.getTestContext().getLog()
4185 << tcu::TestLog::Message
4187 << tcu::TestLog::EndMessage;
4190 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
4192 return *m_pipelineLayout;
4195 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4197 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4199 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
4201 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4203 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, *m_updateTemplate, getPipelineLayout(), 0, (const void*)m_updateRegistry.getRawPointer());
4205 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4207 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0);
4210 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
4213 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4215 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4216 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4217 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4218 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
4219 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
4220 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
4221 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
4222 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4224 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4226 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
4227 return tcu::TestStatus::fail("Image verification failed");
4229 return tcu::TestStatus::pass("Pass");
4232 class ImageFetchComputeInstance : public vkt::TestInstance
4235 ImageFetchComputeInstance (vkt::Context& context,
4236 DescriptorUpdateMethod updateMethod,
4237 vk::VkDescriptorType descriptorType,
4238 ShaderInputInterface shaderInterface,
4239 vk::VkImageViewType viewType,
4240 deUint32 baseMipLevel,
4241 deUint32 baseArraySlice);
4244 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4245 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4246 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout);
4247 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet);
4248 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
4251 tcu::TestStatus iterate (void);
4252 void logTestPlan (void) const;
4253 tcu::TestStatus testResourceAccess (void);
4255 const DescriptorUpdateMethod m_updateMethod;
4256 const vk::VkDescriptorType m_descriptorType;
4257 const ShaderInputInterface m_shaderInterface;
4258 const vk::VkImageViewType m_viewType;
4259 const deUint32 m_baseMipLevel;
4260 const deUint32 m_baseArraySlice;
4261 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
4263 const vk::DeviceInterface& m_vki;
4264 const vk::VkDevice m_device;
4265 const vk::VkQueue m_queue;
4266 const deUint32 m_queueFamilyIndex;
4267 vk::Allocator& m_allocator;
4269 const ComputeInstanceResultBuffer m_result;
4270 const ImageFetchInstanceImages m_images;
4272 RawUpdateRegistry m_updateRegistry;
4273 vk::DescriptorSetUpdateBuilder m_updateBuilder;
4276 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
4277 DescriptorUpdateMethod updateMethod,
4278 vk::VkDescriptorType descriptorType,
4279 ShaderInputInterface shaderInterface,
4280 vk::VkImageViewType viewType,
4281 deUint32 baseMipLevel,
4282 deUint32 baseArraySlice)
4283 : vkt::TestInstance (context)
4284 , m_updateMethod (updateMethod)
4285 , m_descriptorType (descriptorType)
4286 , m_shaderInterface (shaderInterface)
4287 , m_viewType (viewType)
4288 , m_baseMipLevel (baseMipLevel)
4289 , m_baseArraySlice (baseArraySlice)
4290 , m_updateTemplate ()
4291 , m_vki (context.getDeviceInterface())
4292 , m_device (context.getDevice())
4293 , m_queue (context.getUniversalQueue())
4294 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4295 , m_allocator (context.getDefaultAllocator())
4296 , m_result (m_vki, m_device, m_allocator)
4297 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
4298 , m_updateRegistry ()
4299 , m_updateBuilder ()
4303 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
4305 vk::DescriptorSetLayoutBuilder builder;
4306 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
4308 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
4309 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4311 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
4314 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4316 switch (m_shaderInterface)
4318 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4319 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4322 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4323 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4324 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4327 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4328 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4332 DE_FATAL("Impossible");
4335 return builder.build(m_vki, m_device, extraFlags);
4338 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
4340 return vk::DescriptorPoolBuilder()
4341 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
4342 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
4343 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4346 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout)
4348 const vk::VkDescriptorSetAllocateInfo allocInfo =
4350 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4357 vk::Move<vk::VkDescriptorSet> descriptorSet;
4358 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4360 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4364 descriptorSet = vk::Move<vk::VkDescriptorSet>();
4367 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
4369 writeDescriptorSetWithTemplate(*descriptorSet, layout);
4371 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4373 writeDescriptorSet(*descriptorSet);
4376 return descriptorSet;
4379 void ImageFetchComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet)
4381 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4382 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
4383 const vk::VkDescriptorImageInfo imageInfos[2] =
4385 makeDescriptorImageInfo(m_images.getImageViewA(), imageLayout),
4386 makeDescriptorImageInfo(m_images.getImageViewB(), imageLayout),
4390 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4393 switch (m_shaderInterface)
4395 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4396 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
4399 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4400 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
4401 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
4404 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4405 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
4409 DE_FATAL("Impossible");
4412 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4414 m_updateBuilder.update(m_vki, m_device);
4418 void ImageFetchComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush, vk::VkPipelineLayout pipelineLayout)
4420 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4421 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
4422 const vk::VkDescriptorImageInfo imageInfos[2] =
4424 makeDescriptorImageInfo(m_images.getImageViewA(), imageLayout),
4425 makeDescriptorImageInfo(m_images.getImageViewB(), imageLayout),
4427 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
4428 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
4430 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
4434 DE_NULL, // pUpdates
4435 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
4437 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
4442 m_updateRegistry.addWriteObject(resultInfo);
4443 m_updateRegistry.addWriteObject(imageInfos[0]);
4444 m_updateRegistry.addWriteObject(imageInfos[1]);
4447 updateEntries.push_back(createTemplateBinding(0u, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
4450 switch (m_shaderInterface)
4452 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4453 updateEntries.push_back(createTemplateBinding(1u, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
4456 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4457 updateEntries.push_back(createTemplateBinding(1u, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
4458 updateEntries.push_back(createTemplateBinding(2u, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(2), 0));
4461 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4462 updateEntries.push_back(createTemplateBinding(1u, 0, 2, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), sizeof(imageInfos[0])));
4466 DE_FATAL("Impossible");
4469 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
4470 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
4472 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
4476 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
4480 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
4483 return testResourceAccess();
4486 void ImageFetchComputeInstance::logTestPlan (void) const
4488 std::ostringstream msg;
4490 msg << "Fetching 4 values from image in compute shader.\n"
4491 << "Single descriptor set. Descriptor set contains "
4492 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4493 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4494 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4495 (const char*)DE_NULL)
4496 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
4497 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4500 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4501 if (m_baseArraySlice)
4502 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4504 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4506 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4508 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4510 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4511 msg << " from descriptor " << srcResourceNdx;
4517 m_context.getTestContext().getLog()
4518 << tcu::TestLog::Message
4520 << tcu::TestLog::EndMessage;
4523 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
4525 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4526 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4527 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4528 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4530 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4531 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : DE_LENGTH_OF_ARRAY(descriptorSets);
4532 const deUint32* const dynamicOffsets = DE_NULL;
4533 const int numDynamicOffsets = 0;
4534 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
4535 const int numPreBarriers = 0;
4536 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
4537 const int numPostBarriers = 1;
4539 const ComputeCommand compute (m_vki,
4541 pipeline.getPipeline(),
4542 pipeline.getPipelineLayout(),
4543 tcu::UVec3(4, 1, 1),
4544 numDescriptorSets, descriptorSets,
4545 numDynamicOffsets, dynamicOffsets,
4546 numPreBarriers, preBarriers,
4547 numPostBarriers, postBarriers);
4549 tcu::Vec4 results[4];
4550 bool anyResultSet = false;
4551 bool allResultsOk = true;
4553 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4555 writeDescriptorSetWithTemplate(DE_NULL, *descriptorSetLayout, true, pipeline.getPipelineLayout());
4556 compute.submitAndWait(m_queueFamilyIndex, m_queue, *m_updateTemplate, (const void*) m_updateRegistry.getRawPointer());
4558 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4560 writeDescriptorSet(DE_NULL);
4561 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder);
4565 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4567 m_result.readResultContentsTo(&results);
4570 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4572 const tcu::Vec4 result = results[resultNdx];
4573 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
4574 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
4576 if (result != tcu::Vec4(-1.0f))
4577 anyResultSet = true;
4579 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
4581 allResultsOk = false;
4583 m_context.getTestContext().getLog()
4584 << tcu::TestLog::Message
4585 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
4586 << tcu::TestLog::EndMessage;
4590 // read back and verify
4592 return tcu::TestStatus::pass("Pass");
4593 else if (anyResultSet)
4594 return tcu::TestStatus::fail("Invalid result values");
4597 m_context.getTestContext().getLog()
4598 << tcu::TestLog::Message
4599 << "Result buffer was not written to."
4600 << tcu::TestLog::EndMessage;
4601 return tcu::TestStatus::fail("Result buffer was not written to");
4605 class ImageSampleInstanceImages : private ImageInstanceImages
4608 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
4609 vk::VkDevice device,
4610 deUint32 queueFamilyIndex,
4612 vk::Allocator& allocator,
4613 vk::VkDescriptorType descriptorType,
4614 ShaderInputInterface shaderInterface,
4615 vk::VkImageViewType viewType,
4616 deUint32 baseMipLevel,
4617 deUint32 baseArraySlice,
4620 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
4621 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
4623 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
4624 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
4625 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
4626 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
4627 inline bool isImmutable (void) const { return m_isImmutable; }
4630 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
4631 static tcu::Sampler createRefSampler (bool isFirst);
4632 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
4634 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
4635 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
4636 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
4637 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
4639 const vk::VkDescriptorType m_descriptorType;
4640 const ShaderInputInterface m_shaderInterface;
4641 const bool m_isImmutable;
4643 const tcu::Sampler m_refSamplerA;
4644 const tcu::Sampler m_refSamplerB;
4645 const vk::Unique<vk::VkSampler> m_samplerA;
4646 const vk::Unique<vk::VkSampler> m_samplerB;
4649 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
4650 vk::VkDevice device,
4651 deUint32 queueFamilyIndex,
4653 vk::Allocator& allocator,
4654 vk::VkDescriptorType descriptorType,
4655 ShaderInputInterface shaderInterface,
4656 vk::VkImageViewType viewType,
4657 deUint32 baseMipLevel,
4658 deUint32 baseArraySlice,
4660 : ImageInstanceImages (vki,
4667 getNumImages(descriptorType, shaderInterface),
4670 , m_descriptorType (descriptorType)
4671 , m_shaderInterface (shaderInterface)
4672 , m_isImmutable (immutable)
4673 , m_refSamplerA (createRefSampler(true))
4674 , m_refSamplerB (createRefSampler(false))
4675 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
4676 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
4677 ? vk::Move<vk::VkSampler>()
4678 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
4682 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
4684 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
4686 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
4687 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
4689 // choose arbitrary values that are not ambiguous with NEAREST filtering
4693 case vk::VK_IMAGE_VIEW_TYPE_1D:
4694 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
4695 case vk::VK_IMAGE_VIEW_TYPE_2D:
4696 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
4697 case vk::VK_IMAGE_VIEW_TYPE_3D:
4699 const tcu::Vec3 coords[4] =
4703 (float)(12u % imageSize) + 0.25f),
4705 tcu::Vec3((float)(23u % imageSize) + 0.25f,
4706 (float)(73u % imageSize) + 0.5f,
4707 (float)(16u % imageSize) + 0.5f + (float)imageSize),
4709 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
4710 (float)(84u % imageSize) + 0.5f + (float)imageSize,
4711 (float)(117u % imageSize) + 0.75f),
4713 tcu::Vec3((float)imageSize + 0.5f,
4714 (float)(75u % imageSize) + 0.25f,
4715 (float)(83u % imageSize) + 0.25f + (float)imageSize),
4717 const deUint32 slices[4] =
4725 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
4726 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
4727 (float)slices[samplePosNdx],
4730 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
4731 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
4732 coords[samplePosNdx].y() / (float)imageSize,
4733 (float)slices[samplePosNdx],
4735 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
4736 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
4737 coords[samplePosNdx].y() / (float)imageSize,
4738 coords[samplePosNdx].z() / (float)imageSize,
4742 DE_FATAL("Impossible");
4747 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4748 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
4750 // \note these values are in [0, texSize]*3 space for convenience
4751 const tcu::Vec3 coords[4] =
4757 tcu::Vec3((float)(13u % imageSize) + 0.25f,
4759 (float)(16u % imageSize) + 0.5f),
4762 (float)(84u % imageSize) + 0.5f,
4763 (float)(10u % imageSize) + 0.75f),
4765 tcu::Vec3((float)imageSize,
4766 (float)(75u % imageSize) + 0.25f,
4767 (float)(83u % imageSize) + 0.75f),
4769 const deUint32 slices[4] =
4777 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
4778 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
4779 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
4781 // map to [-1, 1]*3 space
4782 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
4783 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
4784 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
4785 (float)slices[samplePosNdx]);
4789 DE_FATAL("Impossible");
4794 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
4796 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
4798 // texture order is ABAB
4799 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
4800 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
4801 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
4802 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
4804 // sampler order is ABAB
4805 const tcu::Sampler& samplerA = m_refSamplerA;
4806 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
4807 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
4809 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
4810 const float lod = 0.0f;
4811 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
4815 case vk::VK_IMAGE_VIEW_TYPE_1D:
4816 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
4817 case vk::VK_IMAGE_VIEW_TYPE_2D:
4818 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);
4819 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
4820 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4821 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);
4825 DE_FATAL("Impossible");
4831 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
4833 // If we are testing separate samplers, just one image is enough
4834 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4836 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4838 // combined: numImages == numSamplers
4839 return getInterfaceNumResources(shaderInterface);
4843 DE_FATAL("Impossible");
4848 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4853 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4857 // nearest, clamping
4858 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4862 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4864 const vk::VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, format);
4866 return vk::createSampler(vki, device, &createInfo);
4869 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4871 DE_ASSERT(levelStorage->empty());
4873 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4874 const deUint32 numLevels = (deUint32)source.getNumLevels();
4876 // cut pyramid from baseMipLevel
4877 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4879 // cut levels from baseArraySlice
4880 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4881 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4882 levelStorage->push_back(cutLevel);
4885 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4888 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4890 DE_ASSERT(levelStorage->empty());
4892 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4893 const deUint32 numLevels = (deUint32)source.getNumLevels();
4895 // cut pyramid from baseMipLevel
4896 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4898 // cut levels from baseArraySlice
4899 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4900 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4901 levelStorage->push_back(cutLevel);
4904 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4907 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4909 DE_ASSERT(levelStorage->empty());
4910 DE_ASSERT(baseArraySlice == 0);
4911 DE_UNREF(baseArraySlice);
4913 const deUint32 numLevels = (deUint32)source.getNumLevels();
4915 // cut pyramid from baseMipLevel
4916 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4917 levelStorage->push_back(source.getLevel(level));
4919 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
4922 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4924 DE_ASSERT(levelStorage->empty());
4926 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
4927 const deUint32 numLevels = (deUint32)source.getNumLevels();
4929 // cut pyramid from baseMipLevel
4930 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4932 // cut levels from baseArraySlice
4933 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4934 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
4935 levelStorage->push_back(cutLevel);
4938 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
4941 class ImageSampleRenderInstance : public SingleCmdRenderInstance
4944 ImageSampleRenderInstance (vkt::Context& context,
4945 DescriptorUpdateMethod updateMethod,
4946 bool isPrimaryCmdBuf,
4947 vk::VkDescriptorType descriptorType,
4948 vk::VkShaderStageFlags stageFlags,
4949 ShaderInputInterface shaderInterface,
4950 vk::VkImageViewType viewType,
4951 deUint32 baseMipLevel,
4952 deUint32 baseArraySlice,
4956 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
4957 vk::VkDevice device,
4958 vk::VkDescriptorType descriptorType,
4959 ShaderInputInterface shaderInterface,
4960 vk::VkShaderStageFlags stageFlags,
4961 const ImageSampleInstanceImages& images,
4962 DescriptorUpdateMethod updateMethod);
4964 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4965 vk::VkDevice device,
4966 vk::VkDescriptorSetLayout descriptorSetLayout);
4968 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4969 vk::VkDevice device,
4970 vk::VkDescriptorType descriptorType,
4971 ShaderInputInterface shaderInterface);
4973 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
4974 DescriptorUpdateMethod updateMethod,
4975 vk::VkDevice device,
4976 vk::VkDescriptorType descriptorType,
4977 ShaderInputInterface shaderInterface,
4978 vk::VkDescriptorSetLayout layout,
4979 vk::VkDescriptorPool pool,
4981 const ImageSampleInstanceImages& images,
4982 vk::DescriptorSetUpdateBuilder& updateBuilder,
4983 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
4984 RawUpdateRegistry& updateRegistry,
4985 vk::VkPipelineLayout pipelineLayout = DE_NULL);
4987 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4988 vk::VkDevice device,
4989 ShaderInputInterface shaderInterface,
4991 const ImageSampleInstanceImages& images,
4992 vk::VkDescriptorSet descriptorSet,
4993 vk::DescriptorSetUpdateBuilder& updateBuilder,
4994 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
4996 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4997 vk::VkDevice device,
4998 ShaderInputInterface shaderInterface,
5000 const ImageSampleInstanceImages& images,
5001 vk::VkDescriptorSet descriptorSet,
5002 vk::DescriptorSetUpdateBuilder& updateBuilder,
5003 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
5005 static void writeSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5006 vk::VkDevice device,
5007 ShaderInputInterface shaderInterface,
5009 const ImageSampleInstanceImages& images,
5010 vk::VkDescriptorSet descriptorSet,
5011 vk::VkDescriptorSetLayout layout,
5012 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5013 RawUpdateRegistry& updateRegistry,
5014 bool withPush = false,
5015 vk::VkPipelineLayout pipelineLayout = 0);
5017 static void writeImageSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5018 vk::VkDevice device,
5019 ShaderInputInterface shaderInterface,
5021 const ImageSampleInstanceImages& images,
5022 vk::VkDescriptorSet descriptorSet,
5023 vk::VkDescriptorSetLayout layout,
5024 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5025 RawUpdateRegistry& updateRegistry,
5026 bool withPush = false,
5027 vk::VkPipelineLayout pipelineLayout = 0);
5029 void logTestPlan (void) const;
5030 vk::VkPipelineLayout getPipelineLayout (void) const;
5031 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5032 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5039 const DescriptorUpdateMethod m_updateMethod;
5040 const vk::VkDescriptorType m_descriptorType;
5041 const vk::VkShaderStageFlags m_stageFlags;
5042 const ShaderInputInterface m_shaderInterface;
5043 const vk::VkImageViewType m_viewType;
5044 const deUint32 m_baseMipLevel;
5045 const deUint32 m_baseArraySlice;
5047 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
5048 RawUpdateRegistry m_updateRegistry;
5049 vk::DescriptorSetUpdateBuilder m_updateBuilder;
5050 const ImageSampleInstanceImages m_images;
5051 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5052 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5053 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5054 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5057 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
5058 DescriptorUpdateMethod updateMethod,
5059 bool isPrimaryCmdBuf,
5060 vk::VkDescriptorType descriptorType,
5061 vk::VkShaderStageFlags stageFlags,
5062 ShaderInputInterface shaderInterface,
5063 vk::VkImageViewType viewType,
5064 deUint32 baseMipLevel,
5065 deUint32 baseArraySlice,
5067 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5068 , m_updateMethod (updateMethod)
5069 , m_descriptorType (descriptorType)
5070 , m_stageFlags (stageFlags)
5071 , m_shaderInterface (shaderInterface)
5072 , m_viewType (viewType)
5073 , m_baseMipLevel (baseMipLevel)
5074 , m_baseArraySlice (baseArraySlice)
5075 , m_updateTemplate ()
5076 , m_updateRegistry ()
5077 , m_updateBuilder ()
5078 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
5079 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images, m_updateMethod))
5080 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5081 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5082 , m_descriptorSet (createDescriptorSet(m_vki, m_updateMethod, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, isImmutable, m_images, m_updateBuilder, m_updateTemplate, m_updateRegistry, *m_pipelineLayout))
5086 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5087 vk::VkDevice device,
5088 vk::VkDescriptorType descriptorType,
5089 ShaderInputInterface shaderInterface,
5090 vk::VkShaderStageFlags stageFlags,
5091 const ImageSampleInstanceImages& images,
5092 DescriptorUpdateMethod updateMethod)
5094 const vk::VkSampler samplers[2] =
5096 images.getSamplerA(),
5097 images.getSamplerB(),
5100 vk::DescriptorSetLayoutBuilder builder;
5101 const bool addSeparateImage = descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER;
5102 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
5104 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
5105 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5107 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
5110 // (combined)samplers follow
5111 switch (shaderInterface)
5113 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5114 if (addSeparateImage)
5115 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5116 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5119 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5120 if (addSeparateImage)
5121 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5122 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5123 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5126 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5127 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5128 if (addSeparateImage)
5129 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5130 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5133 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5134 if (addSeparateImage)
5135 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5136 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
5140 DE_FATAL("Impossible");
5143 return builder.build(vki, device, extraFlags);
5146 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5147 vk::VkDevice device,
5148 vk::VkDescriptorSetLayout descriptorSetLayout)
5150 const vk::VkPipelineLayoutCreateInfo createInfo =
5152 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5154 (vk::VkPipelineLayoutCreateFlags)0,
5155 1, // descriptorSetCount
5156 &descriptorSetLayout, // pSetLayouts
5157 0u, // pushConstantRangeCount
5158 DE_NULL, // pPushConstantRanges
5160 return vk::createPipelineLayout(vki, device, &createInfo);
5163 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5164 vk::VkDevice device,
5165 vk::VkDescriptorType descriptorType,
5166 ShaderInputInterface shaderInterface)
5168 vk::DescriptorPoolBuilder builder;
5170 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5172 // separate samplers need image to sample
5173 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
5175 // also need sample to use, indifferent of whether immutable or not
5176 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
5178 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5180 // combined image samplers
5181 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
5184 DE_FATAL("Impossible");
5186 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5189 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5190 DescriptorUpdateMethod updateMethod,
5191 vk::VkDevice device,
5192 vk::VkDescriptorType descriptorType,
5193 ShaderInputInterface shaderInterface,
5194 vk::VkDescriptorSetLayout layout,
5195 vk::VkDescriptorPool pool,
5197 const ImageSampleInstanceImages& images,
5198 vk::DescriptorSetUpdateBuilder& updateBuilder,
5199 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5200 RawUpdateRegistry& updateRegistry,
5201 vk::VkPipelineLayout pipelineLayout)
5203 const vk::VkDescriptorSetAllocateInfo allocInfo =
5205 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5212 vk::Move<vk::VkDescriptorSet> descriptorSet;
5213 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5215 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5219 descriptorSet = vk::Move<vk::VkDescriptorSet>();
5222 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
5224 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5225 writeSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, *descriptorSet, layout, updateTemplate, updateRegistry);
5226 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5227 writeImageSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, *descriptorSet, layout, updateTemplate, updateRegistry);
5229 DE_FATAL("Impossible");
5231 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5233 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5234 writeSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, DE_NULL, layout, updateTemplate, updateRegistry, true, pipelineLayout);
5235 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5236 writeImageSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, DE_NULL, layout, updateTemplate, updateRegistry, true, pipelineLayout);
5238 DE_FATAL("Impossible");
5240 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5242 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5243 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, updateBuilder, updateMethod);
5244 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5245 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, updateBuilder, updateMethod);
5247 DE_FATAL("Impossible");
5249 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5251 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5252 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, updateBuilder);
5253 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5254 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, updateBuilder);
5256 DE_FATAL("Impossible");
5259 return descriptorSet;
5262 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
5263 vk::VkDevice device,
5264 ShaderInputInterface shaderInterface,
5266 const ImageSampleInstanceImages& images,
5267 vk::VkDescriptorSet descriptorSet,
5268 vk::DescriptorSetUpdateBuilder& updateBuilder,
5269 DescriptorUpdateMethod updateMethod)
5271 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5272 const vk::VkDescriptorImageInfo samplersInfos[2] =
5274 makeDescriptorImageInfo(images.getSamplerA()),
5275 makeDescriptorImageInfo(images.getSamplerB()),
5278 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
5280 // stand alone texture
5281 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(samplerLocation), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
5284 if (!isImmutable || (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH))
5286 switch (shaderInterface)
5288 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5289 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5292 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5293 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5294 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
5297 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5298 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5299 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
5302 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5303 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
5307 DE_FATAL("Impossible");
5311 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5313 updateBuilder.update(vki, device);
5317 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
5318 vk::VkDevice device,
5319 ShaderInputInterface shaderInterface,
5321 const ImageSampleInstanceImages& images,
5322 vk::VkDescriptorSet descriptorSet,
5323 vk::DescriptorSetUpdateBuilder& updateBuilder,
5324 DescriptorUpdateMethod updateMethod)
5326 const vk::VkSampler samplers[2] =
5328 (isImmutable && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? (0) : (images.getSamplerA()),
5329 (isImmutable && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? (0) : (images.getSamplerB()),
5331 const vk::VkDescriptorImageInfo imageSamplers[2] =
5333 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5334 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5337 // combined image samplers
5338 switch (shaderInterface)
5340 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5341 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
5344 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5345 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
5346 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
5349 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5350 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
5354 DE_FATAL("Impossible");
5357 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5359 updateBuilder.update(vki, device);
5363 void ImageSampleRenderInstance::writeSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5364 vk::VkDevice device,
5365 ShaderInputInterface shaderInterface,
5367 const ImageSampleInstanceImages& images,
5368 vk::VkDescriptorSet descriptorSet,
5369 vk::VkDescriptorSetLayout layout,
5370 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5371 RawUpdateRegistry& updateRegistry,
5373 vk::VkPipelineLayout pipelineLayout)
5375 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5376 const vk::VkDescriptorImageInfo samplersInfos[2] =
5378 makeDescriptorImageInfo(images.getSamplerA()),
5379 makeDescriptorImageInfo(images.getSamplerB()),
5382 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
5384 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
5385 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
5387 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
5391 DE_NULL, // pUpdates
5392 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
5394 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
5398 updateRegistry.addWriteObject(imageInfo);
5399 updateRegistry.addWriteObject(samplersInfos[0]);
5400 updateRegistry.addWriteObject(samplersInfos[1]);
5402 // stand alone texture
5403 updateEntries.push_back(createTemplateBinding(samplerLocation, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, updateRegistry.getWriteObjectOffset(0), 0));
5406 if (!isImmutable || withPush)
5408 switch (shaderInterface)
5410 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5411 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
5414 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5415 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
5416 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
5419 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5420 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
5421 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
5424 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5425 updateEntries.push_back(createTemplateBinding(1, 0, 2, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), sizeof(samplersInfos[0])));
5429 DE_FATAL("Impossible");
5433 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
5434 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
5436 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
5440 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
5445 void ImageSampleRenderInstance::writeImageSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5446 vk::VkDevice device,
5447 ShaderInputInterface shaderInterface,
5449 const ImageSampleInstanceImages& images,
5450 vk::VkDescriptorSet descriptorSet,
5451 vk::VkDescriptorSetLayout layout,
5452 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5453 RawUpdateRegistry& updateRegistry,
5455 vk::VkPipelineLayout pipelineLayout)
5457 const vk::VkSampler samplers[2] =
5459 (isImmutable && !withPush) ? (0) : (images.getSamplerA()),
5460 (isImmutable && !withPush) ? (0) : (images.getSamplerB()),
5462 const vk::VkDescriptorImageInfo imageSamplers[2] =
5464 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5465 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5468 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
5469 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
5471 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
5475 DE_NULL, // pUpdates
5476 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
5478 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
5482 updateRegistry.addWriteObject(imageSamplers[0]);
5483 updateRegistry.addWriteObject(imageSamplers[1]);
5485 // combined image samplers
5486 switch (shaderInterface)
5488 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5489 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
5492 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5493 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
5494 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
5497 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5498 updateEntries.push_back(createTemplateBinding(0, 0, 2, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), sizeof(imageSamplers[0])));
5502 DE_FATAL("Impossible");
5505 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
5506 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
5508 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
5512 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
5516 void ImageSampleRenderInstance::logTestPlan (void) const
5518 std::ostringstream msg;
5520 msg << "Rendering 2x2 grid.\n";
5522 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5524 msg << "Single descriptor set. Descriptor set contains "
5525 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5526 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5527 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
5528 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5529 (const char*)DE_NULL)
5530 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
5532 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5534 msg << "Single descriptor set. Descriptor set contains "
5535 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5536 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5537 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
5538 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5539 (const char*)DE_NULL)
5540 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
5543 DE_FATAL("Impossible");
5545 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
5548 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
5549 if (m_baseArraySlice)
5550 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
5552 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
5553 msg << "Sampler mode is LINEAR, with WRAP\n";
5555 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
5557 if (m_stageFlags == 0u)
5559 msg << "Descriptors are not accessed in any shader stage.\n";
5563 msg << "Color in each cell is fetched using the descriptor(s):\n";
5565 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5567 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
5569 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5571 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5573 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5574 msg << " using sampler " << srcResourceNdx;
5575 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5576 msg << " from combined image sampler " << srcResourceNdx;
5578 DE_FATAL("Impossible");
5583 msg << "Descriptors are accessed in {"
5584 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5585 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5586 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5587 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5588 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5592 m_context.getTestContext().getLog()
5593 << tcu::TestLog::Message
5595 << tcu::TestLog::EndMessage;
5598 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
5600 return *m_pipelineLayout;
5603 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
5605 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5607 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
5609 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5611 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, *m_updateTemplate, getPipelineLayout(), 0, (const void*)m_updateRegistry.getRawPointer());
5613 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5615 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0);
5618 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
5621 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5623 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5624 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5625 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5626 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
5627 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
5628 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
5629 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
5630 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
5631 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5633 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5635 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
5636 return tcu::TestStatus::fail("Image verification failed");
5638 return tcu::TestStatus::pass("Pass");
5641 class ImageSampleComputeInstance : public vkt::TestInstance
5644 ImageSampleComputeInstance (vkt::Context& context,
5645 DescriptorUpdateMethod updateMethod,
5646 vk::VkDescriptorType descriptorType,
5647 ShaderInputInterface shaderInterface,
5648 vk::VkImageViewType viewType,
5649 deUint32 baseMipLevel,
5650 deUint32 baseArraySlice,
5651 bool isImmutableSampler);
5654 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5655 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5656 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout);
5657 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, vk::VkPipelineLayout pipelineLayout = DE_NULL);
5658 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet);
5659 void writeImageSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
5660 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet);
5661 void writeSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
5663 tcu::TestStatus iterate (void);
5664 void logTestPlan (void) const;
5665 tcu::TestStatus testResourceAccess (void);
5667 const DescriptorUpdateMethod m_updateMethod;
5668 const vk::VkDescriptorType m_descriptorType;
5669 const ShaderInputInterface m_shaderInterface;
5670 const vk::VkImageViewType m_viewType;
5671 const deUint32 m_baseMipLevel;
5672 const deUint32 m_baseArraySlice;
5673 const bool m_isImmutableSampler;
5674 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
5676 const vk::DeviceInterface& m_vki;
5677 const vk::VkDevice m_device;
5678 const vk::VkQueue m_queue;
5679 const deUint32 m_queueFamilyIndex;
5680 vk::Allocator& m_allocator;
5682 const ComputeInstanceResultBuffer m_result;
5683 const ImageSampleInstanceImages m_images;
5685 RawUpdateRegistry m_updateRegistry;
5686 vk::DescriptorSetUpdateBuilder m_updateBuilder;
5689 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
5690 DescriptorUpdateMethod updateMethod,
5691 vk::VkDescriptorType descriptorType,
5692 ShaderInputInterface shaderInterface,
5693 vk::VkImageViewType viewType,
5694 deUint32 baseMipLevel,
5695 deUint32 baseArraySlice,
5696 bool isImmutableSampler)
5697 : vkt::TestInstance (context)
5698 , m_updateMethod (updateMethod)
5699 , m_descriptorType (descriptorType)
5700 , m_shaderInterface (shaderInterface)
5701 , m_viewType (viewType)
5702 , m_baseMipLevel (baseMipLevel)
5703 , m_baseArraySlice (baseArraySlice)
5704 , m_isImmutableSampler (isImmutableSampler)
5705 , m_updateTemplate ()
5706 , m_vki (context.getDeviceInterface())
5707 , m_device (context.getDevice())
5708 , m_queue (context.getUniversalQueue())
5709 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5710 , m_allocator (context.getDefaultAllocator())
5711 , m_result (m_vki, m_device, m_allocator)
5712 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
5713 , m_updateRegistry ()
5714 , m_updateBuilder ()
5718 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
5720 const vk::VkSampler samplers[2] =
5722 m_images.getSamplerA(),
5723 m_images.getSamplerB(),
5726 vk::DescriptorSetLayoutBuilder builder;
5727 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
5729 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
5730 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5732 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
5736 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5738 // with samplers, separate texture at binding 0
5739 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5740 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5742 // (combined)samplers follow
5743 switch (m_shaderInterface)
5745 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5746 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5749 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5750 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5751 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5754 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5755 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
5759 DE_FATAL("Impossible");
5762 return builder.build(m_vki, m_device, extraFlags);
5765 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
5767 vk::DescriptorPoolBuilder builder;
5769 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
5770 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
5772 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5773 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
5775 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5778 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout)
5780 const vk::VkDescriptorSetAllocateInfo allocInfo =
5782 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5789 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5791 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
5792 writeDescriptorSet(*descriptorSet, layout);
5794 return descriptorSet;
5797 return vk::Move<vk::VkDescriptorSet>();
5800 void ImageSampleComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, vk::VkPipelineLayout pipelineLayout)
5802 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
5804 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5805 writeSamplerDescriptorSetWithTemplate(descriptorSet, layout);
5806 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5807 writeImageSamplerDescriptorSetWithTemplate(descriptorSet, layout);
5809 DE_FATAL("Impossible");
5811 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5813 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5814 writeSamplerDescriptorSetWithTemplate(descriptorSet, layout, true, pipelineLayout);
5815 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5816 writeImageSamplerDescriptorSetWithTemplate(descriptorSet, layout, true, pipelineLayout);
5818 DE_FATAL("Impossible");
5820 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5822 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5823 writeSamplerDescriptorSet(descriptorSet);
5824 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5825 writeImageSamplerDescriptorSet(descriptorSet);
5827 DE_FATAL("Impossible");
5829 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5831 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5832 writeSamplerDescriptorSet(descriptorSet);
5833 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5834 writeImageSamplerDescriptorSet(descriptorSet);
5836 DE_FATAL("Impossible");
5840 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet)
5842 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5843 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5844 const vk::VkDescriptorImageInfo samplersInfos[2] =
5846 makeDescriptorImageInfo(m_images.getSamplerA()),
5847 makeDescriptorImageInfo(m_images.getSamplerB()),
5851 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5853 // stand alone texture
5854 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
5857 if (!m_isImmutableSampler || (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH))
5859 switch (m_shaderInterface)
5861 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5862 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5865 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5866 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5867 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
5870 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5871 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
5875 DE_FATAL("Impossible");
5879 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5881 m_updateBuilder.update(m_vki, m_device);
5885 void ImageSampleComputeInstance::writeSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush, vk::VkPipelineLayout pipelineLayout)
5887 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
5888 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5889 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5890 const vk::VkDescriptorImageInfo samplersInfos[2] =
5892 makeDescriptorImageInfo(m_images.getSamplerA()),
5893 makeDescriptorImageInfo(m_images.getSamplerB()),
5895 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
5897 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
5901 DE_NULL, // pUpdates
5902 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
5904 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
5908 m_updateRegistry.addWriteObject(resultInfo);
5909 m_updateRegistry.addWriteObject(imageInfo);
5910 m_updateRegistry.addWriteObject(samplersInfos[0]);
5911 m_updateRegistry.addWriteObject(samplersInfos[1]);
5914 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
5915 // stand alone texture
5916 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, m_updateRegistry.getWriteObjectOffset(1), 0));
5919 if (!m_isImmutableSampler || withPush)
5921 switch (m_shaderInterface)
5923 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5924 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, m_updateRegistry.getWriteObjectOffset(2), 0));
5927 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5928 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, m_updateRegistry.getWriteObjectOffset(2), 0));
5929 updateEntries.push_back(createTemplateBinding(3, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, m_updateRegistry.getWriteObjectOffset(3), 0));
5932 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5933 updateEntries.push_back(createTemplateBinding(2, 0, 2, vk::VK_DESCRIPTOR_TYPE_SAMPLER, m_updateRegistry.getWriteObjectOffset(2), sizeof(samplersInfos[0])));
5937 DE_FATAL("Impossible");
5941 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
5942 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
5944 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
5948 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
5952 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet)
5954 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5955 const vk::VkSampler samplers[2] =
5957 (m_isImmutableSampler && (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)) ? (0) : (m_images.getSamplerA()),
5958 (m_isImmutableSampler && (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)) ? (0) : (m_images.getSamplerB()),
5960 const vk::VkDescriptorImageInfo imageSamplers[2] =
5962 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5963 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5967 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5969 // combined image samplers
5970 switch (m_shaderInterface)
5972 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5973 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
5976 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5977 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
5978 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
5981 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5982 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
5986 DE_FATAL("Impossible");
5989 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5991 m_updateBuilder.update(m_vki, m_device);
5995 void ImageSampleComputeInstance::writeImageSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush, vk::VkPipelineLayout pipelineLayout)
5997 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
5998 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5999 const vk::VkSampler samplers[2] =
6001 (m_isImmutableSampler && !withPush) ? (0) : (m_images.getSamplerA()),
6002 (m_isImmutableSampler && !withPush) ? (0) : (m_images.getSamplerB()),
6004 const vk::VkDescriptorImageInfo imageSamplers[2] =
6006 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6007 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6009 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
6011 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6015 DE_NULL, // pUpdates
6016 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
6018 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
6022 m_updateRegistry.addWriteObject(resultInfo);
6023 m_updateRegistry.addWriteObject(imageSamplers[0]);
6024 m_updateRegistry.addWriteObject(imageSamplers[1]);
6027 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
6029 // combined image samplers
6030 switch (m_shaderInterface)
6032 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6033 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_updateRegistry.getWriteObjectOffset(1), 0));
6036 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6037 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_updateRegistry.getWriteObjectOffset(1), 0));
6038 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_updateRegistry.getWriteObjectOffset(2), 0));
6041 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6042 updateEntries.push_back(createTemplateBinding(1, 0, 2, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_updateRegistry.getWriteObjectOffset(1), sizeof(imageSamplers[0])));
6046 DE_FATAL("Impossible");
6049 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6050 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6052 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
6056 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
6060 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
6063 return testResourceAccess();
6066 void ImageSampleComputeInstance::logTestPlan (void) const
6068 std::ostringstream msg;
6070 msg << "Accessing resource in a compute program.\n";
6072 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6074 msg << "Single descriptor set. Descriptor set contains "
6075 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6076 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6077 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6078 (const char*)DE_NULL)
6079 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
6081 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6083 msg << "Single descriptor set. Descriptor set contains "
6084 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6085 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6086 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6087 (const char*)DE_NULL)
6088 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
6091 DE_FATAL("Impossible");
6093 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
6096 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
6097 if (m_baseArraySlice)
6098 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
6100 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
6101 msg << "Sampler mode is LINEAR, with WRAP\n";
6103 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
6105 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6107 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
6109 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
6111 const int srcResourceNdx = (resultNdx % 2); // ABAB source
6113 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6114 msg << " using sampler " << srcResourceNdx;
6115 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6116 msg << " from combined image sampler " << srcResourceNdx;
6118 DE_FATAL("Impossible");
6123 m_context.getTestContext().getLog()
6124 << tcu::TestLog::Message
6126 << tcu::TestLog::EndMessage;
6129 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
6131 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
6132 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
6133 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
6134 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
6136 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
6137 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : DE_LENGTH_OF_ARRAY(descriptorSets);
6138 const deUint32* const dynamicOffsets = DE_NULL;
6139 const int numDynamicOffsets = 0;
6140 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
6141 const int numPreBarriers = 0;
6142 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
6143 const int numPostBarriers = 1;
6145 const ComputeCommand compute (m_vki,
6147 pipeline.getPipeline(),
6148 pipeline.getPipelineLayout(),
6149 tcu::UVec3(4, 1, 1),
6150 numDescriptorSets, descriptorSets,
6151 numDynamicOffsets, dynamicOffsets,
6152 numPreBarriers, preBarriers,
6153 numPostBarriers, postBarriers);
6155 tcu::Vec4 results[4];
6156 bool anyResultSet = false;
6157 bool allResultsOk = true;
6159 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
6161 writeDescriptorSet(DE_NULL, *descriptorSetLayout, pipeline.getPipelineLayout()); // descriptor set not applicable
6162 compute.submitAndWait(m_queueFamilyIndex, m_queue, *m_updateTemplate, (void *) m_updateRegistry.getRawPointer());
6164 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6166 writeDescriptorSet(DE_NULL, *descriptorSetLayout, pipeline.getPipelineLayout()); // descriptor set not applicable
6167 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder);
6171 compute.submitAndWait(m_queueFamilyIndex, m_queue);
6173 m_result.readResultContentsTo(&results);
6176 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6178 const tcu::Vec4 result = results[resultNdx];
6179 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
6181 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
6182 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
6184 if (result != tcu::Vec4(-1.0f))
6185 anyResultSet = true;
6187 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
6189 allResultsOk = false;
6191 m_context.getTestContext().getLog()
6192 << tcu::TestLog::Message
6193 << "Test sample " << resultNdx << ":\n"
6194 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
6195 << "\tError expected " << reference << ", got " << result
6196 << tcu::TestLog::EndMessage;
6200 // read back and verify
6202 return tcu::TestStatus::pass("Pass");
6203 else if (anyResultSet)
6204 return tcu::TestStatus::fail("Invalid result values");
6207 m_context.getTestContext().getLog()
6208 << tcu::TestLog::Message
6209 << "Result buffer was not written to."
6210 << tcu::TestLog::EndMessage;
6211 return tcu::TestStatus::fail("Result buffer was not written to");
6215 class ImageDescriptorCase : public QuadrantRendederCase
6220 FLAG_BASE_MIP = (1u << 1u),
6221 FLAG_BASE_SLICE = (1u << 2u),
6223 // enum continues where resource flags ends
6224 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
6226 ImageDescriptorCase (tcu::TestContext& testCtx,
6228 const char* description,
6229 bool isPrimaryCmdBuf,
6230 DescriptorUpdateMethod updateMethod,
6231 vk::VkDescriptorType descriptorType,
6232 vk::VkShaderStageFlags exitingStages,
6233 vk::VkShaderStageFlags activeStages,
6234 ShaderInputInterface shaderInterface,
6235 vk::VkImageViewType viewType,
6239 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
6240 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
6241 std::string genFetchCoordStr (int fetchPosNdx) const;
6242 std::string genSampleCoordStr (int samplePosNdx) const;
6243 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
6244 std::string genNoAccessSource (void) const;
6246 vkt::TestInstance* createInstance (vkt::Context& context) const;
6249 const bool m_isPrimaryCmdBuf;
6250 const DescriptorUpdateMethod m_updateMethod;
6251 const vk::VkDescriptorType m_descriptorType;
6252 const ShaderInputInterface m_shaderInterface;
6253 const vk::VkImageViewType m_viewType;
6254 const deUint32 m_baseMipLevel;
6255 const deUint32 m_baseArraySlice;
6256 const bool m_isImmutableSampler;
6259 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
6261 const char* description,
6262 bool isPrimaryCmdBuf,
6263 DescriptorUpdateMethod updateMethod,
6264 vk::VkDescriptorType descriptorType,
6265 vk::VkShaderStageFlags exitingStages,
6266 vk::VkShaderStageFlags activeStages,
6267 ShaderInputInterface shaderInterface,
6268 vk::VkImageViewType viewType,
6270 : QuadrantRendederCase (testCtx, name, description,
6271 // \note 1D textures are not supported in ES
6272 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
6273 exitingStages, activeStages)
6274 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6275 , m_updateMethod (updateMethod)
6276 , m_descriptorType (descriptorType)
6277 , m_shaderInterface (shaderInterface)
6278 , m_viewType (viewType)
6279 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
6280 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
6281 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
6285 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
6289 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
6290 return "#extension GL_OES_texture_cube_map_array : require\n";
6295 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
6299 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
6300 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
6301 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
6302 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
6303 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
6305 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
6306 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
6307 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
6308 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
6310 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
6312 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
6313 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
6315 switch (m_shaderInterface)
6317 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6319 switch (m_descriptorType)
6321 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6322 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
6323 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
6324 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6325 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
6326 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6327 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
6328 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6329 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
6331 DE_FATAL("invalid descriptor");
6336 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6337 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6338 switch (m_descriptorType)
6340 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6341 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS)
6342 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
6343 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
6344 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
6346 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler u_separateSamplerA;\n"
6347 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
6348 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
6349 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6350 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
6351 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
6352 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6353 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
6354 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
6355 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6356 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
6357 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
6359 DE_FATAL("invalid descriptor");
6363 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6364 switch (m_descriptorType)
6366 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6367 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
6368 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler[2];\n";
6369 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6370 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
6371 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6372 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
6373 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6374 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
6376 DE_FATAL("invalid descriptor");
6381 DE_FATAL("Impossible");
6386 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
6388 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
6389 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
6391 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
6393 return de::toString(fetchPos.x());
6395 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
6397 std::ostringstream buf;
6398 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
6403 std::ostringstream buf;
6404 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
6409 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
6411 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
6412 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
6414 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
6416 std::ostringstream buf;
6417 buf << "float(" << fetchPos.x() << ")";
6420 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
6422 std::ostringstream buf;
6423 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
6426 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
6428 std::ostringstream buf;
6429 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
6434 std::ostringstream buf;
6435 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
6440 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
6444 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
6445 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
6446 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
6447 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
6448 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
6449 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
6450 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
6452 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6453 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
6454 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("A")
6455 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6457 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6458 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
6459 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("B")
6460 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6463 switch (m_descriptorType)
6465 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6466 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6468 const std::string coodStr[4] =
6470 genSampleCoordStr(0),
6471 genSampleCoordStr(1),
6472 genSampleCoordStr(2),
6473 genSampleCoordStr(3),
6475 std::ostringstream buf;
6477 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6479 buf << " if (quadrant_id == 0)\n"
6480 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
6481 << " else if (quadrant_id == 1)\n"
6482 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
6483 << " else if (quadrant_id == 2)\n"
6484 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
6486 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
6490 buf << " if (quadrant_id == 0)\n"
6491 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
6492 << " else if (quadrant_id == 1)\n"
6493 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
6494 << " else if (quadrant_id == 2)\n"
6495 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
6497 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
6503 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6505 const std::string coodStr[4] =
6507 genFetchCoordStr(0),
6508 genFetchCoordStr(1),
6509 genFetchCoordStr(2),
6510 genFetchCoordStr(3),
6512 std::ostringstream buf;
6514 buf << " if (quadrant_id == 0)\n"
6515 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
6516 << " else if (quadrant_id == 1)\n"
6517 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
6518 << " else if (quadrant_id == 2)\n"
6519 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
6521 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
6527 DE_FATAL("invalid descriptor");
6532 std::string ImageDescriptorCase::genNoAccessSource (void) const
6534 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6535 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6537 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6540 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
6542 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
6544 switch (m_descriptorType)
6546 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6547 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6548 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6550 DE_ASSERT(m_isPrimaryCmdBuf);
6551 return new ImageSampleComputeInstance(context, m_updateMethod, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
6554 return new ImageSampleRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
6556 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6557 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6558 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6560 DE_ASSERT(m_isPrimaryCmdBuf);
6561 return new ImageFetchComputeInstance(context, m_updateMethod, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
6564 return new ImageFetchRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
6567 DE_FATAL("Impossible");
6572 class TexelBufferInstanceBuffers
6575 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
6576 vk::VkDevice device,
6577 vk::Allocator& allocator,
6578 vk::VkDescriptorType descriptorType,
6579 int numTexelBuffers,
6580 bool hasViewOffset);
6583 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
6584 vk::VkDevice device,
6585 vk::Allocator& allocator,
6586 vk::VkDescriptorType descriptorType,
6587 de::MovePtr<vk::Allocation> *outAllocation);
6589 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
6590 vk::VkDevice device,
6591 const tcu::TextureFormat& textureFormat,
6593 vk::VkBuffer buffer);
6595 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
6597 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
6598 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
6601 static int getFetchPos (int fetchPosNdx);
6602 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
6604 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
6605 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
6606 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
6607 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
6608 inline const vk::VkBufferMemoryBarrier* getBufferInitBarriers (void) const { return m_bufferBarriers; }
6614 VIEW_OFFSET_VALUE = 256,
6615 VIEW_DATA_SIZE = 256, //!< size in bytes
6616 VIEW_WIDTH = 64, //!< size in pixels
6620 // some arbitrary points
6622 SAMPLE_POINT_1 = 51,
6623 SAMPLE_POINT_2 = 42,
6624 SAMPLE_POINT_3 = 25,
6627 const deUint32 m_numTexelBuffers;
6628 const tcu::TextureFormat m_imageFormat;
6629 const deUint32 m_viewOffset;
6631 de::ArrayBuffer<deUint8> m_sourceBufferA;
6632 de::ArrayBuffer<deUint8> m_sourceBufferB;
6633 const tcu::ConstPixelBufferAccess m_sourceViewA;
6634 const tcu::ConstPixelBufferAccess m_sourceViewB;
6636 de::MovePtr<vk::Allocation> m_bufferMemoryA;
6637 de::MovePtr<vk::Allocation> m_bufferMemoryB;
6638 const vk::Unique<vk::VkBuffer> m_bufferA;
6639 const vk::Unique<vk::VkBuffer> m_bufferB;
6640 const vk::Unique<vk::VkBufferView> m_bufferViewA;
6641 const vk::Unique<vk::VkBufferView> m_bufferViewB;
6642 vk::VkBufferMemoryBarrier m_bufferBarriers[2];
6645 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
6646 vk::VkDevice device,
6647 vk::Allocator& allocator,
6648 vk::VkDescriptorType descriptorType,
6649 int numTexelBuffers,
6651 : m_numTexelBuffers (numTexelBuffers)
6652 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
6653 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
6654 , m_sourceBufferA (BUFFER_SIZE)
6655 , m_sourceBufferB ((numTexelBuffers == 1)
6657 : ((size_t)BUFFER_SIZE))
6658 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
6659 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
6660 , m_bufferMemoryA (DE_NULL)
6661 , m_bufferMemoryB (DE_NULL)
6662 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
6663 , m_bufferB ((numTexelBuffers == 1)
6664 ? vk::Move<vk::VkBuffer>()
6665 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
6666 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
6667 , m_bufferViewB ((numTexelBuffers == 1)
6668 ? vk::Move<vk::VkBufferView>()
6669 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
6671 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
6672 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
6673 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
6675 // specify and upload
6677 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
6678 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
6680 if (numTexelBuffers == 2)
6682 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
6683 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
6686 m_bufferBarriers[0] = createBarrier(descriptorType, *m_bufferA);
6687 m_bufferBarriers[1] = createBarrier(descriptorType, *m_bufferB);
6690 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
6691 vk::VkDevice device,
6692 vk::Allocator& allocator,
6693 vk::VkDescriptorType descriptorType,
6694 de::MovePtr<vk::Allocation> *outAllocation)
6696 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
6697 const vk::VkBufferCreateInfo createInfo =
6699 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
6702 (vk::VkDeviceSize)BUFFER_SIZE, // size
6704 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
6705 0u, // queueFamilyCount
6706 DE_NULL, // pQueueFamilyIndices
6708 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
6709 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
6711 *outAllocation = allocation;
6715 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
6716 vk::VkDevice device,
6717 const tcu::TextureFormat& textureFormat,
6719 vk::VkBuffer buffer)
6721 const vk::VkBufferViewCreateInfo createInfo =
6723 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
6725 (vk::VkBufferViewCreateFlags)0,
6727 vk::mapTextureFormat(textureFormat), // format
6728 (vk::VkDeviceSize)offset, // offset
6729 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
6731 return vk::createBufferView(vki, device, &createInfo);
6734 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
6736 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
6737 const vk::VkBufferMemoryBarrier barrier =
6739 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
6741 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
6742 inputBit, // inputMask
6743 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
6744 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
6747 (vk::VkDeviceSize)BUFFER_SIZE // size
6752 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
6754 DE_ASSERT(access.getHeight() == 1);
6755 DE_ASSERT(access.getDepth() == 1);
6757 const deInt32 width = access.getWidth();
6759 for (int x = 0; x < width; ++x)
6761 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
6762 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
6763 const int blue = 16 * (x % 16); //!< 16-long triangle wave
6765 DE_ASSERT(de::inRange(red, 0, 255));
6766 DE_ASSERT(de::inRange(green, 0, 255));
6767 DE_ASSERT(de::inRange(blue, 0, 255));
6769 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
6773 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
6775 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
6776 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
6779 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
6781 static const int fetchPositions[4] =
6788 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
6791 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
6793 // source order is ABAB
6794 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
6795 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
6796 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
6798 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
6801 class TexelBufferRenderInstance : public SingleCmdRenderInstance
6804 TexelBufferRenderInstance (vkt::Context& context,
6805 DescriptorUpdateMethod updateMethod,
6806 bool isPrimaryCmdBuf,
6807 vk::VkDescriptorType descriptorType,
6808 vk::VkShaderStageFlags stageFlags,
6809 ShaderInputInterface shaderInterface,
6810 bool nonzeroViewOffset);
6813 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
6814 vk::VkDevice device,
6815 vk::VkDescriptorType descriptorType,
6816 ShaderInputInterface shaderInterface,
6817 vk::VkShaderStageFlags stageFlags,
6818 DescriptorUpdateMethod updateMethod);
6820 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
6821 vk::VkDevice device,
6822 vk::VkDescriptorSetLayout descriptorSetLayout);
6824 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
6825 vk::VkDevice device,
6826 vk::VkDescriptorType descriptorType,
6827 ShaderInputInterface shaderInterface);
6829 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
6830 DescriptorUpdateMethod updateMethod,
6831 vk::VkDevice device,
6832 vk::VkDescriptorType descriptorType,
6833 ShaderInputInterface shaderInterface,
6834 vk::VkDescriptorSetLayout layout,
6835 vk::VkDescriptorPool pool,
6836 vk::VkBufferView viewA,
6837 vk::VkBufferView viewB,
6838 vk::DescriptorSetUpdateBuilder& updateBuilder,
6839 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
6840 RawUpdateRegistry& updateRegistry,
6841 vk::VkPipelineLayout pipelineLayout = DE_NULL);
6843 static void writeDescriptorSet (const vk::DeviceInterface& vki,
6844 vk::VkDevice device,
6845 vk::VkDescriptorType descriptorType,
6846 ShaderInputInterface shaderInterface,
6847 vk::VkDescriptorSetLayout layout,
6848 vk::VkDescriptorPool pool,
6849 vk::VkBufferView viewA,
6850 vk::VkBufferView viewB,
6851 vk::VkDescriptorSet descriptorSet,
6852 vk::DescriptorSetUpdateBuilder& updateBuilder,
6853 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
6855 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
6856 vk::VkDevice device,
6857 vk::VkDescriptorType descriptorType,
6858 ShaderInputInterface shaderInterface,
6859 vk::VkDescriptorSetLayout layout,
6860 vk::VkDescriptorPool pool,
6861 vk::VkBufferView viewA,
6862 vk::VkBufferView viewB,
6863 vk::VkDescriptorSet descriptorSet,
6864 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
6865 RawUpdateRegistry& updateRegistry,
6866 bool withPush = false,
6867 vk::VkPipelineLayout pipelineLayout = 0);
6869 void logTestPlan (void) const;
6870 vk::VkPipelineLayout getPipelineLayout (void) const;
6871 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
6872 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
6879 const DescriptorUpdateMethod m_updateMethod;
6880 const vk::VkDescriptorType m_descriptorType;
6881 const vk::VkShaderStageFlags m_stageFlags;
6882 const ShaderInputInterface m_shaderInterface;
6883 const bool m_nonzeroViewOffset;
6885 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
6886 RawUpdateRegistry m_updateRegistry;
6887 vk::DescriptorSetUpdateBuilder m_updateBuilder;
6888 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
6889 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
6890 const TexelBufferInstanceBuffers m_texelBuffers;
6891 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
6892 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
6895 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
6896 DescriptorUpdateMethod updateMethod,
6897 bool isPrimaryCmdBuf,
6898 vk::VkDescriptorType descriptorType,
6899 vk::VkShaderStageFlags stageFlags,
6900 ShaderInputInterface shaderInterface,
6901 bool nonzeroViewOffset)
6902 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
6903 , m_updateMethod (updateMethod)
6904 , m_descriptorType (descriptorType)
6905 , m_stageFlags (stageFlags)
6906 , m_shaderInterface (shaderInterface)
6907 , m_nonzeroViewOffset (nonzeroViewOffset)
6908 , m_updateTemplate ()
6909 , m_updateRegistry ()
6910 , m_updateBuilder ()
6911 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_updateMethod))
6912 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
6913 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
6914 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
6915 , m_descriptorSet (createDescriptorSet(m_vki, m_updateMethod, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_texelBuffers.getBufferViewA(), m_texelBuffers.getBufferViewB(), m_updateBuilder, m_updateTemplate, m_updateRegistry, *m_pipelineLayout))
6919 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
6920 vk::VkDevice device,
6921 vk::VkDescriptorType descriptorType,
6922 ShaderInputInterface shaderInterface,
6923 vk::VkShaderStageFlags stageFlags,
6924 DescriptorUpdateMethod updateMethod)
6926 vk::DescriptorSetLayoutBuilder builder;
6927 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
6929 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
6930 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6932 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
6935 switch (shaderInterface)
6937 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6938 builder.addSingleBinding(descriptorType, stageFlags);
6941 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6942 builder.addSingleBinding(descriptorType, stageFlags);
6943 builder.addSingleBinding(descriptorType, stageFlags);
6946 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6947 builder.addArrayBinding(descriptorType, 2u, stageFlags);
6951 DE_FATAL("Impossible");
6954 return builder.build(vki, device, extraFlags);
6957 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
6958 vk::VkDevice device,
6959 vk::VkDescriptorSetLayout descriptorSetLayout)
6961 const vk::VkPipelineLayoutCreateInfo createInfo =
6963 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
6965 (vk::VkPipelineLayoutCreateFlags)0,
6966 1, // descriptorSetCount
6967 &descriptorSetLayout, // pSetLayouts
6968 0u, // pushConstantRangeCount
6969 DE_NULL, // pPushConstantRanges
6971 return vk::createPipelineLayout(vki, device, &createInfo);
6974 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
6975 vk::VkDevice device,
6976 vk::VkDescriptorType descriptorType,
6977 ShaderInputInterface shaderInterface)
6979 return vk::DescriptorPoolBuilder()
6980 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
6981 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
6984 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
6985 DescriptorUpdateMethod updateMethod,
6986 vk::VkDevice device,
6987 vk::VkDescriptorType descriptorType,
6988 ShaderInputInterface shaderInterface,
6989 vk::VkDescriptorSetLayout layout,
6990 vk::VkDescriptorPool pool,
6991 vk::VkBufferView viewA,
6992 vk::VkBufferView viewB,
6993 vk::DescriptorSetUpdateBuilder& updateBuilder,
6994 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
6995 RawUpdateRegistry& updateRegistry,
6996 vk::VkPipelineLayout pipelineLayout)
6998 const vk::VkDescriptorSetAllocateInfo allocInfo =
7000 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
7007 vk::Move<vk::VkDescriptorSet> descriptorSet;
7008 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7010 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
7014 descriptorSet = vk::Move<vk::VkDescriptorSet>();
7017 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
7019 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplate, updateRegistry);
7021 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7023 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplate, updateRegistry, true, pipelineLayout);
7025 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7027 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, updateMethod);
7029 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7031 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder);
7034 return descriptorSet;
7037 void TexelBufferRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
7038 vk::VkDevice device,
7039 vk::VkDescriptorType descriptorType,
7040 ShaderInputInterface shaderInterface,
7041 vk::VkDescriptorSetLayout layout,
7042 vk::VkDescriptorPool pool,
7043 vk::VkBufferView viewA,
7044 vk::VkBufferView viewB,
7045 vk::VkDescriptorSet descriptorSet,
7046 vk::DescriptorSetUpdateBuilder& updateBuilder,
7047 DescriptorUpdateMethod updateMethod)
7051 const vk::VkBufferView texelBufferInfos[2] =
7057 switch (shaderInterface)
7059 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7060 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
7063 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7064 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
7065 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
7068 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7069 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
7073 DE_FATAL("Impossible");
7076 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7078 updateBuilder.update(vki, device);
7082 void TexelBufferRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
7083 vk::VkDevice device,
7084 vk::VkDescriptorType descriptorType,
7085 ShaderInputInterface shaderInterface,
7086 vk::VkDescriptorSetLayout layout,
7087 vk::VkDescriptorPool pool,
7088 vk::VkBufferView viewA,
7089 vk::VkBufferView viewB,
7090 vk::VkDescriptorSet descriptorSet,
7091 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
7092 RawUpdateRegistry& updateRegistry,
7094 vk::VkPipelineLayout pipelineLayout)
7097 const vk::VkBufferView texelBufferInfos[2] =
7102 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
7103 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
7105 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
7109 DE_NULL, // pUpdates
7110 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
7112 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
7116 updateRegistry.addWriteObject(texelBufferInfos[0]);
7117 updateRegistry.addWriteObject(texelBufferInfos[1]);
7119 switch (shaderInterface)
7121 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7122 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
7125 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7126 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
7127 updateEntries.push_back(createTemplateBinding(1, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
7130 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7131 updateEntries.push_back(createTemplateBinding(0, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(texelBufferInfos[0])));
7135 DE_FATAL("Impossible");
7138 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
7139 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
7141 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
7145 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
7149 void TexelBufferRenderInstance::logTestPlan (void) const
7151 std::ostringstream msg;
7153 msg << "Rendering 2x2 grid.\n"
7154 << "Single descriptor set. Descriptor set contains "
7155 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
7156 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
7157 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
7158 (const char*)DE_NULL)
7159 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
7160 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
7161 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
7163 if (m_stageFlags == 0u)
7165 msg << "Descriptors are not accessed in any shader stage.\n";
7169 msg << "Color in each cell is fetched using the descriptor(s):\n";
7171 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
7173 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
7175 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
7177 const int srcResourceNdx = (resultNdx % 2); // ABAB source
7178 msg << " from texelBuffer " << srcResourceNdx;
7184 msg << "Descriptors are accessed in {"
7185 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
7186 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
7187 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
7188 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
7189 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
7193 m_context.getTestContext().getLog()
7194 << tcu::TestLog::Message
7196 << tcu::TestLog::EndMessage;
7199 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
7201 return *m_pipelineLayout;
7204 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
7206 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7208 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
7210 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7212 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, *m_updateTemplate, getPipelineLayout(), 0, (const void*)m_updateRegistry.getRawPointer());
7214 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7216 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0);
7219 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
7222 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
7224 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
7225 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
7226 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
7227 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
7228 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
7229 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
7230 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
7231 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
7233 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
7235 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
7236 return tcu::TestStatus::fail("Image verification failed");
7238 return tcu::TestStatus::pass("Pass");
7241 class TexelBufferComputeInstance : public vkt::TestInstance
7244 TexelBufferComputeInstance (vkt::Context& context,
7245 DescriptorUpdateMethod updateMethod,
7246 vk::VkDescriptorType descriptorType,
7247 ShaderInputInterface shaderInterface,
7248 bool nonzeroViewOffset);
7251 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
7252 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
7253 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout);
7254 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet);
7255 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
7257 tcu::TestStatus iterate (void);
7258 void logTestPlan (void) const;
7259 tcu::TestStatus testResourceAccess (void);
7261 const DescriptorUpdateMethod m_updateMethod;
7262 const vk::VkDescriptorType m_descriptorType;
7263 const ShaderInputInterface m_shaderInterface;
7264 const bool m_nonzeroViewOffset;
7266 const vk::DeviceInterface& m_vki;
7267 const vk::VkDevice m_device;
7268 const vk::VkQueue m_queue;
7269 const deUint32 m_queueFamilyIndex;
7270 vk::Allocator& m_allocator;
7271 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
7273 const ComputeInstanceResultBuffer m_result;
7274 const TexelBufferInstanceBuffers m_texelBuffers;
7276 RawUpdateRegistry m_updateRegistry;
7277 vk::DescriptorSetUpdateBuilder m_updateBuilder;
7280 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
7281 DescriptorUpdateMethod updateMethod,
7282 vk::VkDescriptorType descriptorType,
7283 ShaderInputInterface shaderInterface,
7284 bool nonzeroViewOffset)
7285 : vkt::TestInstance (context)
7286 , m_updateMethod (updateMethod)
7287 , m_descriptorType (descriptorType)
7288 , m_shaderInterface (shaderInterface)
7289 , m_nonzeroViewOffset (nonzeroViewOffset)
7290 , m_vki (context.getDeviceInterface())
7291 , m_device (context.getDevice())
7292 , m_queue (context.getUniversalQueue())
7293 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
7294 , m_allocator (context.getDefaultAllocator())
7295 , m_updateTemplate ()
7296 , m_result (m_vki, m_device, m_allocator)
7297 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
7298 , m_updateRegistry ()
7299 , m_updateBuilder ()
7303 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
7305 vk::DescriptorSetLayoutBuilder builder;
7306 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
7308 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
7309 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7311 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
7314 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7316 switch (m_shaderInterface)
7318 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7319 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7322 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7323 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7324 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7327 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7328 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7332 DE_FATAL("Impossible");
7335 return builder.build(m_vki, m_device, extraFlags);
7338 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
7340 return vk::DescriptorPoolBuilder()
7341 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
7342 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
7343 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
7346 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout)
7348 const vk::VkDescriptorSetAllocateInfo allocInfo =
7350 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
7357 vk::Move<vk::VkDescriptorSet> descriptorSet;
7358 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7360 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
7364 descriptorSet = vk::Move<vk::VkDescriptorSet>();
7368 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
7370 writeDescriptorSetWithTemplate(*descriptorSet, layout);
7372 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7374 writeDescriptorSet(*descriptorSet);
7377 return descriptorSet;
7380 void TexelBufferComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet)
7382 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
7383 const vk::VkBufferView texelBufferInfos[2] =
7385 m_texelBuffers.getBufferViewA(),
7386 m_texelBuffers.getBufferViewB(),
7390 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
7393 switch (m_shaderInterface)
7395 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7396 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
7399 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7400 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
7401 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
7404 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7405 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
7409 DE_FATAL("Impossible");
7412 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7414 m_updateBuilder.update(m_vki, m_device);
7418 void TexelBufferComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush, vk::VkPipelineLayout pipelineLayout)
7420 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
7421 const vk::VkBufferView texelBufferInfos[2] =
7423 m_texelBuffers.getBufferViewA(),
7424 m_texelBuffers.getBufferViewB(),
7426 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
7427 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
7429 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
7433 DE_NULL, // pUpdates
7434 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
7436 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
7440 m_updateRegistry.addWriteObject(resultInfo);
7441 m_updateRegistry.addWriteObject(texelBufferInfos[0]);
7442 m_updateRegistry.addWriteObject(texelBufferInfos[1]);
7445 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
7448 switch (m_shaderInterface)
7450 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7451 updateEntries.push_back(createTemplateBinding(1, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
7454 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7455 updateEntries.push_back(createTemplateBinding(1, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
7456 updateEntries.push_back(createTemplateBinding(2, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(2), 0));
7459 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7460 updateEntries.push_back(createTemplateBinding(1, 0, 2, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), sizeof(texelBufferInfos[0])));
7464 DE_FATAL("Impossible");
7467 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
7468 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
7470 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
7474 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
7478 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
7481 return testResourceAccess();
7484 void TexelBufferComputeInstance::logTestPlan (void) const
7486 std::ostringstream msg;
7488 msg << "Fetching 4 values from image in compute shader.\n"
7489 << "Single descriptor set. Descriptor set contains "
7490 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
7491 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
7492 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
7493 (const char*)DE_NULL)
7494 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
7495 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
7496 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
7498 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
7500 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
7502 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
7504 const int srcResourceNdx = (resultNdx % 2); // ABAB source
7505 msg << " from texelBuffer " << srcResourceNdx;
7511 m_context.getTestContext().getLog()
7512 << tcu::TestLog::Message
7514 << tcu::TestLog::EndMessage;
7517 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
7519 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
7520 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
7521 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
7522 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
7524 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
7525 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : DE_LENGTH_OF_ARRAY(descriptorSets);
7526 const deUint32* const dynamicOffsets = DE_NULL;
7527 const int numDynamicOffsets = 0;
7528 const vk::VkBufferMemoryBarrier* const preBarriers = m_texelBuffers.getBufferInitBarriers();
7529 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
7530 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
7531 const int numPostBarriers = 1;
7533 const ComputeCommand compute (m_vki,
7535 pipeline.getPipeline(),
7536 pipeline.getPipelineLayout(),
7537 tcu::UVec3(4, 1, 1),
7538 numDescriptorSets, descriptorSets,
7539 numDynamicOffsets, dynamicOffsets,
7540 numPreBarriers, preBarriers,
7541 numPostBarriers, postBarriers);
7543 tcu::Vec4 results[4];
7544 bool anyResultSet = false;
7545 bool allResultsOk = true;
7547 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7549 writeDescriptorSetWithTemplate(DE_NULL, *descriptorSetLayout, true, pipeline.getPipelineLayout());
7550 compute.submitAndWait(m_queueFamilyIndex, m_queue, *m_updateTemplate, (const void*) m_updateRegistry.getRawPointer());
7552 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7554 writeDescriptorSet(DE_NULL);
7555 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder);
7559 compute.submitAndWait(m_queueFamilyIndex, m_queue);
7561 m_result.readResultContentsTo(&results);
7564 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
7566 const tcu::Vec4 result = results[resultNdx];
7567 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
7568 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
7570 if (result != tcu::Vec4(-1.0f))
7571 anyResultSet = true;
7573 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
7575 allResultsOk = false;
7577 m_context.getTestContext().getLog()
7578 << tcu::TestLog::Message
7579 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
7580 << tcu::TestLog::EndMessage;
7584 // read back and verify
7586 return tcu::TestStatus::pass("Pass");
7587 else if (anyResultSet)
7588 return tcu::TestStatus::fail("Invalid result values");
7591 m_context.getTestContext().getLog()
7592 << tcu::TestLog::Message
7593 << "Result buffer was not written to."
7594 << tcu::TestLog::EndMessage;
7595 return tcu::TestStatus::fail("Result buffer was not written to");
7599 class TexelBufferDescriptorCase : public QuadrantRendederCase
7604 FLAG_VIEW_OFFSET = (1u << 1u),
7606 // enum continues where resource flags ends
7607 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
7609 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
7610 DescriptorUpdateMethod updateMethod,
7612 const char* description,
7613 bool isPrimaryCmdBuf,
7614 vk::VkDescriptorType descriptorType,
7615 vk::VkShaderStageFlags exitingStages,
7616 vk::VkShaderStageFlags activeStages,
7617 ShaderInputInterface shaderInterface,
7621 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
7622 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
7623 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
7624 std::string genNoAccessSource (void) const;
7626 vkt::TestInstance* createInstance (vkt::Context& context) const;
7628 const DescriptorUpdateMethod m_updateMethod;
7629 const bool m_isPrimaryCmdBuf;
7630 const vk::VkDescriptorType m_descriptorType;
7631 const ShaderInputInterface m_shaderInterface;
7632 const bool m_nonzeroViewOffset;
7635 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
7636 DescriptorUpdateMethod updateMethod,
7638 const char* description,
7639 bool isPrimaryCmdBuf,
7640 vk::VkDescriptorType descriptorType,
7641 vk::VkShaderStageFlags exitingStages,
7642 vk::VkShaderStageFlags activeStages,
7643 ShaderInputInterface shaderInterface,
7645 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
7646 , m_updateMethod (updateMethod)
7647 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
7648 , m_descriptorType (descriptorType)
7649 , m_shaderInterface (shaderInterface)
7650 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
7654 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
7657 return "#extension GL_EXT_texture_buffer : require\n";
7660 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
7664 const bool isUniform = isUniformDescriptorType(m_descriptorType);
7665 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
7666 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
7668 switch (m_shaderInterface)
7670 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7671 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
7673 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7674 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
7675 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
7677 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7678 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
7681 DE_FATAL("Impossible");
7686 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
7690 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
7691 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
7692 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
7694 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
7695 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
7696 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
7698 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
7699 std::ostringstream buf;
7701 buf << " if (quadrant_id == 0)\n"
7702 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
7703 << " else if (quadrant_id == 1)\n"
7704 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
7705 << " else if (quadrant_id == 2)\n"
7706 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
7708 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
7713 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
7715 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
7716 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7718 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
7721 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
7723 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
7725 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
7727 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
7728 return new TexelBufferComputeInstance(context, m_updateMethod, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
7731 return new TexelBufferRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
7734 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
7735 bool isPrimaryCmdBuf,
7736 DescriptorUpdateMethod updateMethod,
7737 vk::VkDescriptorType descriptorType,
7738 vk::VkShaderStageFlags exitingStages,
7739 vk::VkShaderStageFlags activeStages,
7740 ShaderInputInterface dimension,
7741 deUint32 resourceFlags)
7745 vk::VkImageViewType viewType;
7747 const char* description;
7751 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
7752 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7753 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7755 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
7756 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7757 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7759 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
7760 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7761 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7763 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
7764 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7765 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7767 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
7768 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7769 // no 3d array textures
7771 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
7772 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7773 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7775 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
7776 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7777 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7780 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
7783 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
7785 // SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS only supported in VK_DESCRIPTOR_TYPE_SAMPLER on graphics shaders for now
7786 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS &&
7787 (descriptorType != vk::VK_DESCRIPTOR_TYPE_SAMPLER || activeStages == vk::VK_SHADER_STAGE_COMPUTE_BIT))
7790 group->addChild(new ImageDescriptorCase(group->getTestContext(),
7791 s_imageTypes[ndx].name,
7792 s_imageTypes[ndx].description,
7799 s_imageTypes[ndx].viewType,
7800 s_imageTypes[ndx].flags | resourceFlags));
7804 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
7805 bool isPrimaryCmdBuf,
7806 DescriptorUpdateMethod updateMethod,
7807 vk::VkDescriptorType descriptorType,
7808 vk::VkShaderStageFlags exitingStages,
7809 vk::VkShaderStageFlags activeStages,
7810 ShaderInputInterface dimension,
7811 deUint32 resourceFlags)
7813 DE_ASSERT(resourceFlags == 0);
7814 DE_UNREF(resourceFlags);
7819 const char* description;
7821 } s_texelBufferTypes[] =
7823 { "offset_zero", "View offset is zero", 0u },
7824 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
7827 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
7829 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
7832 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
7834 s_texelBufferTypes[ndx].name,
7835 s_texelBufferTypes[ndx].description,
7841 s_texelBufferTypes[ndx].flags));
7845 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
7846 bool isPrimaryCmdBuf,
7847 DescriptorUpdateMethod updateMethod,
7848 vk::VkDescriptorType descriptorType,
7849 vk::VkShaderStageFlags exitingStages,
7850 vk::VkShaderStageFlags activeStages,
7851 ShaderInputInterface dimension,
7852 deUint32 resourceFlags)
7854 DE_ASSERT(resourceFlags == 0u);
7855 DE_UNREF(resourceFlags);
7860 const char* description;
7861 bool isForDynamicCases;
7865 { "offset_view_zero", "View offset is zero", false, 0u },
7866 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
7868 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
7869 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
7870 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
7871 { "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 },
7874 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
7878 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH || updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7880 // Can't support push descriptor sets with dynamic UBOs or SSBOs
7885 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
7887 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
7890 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
7891 group->addChild(new BufferDescriptorCase(group->getTestContext(),
7893 s_bufferTypes[ndx].name,
7894 s_bufferTypes[ndx].description,
7900 s_bufferTypes[ndx].flags));
7906 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
7910 const bool isPrimary;
7912 const char* description;
7915 { true, "primary_cmd_buf", "Bind in primary command buffer" },
7916 { false, "secondary_cmd_buf", "Bind in secondary command buffer" },
7920 const DescriptorUpdateMethod method;
7922 const char* description;
7923 } s_updateMethods[] =
7925 { DESCRIPTOR_UPDATE_METHOD_NORMAL, "", "Use regular descriptor updates" },
7926 { DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE, "with_template", "Use descriptor update templates" },
7927 { DESCRIPTOR_UPDATE_METHOD_WITH_PUSH, "with_push", "Use push descriptor updates" },
7928 { DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE, "with_push_template", "Use push descriptor update templates" },
7932 const vk::VkDescriptorType descriptorType;
7934 const char* description;
7936 } s_descriptorTypes[] =
7938 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
7939 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
7940 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
7941 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
7942 // \note No way to access SAMPLED_IMAGE without a sampler
7943 //{ vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
7944 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
7945 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
7946 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
7947 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
7948 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
7949 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
7950 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
7955 const char* description;
7956 vk::VkShaderStageFlags existingStages; //!< stages that exists
7957 vk::VkShaderStageFlags activeStages; //!< stages that access resource
7958 bool supportsSecondaryCmdBufs;
7959 } s_shaderStages[] =
7963 "No accessing stages",
7964 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
7971 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
7972 vk::VK_SHADER_STAGE_VERTEX_BIT,
7977 "Tessellation control stage",
7978 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,
7979 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
7984 "Tessellation evaluation stage",
7985 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,
7986 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
7992 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
7993 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
7999 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8000 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8006 vk::VK_SHADER_STAGE_COMPUTE_BIT,
8007 vk::VK_SHADER_STAGE_COMPUTE_BIT,
8012 "Vertex and fragment stages",
8013 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8014 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8020 ShaderInputInterface dimension;
8022 const char* description;
8023 } s_variableDimensions[] =
8025 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
8026 { SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, "multiple_contiguous_descriptors", "Multiple descriptors" },
8027 { SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, "multiple_discontiguous_descriptors", "Multiple descriptors" },
8028 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
8031 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
8033 // .primary_cmd_buf...
8034 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
8036 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
8038 for (int updateMethodNdx = 0; updateMethodNdx < DE_LENGTH_OF_ARRAY(s_updateMethods); ++updateMethodNdx)
8040 de::MovePtr<tcu::TestCaseGroup> updateMethodGroup(new tcu::TestCaseGroup(testCtx, s_updateMethods[updateMethodNdx].name, s_updateMethods[updateMethodNdx].description));
8042 // .sampler, .combined_image_sampler, other resource types ...
8043 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
8045 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
8047 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
8049 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
8051 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
8053 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
8055 de::MovePtr<tcu::TestCaseGroup> dimensionGroup(new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
8056 void (*createTestsFunc)(tcu::TestCaseGroup* group,
8057 bool isPrimaryCmdBuf,
8058 DescriptorUpdateMethod updateMethod,
8059 vk::VkDescriptorType descriptorType,
8060 vk::VkShaderStageFlags existingStages,
8061 vk::VkShaderStageFlags activeStages,
8062 ShaderInputInterface dimension,
8063 deUint32 resourceFlags);
8065 switch (s_descriptorTypes[descriptorNdx].descriptorType)
8067 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
8068 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
8069 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
8070 createTestsFunc = createShaderAccessImageTests;
8073 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
8074 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
8075 createTestsFunc = createShaderAccessTexelBufferTests;
8078 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
8079 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
8080 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
8081 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
8082 createTestsFunc = createShaderAccessBufferTests;
8086 createTestsFunc = DE_NULL;
8087 DE_FATAL("Impossible");
8090 if (createTestsFunc)
8092 createTestsFunc(dimensionGroup.get(),
8093 s_bindTypes[bindTypeNdx].isPrimary,
8094 s_updateMethods[updateMethodNdx].method,
8095 s_descriptorTypes[descriptorNdx].descriptorType,
8096 s_shaderStages[stageNdx].existingStages,
8097 s_shaderStages[stageNdx].activeStages,
8098 s_variableDimensions[dimensionNdx].dimension,
8099 s_descriptorTypes[descriptorNdx].flags);
8102 DE_FATAL("Impossible");
8104 stageGroup->addChild(dimensionGroup.release());
8107 typeGroup->addChild(stageGroup.release());
8111 if (s_updateMethods[updateMethodNdx].method != DESCRIPTOR_UPDATE_METHOD_NORMAL)
8113 updateMethodGroup->addChild(typeGroup.release());
8117 bindGroup->addChild(typeGroup.release());
8121 if (s_updateMethods[updateMethodNdx].method != DESCRIPTOR_UPDATE_METHOD_NORMAL)
8123 bindGroup->addChild(updateMethodGroup.release());
8127 group->addChild(bindGroup.release());
8130 return group.release();