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 (uint32_t binding, uint32_t arrayElement, uint32_t 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 const vk::VkCommandPoolCreateInfo createInfo =
676 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
678 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
679 queueFamilyIndex, // queueFamilyIndex
681 return vk::createCommandPool(vki, device, &createInfo);
684 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
686 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
687 const vk::VkBufferCreateInfo bufferCreateInfo =
689 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
692 pixelDataSize, // size
693 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
694 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
695 0u, // queueFamilyCount
696 DE_NULL, // pQueueFamilyIndices
698 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
699 const vk::VkImageSubresourceRange fullSubrange =
701 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
704 0u, // baseArraySlice
707 const vk::VkImageMemoryBarrier imageBarrier =
709 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
711 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
712 vk::VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
713 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
714 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
715 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
716 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
717 *m_colorAttachmentImage, // image
718 fullSubrange, // subresourceRange
720 const vk::VkBufferMemoryBarrier memoryBarrier =
722 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
724 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
725 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
726 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
727 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
730 (vk::VkDeviceSize)pixelDataSize // size
732 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
734 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
736 *m_cmdPool, // cmdPool
737 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
740 const vk::VkFenceCreateInfo fenceCreateInfo =
742 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
746 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
748 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
750 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
751 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
753 const vk::VkImageSubresourceLayers firstSlice =
755 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspect
760 const vk::VkBufferImageCopy copyRegion =
763 m_targetSize.x(), // bufferRowLength
764 m_targetSize.y(), // bufferImageHeight
765 firstSlice, // imageSubresource
766 { 0, 0, 0 }, // imageOffset
767 { m_targetSize.x(), m_targetSize.y(), 1u } // imageExtent
770 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
772 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
773 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
774 const deUint64 infiniteTimeout = ~(deUint64)0u;
776 // copy content to buffer
777 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
778 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
779 0, (const vk::VkMemoryBarrier*)DE_NULL,
780 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
782 m_vki.cmdCopyImageToBuffer(*cmd, *m_colorAttachmentImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
783 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
784 0, (const vk::VkMemoryBarrier*)DE_NULL,
786 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
787 VK_CHECK(m_vki.endCommandBuffer(*cmd));
789 // wait for transfer to complete
791 const vk::VkSubmitInfo submitInfo =
793 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
796 (const vk::VkSemaphore*)0,
797 (const vk::VkPipelineStageFlags*)DE_NULL,
801 (const vk::VkSemaphore*)0,
804 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *cmdCompleteFence));
806 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
808 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
811 invalidateMappedMemoryRange(m_vki, m_device, bufferMemory->getMemory(), bufferMemory->getOffset(), pixelDataSize);
812 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
815 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
817 tcu::TextureLevel resultImage;
820 if (m_firstIteration)
823 m_firstIteration = false;
828 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
829 const vk::VkImageSubresourceRange fullSubrange =
831 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
834 0u, // baseArraySlice
837 const vk::VkImageMemoryBarrier imageBarrier =
839 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
842 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
843 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
844 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
845 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
846 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
847 *m_colorAttachmentImage, // image
848 fullSubrange, // subresourceRange
850 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
852 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
854 *m_cmdPool, // cmdPool
855 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
858 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
860 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
862 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
863 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
865 const vk::VkFenceCreateInfo fenceCreateInfo =
867 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
869 (vk::VkFenceCreateFlags)0,
872 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
873 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
874 const deUint64 infiniteTimeout = ~(deUint64)0u;
876 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
877 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
878 0, (const vk::VkMemoryBarrier*)DE_NULL,
879 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
881 VK_CHECK(m_vki.endCommandBuffer(*cmd));
884 const vk::VkSubmitInfo submitInfo =
886 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
889 (const vk::VkSemaphore*)0,
890 (const vk::VkPipelineStageFlags*)DE_NULL,
894 (const vk::VkSemaphore*)0,
897 VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
899 VK_CHECK(m_vki.waitForFences(m_device, 1u, &fence.get(), VK_TRUE, infiniteTimeout));
901 // and then render to
906 readRenderTarget(resultImage);
907 return verifyResultImage(resultImage.getAccess());
910 class RenderInstanceShaders
913 RenderInstanceShaders (const vk::DeviceInterface& vki,
915 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
916 const vk::BinaryCollection& programCollection);
918 inline bool hasTessellationStage (void) const { return *m_tessCtrlShaderModule != 0 || *m_tessEvalShaderModule != 0; }
919 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
920 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
923 void addStage (const vk::DeviceInterface& vki,
925 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
926 const vk::BinaryCollection& programCollection,
928 vk::VkShaderStageFlagBits stage,
929 vk::Move<vk::VkShaderModule>* outModule);
931 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const;
933 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
934 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
935 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
936 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
937 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
938 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
941 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
943 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
944 const vk::BinaryCollection& programCollection)
946 addStage(vki, device, deviceFeatures, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX_BIT, &m_vertexShaderModule);
947 addStage(vki, device, deviceFeatures, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessCtrlShaderModule);
948 addStage(vki, device, deviceFeatures, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvalShaderModule);
949 addStage(vki, device, deviceFeatures, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule);
950 addStage(vki, device, deviceFeatures, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule);
952 DE_ASSERT(!m_stageInfos.empty());
955 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
957 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
958 const vk::BinaryCollection& programCollection,
960 vk::VkShaderStageFlagBits stage,
961 vk::Move<vk::VkShaderModule>* outModule)
963 if (programCollection.contains(name))
965 if (vk::isShaderStageSupported(deviceFeatures, stage))
967 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
969 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *module));
974 // Wait for the GPU to idle so that throwing the exception
975 // below doesn't free in-use GPU resource.
976 vki.deviceWaitIdle(device);
977 TCU_THROW(NotSupportedError, (de::toString(stage) + " is not supported").c_str());
982 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const
984 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
986 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
988 (vk::VkPipelineShaderStageCreateFlags)0,
992 DE_NULL, // pSpecializationInfo
994 return stageCreateInfo;
997 class SingleCmdRenderInstance : public SingleTargetRenderInstance
1000 SingleCmdRenderInstance (Context& context,
1001 bool isPrimaryCmdBuf,
1002 const tcu::UVec2& renderSize);
1005 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
1007 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
1008 virtual void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const = 0;
1010 void renderToTarget (void);
1012 const bool m_isPrimaryCmdBuf;
1015 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
1016 bool isPrimaryCmdBuf,
1017 const tcu::UVec2& renderSize)
1018 : SingleTargetRenderInstance (context, renderSize)
1019 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
1023 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
1025 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getDeviceFeatures(), m_context.getBinaryCollection());
1026 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
1027 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
1029 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
1031 (vk::VkPipelineVertexInputStateCreateFlags)0,
1033 DE_NULL, // pVertexBindingDescriptions
1034 0u, // attributeCount
1035 DE_NULL, // pVertexAttributeDescriptions
1037 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
1039 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
1041 (vk::VkPipelineInputAssemblyStateCreateFlags)0,
1042 topology, // topology
1043 VK_FALSE, // primitiveRestartEnable
1045 const vk::VkPipelineTessellationStateCreateInfo tessState =
1047 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
1049 (vk::VkPipelineTessellationStateCreateFlags)0,
1050 3u, // patchControlPoints
1052 const vk::VkViewport viewport =
1056 float(m_targetSize.x()), // width
1057 float(m_targetSize.y()), // height
1061 const vk::VkRect2D renderArea =
1064 { m_targetSize.x(), m_targetSize.y() }, // extent
1066 const vk::VkPipelineViewportStateCreateInfo vpState =
1068 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
1070 (vk::VkPipelineViewportStateCreateFlags)0,
1071 1u, // viewportCount
1076 const vk::VkPipelineRasterizationStateCreateInfo rsState =
1078 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
1080 (vk::VkPipelineRasterizationStateCreateFlags)0,
1081 VK_TRUE, // depthClipEnable
1082 VK_FALSE, // rasterizerDiscardEnable
1083 vk::VK_POLYGON_MODE_FILL, // fillMode
1084 vk::VK_CULL_MODE_NONE, // cullMode
1085 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
1086 VK_FALSE, // depthBiasEnable
1088 0.0f, // depthBiasClamp
1089 0.0f, // slopeScaledDepthBias
1092 const vk::VkSampleMask sampleMask = 0x01u;
1093 const vk::VkPipelineMultisampleStateCreateInfo msState =
1095 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
1097 (vk::VkPipelineMultisampleStateCreateFlags)0,
1098 vk::VK_SAMPLE_COUNT_1_BIT, // rasterSamples
1099 VK_FALSE, // sampleShadingEnable
1100 0.0f, // minSampleShading
1101 &sampleMask, // sampleMask
1102 VK_FALSE, // alphaToCoverageEnable
1103 VK_FALSE, // alphaToOneEnable
1105 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
1107 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
1109 (vk::VkPipelineDepthStencilStateCreateFlags)0,
1110 VK_FALSE, // depthTestEnable
1111 VK_FALSE, // depthWriteEnable
1112 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
1113 VK_FALSE, // depthBoundsTestEnable
1114 VK_FALSE, // stencilTestEnable
1115 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
1116 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
1117 -1.0f, // minDepthBounds
1118 +1.0f, // maxDepthBounds
1120 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
1122 VK_FALSE, // blendEnable
1123 vk::VK_BLEND_FACTOR_ZERO, // srcBlendColor
1124 vk::VK_BLEND_FACTOR_ZERO, // destBlendColor
1125 vk::VK_BLEND_OP_ADD, // blendOpColor
1126 vk::VK_BLEND_FACTOR_ZERO, // srcBlendAlpha
1127 vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha
1128 vk::VK_BLEND_OP_ADD, // blendOpAlpha
1129 (vk::VK_COLOR_COMPONENT_R_BIT |
1130 vk::VK_COLOR_COMPONENT_G_BIT |
1131 vk::VK_COLOR_COMPONENT_B_BIT |
1132 vk::VK_COLOR_COMPONENT_A_BIT), // channelWriteMask
1134 const vk::VkPipelineColorBlendStateCreateInfo cbState =
1136 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
1138 (vk::VkPipelineColorBlendStateCreateFlags)0,
1139 VK_FALSE, // logicOpEnable
1140 vk::VK_LOGIC_OP_CLEAR, // logicOp
1141 1u, // attachmentCount
1142 &cbAttachment, // pAttachments
1143 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
1145 const vk::VkGraphicsPipelineCreateInfo createInfo =
1147 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1149 (vk::VkPipelineCreateFlags)0,
1150 shaderStages.getNumStages(), // stageCount
1151 shaderStages.getStages(), // pStages
1152 &vertexInputState, // pVertexInputState
1153 &iaState, // pInputAssemblyState
1154 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
1155 &vpState, // pViewportState
1156 &rsState, // pRasterState
1157 &msState, // pMultisampleState
1158 &dsState, // pDepthStencilState
1159 &cbState, // pColorBlendState
1160 (const vk::VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
1161 pipelineLayout, // layout
1162 *m_renderPass, // renderPass
1164 (vk::VkPipeline)0, // basePipelineHandle
1165 0u, // basePipelineIndex
1167 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
1170 void SingleCmdRenderInstance::renderToTarget (void)
1172 const vk::VkRect2D renderArea =
1175 { m_targetSize.x(), m_targetSize.y() }, // extent
1177 const vk::VkCommandBufferAllocateInfo mainCmdBufCreateInfo =
1179 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1181 *m_cmdPool, // cmdPool
1182 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1185 const vk::VkCommandBufferBeginInfo mainCmdBufBeginInfo =
1187 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1189 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1190 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
1192 const vk::VkCommandBufferAllocateInfo passCmdBufCreateInfo =
1194 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1196 *m_cmdPool, // cmdPool
1197 vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level
1200 const vk::VkCommandBufferInheritanceInfo passCmdBufInheritInfo =
1202 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1204 (vk::VkRenderPass)*m_renderPass, // renderPass
1206 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
1207 VK_FALSE, // occlusionQueryEnable
1208 (vk::VkQueryControlFlags)0,
1209 (vk::VkQueryPipelineStatisticFlags)0,
1211 const vk::VkCommandBufferBeginInfo passCmdBufBeginInfo =
1213 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1215 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
1216 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // flags
1217 &passCmdBufInheritInfo,
1219 const vk::VkFenceCreateInfo fenceCreateInfo =
1221 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1225 const vk::VkClearValue clearValue = vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
1226 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1228 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1230 *m_renderPass, // renderPass
1231 *m_framebuffer, // framebuffer
1232 renderArea, // renderArea
1233 1u, // clearValueCount
1234 &clearValue, // pClearValues
1237 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1238 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1239 const vk::Unique<vk::VkCommandBuffer> mainCmd (vk::allocateCommandBuffer(m_vki, m_device, &mainCmdBufCreateInfo));
1240 const vk::Unique<vk::VkCommandBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCommandBuffer>()) : (vk::allocateCommandBuffer(m_vki, m_device, &passCmdBufCreateInfo)));
1241 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1242 const deUint64 infiniteTimeout = ~(deUint64)0u;
1243 const vk::VkSubpassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_SUBPASS_CONTENTS_INLINE) : (vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1245 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1246 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1248 if (m_isPrimaryCmdBuf)
1250 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1251 writeDrawCmdBuffer(*mainCmd);
1255 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1256 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1257 writeDrawCmdBuffer(*passCmd);
1258 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1260 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1263 m_vki.cmdEndRenderPass(*mainCmd);
1264 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1266 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1268 const vk::VkSubmitInfo submitInfo =
1270 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1273 (const vk::VkSemaphore*)0,
1274 (const vk::VkPipelineStageFlags*)DE_NULL,
1278 (const vk::VkSemaphore*)0,
1280 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *fence));
1282 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1285 enum ShaderInputInterface
1287 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1288 SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with contiguous binding id's
1289 SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with discontiguous binding id's
1290 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1295 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1297 switch (shaderInterface)
1299 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1300 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS: return 2u;
1301 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS: return 2u;
1302 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1305 DE_FATAL("Impossible");
1310 class BufferRenderInstance : public SingleCmdRenderInstance
1313 BufferRenderInstance (Context& context,
1314 DescriptorUpdateMethod updateMethod,
1315 bool isPrimaryCmdBuf,
1316 vk::VkDescriptorType descriptorType,
1317 vk::VkShaderStageFlags stageFlags,
1318 ShaderInputInterface shaderInterface,
1321 bool dynamicOffsetNonZero);
1323 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1324 vk::VkDevice device,
1325 vk::Allocator& allocator,
1326 vk::VkDescriptorType descriptorType,
1328 deUint32 bufferSize,
1329 de::MovePtr<vk::Allocation>* outMemory);
1331 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1332 vk::VkDevice device,
1333 vk::VkDescriptorType descriptorType,
1334 ShaderInputInterface shaderInterface);
1336 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1337 vk::VkDevice device,
1338 vk::VkDescriptorType descriptorType,
1339 ShaderInputInterface shaderInterface,
1340 vk::VkShaderStageFlags stageFlags,
1341 DescriptorUpdateMethod updateMethod);
1343 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1344 DescriptorUpdateMethod updateMethod,
1345 vk::VkDevice device,
1346 vk::VkDescriptorSetLayout descriptorSetLayout,
1347 vk::VkDescriptorPool descriptorPool,
1348 vk::VkDescriptorType descriptorType,
1349 ShaderInputInterface shaderInterface,
1350 vk::VkBuffer sourceBufferA,
1351 const deUint32 viewOffsetA,
1352 vk::VkBuffer sourceBufferB,
1353 const deUint32 viewOffsetB,
1354 vk::DescriptorSetUpdateBuilder& updateBuilder,
1355 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
1356 RawUpdateRegistry& updateRegistry,
1357 vk::VkPipelineLayout pipelineLayout = DE_NULL);
1359 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1360 vk::VkDevice device,
1361 vk::VkDescriptorSetLayout descriptorSetLayout);
1363 static void writeDescriptorSet (const vk::DeviceInterface& vki,
1364 vk::VkDevice device,
1365 vk::VkDescriptorSetLayout descriptorSetLayout,
1366 vk::VkDescriptorPool descriptorPool,
1367 vk::VkDescriptorType descriptorType,
1368 ShaderInputInterface shaderInterface,
1369 vk::VkBuffer sourceBufferA,
1370 const deUint32 viewOffsetA,
1371 vk::VkBuffer sourceBufferB,
1372 const deUint32 viewOffsetB,
1373 vk::VkDescriptorSet descriptorSet,
1374 vk::DescriptorSetUpdateBuilder& updateBuilder,
1375 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
1377 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
1378 vk::VkDevice device,
1379 vk::VkDescriptorSetLayout descriptorSetLayout,
1380 vk::VkDescriptorPool descriptorPool,
1381 vk::VkDescriptorType descriptorType,
1382 ShaderInputInterface shaderInterface,
1383 vk::VkBuffer sourceBufferA,
1384 const deUint32 viewOffsetA,
1385 vk::VkBuffer sourceBufferB,
1386 const deUint32 viewOffsetB,
1387 vk::VkDescriptorSet descriptorSet,
1388 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
1389 RawUpdateRegistry& updateRegistry,
1390 bool withPush = false,
1391 vk::VkPipelineLayout pipelineLayout = 0);
1393 void logTestPlan (void) const;
1394 vk::VkPipelineLayout getPipelineLayout (void) const;
1395 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1396 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1401 BUFFER_DATA_SIZE = 8 * sizeof(float),
1402 BUFFER_SIZE_A = 2048, //!< a lot more than required
1403 BUFFER_SIZE_B = 2560, //!< a lot more than required
1405 STATIC_OFFSET_VALUE_A = 256,
1406 DYNAMIC_OFFSET_VALUE_A = 512,
1407 STATIC_OFFSET_VALUE_B = 1024,
1408 DYNAMIC_OFFSET_VALUE_B = 768,
1411 const DescriptorUpdateMethod m_updateMethod;
1412 const vk::VkDescriptorType m_descriptorType;
1413 const ShaderInputInterface m_shaderInterface;
1414 const bool m_setViewOffset;
1415 const bool m_setDynamicOffset;
1416 const bool m_dynamicOffsetNonZero;
1417 const vk::VkShaderStageFlags m_stageFlags;
1419 const deUint32 m_viewOffsetA;
1420 const deUint32 m_viewOffsetB;
1421 const deUint32 m_dynamicOffsetA;
1422 const deUint32 m_dynamicOffsetB;
1423 const deUint32 m_effectiveOffsetA;
1424 const deUint32 m_effectiveOffsetB;
1425 const deUint32 m_bufferSizeA;
1426 const deUint32 m_bufferSizeB;
1428 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1429 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1430 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1431 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1432 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1433 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
1434 RawUpdateRegistry m_updateRegistry;
1435 vk::DescriptorSetUpdateBuilder m_updateBuilder;
1436 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1437 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1438 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1441 BufferRenderInstance::BufferRenderInstance (Context& context,
1442 DescriptorUpdateMethod updateMethod,
1443 bool isPrimaryCmdBuf,
1444 vk::VkDescriptorType descriptorType,
1445 vk::VkShaderStageFlags stageFlags,
1446 ShaderInputInterface shaderInterface,
1449 bool dynamicOffsetNonZero)
1450 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1451 , m_updateMethod (updateMethod)
1452 , m_descriptorType (descriptorType)
1453 , m_shaderInterface (shaderInterface)
1454 , m_setViewOffset (viewOffset)
1455 , m_setDynamicOffset (dynamicOffset)
1456 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1457 , m_stageFlags (stageFlags)
1458 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1459 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1460 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1461 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1462 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetA + m_dynamicOffsetA) : (m_viewOffsetA))
1463 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetB + m_dynamicOffsetB) : (m_viewOffsetB))
1464 , m_bufferSizeA (BUFFER_SIZE_A)
1465 , m_bufferSizeB (BUFFER_SIZE_B)
1466 , m_bufferMemoryA (DE_NULL)
1467 , m_bufferMemoryB (DE_NULL)
1468 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1469 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1470 ? vk::Move<vk::VkBuffer>()
1471 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1472 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1473 , m_updateTemplate ()
1474 , m_updateRegistry ()
1475 , m_updateBuilder ()
1476 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_updateMethod))
1477 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1478 , 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))
1480 if (m_setDynamicOffset)
1481 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1482 if (m_dynamicOffsetNonZero)
1483 DE_ASSERT(m_setDynamicOffset);
1486 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1487 vk::VkDevice device,
1488 vk::Allocator& allocator,
1489 vk::VkDescriptorType descriptorType,
1491 deUint32 bufferSize,
1492 de::MovePtr<vk::Allocation>* outMemory)
1494 static const float s_colors[] =
1496 0.0f, 1.0f, 0.0f, 1.0f, // green
1497 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1499 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1500 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1501 DE_ASSERT(offset % sizeof(float) == 0);
1502 DE_ASSERT(bufferSize % sizeof(float) == 0);
1504 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1505 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1506 const float preGuardValue = 0.5f;
1507 const float postGuardValue = 0.75f;
1508 const vk::VkBufferCreateInfo bufferCreateInfo =
1510 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1514 usageFlags, // usage
1515 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1516 0u, // queueFamilyCount
1517 DE_NULL, // pQueueFamilyIndices
1519 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1520 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1521 void* const mapPtr = bufferMemory->getHostPtr();
1523 // guard with interesting values
1524 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1525 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1527 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1528 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1529 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1530 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
1532 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1534 // Flushed host-visible memory is automatically made available to the GPU, no barrier is needed.
1536 *outMemory = bufferMemory;
1540 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1541 vk::VkDevice device,
1542 vk::VkDescriptorType descriptorType,
1543 ShaderInputInterface shaderInterface)
1545 return vk::DescriptorPoolBuilder()
1546 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1547 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1550 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1551 vk::VkDevice device,
1552 vk::VkDescriptorType descriptorType,
1553 ShaderInputInterface shaderInterface,
1554 vk::VkShaderStageFlags stageFlags,
1555 DescriptorUpdateMethod updateMethod)
1557 vk::DescriptorSetLayoutBuilder builder;
1558 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
1560 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
1561 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1563 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
1566 switch (shaderInterface)
1568 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1569 builder.addSingleBinding(descriptorType, stageFlags);
1572 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1573 builder.addSingleBinding(descriptorType, stageFlags);
1574 builder.addSingleBinding(descriptorType, stageFlags);
1577 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1578 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1582 DE_FATAL("Impossible");
1585 return builder.build(vki, device, extraFlags);
1588 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1589 DescriptorUpdateMethod updateMethod,
1590 vk::VkDevice device,
1591 vk::VkDescriptorSetLayout descriptorSetLayout,
1592 vk::VkDescriptorPool descriptorPool,
1593 vk::VkDescriptorType descriptorType,
1594 ShaderInputInterface shaderInterface,
1595 vk::VkBuffer bufferA,
1597 vk::VkBuffer bufferB,
1599 vk::DescriptorSetUpdateBuilder& updateBuilder,
1600 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
1601 RawUpdateRegistry& updateRegistry,
1602 vk::VkPipelineLayout pipelineLayout)
1604 const vk::VkDescriptorSetAllocateInfo allocInfo =
1606 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1610 &descriptorSetLayout
1613 vk::Move<vk::VkDescriptorSet> descriptorSet;
1614 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1616 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1620 descriptorSet = vk::Move<vk::VkDescriptorSet>();
1623 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
1625 writeDescriptorSetWithTemplate(vki, device, descriptorSetLayout, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateTemplate, updateRegistry);
1627 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1629 writeDescriptorSetWithTemplate(vki, device, descriptorSetLayout, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateTemplate, updateRegistry, true, pipelineLayout);
1631 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1633 writeDescriptorSet(vki, device, descriptorSetLayout, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateBuilder, updateMethod);
1635 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
1637 writeDescriptorSet(vki, device, descriptorSetLayout, descriptorPool, descriptorType, shaderInterface, bufferA, offsetA, bufferB, offsetB, *descriptorSet, updateBuilder);
1640 return descriptorSet;
1643 void BufferRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
1644 vk::VkDevice device,
1645 vk::VkDescriptorSetLayout descriptorSetLayout,
1646 vk::VkDescriptorPool descriptorPool,
1647 vk::VkDescriptorType descriptorType,
1648 ShaderInputInterface shaderInterface,
1649 vk::VkBuffer bufferA,
1650 const deUint32 offsetA,
1651 vk::VkBuffer bufferB,
1652 const deUint32 offsetB,
1653 vk::VkDescriptorSet descriptorSet,
1654 vk::DescriptorSetUpdateBuilder& updateBuilder,
1655 DescriptorUpdateMethod updateMethod)
1657 DE_UNREF(descriptorSetLayout);
1658 DE_UNREF(descriptorPool);
1659 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1661 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1662 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1665 switch (shaderInterface)
1667 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1668 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1671 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1672 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1673 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1676 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1677 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1681 DE_FATAL("Impossible");
1684 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
1686 updateBuilder.update(vki, device);
1690 void BufferRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
1691 vk::VkDevice device,
1692 vk::VkDescriptorSetLayout layout,
1693 vk::VkDescriptorPool descriptorPool,
1694 vk::VkDescriptorType descriptorType,
1695 ShaderInputInterface shaderInterface,
1696 vk::VkBuffer bufferA,
1697 const deUint32 offsetA,
1698 vk::VkBuffer bufferB,
1699 const deUint32 offsetB,
1700 vk::VkDescriptorSet descriptorSet,
1701 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
1702 RawUpdateRegistry& updateRegistry,
1704 vk::VkPipelineLayout pipelineLayout)
1706 DE_UNREF(descriptorPool);
1707 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1709 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1710 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1712 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
1713 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
1715 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
1718 0, // descriptorUpdateEntryCount
1719 DE_NULL, // pDescriptorUpdateEntries
1720 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
1722 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
1726 updateRegistry.addWriteObject(bufferInfos[0]);
1727 updateRegistry.addWriteObject(bufferInfos[1]);
1729 switch (shaderInterface)
1731 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1732 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1735 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1736 updateEntries.push_back(createTemplateBinding(0u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
1737 updateEntries.push_back(createTemplateBinding(1u, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
1740 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1741 updateEntries.push_back(createTemplateBinding(0u, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(bufferInfos[0])));
1745 DE_FATAL("Impossible");
1748 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
1749 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
1751 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
1755 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
1759 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1760 vk::VkDevice device,
1761 vk::VkDescriptorSetLayout descriptorSetLayout)
1763 const vk::VkPipelineLayoutCreateInfo createInfo =
1765 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1767 (vk::VkPipelineLayoutCreateFlags)0,
1768 1, // descriptorSetCount
1769 &descriptorSetLayout, // pSetLayouts
1770 0u, // pushConstantRangeCount
1771 DE_NULL, // pPushConstantRanges
1774 return vk::createPipelineLayout(vki, device, &createInfo);
1777 void BufferRenderInstance::logTestPlan (void) const
1779 std::ostringstream msg;
1781 msg << "Rendering 2x2 yellow-green grid.\n"
1782 << "Single descriptor set. Descriptor set contains "
1783 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1784 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
1785 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1786 (const char*)DE_NULL)
1787 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1788 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1790 if (isDynamicDescriptorType(m_descriptorType))
1792 if (m_setDynamicOffset)
1794 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1795 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1799 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1803 if (m_stageFlags == 0u)
1805 msg << "Descriptors are not accessed in any shader stage.\n";
1809 msg << "Descriptors are accessed in {"
1810 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1811 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1812 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1813 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1814 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1818 m_context.getTestContext().getLog()
1819 << tcu::TestLog::Message
1821 << tcu::TestLog::EndMessage;
1824 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1826 return *m_pipelineLayout;
1829 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1831 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1832 const deUint32 dynamicOffsets[] =
1837 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1838 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1840 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1842 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1844 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
1846 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, *m_updateTemplate, getPipelineLayout(), 0, (const void*)m_updateRegistry.getRawPointer());
1848 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
1850 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0);
1853 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1856 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1858 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1859 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1860 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1862 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1864 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1865 return tcu::TestStatus::fail("Image verification failed");
1867 return tcu::TestStatus::pass("Pass");
1870 class ComputeInstanceResultBuffer
1875 DATA_SIZE = sizeof(tcu::Vec4[4])
1878 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1879 vk::VkDevice device,
1880 vk::Allocator& allocator);
1882 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1884 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1885 inline const vk::VkBufferMemoryBarrier* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1888 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1889 vk::VkDevice device,
1890 vk::Allocator& allocator,
1891 de::MovePtr<vk::Allocation>* outAllocation);
1893 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1895 const vk::DeviceInterface& m_vki;
1896 const vk::VkDevice m_device;
1898 de::MovePtr<vk::Allocation> m_bufferMem;
1899 const vk::Unique<vk::VkBuffer> m_buffer;
1900 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1903 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1904 vk::VkDevice device,
1905 vk::Allocator& allocator)
1908 , m_bufferMem (DE_NULL)
1909 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1910 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1914 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1916 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1917 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1920 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1921 vk::VkDevice device,
1922 vk::Allocator& allocator,
1923 de::MovePtr<vk::Allocation>* outAllocation)
1925 const vk::VkBufferCreateInfo createInfo =
1927 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1930 (vk::VkDeviceSize)DATA_SIZE, // size
1931 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1932 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1933 0u, // queueFamilyCount
1934 DE_NULL, // pQueueFamilyIndices
1936 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1937 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1938 const float clearValue = -1.0f;
1939 void* mapPtr = allocation->getHostPtr();
1941 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1942 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1944 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1946 *outAllocation = allocation;
1950 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1952 const vk::VkBufferMemoryBarrier bufferBarrier =
1954 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1956 vk::VK_ACCESS_SHADER_WRITE_BIT, // outputMask
1957 vk::VK_ACCESS_HOST_READ_BIT, // inputMask
1958 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1959 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1961 (vk::VkDeviceSize)0u, // offset
1964 return bufferBarrier;
1967 class ComputePipeline
1970 ComputePipeline (const vk::DeviceInterface& vki,
1971 vk::VkDevice device,
1972 const vk::BinaryCollection& programCollection,
1973 deUint32 numDescriptorSets,
1974 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1976 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1977 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1980 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1981 vk::VkDevice device,
1982 deUint32 numDescriptorSets,
1983 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1985 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1986 vk::VkDevice device,
1987 const vk::BinaryCollection& programCollection,
1988 vk::VkPipelineLayout layout);
1990 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1991 const vk::Unique<vk::VkPipeline> m_pipeline;
1994 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1995 vk::VkDevice device,
1996 const vk::BinaryCollection& programCollection,
1997 deUint32 numDescriptorSets,
1998 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1999 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
2000 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
2004 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
2005 vk::VkDevice device,
2006 deUint32 numDescriptorSets,
2007 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
2009 const vk::VkPipelineLayoutCreateInfo createInfo =
2011 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
2013 (vk::VkPipelineLayoutCreateFlags)0,
2014 numDescriptorSets, // descriptorSetCount
2015 descriptorSetLayouts, // pSetLayouts
2016 0u, // pushConstantRangeCount
2017 DE_NULL, // pPushConstantRanges
2019 return vk::createPipelineLayout(vki, device, &createInfo);
2022 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
2023 vk::VkDevice device,
2024 const vk::BinaryCollection& programCollection,
2025 vk::VkPipelineLayout layout)
2027 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
2028 const vk::VkPipelineShaderStageCreateInfo cs =
2030 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
2032 (vk::VkPipelineShaderStageCreateFlags)0,
2033 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
2034 *computeModule, // shader
2036 DE_NULL, // pSpecializationInfo
2038 const vk::VkComputePipelineCreateInfo createInfo =
2040 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
2045 (vk::VkPipeline)0, // basePipelineHandle
2046 0u, // basePipelineIndex
2048 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
2051 class ComputeCommand
2054 ComputeCommand (const vk::DeviceInterface& vki,
2055 vk::VkDevice device,
2056 vk::VkPipeline pipeline,
2057 vk::VkPipelineLayout pipelineLayout,
2058 const tcu::UVec3& numWorkGroups,
2059 int numDescriptorSets,
2060 const vk::VkDescriptorSet* descriptorSets,
2061 int numDynamicOffsets,
2062 const deUint32* dynamicOffsets,
2064 const vk::VkBufferMemoryBarrier* preBarriers,
2065 int numPostBarriers,
2066 const vk::VkBufferMemoryBarrier* postBarriers);
2068 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::VkDescriptorUpdateTemplateKHR updateTemplate = DE_NULL, const void *rawUpdateData = 0) const;
2069 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::DescriptorSetUpdateBuilder& updateBuilder) const;
2072 const vk::DeviceInterface& m_vki;
2073 const vk::VkDevice m_device;
2074 const vk::VkPipeline m_pipeline;
2075 const vk::VkPipelineLayout m_pipelineLayout;
2076 const tcu::UVec3 m_numWorkGroups;
2077 const int m_numDescriptorSets;
2078 const vk::VkDescriptorSet* const m_descriptorSets;
2079 const int m_numDynamicOffsets;
2080 const deUint32* const m_dynamicOffsets;
2081 const int m_numPreBarriers;
2082 const vk::VkBufferMemoryBarrier* const m_preBarriers;
2083 const int m_numPostBarriers;
2084 const vk::VkBufferMemoryBarrier* const m_postBarriers;
2087 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
2088 vk::VkDevice device,
2089 vk::VkPipeline pipeline,
2090 vk::VkPipelineLayout pipelineLayout,
2091 const tcu::UVec3& numWorkGroups,
2092 int numDescriptorSets,
2093 const vk::VkDescriptorSet* descriptorSets,
2094 int numDynamicOffsets,
2095 const deUint32* dynamicOffsets,
2097 const vk::VkBufferMemoryBarrier* preBarriers,
2098 int numPostBarriers,
2099 const vk::VkBufferMemoryBarrier* postBarriers)
2102 , m_pipeline (pipeline)
2103 , m_pipelineLayout (pipelineLayout)
2104 , m_numWorkGroups (numWorkGroups)
2105 , m_numDescriptorSets (numDescriptorSets)
2106 , m_descriptorSets (descriptorSets)
2107 , m_numDynamicOffsets (numDynamicOffsets)
2108 , m_dynamicOffsets (dynamicOffsets)
2109 , m_numPreBarriers (numPreBarriers)
2110 , m_preBarriers (preBarriers)
2111 , m_numPostBarriers (numPostBarriers)
2112 , m_postBarriers (postBarriers)
2116 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::VkDescriptorUpdateTemplateKHR updateTemplate, const void *rawUpdateData) const
2118 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
2120 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2122 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
2123 queueFamilyIndex, // queueFamilyIndex
2125 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
2127 const vk::VkFenceCreateInfo fenceCreateInfo =
2129 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2134 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
2136 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
2138 *cmdPool, // cmdPool
2139 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
2142 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
2144 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2146 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
2147 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
2150 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
2151 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
2152 const deUint64 infiniteTimeout = ~(deUint64)0u;
2154 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
2156 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
2158 if (m_numDescriptorSets)
2160 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
2163 if (updateTemplate != DE_NULL)
2165 // we need to update the push descriptors
2166 m_vki.cmdPushDescriptorSetWithTemplateKHR(*cmd, updateTemplate, m_pipelineLayout, 0, rawUpdateData);
2169 if (m_numPreBarriers)
2170 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
2171 0, (const vk::VkMemoryBarrier*)DE_NULL,
2172 m_numPreBarriers, m_preBarriers,
2173 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2175 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
2176 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
2177 0, (const vk::VkMemoryBarrier*)DE_NULL,
2178 m_numPostBarriers, m_postBarriers,
2179 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2180 VK_CHECK(m_vki.endCommandBuffer(*cmd));
2184 const vk::VkSubmitInfo submitInfo =
2186 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
2189 (const vk::VkSemaphore*)0,
2190 (const vk::VkPipelineStageFlags*)DE_NULL,
2194 (const vk::VkSemaphore*)0,
2196 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
2198 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
2201 //cmdPushDescriptorSet variant
2202 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue, vk::DescriptorSetUpdateBuilder& updateBuilder) const
2204 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
2206 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
2208 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
2209 queueFamilyIndex, // queueFamilyIndex
2211 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
2213 const vk::VkFenceCreateInfo fenceCreateInfo =
2215 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
2220 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
2222 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
2224 *cmdPool, // cmdPool
2225 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
2228 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
2230 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
2232 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
2233 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
2236 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
2237 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
2238 const deUint64 infiniteTimeout = ~(deUint64)0u;
2240 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
2242 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
2244 if (m_numDescriptorSets)
2246 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
2249 updateBuilder.updateWithPush(m_vki, *cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0);
2251 if (m_numPreBarriers)
2252 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
2253 0, (const vk::VkMemoryBarrier*)DE_NULL,
2254 m_numPreBarriers, m_preBarriers,
2255 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2257 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
2258 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
2259 0, (const vk::VkMemoryBarrier*)DE_NULL,
2260 m_numPostBarriers, m_postBarriers,
2261 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
2262 VK_CHECK(m_vki.endCommandBuffer(*cmd));
2266 const vk::VkSubmitInfo submitInfo =
2268 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
2271 (const vk::VkSemaphore*)0,
2272 (const vk::VkPipelineStageFlags*)DE_NULL,
2276 (const vk::VkSemaphore*)0,
2278 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
2280 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
2283 class BufferComputeInstance : public vkt::TestInstance
2286 BufferComputeInstance (Context& context,
2287 DescriptorUpdateMethod updateMethod,
2288 vk::VkDescriptorType descriptorType,
2289 ShaderInputInterface shaderInterface,
2292 bool dynamicOffsetNonZero);
2295 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
2296 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
2297 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
2298 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
2299 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf);
2300 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf);
2301 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);
2303 tcu::TestStatus iterate (void);
2304 void logTestPlan (void) const;
2305 tcu::TestStatus testResourceAccess (void);
2309 STATIC_OFFSET_VALUE_A = 256,
2310 DYNAMIC_OFFSET_VALUE_A = 512,
2311 STATIC_OFFSET_VALUE_B = 1024,
2312 DYNAMIC_OFFSET_VALUE_B = 768,
2315 const DescriptorUpdateMethod m_updateMethod;
2316 const vk::VkDescriptorType m_descriptorType;
2317 const ShaderInputInterface m_shaderInterface;
2318 const bool m_setViewOffset;
2319 const bool m_setDynamicOffset;
2320 const bool m_dynamicOffsetNonZero;
2322 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
2323 const vk::DeviceInterface& m_vki;
2324 const vk::VkDevice m_device;
2325 const vk::VkQueue m_queue;
2326 const deUint32 m_queueFamilyIndex;
2327 vk::Allocator& m_allocator;
2329 const ComputeInstanceResultBuffer m_result;
2331 RawUpdateRegistry m_updateRegistry;
2332 vk::DescriptorSetUpdateBuilder m_updateBuilder;
2335 BufferComputeInstance::BufferComputeInstance (Context& context,
2336 DescriptorUpdateMethod updateMethod,
2337 vk::VkDescriptorType descriptorType,
2338 ShaderInputInterface shaderInterface,
2341 bool dynamicOffsetNonZero)
2342 : vkt::TestInstance (context)
2343 , m_updateMethod (updateMethod)
2344 , m_descriptorType (descriptorType)
2345 , m_shaderInterface (shaderInterface)
2346 , m_setViewOffset (viewOffset)
2347 , m_setDynamicOffset (dynamicOffset)
2348 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
2349 , m_updateTemplate ()
2350 , m_vki (context.getDeviceInterface())
2351 , m_device (context.getDevice())
2352 , m_queue (context.getUniversalQueue())
2353 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
2354 , m_allocator (context.getDefaultAllocator())
2355 , m_result (m_vki, m_device, m_allocator)
2356 , m_updateRegistry ()
2357 , m_updateBuilder ()
2359 if (m_dynamicOffsetNonZero)
2360 DE_ASSERT(m_setDynamicOffset);
2363 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
2365 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
2367 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2368 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2369 const vk::VkBufferCreateInfo createInfo =
2371 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
2374 (vk::VkDeviceSize)bufferSize, // size
2375 usageFlags, // usage
2376 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2377 0u, // queueFamilyCount
2378 DE_NULL, // pQueueFamilyIndices
2380 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
2381 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
2382 void* mapPtr = allocation->getHostPtr();
2385 deMemset(mapPtr, 0x5A, (size_t)offset);
2386 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
2387 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
2388 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
2390 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
2392 *outAllocation = allocation;
2396 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
2398 vk::DescriptorSetLayoutBuilder builder;
2399 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
2401 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
2402 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
2404 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
2407 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2409 switch (m_shaderInterface)
2411 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2412 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2415 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2416 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2417 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2420 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2421 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2425 DE_FATAL("Impossible");
2428 return builder.build(m_vki, m_device, extraFlags);
2431 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
2433 return vk::DescriptorPoolBuilder()
2434 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2435 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
2436 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
2439 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)
2441 const vk::VkDescriptorSetAllocateInfo allocInfo =
2443 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2450 vk::Move<vk::VkDescriptorSet> descriptorSet;
2451 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
2453 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
2457 descriptorSet = vk::Move<vk::VkDescriptorSet>();
2460 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
2462 writeDescriptorSetWithTemplate(*descriptorSet, layout, viewA, offsetA, viewB, offsetB, resBuf);
2464 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
2466 writeDescriptorSet(*descriptorSet, viewA, offsetA, viewB, offsetB, resBuf);
2469 return descriptorSet;
2472 void BufferComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf)
2474 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2475 const vk::VkDescriptorBufferInfo bufferInfos[2] =
2477 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2478 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2482 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
2485 switch (m_shaderInterface)
2487 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2488 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2491 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2492 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2493 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
2496 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2497 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
2501 DE_FATAL("Impossible");
2504 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
2506 m_updateBuilder.update(m_vki, m_device);
2510 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)
2512 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
2513 const vk::VkDescriptorBufferInfo bufferInfos[2] =
2515 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2516 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
2518 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
2519 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
2521 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
2524 0, // descriptorUpdateEntryCount
2525 DE_NULL, // pDescriptorUpdateEntries
2526 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
2528 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
2532 m_updateRegistry.addWriteObject(resultInfo);
2533 m_updateRegistry.addWriteObject(bufferInfos[0]);
2534 m_updateRegistry.addWriteObject(bufferInfos[1]);
2537 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
2540 switch (m_shaderInterface)
2542 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2543 updateEntries.push_back(createTemplateBinding(1, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
2546 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2547 updateEntries.push_back(createTemplateBinding(1, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
2548 updateEntries.push_back(createTemplateBinding(2, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(2), 0));
2551 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2552 updateEntries.push_back(createTemplateBinding(1, 0, 2, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), sizeof(bufferInfos[0])));
2556 DE_FATAL("Impossible");
2559 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
2560 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
2562 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
2566 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
2570 tcu::TestStatus BufferComputeInstance::iterate (void)
2573 return testResourceAccess();
2576 void BufferComputeInstance::logTestPlan (void) const
2578 std::ostringstream msg;
2580 msg << "Accessing resource in a compute program.\n"
2581 << "Single descriptor set. Descriptor set contains "
2582 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2583 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
2584 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2585 (const char*)DE_NULL)
2586 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2587 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2588 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2590 if (isDynamicDescriptorType(m_descriptorType))
2592 if (m_setDynamicOffset)
2594 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2595 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2599 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2603 msg << "Destination buffer is pre-initialized to -1.\n";
2605 m_context.getTestContext().getLog()
2606 << tcu::TestLog::Message
2608 << tcu::TestLog::EndMessage;
2611 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2615 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2618 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2619 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2620 const deUint32 bindTimeOffsets[] =
2622 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2623 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2626 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2627 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2628 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2629 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2631 const deUint32 dataOffsetA = ((isDynamicCase) ? (bindTimeOffsets[0]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u));
2632 const deUint32 dataOffsetB = ((isDynamicCase) ? (bindTimeOffsets[1]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u));
2633 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2634 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2635 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2636 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2638 de::MovePtr<vk::Allocation> bufferMemA;
2639 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2641 de::MovePtr<vk::Allocation> bufferMemB;
2642 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2643 ? (vk::Move<vk::VkBuffer>())
2644 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2646 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2647 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2648 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer()));
2649 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2651 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2652 const vk::VkBufferMemoryBarrier bufferBarriers[] =
2655 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2657 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2658 inputBit, // inputMask
2659 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2660 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2662 (vk::VkDeviceSize)0u, // offset
2663 (vk::VkDeviceSize)bufferSizeA, // size
2666 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2668 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2669 inputBit, // inputMask
2670 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2671 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2673 (vk::VkDeviceSize)0u, // offset
2674 (vk::VkDeviceSize)bufferSizeB, // size
2678 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2680 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2681 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : DE_LENGTH_OF_ARRAY(descriptorSets);
2682 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2683 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2684 const vk::VkBufferMemoryBarrier* const preBarriers = bufferBarriers;
2685 const int numPreBarriers = numSrcBuffers;
2686 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
2687 const int numPostBarriers = 1;
2689 const ComputeCommand compute (m_vki,
2691 pipeline.getPipeline(),
2692 pipeline.getPipelineLayout(),
2693 tcu::UVec3(4, 1, 1),
2694 numDescriptorSets, descriptorSets,
2695 numDynamicOffsets, dynamicOffsets,
2696 numPreBarriers, preBarriers,
2697 numPostBarriers, postBarriers);
2699 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2700 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? (colorB2) :
2701 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2703 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2704 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? (colorA1) :
2705 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2707 const tcu::Vec4 references[4] =
2714 tcu::Vec4 results[4];
2716 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
2718 writeDescriptorSetWithTemplate(DE_NULL, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer(), true, pipeline.getPipelineLayout());
2719 compute.submitAndWait(m_queueFamilyIndex, m_queue, *m_updateTemplate, (const void*) m_updateRegistry.getRawPointer());
2721 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
2723 writeDescriptorSet(DE_NULL, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer());
2724 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder);
2728 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2730 m_result.readResultContentsTo(&results);
2733 if (results[0] == references[0] &&
2734 results[1] == references[1] &&
2735 results[2] == references[2] &&
2736 results[3] == references[3])
2738 return tcu::TestStatus::pass("Pass");
2740 else if (results[0] == tcu::Vec4(-1.0f) &&
2741 results[1] == tcu::Vec4(-1.0f) &&
2742 results[2] == tcu::Vec4(-1.0f) &&
2743 results[3] == tcu::Vec4(-1.0f))
2745 m_context.getTestContext().getLog()
2746 << tcu::TestLog::Message
2747 << "Result buffer was not written to."
2748 << tcu::TestLog::EndMessage;
2749 return tcu::TestStatus::fail("Result buffer was not written to");
2753 m_context.getTestContext().getLog()
2754 << tcu::TestLog::Message
2755 << "Error expected ["
2756 << references[0] << ", "
2757 << references[1] << ", "
2758 << references[2] << ", "
2759 << references[3] << "], got ["
2760 << results[0] << ", "
2761 << results[1] << ", "
2762 << results[2] << ", "
2763 << results[3] << "]"
2764 << tcu::TestLog::EndMessage;
2765 return tcu::TestStatus::fail("Invalid result values");
2769 class QuadrantRendederCase : public vkt::TestCase
2772 QuadrantRendederCase (tcu::TestContext& testCtx,
2774 const char* description,
2775 glu::GLSLVersion glslVersion,
2776 vk::VkShaderStageFlags exitingStages,
2777 vk::VkShaderStageFlags activeStages);
2779 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
2780 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
2781 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
2782 virtual std::string genNoAccessSource (void) const = 0;
2784 std::string genVertexSource (void) const;
2785 std::string genTessCtrlSource (void) const;
2786 std::string genTessEvalSource (void) const;
2787 std::string genGeometrySource (void) const;
2788 std::string genFragmentSource (void) const;
2789 std::string genComputeSource (void) const;
2791 void initPrograms (vk::SourceCollections& programCollection) const;
2794 const glu::GLSLVersion m_glslVersion;
2795 const vk::VkShaderStageFlags m_exitingStages;
2796 const vk::VkShaderStageFlags m_activeStages;
2799 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2801 const char* description,
2802 glu::GLSLVersion glslVersion,
2803 vk::VkShaderStageFlags exitingStages,
2804 vk::VkShaderStageFlags activeStages)
2805 : vkt::TestCase (testCtx, name, description)
2806 , m_glslVersion (glslVersion)
2807 , m_exitingStages (exitingStages)
2808 , m_activeStages (activeStages)
2810 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2813 std::string QuadrantRendederCase::genVertexSource (void) const
2815 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
2816 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2817 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2819 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2820 std::ostringstream buf;
2822 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2824 const bool onlyVS = (m_activeStages == vk::VK_SHADER_STAGE_VERTEX_BIT);
2826 // active vertex shader
2827 buf << versionDecl << "\n"
2828 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2829 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0)
2830 << "layout(location = 0) out highp vec4 " << nextStageName << "_color;\n"
2831 << (onlyVS ? "" : "layout(location = 1) flat out highp int " + de::toString(nextStageName) + "_quadrant_id;\n")
2832 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
2833 << "void main (void)\n"
2835 << " highp vec4 result_position;\n"
2836 << " highp int quadrant_id;\n"
2837 << s_quadrantGenVertexPosSource
2838 << " gl_Position = result_position;\n"
2839 << (onlyVS ? "" : "\t" + de::toString(nextStageName) + "_quadrant_id = quadrant_id;\n")
2841 << " highp vec4 result_color;\n"
2842 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
2843 << " " << nextStageName << "_color = result_color;\n"
2849 buf << versionDecl << "\n"
2850 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2851 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2852 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
2853 << "void main (void)\n"
2855 << " highp vec4 result_position;\n"
2856 << " highp int quadrant_id;\n"
2857 << s_quadrantGenVertexPosSource
2858 << " gl_Position = result_position;\n"
2859 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2866 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2868 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2869 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2870 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2871 std::ostringstream buf;
2873 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2875 // contributing not implemented
2876 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2879 buf << versionDecl << "\n"
2881 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2882 << "layout(vertices=3) out;\n"
2883 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
2884 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2885 << "layout(location = 0) out highp vec4 tes_color[];\n"
2886 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
2887 << "void main (void)\n"
2889 << " highp vec4 result_color;\n"
2890 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2891 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2893 << " tes_color[gl_InvocationID] = result_color;\n"
2895 << " // no dynamic input block indexing\n"
2896 << " highp vec4 position;\n"
2897 << " if (gl_InvocationID == 0)\n"
2898 << " position = gl_in[0].gl_Position;\n"
2899 << " else if (gl_InvocationID == 1)\n"
2900 << " position = gl_in[1].gl_Position;\n"
2902 << " position = gl_in[2].gl_Position;\n"
2903 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2904 << " gl_TessLevelInner[0] = 2.8;\n"
2905 << " gl_TessLevelInner[1] = 2.8;\n"
2906 << " gl_TessLevelOuter[0] = 2.8;\n"
2907 << " gl_TessLevelOuter[1] = 2.8;\n"
2908 << " gl_TessLevelOuter[2] = 2.8;\n"
2909 << " gl_TessLevelOuter[3] = 2.8;\n"
2912 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2914 // active te shader, tc passthru
2915 buf << versionDecl << "\n"
2917 << "layout(vertices=3) out;\n"
2918 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2919 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2920 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
2921 << "void main (void)\n"
2923 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2925 << " // no dynamic input block indexing\n"
2926 << " highp vec4 position;\n"
2927 << " if (gl_InvocationID == 0)\n"
2928 << " position = gl_in[0].gl_Position;\n"
2929 << " else if (gl_InvocationID == 1)\n"
2930 << " position = gl_in[1].gl_Position;\n"
2932 << " position = gl_in[2].gl_Position;\n"
2933 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2934 << " gl_TessLevelInner[0] = 2.8;\n"
2935 << " gl_TessLevelInner[1] = 2.8;\n"
2936 << " gl_TessLevelOuter[0] = 2.8;\n"
2937 << " gl_TessLevelOuter[1] = 2.8;\n"
2938 << " gl_TessLevelOuter[2] = 2.8;\n"
2939 << " gl_TessLevelOuter[3] = 2.8;\n"
2944 // passthrough not implemented
2945 DE_FATAL("not implemented");
2951 std::string QuadrantRendederCase::genTessEvalSource (void) const
2953 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2954 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2955 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2956 std::ostringstream buf;
2958 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2960 // contributing not implemented
2961 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
2964 buf << versionDecl << "\n"
2966 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2967 << "layout(triangles) in;\n"
2968 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
2969 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2970 << "layout(location = 0) out mediump vec4 frag_color;\n"
2971 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
2972 << "void main (void)\n"
2974 << " highp vec4 result_color;\n"
2975 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2976 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2978 << " frag_color = result_color;\n"
2979 << " 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"
2982 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2984 // contributing not implemented
2985 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2987 // active tc shader, te is passthru
2988 buf << versionDecl << "\n"
2990 << "layout(triangles) in;\n"
2991 << "layout(location = 0) in highp vec4 tes_color[];\n"
2992 << "layout(location = 0) out mediump vec4 frag_color;\n"
2993 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
2994 << "void main (void)\n"
2996 << " frag_color = tes_color[0];\n"
2997 << " 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"
3002 // passthrough not implemented
3003 DE_FATAL("not implemented");
3009 std::string QuadrantRendederCase::genGeometrySource (void) const
3011 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3012 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
3013 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
3014 std::ostringstream buf;
3016 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
3018 // contributing not implemented
3019 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
3021 // active geometry shader
3022 buf << versionDecl << "\n"
3024 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3025 << "layout(triangles) in;\n"
3026 << "layout(triangle_strip, max_vertices=4) out;\n"
3027 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
3028 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
3029 << "layout(location = 0) out mediump vec4 frag_color;\n"
3030 << genPerVertexBlock(vk::VK_SHADER_STAGE_GEOMETRY_BIT, m_glslVersion)
3031 << "void main (void)\n"
3033 << " highp int quadrant_id;\n"
3034 << " highp vec4 result_color;\n"
3036 << " quadrant_id = geo_quadrant_id[0];\n"
3037 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3038 << " frag_color = result_color;\n"
3039 << " gl_Position = gl_in[0].gl_Position;\n"
3040 << " EmitVertex();\n"
3042 << " quadrant_id = geo_quadrant_id[1];\n"
3043 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3044 << " frag_color = result_color;\n"
3045 << " gl_Position = gl_in[1].gl_Position;\n"
3046 << " EmitVertex();\n"
3048 << " quadrant_id = geo_quadrant_id[2];\n"
3049 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3050 << " frag_color = result_color;\n"
3051 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
3052 << " EmitVertex();\n"
3054 << " quadrant_id = geo_quadrant_id[0];\n"
3055 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3056 << " frag_color = result_color;\n"
3057 << " gl_Position = gl_in[2].gl_Position;\n"
3058 << " EmitVertex();\n"
3063 // passthrough not implemented
3064 DE_FATAL("not implemented");
3070 std::string QuadrantRendederCase::genFragmentSource (void) const
3072 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3073 std::ostringstream buf;
3075 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
3077 buf << versionDecl << "\n"
3078 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
3079 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
3081 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
3083 // there are other stages, this is just a contributor
3084 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
3087 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
3088 << "layout(location = 0) out mediump vec4 o_color;\n"
3089 << "void main (void)\n"
3091 << " highp int quadrant_id = frag_quadrant_id;\n"
3092 << " highp vec4 result_color;\n"
3093 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
3095 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
3098 buf << " if (frag_quadrant_id < 2)\n"
3099 << " o_color = result_color;\n"
3101 << " o_color = frag_color;\n";
3104 buf << " o_color = result_color;\n";
3108 else if (m_activeStages == 0u)
3110 // special case, no active stages
3111 buf << versionDecl << "\n"
3112 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
3113 << "layout(location = 0) out mediump vec4 o_color;\n"
3114 << "void main (void)\n"
3116 << " highp int quadrant_id = frag_quadrant_id;\n"
3117 << " highp vec4 result_color;\n"
3118 << genNoAccessSource()
3119 << " o_color = result_color;\n"
3125 buf << versionDecl << "\n"
3126 << "layout(location = 0) in mediump vec4 frag_color;\n"
3127 "layout(location = 0) out mediump vec4 o_color;\n"
3128 "void main (void)\n"
3130 " o_color = frag_color;\n"
3137 std::string QuadrantRendederCase::genComputeSource (void) const
3139 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
3140 std::ostringstream buf;
3142 buf << versionDecl << "\n"
3143 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
3144 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
3145 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
3146 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
3148 << " highp vec4 read_colors[4];\n"
3150 << "void main (void)\n"
3152 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
3153 << " highp vec4 result_color;\n"
3154 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
3155 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
3161 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
3163 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
3164 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
3166 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
3167 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
3169 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
3170 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
3172 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
3173 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
3175 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
3176 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
3178 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
3179 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
3182 class BufferDescriptorCase : public QuadrantRendederCase
3187 FLAG_VIEW_OFFSET = (1u << 1u),
3188 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
3189 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
3191 // enum continues where resource flags ends
3192 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
3194 BufferDescriptorCase (tcu::TestContext& testCtx,
3195 DescriptorUpdateMethod updateMethod,
3197 const char* description,
3198 bool isPrimaryCmdBuf,
3199 vk::VkDescriptorType descriptorType,
3200 vk::VkShaderStageFlags exitingStages,
3201 vk::VkShaderStageFlags activeStages,
3202 ShaderInputInterface shaderInterface,
3206 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
3207 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
3208 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
3209 std::string genNoAccessSource (void) const;
3211 vkt::TestInstance* createInstance (vkt::Context& context) const;
3213 const DescriptorUpdateMethod m_updateMethod;
3214 const bool m_viewOffset;
3215 const bool m_dynamicOffsetSet;
3216 const bool m_dynamicOffsetNonZero;
3217 const bool m_isPrimaryCmdBuf;
3218 const vk::VkDescriptorType m_descriptorType;
3219 const ShaderInputInterface m_shaderInterface;
3222 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
3223 DescriptorUpdateMethod updateMethod,
3225 const char* description,
3226 bool isPrimaryCmdBuf,
3227 vk::VkDescriptorType descriptorType,
3228 vk::VkShaderStageFlags exitingStages,
3229 vk::VkShaderStageFlags activeStages,
3230 ShaderInputInterface shaderInterface,
3232 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
3233 , m_updateMethod (updateMethod)
3234 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
3235 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
3236 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
3237 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
3238 , m_descriptorType (descriptorType)
3239 , m_shaderInterface (shaderInterface)
3243 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
3249 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
3253 const bool isUniform = isUniformDescriptorType(m_descriptorType);
3254 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
3255 std::ostringstream buf;
3257 switch (m_shaderInterface)
3259 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3260 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
3262 << " highp vec4 colorA;\n"
3263 << " highp vec4 colorB;\n"
3264 << "} b_instance;\n";
3267 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3268 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
3270 << " highp vec4 colorA;\n"
3271 << " highp vec4 colorB;\n"
3272 << "} b_instanceA;\n"
3273 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
3275 << " highp vec4 colorA;\n"
3276 << " highp vec4 colorB;\n"
3277 << "} b_instanceB;\n";
3280 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3281 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
3283 << " highp vec4 colorA;\n"
3284 << " highp vec4 colorB;\n"
3285 << "} b_instances[2];\n";
3289 DE_FATAL("Impossible");
3295 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
3299 std::ostringstream buf;
3301 switch (m_shaderInterface)
3303 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3304 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3305 << " result_color = b_instance.colorA;\n"
3307 << " result_color = b_instance.colorB;\n";
3310 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3311 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3312 << " result_color = b_instanceA.colorA;\n"
3314 << " result_color = b_instanceB.colorB;\n";
3317 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3318 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
3319 << " result_color = b_instances[0].colorA;\n"
3321 << " result_color = b_instances[1].colorB;\n";
3325 DE_FATAL("Impossible");
3331 std::string BufferDescriptorCase::genNoAccessSource (void) const
3333 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
3334 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
3336 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
3339 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
3341 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
3343 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
3345 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
3346 return new BufferComputeInstance(context, m_updateMethod, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
3349 return new BufferRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
3352 class ImageInstanceImages
3355 ImageInstanceImages (const vk::DeviceInterface& vki,
3356 vk::VkDevice device,
3357 deUint32 queueFamilyIndex,
3359 vk::Allocator& allocator,
3360 vk::VkDescriptorType descriptorType,
3361 vk::VkImageViewType viewType,
3363 deUint32 baseMipLevel,
3364 deUint32 baseArraySlice);
3367 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
3368 vk::VkDevice device,
3369 vk::Allocator& allocator,
3370 vk::VkDescriptorType descriptorType,
3371 vk::VkImageViewType viewType,
3372 const tcu::TextureLevelPyramid& sourceImage,
3373 de::MovePtr<vk::Allocation>* outAllocation);
3375 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
3376 vk::VkDevice device,
3377 vk::VkImageViewType viewType,
3378 const tcu::TextureLevelPyramid& sourceImage,
3380 deUint32 baseMipLevel,
3381 deUint32 baseArraySlice);
3383 void populateSourceImage (tcu::TextureLevelPyramid* dst,
3384 bool isFirst) const;
3386 void uploadImage (const vk::DeviceInterface& vki,
3387 vk::VkDevice device,
3388 deUint32 queueFamilyIndex,
3390 vk::Allocator& allocator,
3392 vk::VkImageLayout layout,
3393 const tcu::TextureLevelPyramid& data);
3403 const vk::VkImageViewType m_viewType;
3404 const deUint32 m_baseMipLevel;
3405 const deUint32 m_baseArraySlice;
3407 const tcu::TextureFormat m_imageFormat;
3408 tcu::TextureLevelPyramid m_sourceImageA;
3409 tcu::TextureLevelPyramid m_sourceImageB;
3411 de::MovePtr<vk::Allocation> m_imageMemoryA;
3412 de::MovePtr<vk::Allocation> m_imageMemoryB;
3413 vk::Move<vk::VkImage> m_imageA;
3414 vk::Move<vk::VkImage> m_imageB;
3415 vk::Move<vk::VkImageView> m_imageViewA;
3416 vk::Move<vk::VkImageView> m_imageViewB;
3419 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
3420 vk::VkDevice device,
3421 deUint32 queueFamilyIndex,
3423 vk::Allocator& allocator,
3424 vk::VkDescriptorType descriptorType,
3425 vk::VkImageViewType viewType,
3427 deUint32 baseMipLevel,
3428 deUint32 baseArraySlice)
3429 : m_viewType (viewType)
3430 , m_baseMipLevel (baseMipLevel)
3431 , m_baseArraySlice (baseArraySlice)
3432 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
3433 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
3434 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
3435 , m_imageMemoryA (DE_NULL)
3436 , m_imageMemoryB (DE_NULL)
3437 , m_imageA (vk::Move<vk::VkImage>())
3438 , m_imageB (vk::Move<vk::VkImage>())
3439 , m_imageViewA (vk::Move<vk::VkImageView>())
3440 , m_imageViewB (vk::Move<vk::VkImageView>())
3442 const vk::VkImageLayout layout = getImageLayoutForDescriptorType(descriptorType);
3444 DE_ASSERT(numImages == 1 || numImages == 2);
3446 populateSourceImage(&m_sourceImageA, true);
3447 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
3448 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
3449 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, layout, m_sourceImageA);
3453 populateSourceImage(&m_sourceImageB, false);
3454 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
3455 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
3456 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, layout, m_sourceImageB);
3460 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
3461 vk::VkDevice device,
3462 vk::Allocator& allocator,
3463 vk::VkDescriptorType descriptorType,
3464 vk::VkImageViewType viewType,
3465 const tcu::TextureLevelPyramid& sourceImage,
3466 de::MovePtr<vk::Allocation>* outAllocation)
3468 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3469 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
3470 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
3471 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
3472 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
3473 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
3474 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3475 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
3477 const vk::VkExtent3D extent =
3480 (deUint32)baseLevel.getWidth(),
3483 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1u) : (deUint32)baseLevel.getHeight(),
3486 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deUint32)baseLevel.getDepth()) : (1u),
3488 const vk::VkImageCreateInfo createInfo =
3490 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3492 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
3493 viewTypeToImageType(viewType), // imageType
3494 vk::mapTextureFormat(baseLevel.getFormat()), // format
3496 (deUint32)sourceImage.getNumLevels(), // mipLevels
3497 arraySize, // arraySize
3498 vk::VK_SAMPLE_COUNT_1_BIT, // samples
3499 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
3500 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
3501 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3502 0u, // queueFamilyCount
3503 DE_NULL, // pQueueFamilyIndices
3504 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
3506 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
3508 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
3512 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
3513 vk::VkDevice device,
3514 vk::VkImageViewType viewType,
3515 const tcu::TextureLevelPyramid& sourceImage,
3517 deUint32 baseMipLevel,
3518 deUint32 baseArraySlice)
3520 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3521 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
3522 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
3523 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
3524 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
3525 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
3526 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3527 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
3528 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
3531 DE_ASSERT(viewArraySize > 0);
3533 const vk::VkImageSubresourceRange resourceRange =
3535 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3536 baseMipLevel, // baseMipLevel
3537 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
3538 viewTypeBaseSlice, // baseArraySlice
3539 viewArraySize, // arraySize
3541 const vk::VkImageViewCreateInfo createInfo =
3543 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3545 (vk::VkImageViewCreateFlags)0,
3547 viewType, // viewType
3548 vk::mapTextureFormat(baseLevel.getFormat()), // format
3550 vk::VK_COMPONENT_SWIZZLE_R,
3551 vk::VK_COMPONENT_SWIZZLE_G,
3552 vk::VK_COMPONENT_SWIZZLE_B,
3553 vk::VK_COMPONENT_SWIZZLE_A
3555 resourceRange, // subresourceRange
3557 return vk::createImageView(vki, device, &createInfo);
3560 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
3562 const int numLevels = dst->getNumLevels();
3564 for (int level = 0; level < numLevels; ++level)
3566 const int width = IMAGE_SIZE >> level;
3567 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
3568 : (IMAGE_SIZE >> level);
3569 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
3570 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
3571 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
3572 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
3575 dst->allocLevel(level, width, height, depth);
3578 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
3580 for (int z = 0; z < depth; ++z)
3581 for (int y = 0; y < height; ++y)
3582 for (int x = 0; x < width; ++x)
3584 const int gradPos = x + y + z;
3585 const int gradMax = width + height + depth - 3;
3587 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
3588 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
3589 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
3591 DE_ASSERT(de::inRange(red, 0, 255));
3592 DE_ASSERT(de::inRange(green, 0, 255));
3593 DE_ASSERT(de::inRange(blue, 0, 255));
3595 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3601 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3602 vk::VkDevice device,
3603 deUint32 queueFamilyIndex,
3605 vk::Allocator& allocator,
3607 vk::VkImageLayout layout,
3608 const tcu::TextureLevelPyramid& data)
3610 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3611 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3612 ((deUint32)ARRAY_SIZE);
3613 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3614 const vk::VkBufferCreateInfo bufferCreateInfo =
3616 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3619 dataBufferSize, // size
3620 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
3621 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3622 0u, // queueFamilyCount
3623 DE_NULL, // pQueueFamilyIndices
3625 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3626 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3627 const vk::VkFenceCreateInfo fenceCreateInfo =
3629 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3633 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3635 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3637 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
3638 vk::VK_ACCESS_TRANSFER_READ_BIT, // inputMask
3639 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3640 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3641 *dataBuffer, // buffer
3643 dataBufferSize, // size
3645 const vk::VkImageSubresourceRange fullSubrange =
3647 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3649 (deUint32)data.getNumLevels(), // mipLevels
3650 0u, // baseArraySlice
3651 arraySize, // arraySize
3653 const vk::VkImageMemoryBarrier preImageBarrier =
3655 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3658 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // inputMask
3659 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3660 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout
3661 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3662 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3664 fullSubrange // subresourceRange
3666 const vk::VkImageMemoryBarrier postImageBarrier =
3668 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3670 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask
3671 vk::VK_ACCESS_SHADER_READ_BIT, // inputMask
3672 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout
3673 layout, // newLayout
3674 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3675 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3677 fullSubrange // subresourceRange
3679 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
3681 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
3683 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
3684 queueFamilyIndex, // queueFamilyIndex
3686 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3687 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
3689 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
3691 *cmdPool, // cmdPool
3692 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
3695 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
3697 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3699 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
3700 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
3703 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(vki, device, &cmdBufCreateInfo));
3704 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device, &fenceCreateInfo));
3705 const deUint64 infiniteTimeout = ~(deUint64)0u;
3706 std::vector<vk::VkBufferImageCopy> copySlices;
3708 // copy data to buffer
3709 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3710 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3712 // record command buffer
3713 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3714 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
3715 0, (const vk::VkMemoryBarrier*)DE_NULL,
3716 1, &preMemoryBarrier,
3717 1, &preImageBarrier);
3718 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3719 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
3720 0, (const vk::VkMemoryBarrier*)DE_NULL,
3721 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
3722 1, &postImageBarrier);
3723 VK_CHECK(vki.endCommandBuffer(*cmd));
3725 // submit and wait for command buffer to complete before killing it
3727 const vk::VkSubmitInfo submitInfo =
3729 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
3732 (const vk::VkSemaphore*)0,
3733 (const vk::VkPipelineStageFlags*)DE_NULL,
3737 (const vk::VkSemaphore*)0,
3739 VK_CHECK(vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
3741 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3744 class ImageFetchInstanceImages : private ImageInstanceImages
3747 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3748 vk::VkDevice device,
3749 deUint32 queueFamilyIndex,
3751 vk::Allocator& allocator,
3752 vk::VkDescriptorType descriptorType,
3753 ShaderInputInterface shaderInterface,
3754 vk::VkImageViewType viewType,
3755 deUint32 baseMipLevel,
3756 deUint32 baseArraySlice);
3758 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3759 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3761 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3762 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3767 // some arbitrary sample points for all four quadrants
3768 SAMPLE_POINT_0_X = 6,
3769 SAMPLE_POINT_0_Y = 13,
3770 SAMPLE_POINT_0_Z = 49,
3772 SAMPLE_POINT_1_X = 51,
3773 SAMPLE_POINT_1_Y = 40,
3774 SAMPLE_POINT_1_Z = 44,
3776 SAMPLE_POINT_2_X = 42,
3777 SAMPLE_POINT_2_Y = 26,
3778 SAMPLE_POINT_2_Z = 19,
3780 SAMPLE_POINT_3_X = 25,
3781 SAMPLE_POINT_3_Y = 25,
3782 SAMPLE_POINT_3_Z = 18,
3785 const ShaderInputInterface m_shaderInterface;
3788 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3789 vk::VkDevice device,
3790 deUint32 queueFamilyIndex,
3792 vk::Allocator& allocator,
3793 vk::VkDescriptorType descriptorType,
3794 ShaderInputInterface shaderInterface,
3795 vk::VkImageViewType viewType,
3796 deUint32 baseMipLevel,
3797 deUint32 baseArraySlice)
3798 : ImageInstanceImages (vki,
3805 getInterfaceNumResources(shaderInterface), // numImages
3808 , m_shaderInterface (shaderInterface)
3812 bool isImageViewTypeArray (vk::VkImageViewType type)
3814 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;
3817 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3819 const tcu::IVec3 fetchPositions[4] =
3821 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3822 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3823 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3824 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3826 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3827 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3828 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3832 case vk::VK_IMAGE_VIEW_TYPE_1D:
3833 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3834 case vk::VK_IMAGE_VIEW_TYPE_2D:
3835 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3836 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3837 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3838 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3840 DE_FATAL("Impossible");
3841 return tcu::IVec3();
3845 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3847 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3849 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3850 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3851 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3852 tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3854 // add base array layer into the appropriate coordinate, based on the view type
3855 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
3856 fetchPos.z() += 6 * m_baseArraySlice;
3857 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3858 fetchPos.y() += m_baseArraySlice;
3860 fetchPos.z() += m_baseArraySlice;
3862 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3865 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3868 ImageFetchRenderInstance (vkt::Context& context,
3869 DescriptorUpdateMethod updateMethod,
3870 bool isPrimaryCmdBuf,
3871 vk::VkDescriptorType descriptorType,
3872 vk::VkShaderStageFlags stageFlags,
3873 ShaderInputInterface shaderInterface,
3874 vk::VkImageViewType viewType,
3875 deUint32 baseMipLevel,
3876 deUint32 baseArraySlice);
3879 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3880 vk::VkDevice device,
3881 vk::VkDescriptorType descriptorType,
3882 ShaderInputInterface shaderInterface,
3883 vk::VkShaderStageFlags stageFlags,
3884 DescriptorUpdateMethod updateMethod);
3886 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3887 vk::VkDevice device,
3888 vk::VkDescriptorSetLayout descriptorSetLayout);
3890 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3891 vk::VkDevice device,
3892 vk::VkDescriptorType descriptorType,
3893 ShaderInputInterface shaderInterface);
3895 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3896 DescriptorUpdateMethod updateMethod,
3897 vk::VkDevice device,
3898 vk::VkDescriptorType descriptorType,
3899 ShaderInputInterface shaderInterface,
3900 vk::VkDescriptorSetLayout layout,
3901 vk::VkDescriptorPool pool,
3902 vk::VkImageView viewA,
3903 vk::VkImageView viewB,
3904 vk::DescriptorSetUpdateBuilder& updateBuilder,
3905 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
3906 RawUpdateRegistry& updateRegistry,
3907 vk::VkPipelineLayout pipelineLayout = DE_NULL);
3909 static void writeDescriptorSet (const vk::DeviceInterface& vki,
3910 vk::VkDevice device,
3911 vk::VkDescriptorType descriptorType,
3912 ShaderInputInterface shaderInterface,
3913 vk::VkDescriptorSetLayout layout,
3914 vk::VkDescriptorPool pool,
3915 vk::VkImageView viewA,
3916 vk::VkImageView viewB,
3917 vk::VkDescriptorSet descriptorSet,
3918 vk::DescriptorSetUpdateBuilder& updateBuilder,
3919 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
3921 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
3922 vk::VkDevice device,
3923 vk::VkDescriptorType descriptorType,
3924 ShaderInputInterface shaderInterface,
3925 vk::VkDescriptorSetLayout layout,
3926 vk::VkDescriptorPool pool,
3927 vk::VkImageView viewA,
3928 vk::VkImageView viewB,
3929 vk::VkDescriptorSet descriptorSet,
3930 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
3931 RawUpdateRegistry& updateRegistry,
3932 bool withPush = false,
3933 vk::VkPipelineLayout pipelineLayout = 0);
3935 void logTestPlan (void) const;
3936 vk::VkPipelineLayout getPipelineLayout (void) const;
3937 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
3938 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3945 const DescriptorUpdateMethod m_updateMethod;
3946 const vk::VkDescriptorType m_descriptorType;
3947 const vk::VkShaderStageFlags m_stageFlags;
3948 const ShaderInputInterface m_shaderInterface;
3949 const vk::VkImageViewType m_viewType;
3950 const deUint32 m_baseMipLevel;
3951 const deUint32 m_baseArraySlice;
3953 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
3954 RawUpdateRegistry m_updateRegistry;
3955 vk::DescriptorSetUpdateBuilder m_updateBuilder;
3956 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3957 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3958 const ImageFetchInstanceImages m_images;
3959 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3960 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3963 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3964 DescriptorUpdateMethod updateMethod,
3965 bool isPrimaryCmdBuf,
3966 vk::VkDescriptorType descriptorType,
3967 vk::VkShaderStageFlags stageFlags,
3968 ShaderInputInterface shaderInterface,
3969 vk::VkImageViewType viewType,
3970 deUint32 baseMipLevel,
3971 deUint32 baseArraySlice)
3972 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3973 , m_updateMethod (updateMethod)
3974 , m_descriptorType (descriptorType)
3975 , m_stageFlags (stageFlags)
3976 , m_shaderInterface (shaderInterface)
3977 , m_viewType (viewType)
3978 , m_baseMipLevel (baseMipLevel)
3979 , m_baseArraySlice (baseArraySlice)
3980 , m_updateTemplate ()
3981 , m_updateRegistry ()
3982 , m_updateBuilder ()
3983 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_updateMethod))
3984 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3985 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3986 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3987 , 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))
3991 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3992 vk::VkDevice device,
3993 vk::VkDescriptorType descriptorType,
3994 ShaderInputInterface shaderInterface,
3995 vk::VkShaderStageFlags stageFlags,
3996 DescriptorUpdateMethod updateMethod)
3998 vk::DescriptorSetLayoutBuilder builder;
3999 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
4001 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
4002 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4004 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
4007 switch (shaderInterface)
4009 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4010 builder.addSingleBinding(descriptorType, stageFlags);
4013 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4014 builder.addSingleBinding(descriptorType, stageFlags);
4015 builder.addSingleBinding(descriptorType, stageFlags);
4018 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4019 builder.addArrayBinding(descriptorType, 2u, stageFlags);
4023 DE_FATAL("Impossible");
4026 return builder.build(vki, device, extraFlags);
4029 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4030 vk::VkDevice device,
4031 vk::VkDescriptorSetLayout descriptorSetLayout)
4033 const vk::VkPipelineLayoutCreateInfo createInfo =
4035 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4037 (vk::VkPipelineLayoutCreateFlags)0,
4038 1, // descriptorSetCount
4039 &descriptorSetLayout, // pSetLayouts
4040 0u, // pushConstantRangeCount
4041 DE_NULL, // pPushConstantRanges
4043 return vk::createPipelineLayout(vki, device, &createInfo);
4046 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4047 vk::VkDevice device,
4048 vk::VkDescriptorType descriptorType,
4049 ShaderInputInterface shaderInterface)
4051 return vk::DescriptorPoolBuilder()
4052 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
4053 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4056 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
4057 DescriptorUpdateMethod updateMethod,
4058 vk::VkDevice device,
4059 vk::VkDescriptorType descriptorType,
4060 ShaderInputInterface shaderInterface,
4061 vk::VkDescriptorSetLayout layout,
4062 vk::VkDescriptorPool pool,
4063 vk::VkImageView viewA,
4064 vk::VkImageView viewB,
4065 vk::DescriptorSetUpdateBuilder& updateBuilder,
4066 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
4067 RawUpdateRegistry& updateRegistry,
4068 vk::VkPipelineLayout pipelineLayout)
4070 const vk::VkDescriptorSetAllocateInfo allocInfo =
4072 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4079 vk::Move<vk::VkDescriptorSet> descriptorSet;
4080 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4082 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4086 descriptorSet = vk::Move<vk::VkDescriptorSet>();
4089 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
4091 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplate, updateRegistry);
4093 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4095 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplate, updateRegistry, true, pipelineLayout);
4097 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4099 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, updateMethod);
4101 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4103 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder);
4105 return descriptorSet;
4108 void ImageFetchRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
4109 vk::VkDevice device,
4110 vk::VkDescriptorType descriptorType,
4111 ShaderInputInterface shaderInterface,
4112 vk::VkDescriptorSetLayout layout,
4113 vk::VkDescriptorPool pool,
4114 vk::VkImageView viewA,
4115 vk::VkImageView viewB,
4116 vk::VkDescriptorSet descriptorSet,
4117 vk::DescriptorSetUpdateBuilder& updateBuilder,
4118 DescriptorUpdateMethod updateMethod)
4122 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
4123 const vk::VkDescriptorImageInfo imageInfos[2] =
4125 makeDescriptorImageInfo(viewA, imageLayout),
4126 makeDescriptorImageInfo(viewB, imageLayout),
4129 switch (shaderInterface)
4131 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4132 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4135 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4136 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
4137 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
4140 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4141 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
4145 DE_FATAL("Impossible");
4148 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4150 updateBuilder.update(vki, device);
4154 void ImageFetchRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
4155 vk::VkDevice device,
4156 vk::VkDescriptorType descriptorType,
4157 ShaderInputInterface shaderInterface,
4158 vk::VkDescriptorSetLayout layout,
4159 vk::VkDescriptorPool pool,
4160 vk::VkImageView viewA,
4161 vk::VkImageView viewB,
4162 vk::VkDescriptorSet descriptorSet,
4163 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
4164 RawUpdateRegistry& updateRegistry,
4166 vk::VkPipelineLayout pipelineLayout)
4169 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
4170 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
4172 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
4176 DE_NULL, // pUpdates
4177 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
4179 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
4183 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
4184 const vk::VkDescriptorImageInfo imageInfos[2] =
4186 makeDescriptorImageInfo(viewA, imageLayout),
4187 makeDescriptorImageInfo(viewB, imageLayout),
4189 updateRegistry.addWriteObject(imageInfos[0]);
4190 updateRegistry.addWriteObject(imageInfos[1]);
4192 switch (shaderInterface)
4194 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4195 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4198 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4199 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
4200 updateEntries.push_back(createTemplateBinding(1, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
4203 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4204 updateEntries.push_back(createTemplateBinding(0, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(imageInfos[0])));
4208 DE_FATAL("Impossible");
4211 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
4212 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
4214 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
4218 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
4222 void ImageFetchRenderInstance::logTestPlan (void) const
4224 std::ostringstream msg;
4226 msg << "Rendering 2x2 grid.\n"
4227 << "Single descriptor set. Descriptor set contains "
4228 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4229 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4230 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4231 (const char*)DE_NULL)
4232 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
4233 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4236 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4237 if (m_baseArraySlice)
4238 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4240 if (m_stageFlags == 0u)
4242 msg << "Descriptors are not accessed in any shader stage.\n";
4246 msg << "Color in each cell is fetched using the descriptor(s):\n";
4248 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4250 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4252 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4254 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4255 msg << " from descriptor " << srcResourceNdx;
4261 msg << "Descriptors are accessed in {"
4262 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4263 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4264 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4265 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4266 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4270 m_context.getTestContext().getLog()
4271 << tcu::TestLog::Message
4273 << tcu::TestLog::EndMessage;
4276 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
4278 return *m_pipelineLayout;
4281 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4283 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4285 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
4287 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4289 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, *m_updateTemplate, getPipelineLayout(), 0, (const void*)m_updateRegistry.getRawPointer());
4291 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4293 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0);
4296 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
4299 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4301 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4302 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4303 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4304 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
4305 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
4306 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
4307 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
4308 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4310 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4312 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
4313 return tcu::TestStatus::fail("Image verification failed");
4315 return tcu::TestStatus::pass("Pass");
4318 class ImageFetchComputeInstance : public vkt::TestInstance
4321 ImageFetchComputeInstance (vkt::Context& context,
4322 DescriptorUpdateMethod updateMethod,
4323 vk::VkDescriptorType descriptorType,
4324 ShaderInputInterface shaderInterface,
4325 vk::VkImageViewType viewType,
4326 deUint32 baseMipLevel,
4327 deUint32 baseArraySlice);
4330 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4331 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4332 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout);
4333 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet);
4334 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
4337 tcu::TestStatus iterate (void);
4338 void logTestPlan (void) const;
4339 tcu::TestStatus testResourceAccess (void);
4341 const DescriptorUpdateMethod m_updateMethod;
4342 const vk::VkDescriptorType m_descriptorType;
4343 const ShaderInputInterface m_shaderInterface;
4344 const vk::VkImageViewType m_viewType;
4345 const deUint32 m_baseMipLevel;
4346 const deUint32 m_baseArraySlice;
4347 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
4349 const vk::DeviceInterface& m_vki;
4350 const vk::VkDevice m_device;
4351 const vk::VkQueue m_queue;
4352 const deUint32 m_queueFamilyIndex;
4353 vk::Allocator& m_allocator;
4355 const ComputeInstanceResultBuffer m_result;
4356 const ImageFetchInstanceImages m_images;
4358 RawUpdateRegistry m_updateRegistry;
4359 vk::DescriptorSetUpdateBuilder m_updateBuilder;
4362 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
4363 DescriptorUpdateMethod updateMethod,
4364 vk::VkDescriptorType descriptorType,
4365 ShaderInputInterface shaderInterface,
4366 vk::VkImageViewType viewType,
4367 deUint32 baseMipLevel,
4368 deUint32 baseArraySlice)
4369 : vkt::TestInstance (context)
4370 , m_updateMethod (updateMethod)
4371 , m_descriptorType (descriptorType)
4372 , m_shaderInterface (shaderInterface)
4373 , m_viewType (viewType)
4374 , m_baseMipLevel (baseMipLevel)
4375 , m_baseArraySlice (baseArraySlice)
4376 , m_updateTemplate ()
4377 , m_vki (context.getDeviceInterface())
4378 , m_device (context.getDevice())
4379 , m_queue (context.getUniversalQueue())
4380 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4381 , m_allocator (context.getDefaultAllocator())
4382 , m_result (m_vki, m_device, m_allocator)
4383 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
4384 , m_updateRegistry ()
4385 , m_updateBuilder ()
4389 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
4391 vk::DescriptorSetLayoutBuilder builder;
4392 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
4394 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
4395 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4397 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
4400 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4402 switch (m_shaderInterface)
4404 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4405 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4408 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4409 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4410 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4413 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4414 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4418 DE_FATAL("Impossible");
4421 return builder.build(m_vki, m_device, extraFlags);
4424 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
4426 return vk::DescriptorPoolBuilder()
4427 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
4428 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
4429 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4432 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout)
4434 const vk::VkDescriptorSetAllocateInfo allocInfo =
4436 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4443 vk::Move<vk::VkDescriptorSet> descriptorSet;
4444 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4446 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4450 descriptorSet = vk::Move<vk::VkDescriptorSet>();
4453 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
4455 writeDescriptorSetWithTemplate(*descriptorSet, layout);
4457 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4459 writeDescriptorSet(*descriptorSet);
4462 return descriptorSet;
4465 void ImageFetchComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet)
4467 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4468 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
4469 const vk::VkDescriptorImageInfo imageInfos[2] =
4471 makeDescriptorImageInfo(m_images.getImageViewA(), imageLayout),
4472 makeDescriptorImageInfo(m_images.getImageViewB(), imageLayout),
4476 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4479 switch (m_shaderInterface)
4481 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4482 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
4485 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4486 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
4487 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
4490 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4491 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
4495 DE_FATAL("Impossible");
4498 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
4500 m_updateBuilder.update(m_vki, m_device);
4504 void ImageFetchComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush, vk::VkPipelineLayout pipelineLayout)
4506 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4507 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
4508 const vk::VkDescriptorImageInfo imageInfos[2] =
4510 makeDescriptorImageInfo(m_images.getImageViewA(), imageLayout),
4511 makeDescriptorImageInfo(m_images.getImageViewB(), imageLayout),
4513 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
4514 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
4516 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
4520 DE_NULL, // pUpdates
4521 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
4523 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
4528 m_updateRegistry.addWriteObject(resultInfo);
4529 m_updateRegistry.addWriteObject(imageInfos[0]);
4530 m_updateRegistry.addWriteObject(imageInfos[1]);
4533 updateEntries.push_back(createTemplateBinding(0u, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
4536 switch (m_shaderInterface)
4538 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4539 updateEntries.push_back(createTemplateBinding(1u, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
4542 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4543 updateEntries.push_back(createTemplateBinding(1u, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
4544 updateEntries.push_back(createTemplateBinding(2u, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(2), 0));
4547 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4548 updateEntries.push_back(createTemplateBinding(1u, 0, 2, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), sizeof(imageInfos[0])));
4552 DE_FATAL("Impossible");
4555 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
4556 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
4558 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
4562 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
4566 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
4569 return testResourceAccess();
4572 void ImageFetchComputeInstance::logTestPlan (void) const
4574 std::ostringstream msg;
4576 msg << "Fetching 4 values from image in compute shader.\n"
4577 << "Single descriptor set. Descriptor set contains "
4578 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4579 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4580 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4581 (const char*)DE_NULL)
4582 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
4583 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4586 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4587 if (m_baseArraySlice)
4588 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4590 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4592 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4594 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4596 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4597 msg << " from descriptor " << srcResourceNdx;
4603 m_context.getTestContext().getLog()
4604 << tcu::TestLog::Message
4606 << tcu::TestLog::EndMessage;
4609 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
4611 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4612 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4613 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4614 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4616 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4617 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : DE_LENGTH_OF_ARRAY(descriptorSets);
4618 const deUint32* const dynamicOffsets = DE_NULL;
4619 const int numDynamicOffsets = 0;
4620 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
4621 const int numPreBarriers = 0;
4622 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
4623 const int numPostBarriers = 1;
4625 const ComputeCommand compute (m_vki,
4627 pipeline.getPipeline(),
4628 pipeline.getPipelineLayout(),
4629 tcu::UVec3(4, 1, 1),
4630 numDescriptorSets, descriptorSets,
4631 numDynamicOffsets, dynamicOffsets,
4632 numPreBarriers, preBarriers,
4633 numPostBarriers, postBarriers);
4635 tcu::Vec4 results[4];
4636 bool anyResultSet = false;
4637 bool allResultsOk = true;
4639 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
4641 writeDescriptorSetWithTemplate(DE_NULL, *descriptorSetLayout, true, pipeline.getPipelineLayout());
4642 compute.submitAndWait(m_queueFamilyIndex, m_queue, *m_updateTemplate, (const void*) m_updateRegistry.getRawPointer());
4644 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
4646 writeDescriptorSet(DE_NULL);
4647 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder);
4651 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4653 m_result.readResultContentsTo(&results);
4656 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4658 const tcu::Vec4 result = results[resultNdx];
4659 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
4660 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
4662 if (result != tcu::Vec4(-1.0f))
4663 anyResultSet = true;
4665 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
4667 allResultsOk = false;
4669 m_context.getTestContext().getLog()
4670 << tcu::TestLog::Message
4671 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
4672 << tcu::TestLog::EndMessage;
4676 // read back and verify
4678 return tcu::TestStatus::pass("Pass");
4679 else if (anyResultSet)
4680 return tcu::TestStatus::fail("Invalid result values");
4683 m_context.getTestContext().getLog()
4684 << tcu::TestLog::Message
4685 << "Result buffer was not written to."
4686 << tcu::TestLog::EndMessage;
4687 return tcu::TestStatus::fail("Result buffer was not written to");
4691 class ImageSampleInstanceImages : private ImageInstanceImages
4694 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
4695 vk::VkDevice device,
4696 deUint32 queueFamilyIndex,
4698 vk::Allocator& allocator,
4699 vk::VkDescriptorType descriptorType,
4700 ShaderInputInterface shaderInterface,
4701 vk::VkImageViewType viewType,
4702 deUint32 baseMipLevel,
4703 deUint32 baseArraySlice,
4706 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
4707 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
4709 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
4710 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
4711 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
4712 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
4713 inline bool isImmutable (void) const { return m_isImmutable; }
4716 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
4717 static tcu::Sampler createRefSampler (bool isFirst);
4718 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
4720 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
4721 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
4722 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
4723 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
4725 const vk::VkDescriptorType m_descriptorType;
4726 const ShaderInputInterface m_shaderInterface;
4727 const bool m_isImmutable;
4729 const tcu::Sampler m_refSamplerA;
4730 const tcu::Sampler m_refSamplerB;
4731 const vk::Unique<vk::VkSampler> m_samplerA;
4732 const vk::Unique<vk::VkSampler> m_samplerB;
4735 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
4736 vk::VkDevice device,
4737 deUint32 queueFamilyIndex,
4739 vk::Allocator& allocator,
4740 vk::VkDescriptorType descriptorType,
4741 ShaderInputInterface shaderInterface,
4742 vk::VkImageViewType viewType,
4743 deUint32 baseMipLevel,
4744 deUint32 baseArraySlice,
4746 : ImageInstanceImages (vki,
4753 getNumImages(descriptorType, shaderInterface),
4756 , m_descriptorType (descriptorType)
4757 , m_shaderInterface (shaderInterface)
4758 , m_isImmutable (immutable)
4759 , m_refSamplerA (createRefSampler(true))
4760 , m_refSamplerB (createRefSampler(false))
4761 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
4762 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
4763 ? vk::Move<vk::VkSampler>()
4764 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
4768 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
4770 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
4772 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
4773 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
4775 // choose arbitrary values that are not ambiguous with NEAREST filtering
4779 case vk::VK_IMAGE_VIEW_TYPE_1D:
4780 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
4781 case vk::VK_IMAGE_VIEW_TYPE_2D:
4782 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
4783 case vk::VK_IMAGE_VIEW_TYPE_3D:
4785 const tcu::Vec3 coords[4] =
4789 (float)(12u % imageSize) + 0.25f),
4791 tcu::Vec3((float)(23u % imageSize) + 0.25f,
4792 (float)(73u % imageSize) + 0.5f,
4793 (float)(16u % imageSize) + 0.5f + (float)imageSize),
4795 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
4796 (float)(84u % imageSize) + 0.5f + (float)imageSize,
4797 (float)(117u % imageSize) + 0.75f),
4799 tcu::Vec3((float)imageSize + 0.5f,
4800 (float)(75u % imageSize) + 0.25f,
4801 (float)(83u % imageSize) + 0.25f + (float)imageSize),
4803 const deUint32 slices[4] =
4811 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
4812 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
4813 (float)slices[samplePosNdx],
4816 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
4817 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
4818 coords[samplePosNdx].y() / (float)imageSize,
4819 (float)slices[samplePosNdx],
4821 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
4822 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
4823 coords[samplePosNdx].y() / (float)imageSize,
4824 coords[samplePosNdx].z() / (float)imageSize,
4828 DE_FATAL("Impossible");
4833 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4834 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
4836 // \note these values are in [0, texSize]*3 space for convenience
4837 const tcu::Vec3 coords[4] =
4843 tcu::Vec3((float)(13u % imageSize) + 0.25f,
4845 (float)(16u % imageSize) + 0.5f),
4848 (float)(84u % imageSize) + 0.5f,
4849 (float)(10u % imageSize) + 0.75f),
4851 tcu::Vec3((float)imageSize,
4852 (float)(75u % imageSize) + 0.25f,
4853 (float)(83u % imageSize) + 0.75f),
4855 const deUint32 slices[4] =
4863 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
4864 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
4865 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
4867 // map to [-1, 1]*3 space
4868 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
4869 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
4870 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
4871 (float)slices[samplePosNdx]);
4875 DE_FATAL("Impossible");
4880 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
4882 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
4884 // texture order is ABAB
4885 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
4886 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
4887 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
4888 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
4890 // sampler order is ABAB
4891 const tcu::Sampler& samplerA = m_refSamplerA;
4892 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
4893 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
4895 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
4896 const float lod = 0.0f;
4897 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
4901 case vk::VK_IMAGE_VIEW_TYPE_1D:
4902 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
4903 case vk::VK_IMAGE_VIEW_TYPE_2D:
4904 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);
4905 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
4906 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4907 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);
4911 DE_FATAL("Impossible");
4917 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
4919 // If we are testing separate samplers, just one image is enough
4920 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4922 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4924 // combined: numImages == numSamplers
4925 return getInterfaceNumResources(shaderInterface);
4929 DE_FATAL("Impossible");
4934 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4939 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4943 // nearest, clamping
4944 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4948 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4950 const vk::VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, format);
4952 return vk::createSampler(vki, device, &createInfo);
4955 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4957 DE_ASSERT(levelStorage->empty());
4959 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4960 const deUint32 numLevels = (deUint32)source.getNumLevels();
4962 // cut pyramid from baseMipLevel
4963 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4965 // cut levels from baseArraySlice
4966 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4967 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4968 levelStorage->push_back(cutLevel);
4971 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4974 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4976 DE_ASSERT(levelStorage->empty());
4978 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4979 const deUint32 numLevels = (deUint32)source.getNumLevels();
4981 // cut pyramid from baseMipLevel
4982 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4984 // cut levels from baseArraySlice
4985 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4986 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4987 levelStorage->push_back(cutLevel);
4990 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4993 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4995 DE_ASSERT(levelStorage->empty());
4996 DE_ASSERT(baseArraySlice == 0);
4997 DE_UNREF(baseArraySlice);
4999 const deUint32 numLevels = (deUint32)source.getNumLevels();
5001 // cut pyramid from baseMipLevel
5002 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5003 levelStorage->push_back(source.getLevel(level));
5005 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
5008 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
5010 DE_ASSERT(levelStorage->empty());
5012 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
5013 const deUint32 numLevels = (deUint32)source.getNumLevels();
5015 // cut pyramid from baseMipLevel
5016 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
5018 // cut levels from baseArraySlice
5019 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
5020 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
5021 levelStorage->push_back(cutLevel);
5024 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
5027 class ImageSampleRenderInstance : public SingleCmdRenderInstance
5030 ImageSampleRenderInstance (vkt::Context& context,
5031 DescriptorUpdateMethod updateMethod,
5032 bool isPrimaryCmdBuf,
5033 vk::VkDescriptorType descriptorType,
5034 vk::VkShaderStageFlags stageFlags,
5035 ShaderInputInterface shaderInterface,
5036 vk::VkImageViewType viewType,
5037 deUint32 baseMipLevel,
5038 deUint32 baseArraySlice,
5042 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
5043 vk::VkDevice device,
5044 vk::VkDescriptorType descriptorType,
5045 ShaderInputInterface shaderInterface,
5046 vk::VkShaderStageFlags stageFlags,
5047 const ImageSampleInstanceImages& images,
5048 DescriptorUpdateMethod updateMethod);
5050 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5051 vk::VkDevice device,
5052 vk::VkDescriptorSetLayout descriptorSetLayout);
5054 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5055 vk::VkDevice device,
5056 vk::VkDescriptorType descriptorType,
5057 ShaderInputInterface shaderInterface);
5059 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
5060 DescriptorUpdateMethod updateMethod,
5061 vk::VkDevice device,
5062 vk::VkDescriptorType descriptorType,
5063 ShaderInputInterface shaderInterface,
5064 vk::VkDescriptorSetLayout layout,
5065 vk::VkDescriptorPool pool,
5067 const ImageSampleInstanceImages& images,
5068 vk::DescriptorSetUpdateBuilder& updateBuilder,
5069 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5070 RawUpdateRegistry& updateRegistry,
5071 vk::VkPipelineLayout pipelineLayout = DE_NULL);
5073 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
5074 vk::VkDevice device,
5075 ShaderInputInterface shaderInterface,
5077 const ImageSampleInstanceImages& images,
5078 vk::VkDescriptorSet descriptorSet,
5079 vk::DescriptorSetUpdateBuilder& updateBuilder,
5080 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
5082 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
5083 vk::VkDevice device,
5084 ShaderInputInterface shaderInterface,
5086 const ImageSampleInstanceImages& images,
5087 vk::VkDescriptorSet descriptorSet,
5088 vk::DescriptorSetUpdateBuilder& updateBuilder,
5089 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
5091 static void writeSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5092 vk::VkDevice device,
5093 ShaderInputInterface shaderInterface,
5095 const ImageSampleInstanceImages& images,
5096 vk::VkDescriptorSet descriptorSet,
5097 vk::VkDescriptorSetLayout layout,
5098 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5099 RawUpdateRegistry& updateRegistry,
5100 bool withPush = false,
5101 vk::VkPipelineLayout pipelineLayout = 0);
5103 static void writeImageSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5104 vk::VkDevice device,
5105 ShaderInputInterface shaderInterface,
5107 const ImageSampleInstanceImages& images,
5108 vk::VkDescriptorSet descriptorSet,
5109 vk::VkDescriptorSetLayout layout,
5110 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5111 RawUpdateRegistry& updateRegistry,
5112 bool withPush = false,
5113 vk::VkPipelineLayout pipelineLayout = 0);
5115 void logTestPlan (void) const;
5116 vk::VkPipelineLayout getPipelineLayout (void) const;
5117 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5118 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5125 const DescriptorUpdateMethod m_updateMethod;
5126 const vk::VkDescriptorType m_descriptorType;
5127 const vk::VkShaderStageFlags m_stageFlags;
5128 const ShaderInputInterface m_shaderInterface;
5129 const vk::VkImageViewType m_viewType;
5130 const deUint32 m_baseMipLevel;
5131 const deUint32 m_baseArraySlice;
5133 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
5134 RawUpdateRegistry m_updateRegistry;
5135 vk::DescriptorSetUpdateBuilder m_updateBuilder;
5136 const ImageSampleInstanceImages m_images;
5137 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5138 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5139 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5140 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5143 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
5144 DescriptorUpdateMethod updateMethod,
5145 bool isPrimaryCmdBuf,
5146 vk::VkDescriptorType descriptorType,
5147 vk::VkShaderStageFlags stageFlags,
5148 ShaderInputInterface shaderInterface,
5149 vk::VkImageViewType viewType,
5150 deUint32 baseMipLevel,
5151 deUint32 baseArraySlice,
5153 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5154 , m_updateMethod (updateMethod)
5155 , m_descriptorType (descriptorType)
5156 , m_stageFlags (stageFlags)
5157 , m_shaderInterface (shaderInterface)
5158 , m_viewType (viewType)
5159 , m_baseMipLevel (baseMipLevel)
5160 , m_baseArraySlice (baseArraySlice)
5161 , m_updateTemplate ()
5162 , m_updateRegistry ()
5163 , m_updateBuilder ()
5164 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
5165 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images, m_updateMethod))
5166 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5167 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5168 , 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))
5172 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5173 vk::VkDevice device,
5174 vk::VkDescriptorType descriptorType,
5175 ShaderInputInterface shaderInterface,
5176 vk::VkShaderStageFlags stageFlags,
5177 const ImageSampleInstanceImages& images,
5178 DescriptorUpdateMethod updateMethod)
5180 const vk::VkSampler samplers[2] =
5182 images.getSamplerA(),
5183 images.getSamplerB(),
5186 vk::DescriptorSetLayoutBuilder builder;
5187 const bool addSeparateImage = descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER;
5188 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
5190 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
5191 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5193 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
5196 // (combined)samplers follow
5197 switch (shaderInterface)
5199 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5200 if (addSeparateImage)
5201 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5202 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5205 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5206 if (addSeparateImage)
5207 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5208 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5209 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5212 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5213 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5214 if (addSeparateImage)
5215 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5216 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5219 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5220 if (addSeparateImage)
5221 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
5222 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
5226 DE_FATAL("Impossible");
5229 return builder.build(vki, device, extraFlags);
5232 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5233 vk::VkDevice device,
5234 vk::VkDescriptorSetLayout descriptorSetLayout)
5236 const vk::VkPipelineLayoutCreateInfo createInfo =
5238 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5240 (vk::VkPipelineLayoutCreateFlags)0,
5241 1, // descriptorSetCount
5242 &descriptorSetLayout, // pSetLayouts
5243 0u, // pushConstantRangeCount
5244 DE_NULL, // pPushConstantRanges
5246 return vk::createPipelineLayout(vki, device, &createInfo);
5249 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5250 vk::VkDevice device,
5251 vk::VkDescriptorType descriptorType,
5252 ShaderInputInterface shaderInterface)
5254 vk::DescriptorPoolBuilder builder;
5256 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5258 // separate samplers need image to sample
5259 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
5261 // also need sample to use, indifferent of whether immutable or not
5262 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
5264 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5266 // combined image samplers
5267 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
5270 DE_FATAL("Impossible");
5272 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5275 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5276 DescriptorUpdateMethod updateMethod,
5277 vk::VkDevice device,
5278 vk::VkDescriptorType descriptorType,
5279 ShaderInputInterface shaderInterface,
5280 vk::VkDescriptorSetLayout layout,
5281 vk::VkDescriptorPool pool,
5283 const ImageSampleInstanceImages& images,
5284 vk::DescriptorSetUpdateBuilder& updateBuilder,
5285 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5286 RawUpdateRegistry& updateRegistry,
5287 vk::VkPipelineLayout pipelineLayout)
5289 const vk::VkDescriptorSetAllocateInfo allocInfo =
5291 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5298 vk::Move<vk::VkDescriptorSet> descriptorSet;
5299 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5301 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5305 descriptorSet = vk::Move<vk::VkDescriptorSet>();
5308 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
5310 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5311 writeSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, *descriptorSet, layout, updateTemplate, updateRegistry);
5312 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5313 writeImageSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, *descriptorSet, layout, updateTemplate, updateRegistry);
5315 DE_FATAL("Impossible");
5317 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5319 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5320 writeSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, DE_NULL, layout, updateTemplate, updateRegistry, true, pipelineLayout);
5321 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5322 writeImageSamplerDescriptorSetWithTemplate(vki, device, shaderInterface, isImmutable, images, DE_NULL, layout, updateTemplate, updateRegistry, true, pipelineLayout);
5324 DE_FATAL("Impossible");
5326 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5328 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5329 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, updateBuilder, updateMethod);
5330 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5331 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, updateBuilder, updateMethod);
5333 DE_FATAL("Impossible");
5335 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5337 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5338 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, updateBuilder);
5339 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5340 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet, updateBuilder);
5342 DE_FATAL("Impossible");
5345 return descriptorSet;
5348 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
5349 vk::VkDevice device,
5350 ShaderInputInterface shaderInterface,
5352 const ImageSampleInstanceImages& images,
5353 vk::VkDescriptorSet descriptorSet,
5354 vk::DescriptorSetUpdateBuilder& updateBuilder,
5355 DescriptorUpdateMethod updateMethod)
5357 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5358 const vk::VkDescriptorImageInfo samplersInfos[2] =
5360 makeDescriptorImageInfo(images.getSamplerA()),
5361 makeDescriptorImageInfo(images.getSamplerB()),
5364 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
5366 // stand alone texture
5367 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(samplerLocation), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
5370 if (!isImmutable || (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH))
5372 switch (shaderInterface)
5374 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5375 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5378 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5379 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5380 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
5383 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5384 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5385 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
5388 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5389 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
5393 DE_FATAL("Impossible");
5397 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5399 updateBuilder.update(vki, device);
5403 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
5404 vk::VkDevice device,
5405 ShaderInputInterface shaderInterface,
5407 const ImageSampleInstanceImages& images,
5408 vk::VkDescriptorSet descriptorSet,
5409 vk::DescriptorSetUpdateBuilder& updateBuilder,
5410 DescriptorUpdateMethod updateMethod)
5412 const vk::VkSampler samplers[2] =
5414 (isImmutable && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? (0) : (images.getSamplerA()),
5415 (isImmutable && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? (0) : (images.getSamplerB()),
5417 const vk::VkDescriptorImageInfo imageSamplers[2] =
5419 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5420 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5423 // combined image samplers
5424 switch (shaderInterface)
5426 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5427 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
5430 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5431 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
5432 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
5435 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5436 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
5440 DE_FATAL("Impossible");
5443 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5445 updateBuilder.update(vki, device);
5449 void ImageSampleRenderInstance::writeSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5450 vk::VkDevice device,
5451 ShaderInputInterface shaderInterface,
5453 const ImageSampleInstanceImages& images,
5454 vk::VkDescriptorSet descriptorSet,
5455 vk::VkDescriptorSetLayout layout,
5456 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5457 RawUpdateRegistry& updateRegistry,
5459 vk::VkPipelineLayout pipelineLayout)
5461 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5462 const vk::VkDescriptorImageInfo samplersInfos[2] =
5464 makeDescriptorImageInfo(images.getSamplerA()),
5465 makeDescriptorImageInfo(images.getSamplerB()),
5468 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
5470 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
5471 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
5473 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
5477 DE_NULL, // pUpdates
5478 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
5480 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
5484 updateRegistry.addWriteObject(imageInfo);
5485 updateRegistry.addWriteObject(samplersInfos[0]);
5486 updateRegistry.addWriteObject(samplersInfos[1]);
5488 // stand alone texture
5489 updateEntries.push_back(createTemplateBinding(samplerLocation, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, updateRegistry.getWriteObjectOffset(0), 0));
5492 if (!isImmutable || withPush)
5494 switch (shaderInterface)
5496 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5497 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
5500 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5501 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
5502 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
5505 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5506 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
5507 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(2), 0));
5510 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5511 updateEntries.push_back(createTemplateBinding(1, 0, 2, vk::VK_DESCRIPTOR_TYPE_SAMPLER, updateRegistry.getWriteObjectOffset(1), sizeof(samplersInfos[0])));
5515 DE_FATAL("Impossible");
5519 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
5520 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
5522 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
5526 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
5531 void ImageSampleRenderInstance::writeImageSamplerDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
5532 vk::VkDevice device,
5533 ShaderInputInterface shaderInterface,
5535 const ImageSampleInstanceImages& images,
5536 vk::VkDescriptorSet descriptorSet,
5537 vk::VkDescriptorSetLayout layout,
5538 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
5539 RawUpdateRegistry& updateRegistry,
5541 vk::VkPipelineLayout pipelineLayout)
5543 const vk::VkSampler samplers[2] =
5545 (isImmutable && !withPush) ? (0) : (images.getSamplerA()),
5546 (isImmutable && !withPush) ? (0) : (images.getSamplerB()),
5548 const vk::VkDescriptorImageInfo imageSamplers[2] =
5550 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5551 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
5554 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
5555 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
5557 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
5561 DE_NULL, // pUpdates
5562 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
5564 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
5568 updateRegistry.addWriteObject(imageSamplers[0]);
5569 updateRegistry.addWriteObject(imageSamplers[1]);
5571 // combined image samplers
5572 switch (shaderInterface)
5574 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5575 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
5578 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5579 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), 0));
5580 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(1), 0));
5583 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5584 updateEntries.push_back(createTemplateBinding(0, 0, 2, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, updateRegistry.getWriteObjectOffset(0), sizeof(imageSamplers[0])));
5588 DE_FATAL("Impossible");
5591 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
5592 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
5594 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
5598 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
5602 void ImageSampleRenderInstance::logTestPlan (void) const
5604 std::ostringstream msg;
5606 msg << "Rendering 2x2 grid.\n";
5608 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5610 msg << "Single descriptor set. Descriptor set contains "
5611 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5612 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5613 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
5614 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5615 (const char*)DE_NULL)
5616 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
5618 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5620 msg << "Single descriptor set. Descriptor set contains "
5621 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5622 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5623 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
5624 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5625 (const char*)DE_NULL)
5626 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
5629 DE_FATAL("Impossible");
5631 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
5634 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
5635 if (m_baseArraySlice)
5636 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
5638 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
5639 msg << "Sampler mode is LINEAR, with WRAP\n";
5641 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
5643 if (m_stageFlags == 0u)
5645 msg << "Descriptors are not accessed in any shader stage.\n";
5649 msg << "Color in each cell is fetched using the descriptor(s):\n";
5651 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5653 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
5655 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5657 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5659 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5660 msg << " using sampler " << srcResourceNdx;
5661 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5662 msg << " from combined image sampler " << srcResourceNdx;
5664 DE_FATAL("Impossible");
5669 msg << "Descriptors are accessed in {"
5670 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5671 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5672 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5673 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5674 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5678 m_context.getTestContext().getLog()
5679 << tcu::TestLog::Message
5681 << tcu::TestLog::EndMessage;
5684 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
5686 return *m_pipelineLayout;
5689 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
5691 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5693 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
5695 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5697 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, *m_updateTemplate, getPipelineLayout(), 0, (const void*)m_updateRegistry.getRawPointer());
5699 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5701 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0);
5704 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
5707 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5709 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5710 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5711 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5712 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
5713 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
5714 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
5715 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
5716 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
5717 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5719 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5721 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
5722 return tcu::TestStatus::fail("Image verification failed");
5724 return tcu::TestStatus::pass("Pass");
5727 class ImageSampleComputeInstance : public vkt::TestInstance
5730 ImageSampleComputeInstance (vkt::Context& context,
5731 DescriptorUpdateMethod updateMethod,
5732 vk::VkDescriptorType descriptorType,
5733 ShaderInputInterface shaderInterface,
5734 vk::VkImageViewType viewType,
5735 deUint32 baseMipLevel,
5736 deUint32 baseArraySlice,
5737 bool isImmutableSampler);
5740 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5741 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5742 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout);
5743 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, vk::VkPipelineLayout pipelineLayout = DE_NULL);
5744 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet);
5745 void writeImageSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
5746 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet);
5747 void writeSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
5749 tcu::TestStatus iterate (void);
5750 void logTestPlan (void) const;
5751 tcu::TestStatus testResourceAccess (void);
5753 const DescriptorUpdateMethod m_updateMethod;
5754 const vk::VkDescriptorType m_descriptorType;
5755 const ShaderInputInterface m_shaderInterface;
5756 const vk::VkImageViewType m_viewType;
5757 const deUint32 m_baseMipLevel;
5758 const deUint32 m_baseArraySlice;
5759 const bool m_isImmutableSampler;
5760 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
5762 const vk::DeviceInterface& m_vki;
5763 const vk::VkDevice m_device;
5764 const vk::VkQueue m_queue;
5765 const deUint32 m_queueFamilyIndex;
5766 vk::Allocator& m_allocator;
5768 const ComputeInstanceResultBuffer m_result;
5769 const ImageSampleInstanceImages m_images;
5771 RawUpdateRegistry m_updateRegistry;
5772 vk::DescriptorSetUpdateBuilder m_updateBuilder;
5775 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
5776 DescriptorUpdateMethod updateMethod,
5777 vk::VkDescriptorType descriptorType,
5778 ShaderInputInterface shaderInterface,
5779 vk::VkImageViewType viewType,
5780 deUint32 baseMipLevel,
5781 deUint32 baseArraySlice,
5782 bool isImmutableSampler)
5783 : vkt::TestInstance (context)
5784 , m_updateMethod (updateMethod)
5785 , m_descriptorType (descriptorType)
5786 , m_shaderInterface (shaderInterface)
5787 , m_viewType (viewType)
5788 , m_baseMipLevel (baseMipLevel)
5789 , m_baseArraySlice (baseArraySlice)
5790 , m_isImmutableSampler (isImmutableSampler)
5791 , m_updateTemplate ()
5792 , m_vki (context.getDeviceInterface())
5793 , m_device (context.getDevice())
5794 , m_queue (context.getUniversalQueue())
5795 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5796 , m_allocator (context.getDefaultAllocator())
5797 , m_result (m_vki, m_device, m_allocator)
5798 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
5799 , m_updateRegistry ()
5800 , m_updateBuilder ()
5804 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
5806 const vk::VkSampler samplers[2] =
5808 m_images.getSamplerA(),
5809 m_images.getSamplerB(),
5812 vk::DescriptorSetLayoutBuilder builder;
5813 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
5815 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
5816 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5818 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
5822 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5824 // with samplers, separate texture at binding 0
5825 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5826 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5828 // (combined)samplers follow
5829 switch (m_shaderInterface)
5831 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5832 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5835 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5836 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
5837 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
5840 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5841 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
5845 DE_FATAL("Impossible");
5848 return builder.build(m_vki, m_device, extraFlags);
5851 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
5853 vk::DescriptorPoolBuilder builder;
5855 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
5856 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
5858 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5859 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
5861 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5864 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout)
5866 const vk::VkDescriptorSetAllocateInfo allocInfo =
5868 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5875 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5877 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
5878 writeDescriptorSet(*descriptorSet, layout);
5880 return descriptorSet;
5883 return vk::Move<vk::VkDescriptorSet>();
5886 void ImageSampleComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, vk::VkPipelineLayout pipelineLayout)
5888 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
5890 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5891 writeSamplerDescriptorSetWithTemplate(descriptorSet, layout);
5892 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5893 writeImageSamplerDescriptorSetWithTemplate(descriptorSet, layout);
5895 DE_FATAL("Impossible");
5897 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
5899 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5900 writeSamplerDescriptorSetWithTemplate(descriptorSet, layout, true, pipelineLayout);
5901 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5902 writeImageSamplerDescriptorSetWithTemplate(descriptorSet, layout, true, pipelineLayout);
5904 DE_FATAL("Impossible");
5906 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
5908 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5909 writeSamplerDescriptorSet(descriptorSet);
5910 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5911 writeImageSamplerDescriptorSet(descriptorSet);
5913 DE_FATAL("Impossible");
5915 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5917 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5918 writeSamplerDescriptorSet(descriptorSet);
5919 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
5920 writeImageSamplerDescriptorSet(descriptorSet);
5922 DE_FATAL("Impossible");
5926 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet)
5928 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5929 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5930 const vk::VkDescriptorImageInfo samplersInfos[2] =
5932 makeDescriptorImageInfo(m_images.getSamplerA()),
5933 makeDescriptorImageInfo(m_images.getSamplerB()),
5937 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5939 // stand alone texture
5940 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
5943 if (!m_isImmutableSampler || (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH))
5945 switch (m_shaderInterface)
5947 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5948 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5951 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5952 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
5953 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
5956 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5957 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
5961 DE_FATAL("Impossible");
5965 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
5967 m_updateBuilder.update(m_vki, m_device);
5971 void ImageSampleComputeInstance::writeSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush, vk::VkPipelineLayout pipelineLayout)
5973 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
5974 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5975 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
5976 const vk::VkDescriptorImageInfo samplersInfos[2] =
5978 makeDescriptorImageInfo(m_images.getSamplerA()),
5979 makeDescriptorImageInfo(m_images.getSamplerB()),
5981 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
5983 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
5987 DE_NULL, // pUpdates
5988 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
5990 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
5994 m_updateRegistry.addWriteObject(resultInfo);
5995 m_updateRegistry.addWriteObject(imageInfo);
5996 m_updateRegistry.addWriteObject(samplersInfos[0]);
5997 m_updateRegistry.addWriteObject(samplersInfos[1]);
6000 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
6001 // stand alone texture
6002 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, m_updateRegistry.getWriteObjectOffset(1), 0));
6005 if (!m_isImmutableSampler || withPush)
6007 switch (m_shaderInterface)
6009 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6010 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, m_updateRegistry.getWriteObjectOffset(2), 0));
6013 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6014 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, m_updateRegistry.getWriteObjectOffset(2), 0));
6015 updateEntries.push_back(createTemplateBinding(3, 0, 1, vk::VK_DESCRIPTOR_TYPE_SAMPLER, m_updateRegistry.getWriteObjectOffset(3), 0));
6018 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6019 updateEntries.push_back(createTemplateBinding(2, 0, 2, vk::VK_DESCRIPTOR_TYPE_SAMPLER, m_updateRegistry.getWriteObjectOffset(2), sizeof(samplersInfos[0])));
6023 DE_FATAL("Impossible");
6027 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6028 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6030 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
6034 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
6038 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet)
6040 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6041 const vk::VkSampler samplers[2] =
6043 (m_isImmutableSampler && (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)) ? (0) : (m_images.getSamplerA()),
6044 (m_isImmutableSampler && (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)) ? (0) : (m_images.getSamplerB()),
6046 const vk::VkDescriptorImageInfo imageSamplers[2] =
6048 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6049 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6053 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
6055 // combined image samplers
6056 switch (m_shaderInterface)
6058 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6059 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6062 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6063 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
6064 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
6067 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6068 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
6072 DE_FATAL("Impossible");
6075 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
6077 m_updateBuilder.update(m_vki, m_device);
6081 void ImageSampleComputeInstance::writeImageSamplerDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush, vk::VkPipelineLayout pipelineLayout)
6083 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
6084 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
6085 const vk::VkSampler samplers[2] =
6087 (m_isImmutableSampler && !withPush) ? (0) : (m_images.getSamplerA()),
6088 (m_isImmutableSampler && !withPush) ? (0) : (m_images.getSamplerB()),
6090 const vk::VkDescriptorImageInfo imageSamplers[2] =
6092 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6093 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
6095 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
6097 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
6101 DE_NULL, // pUpdates
6102 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
6104 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
6108 m_updateRegistry.addWriteObject(resultInfo);
6109 m_updateRegistry.addWriteObject(imageSamplers[0]);
6110 m_updateRegistry.addWriteObject(imageSamplers[1]);
6113 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
6115 // combined image samplers
6116 switch (m_shaderInterface)
6118 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6119 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_updateRegistry.getWriteObjectOffset(1), 0));
6122 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6123 updateEntries.push_back(createTemplateBinding(1, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_updateRegistry.getWriteObjectOffset(1), 0));
6124 updateEntries.push_back(createTemplateBinding(2, 0, 1, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_updateRegistry.getWriteObjectOffset(2), 0));
6127 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6128 updateEntries.push_back(createTemplateBinding(1, 0, 2, vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, m_updateRegistry.getWriteObjectOffset(1), sizeof(imageSamplers[0])));
6132 DE_FATAL("Impossible");
6135 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
6136 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
6138 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
6142 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
6146 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
6149 return testResourceAccess();
6152 void ImageSampleComputeInstance::logTestPlan (void) const
6154 std::ostringstream msg;
6156 msg << "Accessing resource in a compute program.\n";
6158 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6160 msg << "Single descriptor set. Descriptor set contains "
6161 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6162 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6163 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6164 (const char*)DE_NULL)
6165 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
6167 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6169 msg << "Single descriptor set. Descriptor set contains "
6170 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
6171 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
6172 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
6173 (const char*)DE_NULL)
6174 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
6177 DE_FATAL("Impossible");
6179 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
6182 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
6183 if (m_baseArraySlice)
6184 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
6186 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
6187 msg << "Sampler mode is LINEAR, with WRAP\n";
6189 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
6191 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6193 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
6195 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
6197 const int srcResourceNdx = (resultNdx % 2); // ABAB source
6199 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6200 msg << " using sampler " << srcResourceNdx;
6201 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
6202 msg << " from combined image sampler " << srcResourceNdx;
6204 DE_FATAL("Impossible");
6209 m_context.getTestContext().getLog()
6210 << tcu::TestLog::Message
6212 << tcu::TestLog::EndMessage;
6215 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
6217 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
6218 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
6219 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
6220 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
6222 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
6223 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : DE_LENGTH_OF_ARRAY(descriptorSets);
6224 const deUint32* const dynamicOffsets = DE_NULL;
6225 const int numDynamicOffsets = 0;
6226 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
6227 const int numPreBarriers = 0;
6228 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
6229 const int numPostBarriers = 1;
6231 const ComputeCommand compute (m_vki,
6233 pipeline.getPipeline(),
6234 pipeline.getPipelineLayout(),
6235 tcu::UVec3(4, 1, 1),
6236 numDescriptorSets, descriptorSets,
6237 numDynamicOffsets, dynamicOffsets,
6238 numPreBarriers, preBarriers,
6239 numPostBarriers, postBarriers);
6241 tcu::Vec4 results[4];
6242 bool anyResultSet = false;
6243 bool allResultsOk = true;
6245 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
6247 writeDescriptorSet(DE_NULL, *descriptorSetLayout, pipeline.getPipelineLayout()); // descriptor set not applicable
6248 compute.submitAndWait(m_queueFamilyIndex, m_queue, *m_updateTemplate, (void *) m_updateRegistry.getRawPointer());
6250 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
6252 writeDescriptorSet(DE_NULL, *descriptorSetLayout, pipeline.getPipelineLayout()); // descriptor set not applicable
6253 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder);
6257 compute.submitAndWait(m_queueFamilyIndex, m_queue);
6259 m_result.readResultContentsTo(&results);
6262 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6264 const tcu::Vec4 result = results[resultNdx];
6265 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
6267 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
6268 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
6270 if (result != tcu::Vec4(-1.0f))
6271 anyResultSet = true;
6273 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
6275 allResultsOk = false;
6277 m_context.getTestContext().getLog()
6278 << tcu::TestLog::Message
6279 << "Test sample " << resultNdx << ":\n"
6280 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
6281 << "\tError expected " << reference << ", got " << result
6282 << tcu::TestLog::EndMessage;
6286 // read back and verify
6288 return tcu::TestStatus::pass("Pass");
6289 else if (anyResultSet)
6290 return tcu::TestStatus::fail("Invalid result values");
6293 m_context.getTestContext().getLog()
6294 << tcu::TestLog::Message
6295 << "Result buffer was not written to."
6296 << tcu::TestLog::EndMessage;
6297 return tcu::TestStatus::fail("Result buffer was not written to");
6301 class ImageDescriptorCase : public QuadrantRendederCase
6306 FLAG_BASE_MIP = (1u << 1u),
6307 FLAG_BASE_SLICE = (1u << 2u),
6309 // enum continues where resource flags ends
6310 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
6312 ImageDescriptorCase (tcu::TestContext& testCtx,
6314 const char* description,
6315 bool isPrimaryCmdBuf,
6316 DescriptorUpdateMethod updateMethod,
6317 vk::VkDescriptorType descriptorType,
6318 vk::VkShaderStageFlags exitingStages,
6319 vk::VkShaderStageFlags activeStages,
6320 ShaderInputInterface shaderInterface,
6321 vk::VkImageViewType viewType,
6325 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
6326 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
6327 std::string genFetchCoordStr (int fetchPosNdx) const;
6328 std::string genSampleCoordStr (int samplePosNdx) const;
6329 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
6330 std::string genNoAccessSource (void) const;
6332 vkt::TestInstance* createInstance (vkt::Context& context) const;
6335 const bool m_isPrimaryCmdBuf;
6336 const DescriptorUpdateMethod m_updateMethod;
6337 const vk::VkDescriptorType m_descriptorType;
6338 const ShaderInputInterface m_shaderInterface;
6339 const vk::VkImageViewType m_viewType;
6340 const deUint32 m_baseMipLevel;
6341 const deUint32 m_baseArraySlice;
6342 const bool m_isImmutableSampler;
6345 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
6347 const char* description,
6348 bool isPrimaryCmdBuf,
6349 DescriptorUpdateMethod updateMethod,
6350 vk::VkDescriptorType descriptorType,
6351 vk::VkShaderStageFlags exitingStages,
6352 vk::VkShaderStageFlags activeStages,
6353 ShaderInputInterface shaderInterface,
6354 vk::VkImageViewType viewType,
6356 : QuadrantRendederCase (testCtx, name, description,
6357 // \note 1D textures are not supported in ES
6358 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
6359 exitingStages, activeStages)
6360 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6361 , m_updateMethod (updateMethod)
6362 , m_descriptorType (descriptorType)
6363 , m_shaderInterface (shaderInterface)
6364 , m_viewType (viewType)
6365 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
6366 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
6367 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
6371 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
6375 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
6376 return "#extension GL_OES_texture_cube_map_array : require\n";
6381 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
6385 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
6386 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
6387 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
6388 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
6389 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
6391 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
6392 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
6393 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
6394 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
6396 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
6398 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
6399 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
6401 switch (m_shaderInterface)
6403 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6405 switch (m_descriptorType)
6407 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6408 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
6409 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
6410 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6411 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
6412 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6413 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
6414 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6415 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
6417 DE_FATAL("invalid descriptor");
6422 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6423 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
6424 switch (m_descriptorType)
6426 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6427 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS)
6428 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
6429 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
6430 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
6432 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler u_separateSamplerA;\n"
6433 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
6434 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
6435 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6436 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
6437 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
6438 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6439 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
6440 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
6441 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6442 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
6443 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
6445 DE_FATAL("invalid descriptor");
6449 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6450 switch (m_descriptorType)
6452 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6453 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
6454 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler[2];\n";
6455 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6456 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
6457 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6458 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
6459 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6460 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
6462 DE_FATAL("invalid descriptor");
6467 DE_FATAL("Impossible");
6472 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
6474 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
6475 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
6477 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
6479 return de::toString(fetchPos.x());
6481 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
6483 std::ostringstream buf;
6484 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
6489 std::ostringstream buf;
6490 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
6495 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
6497 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
6498 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
6500 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
6502 std::ostringstream buf;
6503 buf << "float(" << fetchPos.x() << ")";
6506 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
6508 std::ostringstream buf;
6509 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
6512 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
6514 std::ostringstream buf;
6515 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
6520 std::ostringstream buf;
6521 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
6526 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
6530 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
6531 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
6532 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
6533 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
6534 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
6535 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
6536 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
6538 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6539 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
6540 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("A")
6541 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6543 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6544 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
6545 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("B")
6546 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6549 switch (m_descriptorType)
6551 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6552 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6554 const std::string coodStr[4] =
6556 genSampleCoordStr(0),
6557 genSampleCoordStr(1),
6558 genSampleCoordStr(2),
6559 genSampleCoordStr(3),
6561 std::ostringstream buf;
6563 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
6565 buf << " if (quadrant_id == 0)\n"
6566 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
6567 << " else if (quadrant_id == 1)\n"
6568 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
6569 << " else if (quadrant_id == 2)\n"
6570 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
6572 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
6576 buf << " if (quadrant_id == 0)\n"
6577 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
6578 << " else if (quadrant_id == 1)\n"
6579 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
6580 << " else if (quadrant_id == 2)\n"
6581 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
6583 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
6589 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6591 const std::string coodStr[4] =
6593 genFetchCoordStr(0),
6594 genFetchCoordStr(1),
6595 genFetchCoordStr(2),
6596 genFetchCoordStr(3),
6598 std::ostringstream buf;
6600 buf << " if (quadrant_id == 0)\n"
6601 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
6602 << " else if (quadrant_id == 1)\n"
6603 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
6604 << " else if (quadrant_id == 2)\n"
6605 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
6607 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
6613 DE_FATAL("invalid descriptor");
6618 std::string ImageDescriptorCase::genNoAccessSource (void) const
6620 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6621 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6623 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6626 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
6628 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
6630 switch (m_descriptorType)
6632 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6633 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6634 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6636 DE_ASSERT(m_isPrimaryCmdBuf);
6637 return new ImageSampleComputeInstance(context, m_updateMethod, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
6640 return new ImageSampleRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
6642 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6643 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6644 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6646 DE_ASSERT(m_isPrimaryCmdBuf);
6647 return new ImageFetchComputeInstance(context, m_updateMethod, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
6650 return new ImageFetchRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
6653 DE_FATAL("Impossible");
6658 class TexelBufferInstanceBuffers
6661 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
6662 vk::VkDevice device,
6663 vk::Allocator& allocator,
6664 vk::VkDescriptorType descriptorType,
6665 int numTexelBuffers,
6666 bool hasViewOffset);
6669 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
6670 vk::VkDevice device,
6671 vk::Allocator& allocator,
6672 vk::VkDescriptorType descriptorType,
6673 de::MovePtr<vk::Allocation> *outAllocation);
6675 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
6676 vk::VkDevice device,
6677 const tcu::TextureFormat& textureFormat,
6679 vk::VkBuffer buffer);
6681 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
6683 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
6684 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
6687 static int getFetchPos (int fetchPosNdx);
6688 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
6690 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
6691 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
6692 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
6693 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
6694 inline const vk::VkBufferMemoryBarrier* getBufferInitBarriers (void) const { return m_bufferBarriers; }
6700 VIEW_OFFSET_VALUE = 256,
6701 VIEW_DATA_SIZE = 256, //!< size in bytes
6702 VIEW_WIDTH = 64, //!< size in pixels
6706 // some arbitrary points
6708 SAMPLE_POINT_1 = 51,
6709 SAMPLE_POINT_2 = 42,
6710 SAMPLE_POINT_3 = 25,
6713 const deUint32 m_numTexelBuffers;
6714 const tcu::TextureFormat m_imageFormat;
6715 const deUint32 m_viewOffset;
6717 de::ArrayBuffer<deUint8> m_sourceBufferA;
6718 de::ArrayBuffer<deUint8> m_sourceBufferB;
6719 const tcu::ConstPixelBufferAccess m_sourceViewA;
6720 const tcu::ConstPixelBufferAccess m_sourceViewB;
6722 de::MovePtr<vk::Allocation> m_bufferMemoryA;
6723 de::MovePtr<vk::Allocation> m_bufferMemoryB;
6724 const vk::Unique<vk::VkBuffer> m_bufferA;
6725 const vk::Unique<vk::VkBuffer> m_bufferB;
6726 const vk::Unique<vk::VkBufferView> m_bufferViewA;
6727 const vk::Unique<vk::VkBufferView> m_bufferViewB;
6728 vk::VkBufferMemoryBarrier m_bufferBarriers[2];
6731 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
6732 vk::VkDevice device,
6733 vk::Allocator& allocator,
6734 vk::VkDescriptorType descriptorType,
6735 int numTexelBuffers,
6737 : m_numTexelBuffers (numTexelBuffers)
6738 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
6739 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
6740 , m_sourceBufferA (BUFFER_SIZE)
6741 , m_sourceBufferB ((numTexelBuffers == 1)
6743 : ((size_t)BUFFER_SIZE))
6744 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
6745 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
6746 , m_bufferMemoryA (DE_NULL)
6747 , m_bufferMemoryB (DE_NULL)
6748 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
6749 , m_bufferB ((numTexelBuffers == 1)
6750 ? vk::Move<vk::VkBuffer>()
6751 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
6752 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
6753 , m_bufferViewB ((numTexelBuffers == 1)
6754 ? vk::Move<vk::VkBufferView>()
6755 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
6757 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
6758 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
6759 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
6761 // specify and upload
6763 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
6764 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
6766 if (numTexelBuffers == 2)
6768 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
6769 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
6772 m_bufferBarriers[0] = createBarrier(descriptorType, *m_bufferA);
6773 m_bufferBarriers[1] = createBarrier(descriptorType, *m_bufferB);
6776 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
6777 vk::VkDevice device,
6778 vk::Allocator& allocator,
6779 vk::VkDescriptorType descriptorType,
6780 de::MovePtr<vk::Allocation> *outAllocation)
6782 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
6783 const vk::VkBufferCreateInfo createInfo =
6785 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
6788 (vk::VkDeviceSize)BUFFER_SIZE, // size
6790 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
6791 0u, // queueFamilyCount
6792 DE_NULL, // pQueueFamilyIndices
6794 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
6795 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
6797 *outAllocation = allocation;
6801 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
6802 vk::VkDevice device,
6803 const tcu::TextureFormat& textureFormat,
6805 vk::VkBuffer buffer)
6807 const vk::VkBufferViewCreateInfo createInfo =
6809 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
6811 (vk::VkBufferViewCreateFlags)0,
6813 vk::mapTextureFormat(textureFormat), // format
6814 (vk::VkDeviceSize)offset, // offset
6815 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
6817 return vk::createBufferView(vki, device, &createInfo);
6820 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
6822 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
6823 const vk::VkBufferMemoryBarrier barrier =
6825 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
6827 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
6828 inputBit, // inputMask
6829 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
6830 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
6833 (vk::VkDeviceSize)BUFFER_SIZE // size
6838 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
6840 DE_ASSERT(access.getHeight() == 1);
6841 DE_ASSERT(access.getDepth() == 1);
6843 const deInt32 width = access.getWidth();
6845 for (int x = 0; x < width; ++x)
6847 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
6848 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
6849 const int blue = 16 * (x % 16); //!< 16-long triangle wave
6851 DE_ASSERT(de::inRange(red, 0, 255));
6852 DE_ASSERT(de::inRange(green, 0, 255));
6853 DE_ASSERT(de::inRange(blue, 0, 255));
6855 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
6859 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
6861 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
6862 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
6865 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
6867 static const int fetchPositions[4] =
6874 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
6877 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
6879 // source order is ABAB
6880 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
6881 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
6882 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
6884 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
6887 class TexelBufferRenderInstance : public SingleCmdRenderInstance
6890 TexelBufferRenderInstance (vkt::Context& context,
6891 DescriptorUpdateMethod updateMethod,
6892 bool isPrimaryCmdBuf,
6893 vk::VkDescriptorType descriptorType,
6894 vk::VkShaderStageFlags stageFlags,
6895 ShaderInputInterface shaderInterface,
6896 bool nonzeroViewOffset);
6899 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
6900 vk::VkDevice device,
6901 vk::VkDescriptorType descriptorType,
6902 ShaderInputInterface shaderInterface,
6903 vk::VkShaderStageFlags stageFlags,
6904 DescriptorUpdateMethod updateMethod);
6906 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
6907 vk::VkDevice device,
6908 vk::VkDescriptorSetLayout descriptorSetLayout);
6910 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
6911 vk::VkDevice device,
6912 vk::VkDescriptorType descriptorType,
6913 ShaderInputInterface shaderInterface);
6915 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
6916 DescriptorUpdateMethod updateMethod,
6917 vk::VkDevice device,
6918 vk::VkDescriptorType descriptorType,
6919 ShaderInputInterface shaderInterface,
6920 vk::VkDescriptorSetLayout layout,
6921 vk::VkDescriptorPool pool,
6922 vk::VkBufferView viewA,
6923 vk::VkBufferView viewB,
6924 vk::DescriptorSetUpdateBuilder& updateBuilder,
6925 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
6926 RawUpdateRegistry& updateRegistry,
6927 vk::VkPipelineLayout pipelineLayout = DE_NULL);
6929 static void writeDescriptorSet (const vk::DeviceInterface& vki,
6930 vk::VkDevice device,
6931 vk::VkDescriptorType descriptorType,
6932 ShaderInputInterface shaderInterface,
6933 vk::VkDescriptorSetLayout layout,
6934 vk::VkDescriptorPool pool,
6935 vk::VkBufferView viewA,
6936 vk::VkBufferView viewB,
6937 vk::VkDescriptorSet descriptorSet,
6938 vk::DescriptorSetUpdateBuilder& updateBuilder,
6939 DescriptorUpdateMethod updateMethod = DESCRIPTOR_UPDATE_METHOD_NORMAL);
6941 static void writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
6942 vk::VkDevice device,
6943 vk::VkDescriptorType descriptorType,
6944 ShaderInputInterface shaderInterface,
6945 vk::VkDescriptorSetLayout layout,
6946 vk::VkDescriptorPool pool,
6947 vk::VkBufferView viewA,
6948 vk::VkBufferView viewB,
6949 vk::VkDescriptorSet descriptorSet,
6950 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
6951 RawUpdateRegistry& updateRegistry,
6952 bool withPush = false,
6953 vk::VkPipelineLayout pipelineLayout = 0);
6955 void logTestPlan (void) const;
6956 vk::VkPipelineLayout getPipelineLayout (void) const;
6957 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
6958 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
6965 const DescriptorUpdateMethod m_updateMethod;
6966 const vk::VkDescriptorType m_descriptorType;
6967 const vk::VkShaderStageFlags m_stageFlags;
6968 const ShaderInputInterface m_shaderInterface;
6969 const bool m_nonzeroViewOffset;
6971 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
6972 RawUpdateRegistry m_updateRegistry;
6973 vk::DescriptorSetUpdateBuilder m_updateBuilder;
6974 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
6975 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
6976 const TexelBufferInstanceBuffers m_texelBuffers;
6977 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
6978 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
6981 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
6982 DescriptorUpdateMethod updateMethod,
6983 bool isPrimaryCmdBuf,
6984 vk::VkDescriptorType descriptorType,
6985 vk::VkShaderStageFlags stageFlags,
6986 ShaderInputInterface shaderInterface,
6987 bool nonzeroViewOffset)
6988 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
6989 , m_updateMethod (updateMethod)
6990 , m_descriptorType (descriptorType)
6991 , m_stageFlags (stageFlags)
6992 , m_shaderInterface (shaderInterface)
6993 , m_nonzeroViewOffset (nonzeroViewOffset)
6994 , m_updateTemplate ()
6995 , m_updateRegistry ()
6996 , m_updateBuilder ()
6997 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_updateMethod))
6998 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
6999 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
7000 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
7001 , 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))
7005 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
7006 vk::VkDevice device,
7007 vk::VkDescriptorType descriptorType,
7008 ShaderInputInterface shaderInterface,
7009 vk::VkShaderStageFlags stageFlags,
7010 DescriptorUpdateMethod updateMethod)
7012 vk::DescriptorSetLayoutBuilder builder;
7013 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
7015 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
7016 updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7018 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
7021 switch (shaderInterface)
7023 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7024 builder.addSingleBinding(descriptorType, stageFlags);
7027 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7028 builder.addSingleBinding(descriptorType, stageFlags);
7029 builder.addSingleBinding(descriptorType, stageFlags);
7032 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7033 builder.addArrayBinding(descriptorType, 2u, stageFlags);
7037 DE_FATAL("Impossible");
7040 return builder.build(vki, device, extraFlags);
7043 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
7044 vk::VkDevice device,
7045 vk::VkDescriptorSetLayout descriptorSetLayout)
7047 const vk::VkPipelineLayoutCreateInfo createInfo =
7049 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
7051 (vk::VkPipelineLayoutCreateFlags)0,
7052 1, // descriptorSetCount
7053 &descriptorSetLayout, // pSetLayouts
7054 0u, // pushConstantRangeCount
7055 DE_NULL, // pPushConstantRanges
7057 return vk::createPipelineLayout(vki, device, &createInfo);
7060 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
7061 vk::VkDevice device,
7062 vk::VkDescriptorType descriptorType,
7063 ShaderInputInterface shaderInterface)
7065 return vk::DescriptorPoolBuilder()
7066 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
7067 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
7070 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
7071 DescriptorUpdateMethod updateMethod,
7072 vk::VkDevice device,
7073 vk::VkDescriptorType descriptorType,
7074 ShaderInputInterface shaderInterface,
7075 vk::VkDescriptorSetLayout layout,
7076 vk::VkDescriptorPool pool,
7077 vk::VkBufferView viewA,
7078 vk::VkBufferView viewB,
7079 vk::DescriptorSetUpdateBuilder& updateBuilder,
7080 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
7081 RawUpdateRegistry& updateRegistry,
7082 vk::VkPipelineLayout pipelineLayout)
7084 const vk::VkDescriptorSetAllocateInfo allocInfo =
7086 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
7093 vk::Move<vk::VkDescriptorSet> descriptorSet;
7094 if (updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7096 descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
7100 descriptorSet = vk::Move<vk::VkDescriptorSet>();
7103 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
7105 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplate, updateRegistry);
7107 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7109 writeDescriptorSetWithTemplate(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateTemplate, updateRegistry, true, pipelineLayout);
7111 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7113 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder, updateMethod);
7115 else if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7117 writeDescriptorSet(vki, device, descriptorType, shaderInterface, layout, pool, viewA, viewB, *descriptorSet, updateBuilder);
7120 return descriptorSet;
7123 void TexelBufferRenderInstance::writeDescriptorSet (const vk::DeviceInterface& vki,
7124 vk::VkDevice device,
7125 vk::VkDescriptorType descriptorType,
7126 ShaderInputInterface shaderInterface,
7127 vk::VkDescriptorSetLayout layout,
7128 vk::VkDescriptorPool pool,
7129 vk::VkBufferView viewA,
7130 vk::VkBufferView viewB,
7131 vk::VkDescriptorSet descriptorSet,
7132 vk::DescriptorSetUpdateBuilder& updateBuilder,
7133 DescriptorUpdateMethod updateMethod)
7137 const vk::VkBufferView texelBufferInfos[2] =
7143 switch (shaderInterface)
7145 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7146 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
7149 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7150 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
7151 updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
7154 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7155 updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
7159 DE_FATAL("Impossible");
7162 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7164 updateBuilder.update(vki, device);
7168 void TexelBufferRenderInstance::writeDescriptorSetWithTemplate (const vk::DeviceInterface& vki,
7169 vk::VkDevice device,
7170 vk::VkDescriptorType descriptorType,
7171 ShaderInputInterface shaderInterface,
7172 vk::VkDescriptorSetLayout layout,
7173 vk::VkDescriptorPool pool,
7174 vk::VkBufferView viewA,
7175 vk::VkBufferView viewB,
7176 vk::VkDescriptorSet descriptorSet,
7177 vk::Move<vk::VkDescriptorUpdateTemplateKHR>& updateTemplate,
7178 RawUpdateRegistry& updateRegistry,
7180 vk::VkPipelineLayout pipelineLayout)
7183 const vk::VkBufferView texelBufferInfos[2] =
7188 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
7189 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
7191 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
7195 DE_NULL, // pUpdates
7196 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
7198 vk::VK_PIPELINE_BIND_POINT_GRAPHICS,
7202 updateRegistry.addWriteObject(texelBufferInfos[0]);
7203 updateRegistry.addWriteObject(texelBufferInfos[1]);
7205 switch (shaderInterface)
7207 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7208 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
7211 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7212 updateEntries.push_back(createTemplateBinding(0, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(0), 0));
7213 updateEntries.push_back(createTemplateBinding(1, 0, 1, descriptorType, updateRegistry.getWriteObjectOffset(1), 0));
7216 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7217 updateEntries.push_back(createTemplateBinding(0, 0, 2, descriptorType, updateRegistry.getWriteObjectOffset(0), sizeof(texelBufferInfos[0])));
7221 DE_FATAL("Impossible");
7224 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
7225 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
7227 updateTemplate = vk::createDescriptorUpdateTemplateKHR(vki, device, &templateCreateInfo);
7231 vki.updateDescriptorSetWithTemplateKHR(device, descriptorSet, *updateTemplate, updateRegistry.getRawPointer());
7235 void TexelBufferRenderInstance::logTestPlan (void) const
7237 std::ostringstream msg;
7239 msg << "Rendering 2x2 grid.\n"
7240 << "Single descriptor set. Descriptor set contains "
7241 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
7242 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
7243 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
7244 (const char*)DE_NULL)
7245 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
7246 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
7247 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
7249 if (m_stageFlags == 0u)
7251 msg << "Descriptors are not accessed in any shader stage.\n";
7255 msg << "Color in each cell is fetched using the descriptor(s):\n";
7257 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
7259 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
7261 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
7263 const int srcResourceNdx = (resultNdx % 2); // ABAB source
7264 msg << " from texelBuffer " << srcResourceNdx;
7270 msg << "Descriptors are accessed in {"
7271 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
7272 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
7273 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
7274 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
7275 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
7279 m_context.getTestContext().getLog()
7280 << tcu::TestLog::Message
7282 << tcu::TestLog::EndMessage;
7285 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
7287 return *m_pipelineLayout;
7290 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
7292 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7294 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
7296 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7298 m_vki.cmdPushDescriptorSetWithTemplateKHR(cmd, *m_updateTemplate, getPipelineLayout(), 0, (const void*)m_updateRegistry.getRawPointer());
7300 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7302 m_updateBuilder.updateWithPush(m_vki, cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0);
7305 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
7308 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
7310 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
7311 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
7312 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
7313 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
7314 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
7315 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
7316 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
7317 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
7319 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
7321 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
7322 return tcu::TestStatus::fail("Image verification failed");
7324 return tcu::TestStatus::pass("Pass");
7327 class TexelBufferComputeInstance : public vkt::TestInstance
7330 TexelBufferComputeInstance (vkt::Context& context,
7331 DescriptorUpdateMethod updateMethod,
7332 vk::VkDescriptorType descriptorType,
7333 ShaderInputInterface shaderInterface,
7334 bool nonzeroViewOffset);
7337 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
7338 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
7339 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout);
7340 void writeDescriptorSet (vk::VkDescriptorSet descriptorSet);
7341 void writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush = false, vk::VkPipelineLayout pipelineLayout = DE_NULL);
7343 tcu::TestStatus iterate (void);
7344 void logTestPlan (void) const;
7345 tcu::TestStatus testResourceAccess (void);
7347 const DescriptorUpdateMethod m_updateMethod;
7348 const vk::VkDescriptorType m_descriptorType;
7349 const ShaderInputInterface m_shaderInterface;
7350 const bool m_nonzeroViewOffset;
7352 const vk::DeviceInterface& m_vki;
7353 const vk::VkDevice m_device;
7354 const vk::VkQueue m_queue;
7355 const deUint32 m_queueFamilyIndex;
7356 vk::Allocator& m_allocator;
7357 vk::Move<vk::VkDescriptorUpdateTemplateKHR> m_updateTemplate;
7359 const ComputeInstanceResultBuffer m_result;
7360 const TexelBufferInstanceBuffers m_texelBuffers;
7362 RawUpdateRegistry m_updateRegistry;
7363 vk::DescriptorSetUpdateBuilder m_updateBuilder;
7366 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
7367 DescriptorUpdateMethod updateMethod,
7368 vk::VkDescriptorType descriptorType,
7369 ShaderInputInterface shaderInterface,
7370 bool nonzeroViewOffset)
7371 : vkt::TestInstance (context)
7372 , m_updateMethod (updateMethod)
7373 , m_descriptorType (descriptorType)
7374 , m_shaderInterface (shaderInterface)
7375 , m_nonzeroViewOffset (nonzeroViewOffset)
7376 , m_vki (context.getDeviceInterface())
7377 , m_device (context.getDevice())
7378 , m_queue (context.getUniversalQueue())
7379 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
7380 , m_allocator (context.getDefaultAllocator())
7381 , m_updateTemplate ()
7382 , m_result (m_vki, m_device, m_allocator)
7383 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
7384 , m_updateRegistry ()
7385 , m_updateBuilder ()
7389 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
7391 vk::DescriptorSetLayoutBuilder builder;
7392 vk::VkDescriptorSetLayoutCreateFlags extraFlags = 0;
7394 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE ||
7395 m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7397 extraFlags |= vk::VK_DESCRIPTOR_SET_LAYOUT_CREATE_PUSH_DESCRIPTOR_BIT_KHR;
7400 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7402 switch (m_shaderInterface)
7404 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7405 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7408 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7409 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7410 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7413 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7414 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
7418 DE_FATAL("Impossible");
7421 return builder.build(m_vki, m_device, extraFlags);
7424 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
7426 return vk::DescriptorPoolBuilder()
7427 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
7428 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
7429 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
7432 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout)
7434 const vk::VkDescriptorSetAllocateInfo allocInfo =
7436 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
7443 vk::Move<vk::VkDescriptorSet> descriptorSet;
7444 if (m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH && m_updateMethod != DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7446 descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
7450 descriptorSet = vk::Move<vk::VkDescriptorSet>();
7454 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE)
7456 writeDescriptorSetWithTemplate(*descriptorSet, layout);
7458 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7460 writeDescriptorSet(*descriptorSet);
7463 return descriptorSet;
7466 void TexelBufferComputeInstance::writeDescriptorSet (vk::VkDescriptorSet descriptorSet)
7468 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
7469 const vk::VkBufferView texelBufferInfos[2] =
7471 m_texelBuffers.getBufferViewA(),
7472 m_texelBuffers.getBufferViewB(),
7476 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
7479 switch (m_shaderInterface)
7481 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7482 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
7485 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7486 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
7487 m_updateBuilder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
7490 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7491 m_updateBuilder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
7495 DE_FATAL("Impossible");
7498 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_NORMAL)
7500 m_updateBuilder.update(m_vki, m_device);
7504 void TexelBufferComputeInstance::writeDescriptorSetWithTemplate (vk::VkDescriptorSet descriptorSet, vk::VkDescriptorSetLayout layout, bool withPush, vk::VkPipelineLayout pipelineLayout)
7506 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
7507 const vk::VkBufferView texelBufferInfos[2] =
7509 m_texelBuffers.getBufferViewA(),
7510 m_texelBuffers.getBufferViewB(),
7512 std::vector<vk::VkDescriptorUpdateTemplateEntryKHR> updateEntries;
7513 vk::VkDescriptorUpdateTemplateCreateInfoKHR templateCreateInfo =
7515 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_UPDATE_TEMPLATE_CREATE_INFO_KHR,
7519 DE_NULL, // pUpdates
7520 withPush ? vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_PUSH_DESCRIPTORS_KHR : vk::VK_DESCRIPTOR_UPDATE_TEMPLATE_TYPE_DESCRIPTOR_SET_KHR,
7522 vk::VK_PIPELINE_BIND_POINT_COMPUTE,
7526 m_updateRegistry.addWriteObject(resultInfo);
7527 m_updateRegistry.addWriteObject(texelBufferInfos[0]);
7528 m_updateRegistry.addWriteObject(texelBufferInfos[1]);
7531 updateEntries.push_back(createTemplateBinding(0, 0, 1, vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, m_updateRegistry.getWriteObjectOffset(0), 0));
7534 switch (m_shaderInterface)
7536 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7537 updateEntries.push_back(createTemplateBinding(1, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
7540 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7541 updateEntries.push_back(createTemplateBinding(1, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), 0));
7542 updateEntries.push_back(createTemplateBinding(2, 0, 1, m_descriptorType, m_updateRegistry.getWriteObjectOffset(2), 0));
7545 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7546 updateEntries.push_back(createTemplateBinding(1, 0, 2, m_descriptorType, m_updateRegistry.getWriteObjectOffset(1), sizeof(texelBufferInfos[0])));
7550 DE_FATAL("Impossible");
7553 templateCreateInfo.pDescriptorUpdateEntries = &updateEntries[0];
7554 templateCreateInfo.descriptorUpdateEntryCount = (deUint32)updateEntries.size();
7556 m_updateTemplate = vk::createDescriptorUpdateTemplateKHR(m_vki, m_device, &templateCreateInfo);
7560 m_vki.updateDescriptorSetWithTemplateKHR(m_device, descriptorSet, *m_updateTemplate, m_updateRegistry.getRawPointer());
7564 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
7567 return testResourceAccess();
7570 void TexelBufferComputeInstance::logTestPlan (void) const
7572 std::ostringstream msg;
7574 msg << "Fetching 4 values from image in compute shader.\n"
7575 << "Single descriptor set. Descriptor set contains "
7576 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
7577 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
7578 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
7579 (const char*)DE_NULL)
7580 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
7581 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
7582 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
7584 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
7586 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
7588 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
7590 const int srcResourceNdx = (resultNdx % 2); // ABAB source
7591 msg << " from texelBuffer " << srcResourceNdx;
7597 m_context.getTestContext().getLog()
7598 << tcu::TestLog::Message
7600 << tcu::TestLog::EndMessage;
7603 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
7605 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
7606 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
7607 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
7608 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
7610 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
7611 const int numDescriptorSets = (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE || m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH) ? 0 : DE_LENGTH_OF_ARRAY(descriptorSets);
7612 const deUint32* const dynamicOffsets = DE_NULL;
7613 const int numDynamicOffsets = 0;
7614 const vk::VkBufferMemoryBarrier* const preBarriers = m_texelBuffers.getBufferInitBarriers();
7615 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
7616 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
7617 const int numPostBarriers = 1;
7619 const ComputeCommand compute (m_vki,
7621 pipeline.getPipeline(),
7622 pipeline.getPipelineLayout(),
7623 tcu::UVec3(4, 1, 1),
7624 numDescriptorSets, descriptorSets,
7625 numDynamicOffsets, dynamicOffsets,
7626 numPreBarriers, preBarriers,
7627 numPostBarriers, postBarriers);
7629 tcu::Vec4 results[4];
7630 bool anyResultSet = false;
7631 bool allResultsOk = true;
7633 if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7635 writeDescriptorSetWithTemplate(DE_NULL, *descriptorSetLayout, true, pipeline.getPipelineLayout());
7636 compute.submitAndWait(m_queueFamilyIndex, m_queue, *m_updateTemplate, (const void*) m_updateRegistry.getRawPointer());
7638 else if (m_updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH)
7640 writeDescriptorSet(DE_NULL);
7641 compute.submitAndWait(m_queueFamilyIndex, m_queue, m_updateBuilder);
7645 compute.submitAndWait(m_queueFamilyIndex, m_queue);
7647 m_result.readResultContentsTo(&results);
7650 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
7652 const tcu::Vec4 result = results[resultNdx];
7653 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
7654 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
7656 if (result != tcu::Vec4(-1.0f))
7657 anyResultSet = true;
7659 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
7661 allResultsOk = false;
7663 m_context.getTestContext().getLog()
7664 << tcu::TestLog::Message
7665 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
7666 << tcu::TestLog::EndMessage;
7670 // read back and verify
7672 return tcu::TestStatus::pass("Pass");
7673 else if (anyResultSet)
7674 return tcu::TestStatus::fail("Invalid result values");
7677 m_context.getTestContext().getLog()
7678 << tcu::TestLog::Message
7679 << "Result buffer was not written to."
7680 << tcu::TestLog::EndMessage;
7681 return tcu::TestStatus::fail("Result buffer was not written to");
7685 class TexelBufferDescriptorCase : public QuadrantRendederCase
7690 FLAG_VIEW_OFFSET = (1u << 1u),
7692 // enum continues where resource flags ends
7693 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
7695 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
7696 DescriptorUpdateMethod updateMethod,
7698 const char* description,
7699 bool isPrimaryCmdBuf,
7700 vk::VkDescriptorType descriptorType,
7701 vk::VkShaderStageFlags exitingStages,
7702 vk::VkShaderStageFlags activeStages,
7703 ShaderInputInterface shaderInterface,
7707 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
7708 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
7709 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
7710 std::string genNoAccessSource (void) const;
7712 vkt::TestInstance* createInstance (vkt::Context& context) const;
7714 const DescriptorUpdateMethod m_updateMethod;
7715 const bool m_isPrimaryCmdBuf;
7716 const vk::VkDescriptorType m_descriptorType;
7717 const ShaderInputInterface m_shaderInterface;
7718 const bool m_nonzeroViewOffset;
7721 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
7722 DescriptorUpdateMethod updateMethod,
7724 const char* description,
7725 bool isPrimaryCmdBuf,
7726 vk::VkDescriptorType descriptorType,
7727 vk::VkShaderStageFlags exitingStages,
7728 vk::VkShaderStageFlags activeStages,
7729 ShaderInputInterface shaderInterface,
7731 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
7732 , m_updateMethod (updateMethod)
7733 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
7734 , m_descriptorType (descriptorType)
7735 , m_shaderInterface (shaderInterface)
7736 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
7740 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
7743 return "#extension GL_EXT_texture_buffer : require\n";
7746 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
7750 const bool isUniform = isUniformDescriptorType(m_descriptorType);
7751 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
7752 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
7754 switch (m_shaderInterface)
7756 case SHADER_INPUT_SINGLE_DESCRIPTOR:
7757 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
7759 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
7760 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
7761 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
7763 case SHADER_INPUT_DESCRIPTOR_ARRAY:
7764 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
7767 DE_FATAL("Impossible");
7772 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
7776 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
7777 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
7778 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
7780 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
7781 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
7782 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
7784 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
7785 std::ostringstream buf;
7787 buf << " if (quadrant_id == 0)\n"
7788 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
7789 << " else if (quadrant_id == 1)\n"
7790 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
7791 << " else if (quadrant_id == 2)\n"
7792 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
7794 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
7799 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
7801 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
7802 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
7804 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
7807 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
7809 verifyDriverSupport(context.getDeviceFeatures(), context.getDeviceExtensions(), m_updateMethod, m_descriptorType, m_activeStages);
7811 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
7813 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
7814 return new TexelBufferComputeInstance(context, m_updateMethod, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
7817 return new TexelBufferRenderInstance(context, m_updateMethod, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
7820 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
7821 bool isPrimaryCmdBuf,
7822 DescriptorUpdateMethod updateMethod,
7823 vk::VkDescriptorType descriptorType,
7824 vk::VkShaderStageFlags exitingStages,
7825 vk::VkShaderStageFlags activeStages,
7826 ShaderInputInterface dimension,
7827 deUint32 resourceFlags)
7831 vk::VkImageViewType viewType;
7833 const char* description;
7837 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
7838 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7839 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7841 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
7842 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7843 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7845 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
7846 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7847 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7849 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
7850 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7851 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7853 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
7854 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7855 // no 3d array textures
7857 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
7858 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7859 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7861 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
7862 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
7863 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
7866 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
7869 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
7871 // SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS only supported in VK_DESCRIPTOR_TYPE_SAMPLER on graphics shaders for now
7872 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS &&
7873 (descriptorType != vk::VK_DESCRIPTOR_TYPE_SAMPLER || activeStages == vk::VK_SHADER_STAGE_COMPUTE_BIT))
7876 group->addChild(new ImageDescriptorCase(group->getTestContext(),
7877 s_imageTypes[ndx].name,
7878 s_imageTypes[ndx].description,
7885 s_imageTypes[ndx].viewType,
7886 s_imageTypes[ndx].flags | resourceFlags));
7890 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
7891 bool isPrimaryCmdBuf,
7892 DescriptorUpdateMethod updateMethod,
7893 vk::VkDescriptorType descriptorType,
7894 vk::VkShaderStageFlags exitingStages,
7895 vk::VkShaderStageFlags activeStages,
7896 ShaderInputInterface dimension,
7897 deUint32 resourceFlags)
7899 DE_ASSERT(resourceFlags == 0);
7900 DE_UNREF(resourceFlags);
7905 const char* description;
7907 } s_texelBufferTypes[] =
7909 { "offset_zero", "View offset is zero", 0u },
7910 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
7913 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
7915 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
7918 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
7920 s_texelBufferTypes[ndx].name,
7921 s_texelBufferTypes[ndx].description,
7927 s_texelBufferTypes[ndx].flags));
7931 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
7932 bool isPrimaryCmdBuf,
7933 DescriptorUpdateMethod updateMethod,
7934 vk::VkDescriptorType descriptorType,
7935 vk::VkShaderStageFlags exitingStages,
7936 vk::VkShaderStageFlags activeStages,
7937 ShaderInputInterface dimension,
7938 deUint32 resourceFlags)
7940 DE_ASSERT(resourceFlags == 0u);
7941 DE_UNREF(resourceFlags);
7946 const char* description;
7947 bool isForDynamicCases;
7951 { "offset_view_zero", "View offset is zero", false, 0u },
7952 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
7954 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
7955 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
7956 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
7957 { "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 },
7960 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
7964 if (updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH || updateMethod == DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE)
7966 // Can't support push descriptor sets with dynamic UBOs or SSBOs
7971 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
7973 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
7976 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
7977 group->addChild(new BufferDescriptorCase(group->getTestContext(),
7979 s_bufferTypes[ndx].name,
7980 s_bufferTypes[ndx].description,
7986 s_bufferTypes[ndx].flags));
7992 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
7996 const bool isPrimary;
7998 const char* description;
8001 { true, "primary_cmd_buf", "Bind in primary command buffer" },
8002 { false, "secondary_cmd_buf", "Bind in secondary command buffer" },
8006 const DescriptorUpdateMethod method;
8008 const char* description;
8009 } s_updateMethods[] =
8011 { DESCRIPTOR_UPDATE_METHOD_NORMAL, "", "Use regular descriptor updates" },
8012 { DESCRIPTOR_UPDATE_METHOD_WITH_TEMPLATE, "with_template", "Use descriptor update templates" },
8013 { DESCRIPTOR_UPDATE_METHOD_WITH_PUSH, "with_push", "Use push descriptor updates" },
8014 { DESCRIPTOR_UPDATE_METHOD_WITH_PUSH_TEMPLATE, "with_push_template", "Use push descriptor update templates" },
8018 const vk::VkDescriptorType descriptorType;
8020 const char* description;
8022 } s_descriptorTypes[] =
8024 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
8025 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
8026 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
8027 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
8028 // \note No way to access SAMPLED_IMAGE without a sampler
8029 //{ vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
8030 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
8031 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
8032 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
8033 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
8034 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
8035 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
8036 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
8041 const char* description;
8042 vk::VkShaderStageFlags existingStages; //!< stages that exists
8043 vk::VkShaderStageFlags activeStages; //!< stages that access resource
8044 bool supportsSecondaryCmdBufs;
8045 } s_shaderStages[] =
8049 "No accessing stages",
8050 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8057 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8058 vk::VK_SHADER_STAGE_VERTEX_BIT,
8063 "Tessellation control stage",
8064 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,
8065 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
8070 "Tessellation evaluation stage",
8071 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,
8072 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
8078 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8079 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
8085 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8086 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8092 vk::VK_SHADER_STAGE_COMPUTE_BIT,
8093 vk::VK_SHADER_STAGE_COMPUTE_BIT,
8098 "Vertex and fragment stages",
8099 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8100 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
8106 ShaderInputInterface dimension;
8108 const char* description;
8109 } s_variableDimensions[] =
8111 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
8112 { SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, "multiple_contiguous_descriptors", "Multiple descriptors" },
8113 { SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, "multiple_discontiguous_descriptors", "Multiple descriptors" },
8114 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
8117 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
8119 // .primary_cmd_buf...
8120 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
8122 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
8124 for (int updateMethodNdx = 0; updateMethodNdx < DE_LENGTH_OF_ARRAY(s_updateMethods); ++updateMethodNdx)
8126 de::MovePtr<tcu::TestCaseGroup> updateMethodGroup(new tcu::TestCaseGroup(testCtx, s_updateMethods[updateMethodNdx].name, s_updateMethods[updateMethodNdx].description));
8128 // .sampler, .combined_image_sampler, other resource types ...
8129 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
8131 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
8133 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
8135 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
8137 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
8139 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
8141 de::MovePtr<tcu::TestCaseGroup> dimensionGroup(new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
8142 void (*createTestsFunc)(tcu::TestCaseGroup* group,
8143 bool isPrimaryCmdBuf,
8144 DescriptorUpdateMethod updateMethod,
8145 vk::VkDescriptorType descriptorType,
8146 vk::VkShaderStageFlags existingStages,
8147 vk::VkShaderStageFlags activeStages,
8148 ShaderInputInterface dimension,
8149 deUint32 resourceFlags);
8151 switch (s_descriptorTypes[descriptorNdx].descriptorType)
8153 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
8154 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
8155 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
8156 createTestsFunc = createShaderAccessImageTests;
8159 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
8160 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
8161 createTestsFunc = createShaderAccessTexelBufferTests;
8164 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
8165 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
8166 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
8167 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
8168 createTestsFunc = createShaderAccessBufferTests;
8172 createTestsFunc = DE_NULL;
8173 DE_FATAL("Impossible");
8176 if (createTestsFunc)
8178 createTestsFunc(dimensionGroup.get(),
8179 s_bindTypes[bindTypeNdx].isPrimary,
8180 s_updateMethods[updateMethodNdx].method,
8181 s_descriptorTypes[descriptorNdx].descriptorType,
8182 s_shaderStages[stageNdx].existingStages,
8183 s_shaderStages[stageNdx].activeStages,
8184 s_variableDimensions[dimensionNdx].dimension,
8185 s_descriptorTypes[descriptorNdx].flags);
8188 DE_FATAL("Impossible");
8190 stageGroup->addChild(dimensionGroup.release());
8193 typeGroup->addChild(stageGroup.release());
8197 if (s_updateMethods[updateMethodNdx].method != DESCRIPTOR_UPDATE_METHOD_NORMAL)
8199 updateMethodGroup->addChild(typeGroup.release());
8203 bindGroup->addChild(typeGroup.release());
8207 if (s_updateMethods[updateMethodNdx].method != DESCRIPTOR_UPDATE_METHOD_NORMAL)
8209 bindGroup->addChild(updateMethodGroup.release());
8213 group->addChild(bindGroup.release());
8216 return group.release();