1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and/or associated documentation files (the
9 * "Materials"), to deal in the Materials without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Materials, and to
12 * permit persons to whom the Materials are furnished to do so, subject to
13 * the following conditions:
15 * The above copyright notice(s) and this permission notice shall be
16 * included in all copies or substantial portions of the Materials.
18 * The Materials are Confidential Information as defined by the
19 * Khronos Membership Agreement until designated non-confidential by
20 * Khronos, at which point this condition clause shall be removed.
22 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
25 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
26 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
32 * \brief Binding shader access tests
33 *//*--------------------------------------------------------------------*/
35 #include "vktBindingShaderAccessTests.hpp"
37 #include "vktTestCase.hpp"
41 #include "vkRefUtil.hpp"
42 #include "vkPlatform.hpp"
43 #include "vkPrograms.hpp"
44 #include "vkMemUtil.hpp"
45 #include "vkBuilderUtil.hpp"
46 #include "vkQueryUtil.hpp"
48 #include "tcuVector.hpp"
49 #include "tcuVectorUtil.hpp"
50 #include "tcuTexture.hpp"
51 #include "tcuTextureUtil.hpp"
52 #include "tcuResultCollector.hpp"
53 #include "tcuTestLog.hpp"
54 #include "tcuRGBA.hpp"
55 #include "tcuSurface.hpp"
56 #include "tcuImageCompare.hpp"
58 #include "deUniquePtr.hpp"
59 #include "deSharedPtr.hpp"
60 #include "deStringUtil.hpp"
61 #include "deArrayUtil.hpp"
67 namespace BindingModel
74 RESOURCE_FLAG_IMMUTABLE_SAMPLER = (1u << 0u),
76 RESOURCE_FLAG_LAST = (1u << 1u)
79 static const char* const s_quadrantGenVertexPosSource = " highp int quadPhase = gl_VertexID % 6;\n"
80 " highp int quadXcoord = int(quadPhase == 1 || quadPhase == 4 || quadPhase == 5);\n"
81 " highp int quadYcoord = int(quadPhase == 2 || quadPhase == 3 || quadPhase == 5);\n"
82 " highp int quadOriginX = (gl_VertexID / 6) % 2;\n"
83 " highp int quadOriginY = (gl_VertexID / 6) / 2;\n"
84 " quadrant_id = gl_VertexID / 6;\n"
85 " result_position = vec4(float(quadOriginX + quadXcoord - 1), float(quadOriginY + quadYcoord - 1), 0.0, 1.0);\n";
87 bool isUniformDescriptorType (vk::VkDescriptorType type)
89 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
90 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
91 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
94 bool isDynamicDescriptorType (vk::VkDescriptorType type)
96 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || type == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
99 vk::VkFormat mapToVkTextureFormat (const tcu::TextureFormat& format)
101 if (format == tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8))
102 return vk::VK_FORMAT_R8G8B8A8_UNORM;
104 DE_FATAL("Not implemented");
105 return vk::VK_FORMAT_UNDEFINED;
108 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type)
112 case vk::VK_IMAGE_VIEW_TYPE_1D:
113 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return vk::VK_IMAGE_TYPE_1D;
114 case vk::VK_IMAGE_VIEW_TYPE_2D:
115 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return vk::VK_IMAGE_TYPE_2D;
116 case vk::VK_IMAGE_VIEW_TYPE_3D: return vk::VK_IMAGE_TYPE_3D;
117 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
118 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return vk::VK_IMAGE_TYPE_2D;
121 DE_FATAL("Impossible");
122 return (vk::VkImageType)0;
126 vk::VkTexFilter mapMagFilterToVkTexFilter (tcu::Sampler::FilterMode mode)
130 case tcu::Sampler::NEAREST: return vk::VK_TEX_FILTER_NEAREST;
131 case tcu::Sampler::LINEAR: return vk::VK_TEX_FILTER_LINEAR;
134 DE_FATAL("Illegal filter mode");
135 return (vk::VkTexFilter)0;
139 vk::VkTexFilter mapMinFilterToVkTexFilter (tcu::Sampler::FilterMode mode)
143 case tcu::Sampler::NEAREST: return vk::VK_TEX_FILTER_NEAREST;
144 case tcu::Sampler::LINEAR: return vk::VK_TEX_FILTER_LINEAR;
145 case tcu::Sampler::NEAREST_MIPMAP_NEAREST: return vk::VK_TEX_FILTER_NEAREST;
146 case tcu::Sampler::LINEAR_MIPMAP_NEAREST: return vk::VK_TEX_FILTER_LINEAR;
147 case tcu::Sampler::NEAREST_MIPMAP_LINEAR: return vk::VK_TEX_FILTER_NEAREST;
148 case tcu::Sampler::LINEAR_MIPMAP_LINEAR: return vk::VK_TEX_FILTER_LINEAR;
151 DE_FATAL("Illegal filter mode");
152 return (vk::VkTexFilter)0;
156 vk::VkTexMipmapMode mapMinFilterToVkTexMipmapMode (tcu::Sampler::FilterMode mode)
160 case tcu::Sampler::NEAREST: return vk::VK_TEX_MIPMAP_MODE_BASE;
161 case tcu::Sampler::LINEAR: return vk::VK_TEX_MIPMAP_MODE_BASE;
162 case tcu::Sampler::NEAREST_MIPMAP_NEAREST: return vk::VK_TEX_MIPMAP_MODE_NEAREST;
163 case tcu::Sampler::LINEAR_MIPMAP_NEAREST: return vk::VK_TEX_MIPMAP_MODE_NEAREST;
164 case tcu::Sampler::NEAREST_MIPMAP_LINEAR: return vk::VK_TEX_MIPMAP_MODE_LINEAR;
165 case tcu::Sampler::LINEAR_MIPMAP_LINEAR: return vk::VK_TEX_MIPMAP_MODE_LINEAR;
168 DE_FATAL("Illegal filter mode");
169 return (vk::VkTexMipmapMode)0;
173 vk::VkTexAddress mapToVkTexAddress (tcu::Sampler::WrapMode mode)
177 case tcu::Sampler::CLAMP_TO_EDGE: return vk::VK_TEX_ADDRESS_CLAMP;
178 case tcu::Sampler::CLAMP_TO_BORDER: return vk::VK_TEX_ADDRESS_CLAMP_BORDER;
179 case tcu::Sampler::REPEAT_GL: return vk::VK_TEX_ADDRESS_WRAP;
180 case tcu::Sampler::MIRRORED_REPEAT_GL: return vk::VK_TEX_ADDRESS_MIRROR;
183 DE_FATAL("Illegal wrap mode");
184 return (vk::VkTexAddress)0;
188 vk::VkCompareOp mapToVkCompareOp (tcu::Sampler::CompareMode mode)
192 case tcu::Sampler::COMPAREMODE_LESS: return vk::VK_COMPARE_OP_LESS;
193 case tcu::Sampler::COMPAREMODE_LESS_OR_EQUAL: return vk::VK_COMPARE_OP_LESS_EQUAL;
194 case tcu::Sampler::COMPAREMODE_GREATER: return vk::VK_COMPARE_OP_GREATER;
195 case tcu::Sampler::COMPAREMODE_GREATER_OR_EQUAL: return vk::VK_COMPARE_OP_GREATER_EQUAL;
196 case tcu::Sampler::COMPAREMODE_EQUAL: return vk::VK_COMPARE_OP_EQUAL;
197 case tcu::Sampler::COMPAREMODE_NOT_EQUAL: return vk::VK_COMPARE_OP_NOT_EQUAL;
198 case tcu::Sampler::COMPAREMODE_ALWAYS: return vk::VK_COMPARE_OP_ALWAYS;
199 case tcu::Sampler::COMPAREMODE_NEVER: return vk::VK_COMPARE_OP_NEVER;
202 DE_FATAL("Illegal compare mode");
203 return (vk::VkCompareOp)0;
207 deUint32 getTextureLevelPyramidDataSize (const tcu::TextureLevelPyramid& srcImage)
209 deUint32 dataSize = 0;
210 for (int level = 0; level < srcImage.getNumLevels(); ++level)
212 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
215 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
217 dataSize += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
222 void writeTextureLevelPyramidData (void* dst, deUint32 dstLen, const tcu::TextureLevelPyramid& srcImage, vk::VkImageViewType viewType, std::vector<vk::VkBufferImageCopy>* copySlices)
224 // \note cube is copied face-by-face
225 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (srcImage.getLevel(0).getHeight()) :
226 (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
227 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
228 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
230 deUint32 levelOffset = 0;
232 DE_ASSERT(arraySize != 0);
234 for (int level = 0; level < srcImage.getNumLevels(); ++level)
236 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
237 const tcu::PixelBufferAccess dstAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), (deUint8*)dst + levelOffset);
238 const deUint32 dataSize = srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
239 const deUint32 sliceDataSize = dataSize / arraySize;
240 const deInt32 sliceHeight = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (srcAccess.getHeight());
241 const deInt32 sliceDepth = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (srcAccess.getDepth()) : (1);
242 const tcu::IVec3 sliceSize (srcAccess.getWidth(), sliceHeight, sliceDepth);
245 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
247 for (int sliceNdx = 0; sliceNdx < (int)arraySize; ++sliceNdx)
249 const vk::VkBufferImageCopy copySlice =
251 (vk::VkDeviceSize)levelOffset + sliceNdx * sliceDataSize, // bufferOffset
252 (deUint32)sliceSize.x(), // bufferRowLength
253 (deUint32)sliceSize.y(), // bufferImageHeight
255 vk::VK_IMAGE_ASPECT_COLOR, // aspect
256 (deUint32)level, // mipLevel
257 (deUint32)sliceNdx // arraySlice
258 }, // imageSubresource
270 copySlices->push_back(copySlice);
273 DE_ASSERT(arraySize * sliceDataSize == dataSize);
275 tcu::copy(dstAccess, srcAccess);
276 levelOffset += dataSize;
279 DE_ASSERT(dstLen == levelOffset);
283 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement)
285 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer);
286 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
288 VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
292 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkImage image, vk::MemoryRequirement requirement)
294 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vki, device, image);
295 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
297 VK_CHECK(vki.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
301 vk::VkDescriptorInfo createDescriptorInfo (vk::VkBufferView bufferView)
303 const vk::VkDescriptorInfo resultInfo =
305 bufferView, // bufferView
309 (vk::VkImageLayout)0, // imageLayout
314 vk::VkDescriptorInfo createDescriptorInfo (vk::VkSampler sampler)
316 const vk::VkDescriptorInfo resultInfo =
322 (vk::VkImageLayout)0, // imageLayout
327 vk::VkDescriptorInfo createDescriptorInfo (vk::VkImageView imageView, vk::VkImageLayout layout)
329 const vk::VkDescriptorInfo resultInfo =
333 imageView, // imageView
335 layout, // imageLayout
340 vk::VkDescriptorInfo createDescriptorInfo (vk::VkSampler sampler, vk::VkImageView imageView, vk::VkImageLayout layout)
342 const vk::VkDescriptorInfo resultInfo =
346 imageView, // imageView
348 layout, // imageLayout
353 vk::VkClearValue createClearValueColor (const tcu::Vec4& color)
355 vk::VkClearValue retVal;
357 retVal.color.f32[0] = color.x();
358 retVal.color.f32[1] = color.y();
359 retVal.color.f32[2] = color.z();
360 retVal.color.f32[3] = color.w();
365 void drawQuadrantReferenceResult (const tcu::PixelBufferAccess& dst, const tcu::Vec4& c1, const tcu::Vec4& c2, const tcu::Vec4& c3, const tcu::Vec4& c4)
367 tcu::clear(tcu::getSubregion(dst, 0, 0, dst.getWidth() / 2, dst.getHeight() / 2), c1);
368 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, 0, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() / 2), c2);
369 tcu::clear(tcu::getSubregion(dst, 0, dst.getHeight() / 2, dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c3);
370 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, dst.getHeight() / 2, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c4);
373 class SingleTargetRenderInstance : public vkt::TestInstance
376 SingleTargetRenderInstance (Context& context,
377 const tcu::UVec2& size);
380 static vk::Move<vk::VkImage> createColorAttachment (const vk::DeviceInterface& vki,
382 vk::Allocator& allocator,
383 const tcu::TextureFormat& format,
384 const tcu::UVec2& size,
385 de::MovePtr<vk::Allocation>* outAllocation);
387 static vk::Move<vk::VkAttachmentView> createColorAttachmentView (const vk::DeviceInterface& vki,
389 const tcu::TextureFormat& format,
392 static vk::Move<vk::VkRenderPass> createRenderPass (const vk::DeviceInterface& vki,
394 const tcu::TextureFormat& format);
396 static vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vki,
398 vk::VkRenderPass renderpass,
399 vk::VkAttachmentView colorAttachmentView,
400 const tcu::UVec2& size);
402 static vk::Move<vk::VkCmdPool> createCommandPool (const vk::DeviceInterface& vki,
404 deUint32 queueFamilyIndex);
406 virtual void logTestPlan (void) const = 0;
407 virtual void renderToTarget (void) = 0;
408 virtual tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const = 0;
410 void readRenderTarget (tcu::TextureLevel& dst);
411 tcu::TestStatus iterate (void);
414 const tcu::TextureFormat m_targetFormat;
415 const tcu::UVec2 m_targetSize;
417 const vk::DeviceInterface& m_vki;
418 const vk::VkDevice m_device;
419 const vk::VkQueue m_queue;
420 const deUint32 m_queueFamilyIndex;
421 vk::Allocator& m_allocator;
422 de::MovePtr<vk::Allocation> m_colorAttachmentMemory;
423 const vk::Unique<vk::VkImage> m_colorAttachmentImage;
424 const vk::Unique<vk::VkAttachmentView> m_colorAttachmentView;
425 const vk::Unique<vk::VkRenderPass> m_renderPass;
426 const vk::Unique<vk::VkFramebuffer> m_framebuffer;
427 const vk::Unique<vk::VkCmdPool> m_cmdPool;
429 bool m_firstIteration;
432 SingleTargetRenderInstance::SingleTargetRenderInstance (Context& context,
433 const tcu::UVec2& size)
434 : vkt::TestInstance (context)
435 , m_targetFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
436 , m_targetSize (size)
437 , m_vki (context.getDeviceInterface())
438 , m_device (context.getDevice())
439 , m_queue (context.getUniversalQueue())
440 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
441 , m_allocator (context.getDefaultAllocator())
442 , m_colorAttachmentMemory (DE_NULL)
443 , m_colorAttachmentImage (createColorAttachment(m_vki, m_device, m_allocator, m_targetFormat, m_targetSize, &m_colorAttachmentMemory))
444 , m_colorAttachmentView (createColorAttachmentView(m_vki, m_device, m_targetFormat, *m_colorAttachmentImage))
445 , m_renderPass (createRenderPass(m_vki, m_device, m_targetFormat))
446 , m_framebuffer (createFramebuffer(m_vki, m_device, *m_renderPass, *m_colorAttachmentView, m_targetSize))
447 , m_cmdPool (createCommandPool(m_vki, m_device, context.getUniversalQueueFamilyIndex()))
448 , m_firstIteration (true)
452 vk::Move<vk::VkImage> SingleTargetRenderInstance::createColorAttachment (const vk::DeviceInterface& vki,
454 vk::Allocator& allocator,
455 const tcu::TextureFormat& format,
456 const tcu::UVec2& size,
457 de::MovePtr<vk::Allocation>* outAllocation)
459 const vk::VkImageCreateInfo imageInfo =
461 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
463 vk::VK_IMAGE_TYPE_2D, // imageType
464 mapToVkTextureFormat(format), // format
465 { (deInt32)size.x(), (deInt32)size.y(), 1 }, // extent
469 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
470 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT, // usage
472 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
473 0u, // queueFamilyCount
474 DE_NULL, // pQueueFamilyIndices
477 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &imageInfo));
478 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any));
480 *outAllocation = allocation;
484 vk::Move<vk::VkAttachmentView> SingleTargetRenderInstance::createColorAttachmentView (const vk::DeviceInterface& vki,
486 const tcu::TextureFormat& format,
489 const vk::VkAttachmentViewCreateInfo createInfo =
491 vk::VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
494 mapToVkTextureFormat(format), // format
496 0u, // baseArraySlice
501 return vk::createAttachmentView(vki, device, &createInfo);
504 vk::Move<vk::VkRenderPass> SingleTargetRenderInstance::createRenderPass (const vk::DeviceInterface& vki,
506 const tcu::TextureFormat& format)
508 const vk::VkAttachmentDescription attachmentDescription =
510 vk::VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION,
512 mapToVkTextureFormat(format), // format
514 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp
515 vk::VK_ATTACHMENT_STORE_OP_STORE, // storeOp
516 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
517 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
518 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
519 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout
521 const vk::VkAttachmentReference colorAttachment =
524 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
526 const vk::VkAttachmentReference depthStencilAttachment =
528 vk::VK_NO_ATTACHMENT, // attachment
529 vk::VK_IMAGE_LAYOUT_UNDEFINED // layout
531 const vk::VkSubpassDescription subpass =
533 vk::VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION,
535 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
538 DE_NULL, // inputAttachments
540 &colorAttachment, // colorAttachments
541 DE_NULL, // resolveAttachments
542 depthStencilAttachment, // depthStencilAttachment
544 DE_NULL // preserveAttachments
546 const vk::VkRenderPassCreateInfo renderPassCreateInfo =
548 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
550 1u, // attachmentCount
551 &attachmentDescription, // pAttachments
553 &subpass, // pSubpasses
554 0u, // dependencyCount
555 DE_NULL, // pDependencies
558 return vk::createRenderPass(vki, device, &renderPassCreateInfo);
561 vk::Move<vk::VkFramebuffer> SingleTargetRenderInstance::createFramebuffer (const vk::DeviceInterface& vki,
563 vk::VkRenderPass renderpass,
564 vk::VkAttachmentView colorAttachmentView,
565 const tcu::UVec2& size)
567 const vk::VkAttachmentBindInfo colorAttachment =
569 colorAttachmentView, // view;
570 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // layout;
572 const vk::VkFramebufferCreateInfo framebufferCreateInfo =
574 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
576 renderpass, // renderPass
577 1u, // attachmentCount
578 &colorAttachment, // pAttachments
584 return vk::createFramebuffer(vki, device, &framebufferCreateInfo);
587 vk::Move<vk::VkCmdPool> SingleTargetRenderInstance::createCommandPool (const vk::DeviceInterface& vki,
589 deUint32 queueFamilyIndex)
591 const vk::VkCmdPoolCreateInfo createInfo =
593 vk::VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,
595 queueFamilyIndex, // queueFamilyIndex
596 vk::VK_CMD_POOL_CREATE_TRANSIENT_BIT, // flags
598 return vk::createCommandPool(vki, device, &createInfo);
601 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
603 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
604 const vk::VkBufferCreateInfo bufferCreateInfo =
606 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
608 pixelDataSize, // size
609 vk::VK_BUFFER_USAGE_TRANSFER_DESTINATION_BIT, // usage
611 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
612 0u, // queueFamilyCount
613 DE_NULL, // pQueueFamilyIndices
615 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
616 const vk::VkImageSubresourceRange fullSubrange =
618 vk::VK_IMAGE_ASPECT_COLOR, // aspect
621 0u, // baseArraySlice
624 const vk::VkImageMemoryBarrier imageBarrier =
626 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
628 vk::VK_MEMORY_OUTPUT_COLOR_ATTACHMENT_BIT, // outputMask
629 vk::VK_MEMORY_INPUT_TRANSFER_BIT, // inputMask
630 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
631 vk::VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, // newLayout
632 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
633 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
634 *m_colorAttachmentImage, // image
635 fullSubrange, // subresourceRange
637 const vk::VkBufferMemoryBarrier memoryBarrier =
639 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
641 vk::VK_MEMORY_OUTPUT_TRANSFER_BIT, // outputMask
642 vk::VK_MEMORY_INPUT_HOST_READ_BIT, // inputMask
643 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
644 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
647 (vk::VkDeviceSize)pixelDataSize // size
649 const vk::VkCmdBufferCreateInfo cmdBufCreateInfo =
651 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
653 *m_cmdPool, // cmdPool
654 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
657 const vk::VkFenceCreateInfo fenceCreateInfo =
659 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
663 const vk::VkCmdBufferBeginInfo cmdBufBeginInfo =
665 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
667 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
668 (vk::VkRenderPass)0u, // renderPass
669 (vk::VkFramebuffer)0u, // framebuffer
671 const vk::VkImageSubresource firstSlice =
673 vk::VK_IMAGE_ASPECT_COLOR, // aspect
677 const vk::VkBufferImageCopy copyRegion =
680 m_targetSize.x(), // bufferRowLength
681 m_targetSize.y(), // bufferImageHeight
682 firstSlice, // imageSubresource
683 { 0, 0, 0 }, // imageOffset
684 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y(), 1 } // imageExtent
687 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
689 const vk::Unique<vk::VkCmdBuffer> cmd (vk::createCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
690 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
691 const void* const imageBarrierPtr = &imageBarrier;
692 const void* const bufferBarrierPtr = &memoryBarrier;
693 const deUint64 infiniteTimeout = ~(deUint64)0u;
695 // copy content to buffer
696 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
697 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_FALSE, 1, &imageBarrierPtr);
698 m_vki.cmdCopyImageToBuffer(*cmd, *m_colorAttachmentImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SOURCE_OPTIMAL, *buffer, 1, ©Region);
699 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, 1, &bufferBarrierPtr);
700 VK_CHECK(m_vki.endCommandBuffer(*cmd));
702 // wait for transfer to complete
703 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &cmd.get(), *cmdCompleteFence));
704 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
706 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
709 invalidateMappedMemoryRange(m_vki, m_device, bufferMemory->getMemory(), bufferMemory->getOffset(), pixelDataSize);
710 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
713 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
715 tcu::TextureLevel resultImage;
718 if (m_firstIteration)
721 m_firstIteration = false;
726 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
727 const vk::VkImageSubresourceRange fullSubrange =
729 vk::VK_IMAGE_ASPECT_COLOR, // aspect
732 0u, // baseArraySlice
735 const vk::VkImageMemoryBarrier imageBarrier =
737 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
740 vk::VK_MEMORY_INPUT_COLOR_ATTACHMENT_BIT, // inputMask
741 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
742 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
743 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
744 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
745 *m_colorAttachmentImage, // image
746 fullSubrange, // subresourceRange
748 const vk::VkCmdBufferCreateInfo cmdBufCreateInfo =
750 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
752 *m_cmdPool, // cmdPool
753 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
756 const vk::VkCmdBufferBeginInfo cmdBufBeginInfo =
758 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
760 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
761 (vk::VkRenderPass)0u, // renderPass
762 (vk::VkFramebuffer)0u, // framebuffer
765 const vk::Unique<vk::VkCmdBuffer> cmd (vk::createCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
766 const void* const imageBarrierPtr = &imageBarrier;
768 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
769 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, 1, &imageBarrierPtr);
770 VK_CHECK(m_vki.endCommandBuffer(*cmd));
771 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &cmd.get(), 0));
773 // and then render to
778 readRenderTarget(resultImage);
779 return verifyResultImage(resultImage.getAccess());
782 class RenderInstanceShaders
785 RenderInstanceShaders (const vk::DeviceInterface& vki,
787 const vk::BinaryCollection& programCollection);
789 inline bool hasTessellationStage (void) const { return *m_tessCtrlShader != 0 || *m_tessEvalShader != 0; }
790 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
791 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
794 void addStage (const vk::DeviceInterface& vki,
796 const vk::BinaryCollection& programCollection,
798 vk::VkShaderStage stage,
799 vk::Move<vk::VkShaderModule>* outModule,
800 vk::Move<vk::VkShader>* outShader);
802 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStage stage, vk::VkShader shader) const;
804 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
805 vk::Move<vk::VkShader> m_vertexShader;
806 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
807 vk::Move<vk::VkShader> m_tessCtrlShader;
808 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
809 vk::Move<vk::VkShader> m_tessEvalShader;
810 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
811 vk::Move<vk::VkShader> m_geometryShader;
812 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
813 vk::Move<vk::VkShader> m_fragmentShader;
814 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
817 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
819 const vk::BinaryCollection& programCollection)
821 addStage(vki, device, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX, &m_vertexShaderModule, &m_vertexShader);
822 addStage(vki, device, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESS_CONTROL, &m_tessCtrlShaderModule, &m_tessCtrlShader);
823 addStage(vki, device, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESS_EVALUATION, &m_tessEvalShaderModule, &m_tessEvalShader);
824 addStage(vki, device, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY, &m_geometryShaderModule, &m_geometryShader);
825 addStage(vki, device, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT, &m_fragmentShaderModule, &m_fragmentShader);
827 DE_ASSERT(!m_stageInfos.empty());
830 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
832 const vk::BinaryCollection& programCollection,
834 vk::VkShaderStage stage,
835 vk::Move<vk::VkShaderModule>* outModule,
836 vk::Move<vk::VkShader>* outShader)
838 if (programCollection.contains(name))
840 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
841 const vk::VkShaderCreateInfo createInfo =
843 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
849 vk::Move<vk::VkShader> shader = vk::createShader(vki, device, &createInfo);
851 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *shader));
857 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStage stage, vk::VkShader shader) const
859 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
861 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
865 DE_NULL, // pSpecializationInfo
867 return stageCreateInfo;
870 class SingleCmdRenderInstance : public SingleTargetRenderInstance
873 SingleCmdRenderInstance (Context& context,
874 bool isPrimaryCmdBuf,
875 const tcu::UVec2& renderSize);
878 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
880 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
881 virtual void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const = 0;
883 void renderToTarget (void);
885 const bool m_isPrimaryCmdBuf;
888 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
889 bool isPrimaryCmdBuf,
890 const tcu::UVec2& renderSize)
891 : SingleTargetRenderInstance (context, renderSize)
892 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
896 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
898 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getBinaryCollection());
899 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
900 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
902 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
905 DE_NULL, // pVertexBindingDescriptions
906 0u, // attributeCount
907 DE_NULL, // pVertexAttributeDescriptions
909 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
911 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
913 topology, // topology
914 vk::VK_FALSE, // primitiveRestartEnable
916 const vk::VkPipelineTessellationStateCreateInfo tessState =
918 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
920 3u, // patchControlPoints
922 const vk::VkPipelineViewportStateCreateInfo vpState =
924 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
928 const vk::VkPipelineRasterStateCreateInfo rsState =
930 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTER_STATE_CREATE_INFO,
932 vk::VK_TRUE, // depthClipEnable
933 vk::VK_FALSE, // rasterizerDiscardEnable
934 vk::VK_FILL_MODE_SOLID, // fillMode
935 vk::VK_CULL_MODE_NONE, // cullMode
936 vk::VK_FRONT_FACE_CCW, // frontFace
938 const vk::VkPipelineMultisampleStateCreateInfo msState =
940 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
943 vk::VK_FALSE, // sampleShadingEnable
944 0.0f, // minSampleShading
947 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
949 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
951 vk::VK_FALSE, // depthTestEnable
952 vk::VK_FALSE, // depthWriteEnable
953 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
954 vk::VK_FALSE, // depthBoundsEnable
955 vk::VK_FALSE, // stencilTestEnable
956 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS }, // front
957 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS }, // back
959 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
961 vk::VK_FALSE, // blendEnable
962 vk::VK_BLEND_ZERO, // srcBlendColor
963 vk::VK_BLEND_ZERO, // destBlendColor
964 vk::VK_BLEND_OP_ADD, // blendOpColor
965 vk::VK_BLEND_ZERO, // srcBlendAlpha
966 vk::VK_BLEND_ZERO, // destBlendAlpha
967 vk::VK_BLEND_OP_ADD, // blendOpAlpha
968 vk::VK_CHANNEL_R_BIT | vk::VK_CHANNEL_G_BIT | vk::VK_CHANNEL_B_BIT | vk::VK_CHANNEL_A_BIT, // channelWriteMask
970 const vk::VkPipelineColorBlendStateCreateInfo cbState =
972 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
974 vk::VK_FALSE, // alphaToCoverageEnable
975 vk::VK_FALSE, // logicOpEnable
976 vk::VK_LOGIC_OP_CLEAR, // logicOp
977 1u, // attachmentCount
978 &cbAttachment, // pAttachments
980 const vk::VkGraphicsPipelineCreateInfo createInfo =
982 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
984 shaderStages.getNumStages(), // stageCount
985 shaderStages.getStages(), // pStages
986 &vertexInputState, // pVertexInputState
987 &iaState, // pInputAssemblyState
988 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
989 &vpState, // pViewportState
990 &rsState, // pRasterState
991 &msState, // pMultisampleState
992 &dsState, // pDepthStencilState
993 &cbState, // pColorBlendState
995 pipelineLayout, // layout
996 *m_renderPass, // renderPass
998 (vk::VkPipeline)0, // basePipelineHandle
999 0u, // basePipelineIndex
1001 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
1004 void SingleCmdRenderInstance::renderToTarget (void)
1006 const vk::VkViewport viewport =
1010 float(m_targetSize.x()), // width
1011 float(m_targetSize.y()), // height
1015 const vk::VkRect2D renderArea =
1018 { (deInt32)m_targetSize.x(), (deInt32)m_targetSize.y() }, // extent
1020 const vk::VkDynamicViewportStateCreateInfo viewportStateCreateInfo =
1022 vk::VK_STRUCTURE_TYPE_DYNAMIC_VIEWPORT_STATE_CREATE_INFO,
1024 1, // viewportAndScissorCount
1025 &viewport, // pViewports
1026 &renderArea, // pScissors
1028 const vk::VkDynamicRasterStateCreateInfo rasterStateCreateInfo =
1030 vk::VK_STRUCTURE_TYPE_DYNAMIC_RASTER_STATE_CREATE_INFO,
1033 0.0f, // depthBiasClamp
1034 0.0f, // slopeScaledDepthBias
1037 const vk::VkDynamicColorBlendStateCreateInfo colorBlendStateCreateInfo =
1039 vk::VK_STRUCTURE_TYPE_DYNAMIC_COLOR_BLEND_STATE_CREATE_INFO,
1041 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
1043 const vk::VkDynamicDepthStencilStateCreateInfo depthStencilStateCreateInfo =
1045 vk::VK_STRUCTURE_TYPE_DYNAMIC_DEPTH_STENCIL_STATE_CREATE_INFO,
1047 0.0f, // minDepthBounds
1048 1.0f, // maxDepthBounds
1049 0u, // stencilReadMask
1050 0u, // stencilWriteMask
1051 0u, // stencilFrontRef
1052 0u, // stencilBackRef
1054 const vk::VkCmdBufferCreateInfo mainCmdBufCreateInfo =
1056 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
1058 *m_cmdPool, // cmdPool
1059 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
1062 const vk::VkCmdBufferBeginInfo mainCmdBufBeginInfo =
1064 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
1066 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
1067 (vk::VkRenderPass)0u, // renderPass
1068 (vk::VkFramebuffer)0u, // framebuffer
1070 const vk::VkCmdBufferCreateInfo passCmdBufCreateInfo =
1072 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
1074 *m_cmdPool, // cmdPool
1075 vk::VK_CMD_BUFFER_LEVEL_SECONDARY, // level
1078 const vk::VkCmdBufferBeginInfo passCmdBufBeginInfo =
1080 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
1082 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
1083 (vk::VkRenderPass)*m_renderPass, // renderPass
1084 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
1086 const vk::VkFenceCreateInfo fenceCreateInfo =
1088 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1092 const vk::VkClearValue clearValue = createClearValueColor(tcu::Vec4(0.0f, 0.0f, 0.0f, 0.0f));
1093 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1095 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1097 *m_renderPass, // renderPass
1098 *m_framebuffer, // framebuffer
1099 renderArea, // renderArea
1100 1u, // attachmentCount
1101 &clearValue, // pAttachmentClearValues
1104 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1105 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1106 const vk::Unique<vk::VkCmdBuffer> mainCmd (vk::createCommandBuffer(m_vki, m_device, &mainCmdBufCreateInfo));
1107 const vk::Unique<vk::VkCmdBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCmdBuffer>()) : (vk::createCommandBuffer(m_vki, m_device, &passCmdBufCreateInfo)));
1108 const vk::Unique<vk::VkDynamicViewportState> dynamicVpState (vk::createDynamicViewportState(m_vki, m_device, &viewportStateCreateInfo));
1109 const vk::Unique<vk::VkDynamicRasterState> dynamicRsState (vk::createDynamicRasterState(m_vki, m_device, &rasterStateCreateInfo));
1110 const vk::Unique<vk::VkDynamicColorBlendState> dynamicCbState (vk::createDynamicColorBlendState(m_vki, m_device, &colorBlendStateCreateInfo));
1111 const vk::Unique<vk::VkDynamicDepthStencilState> dynamicDsState (vk::createDynamicDepthStencilState(m_vki, m_device, &depthStencilStateCreateInfo));
1112 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1113 const deUint64 infiniteTimeout = ~(deUint64)0u;
1114 const vk::VkRenderPassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_RENDER_PASS_CONTENTS_INLINE) : (vk::VK_RENDER_PASS_CONTENTS_SECONDARY_CMD_BUFFERS);
1116 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1117 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1119 if (m_isPrimaryCmdBuf)
1121 m_vki.cmdBindDynamicViewportState(*mainCmd, *dynamicVpState);
1122 m_vki.cmdBindDynamicRasterState(*mainCmd, *dynamicRsState);
1123 m_vki.cmdBindDynamicColorBlendState(*mainCmd, *dynamicCbState);
1124 m_vki.cmdBindDynamicDepthStencilState(*mainCmd, *dynamicDsState);
1125 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1126 writeDrawCmdBuffer(*mainCmd);
1130 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1131 m_vki.cmdBindDynamicViewportState(*passCmd, *dynamicVpState);
1132 m_vki.cmdBindDynamicRasterState(*passCmd, *dynamicRsState);
1133 m_vki.cmdBindDynamicColorBlendState(*passCmd, *dynamicCbState);
1134 m_vki.cmdBindDynamicDepthStencilState(*passCmd, *dynamicDsState);
1135 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1136 writeDrawCmdBuffer(*passCmd);
1137 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1139 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1142 m_vki.cmdEndRenderPass(*mainCmd);
1143 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1145 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1146 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &mainCmd.get(), *fence));
1147 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1150 enum ShaderInputInterface
1152 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1153 SHADER_INPUT_MULTIPLE_DESCRIPTORS, //!< multiple descriptors
1154 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1159 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1161 switch (shaderInterface)
1163 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1164 case SHADER_INPUT_MULTIPLE_DESCRIPTORS: return 2u;
1165 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1168 DE_FATAL("Impossible");
1173 class BufferRenderInstance : public SingleCmdRenderInstance
1176 BufferRenderInstance (Context& context,
1177 bool isPrimaryCmdBuf,
1178 vk::VkDescriptorType descriptorType,
1179 vk::VkShaderStageFlags stageFlags,
1180 ShaderInputInterface shaderInterface,
1183 bool dynamicOffsetNonZero);
1185 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1186 vk::VkDevice device,
1187 vk::Allocator& allocator,
1188 vk::VkDescriptorType descriptorType,
1190 deUint32 bufferSize,
1191 de::MovePtr<vk::Allocation>* outMemory);
1193 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
1194 vk::VkDevice device,
1195 vk::VkBuffer buffer,
1198 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1199 vk::VkDevice device,
1200 vk::VkDescriptorType descriptorType,
1201 ShaderInputInterface shaderInterface);
1203 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1204 vk::VkDevice device,
1205 vk::VkDescriptorType descriptorType,
1206 ShaderInputInterface shaderInterface,
1207 vk::VkShaderStageFlags stageFlags);
1209 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1210 vk::VkDevice device,
1211 vk::VkDescriptorSetLayout descriptorSetLayout,
1212 vk::VkDescriptorPool descriptorPool,
1213 vk::VkDescriptorType descriptorType,
1214 ShaderInputInterface shaderInterface,
1215 vk::VkBufferView bufferViewA,
1216 vk::VkBufferView bufferViewB);
1218 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1219 vk::VkDevice device,
1220 vk::VkDescriptorSetLayout descriptorSetLayout);
1222 void logTestPlan (void) const;
1223 vk::VkPipelineLayout getPipelineLayout (void) const;
1224 void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const;
1225 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1230 BUFFER_DATA_SIZE = 8 * sizeof(float),
1231 BUFFER_SIZE_A = 2048, //!< a lot more than required
1232 BUFFER_SIZE_B = 2560, //!< a lot more than required
1234 STATIC_OFFSET_VALUE_A = 256,
1235 DYNAMIC_OFFSET_VALUE_A = 512,
1236 STATIC_OFFSET_VALUE_B = 1024,
1237 DYNAMIC_OFFSET_VALUE_B = 768,
1240 const vk::VkDescriptorType m_descriptorType;
1241 const ShaderInputInterface m_shaderInterface;
1242 const bool m_setViewOffset;
1243 const bool m_setDynamicOffset;
1244 const bool m_dynamicOffsetNonZero;
1245 const vk::VkShaderStageFlags m_stageFlags;
1247 const deUint32 m_viewOffsetA;
1248 const deUint32 m_viewOffsetB;
1249 const deUint32 m_dynamicOffsetA;
1250 const deUint32 m_dynamicOffsetB;
1251 const deUint32 m_effectiveOffsetA;
1252 const deUint32 m_effectiveOffsetB;
1253 const deUint32 m_bufferSizeA;
1254 const deUint32 m_bufferSizeB;
1256 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1257 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1258 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1259 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1260 const vk::Unique<vk::VkBufferView> m_bufferViewA;
1261 const vk::Unique<vk::VkBufferView> m_bufferViewB;
1262 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1263 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1264 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1265 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1268 BufferRenderInstance::BufferRenderInstance (Context& context,
1269 bool isPrimaryCmdBuf,
1270 vk::VkDescriptorType descriptorType,
1271 vk::VkShaderStageFlags stageFlags,
1272 ShaderInputInterface shaderInterface,
1275 bool dynamicOffsetNonZero)
1276 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1277 , m_descriptorType (descriptorType)
1278 , m_shaderInterface (shaderInterface)
1279 , m_setViewOffset (viewOffset)
1280 , m_setDynamicOffset (dynamicOffset)
1281 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1282 , m_stageFlags (stageFlags)
1283 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1284 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1285 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1286 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1287 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_dynamicOffsetA) : (m_viewOffsetA))
1288 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_dynamicOffsetB) : (m_viewOffsetB))
1289 , m_bufferSizeA (BUFFER_SIZE_A)
1290 , m_bufferSizeB (BUFFER_SIZE_B)
1291 , m_bufferMemoryA (DE_NULL)
1292 , m_bufferMemoryB (DE_NULL)
1293 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1294 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1295 ? vk::Move<vk::VkBuffer>()
1296 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1297 , m_bufferViewA (createBufferView(m_vki, m_device, *m_sourceBufferA, m_viewOffsetA))
1298 , m_bufferViewB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1299 ? vk::Move<vk::VkBufferView>()
1300 : createBufferView(m_vki, m_device, *m_sourceBufferB, m_viewOffsetB))
1301 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1302 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
1303 , m_descriptorSet (createDescriptorSet(m_vki, m_device, *m_descriptorSetLayout, *m_descriptorPool, m_descriptorType, m_shaderInterface, *m_bufferViewA, *m_bufferViewB))
1304 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1306 if (m_setDynamicOffset)
1307 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1308 if (m_dynamicOffsetNonZero)
1309 DE_ASSERT(m_setDynamicOffset);
1312 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1313 vk::VkDevice device,
1314 vk::Allocator& allocator,
1315 vk::VkDescriptorType descriptorType,
1317 deUint32 bufferSize,
1318 de::MovePtr<vk::Allocation>* outMemory)
1320 static const float s_colors[] =
1322 0.0f, 1.0f, 0.0f, 1.0f, // green
1323 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1325 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1326 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1327 DE_ASSERT(offset % sizeof(float) == 0);
1328 DE_ASSERT(bufferSize % sizeof(float) == 0);
1330 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1331 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1332 const float preGuardValue = 0.5f;
1333 const float postGuardValue = 0.75f;
1334 const vk::VkBufferCreateInfo bufferCreateInfo =
1336 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1339 usageFlags, // usage
1341 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1342 0u, // queueFamilyCount
1343 DE_NULL, // pQueueFamilyIndices
1345 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1346 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1347 void* const mapPtr = bufferMemory->getHostPtr();
1349 // guard with interesting values
1350 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1351 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1353 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1354 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1355 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1356 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
1358 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1360 *outMemory = bufferMemory;
1364 vk::Move<vk::VkBufferView> BufferRenderInstance::createBufferView (const vk::DeviceInterface& vki,
1365 vk::VkDevice device,
1366 vk::VkBuffer buffer,
1369 const vk::VkBufferViewCreateInfo createInfo =
1371 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
1374 vk::VK_BUFFER_VIEW_TYPE_RAW, // viewType
1375 vk::VK_FORMAT_UNDEFINED, // format
1376 (vk::VkDeviceSize)offset, // offset
1377 (vk::VkDeviceSize)BUFFER_DATA_SIZE // range
1379 return vk::createBufferView(vki, device, &createInfo);
1382 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1383 vk::VkDevice device,
1384 vk::VkDescriptorType descriptorType,
1385 ShaderInputInterface shaderInterface)
1387 return vk::DescriptorPoolBuilder()
1388 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1389 .build(vki, device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
1392 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1393 vk::VkDevice device,
1394 vk::VkDescriptorType descriptorType,
1395 ShaderInputInterface shaderInterface,
1396 vk::VkShaderStageFlags stageFlags)
1398 vk::DescriptorSetLayoutBuilder builder;
1400 switch (shaderInterface)
1402 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1403 builder.addSingleBinding(descriptorType, stageFlags);
1406 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1407 builder.addSingleBinding(descriptorType, stageFlags);
1408 builder.addSingleBinding(descriptorType, stageFlags);
1411 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1412 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1416 DE_FATAL("Impossible");
1419 return builder.build(vki, device);
1422 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1423 vk::VkDevice device,
1424 vk::VkDescriptorSetLayout descriptorSetLayout,
1425 vk::VkDescriptorPool descriptorPool,
1426 vk::VkDescriptorType descriptorType,
1427 ShaderInputInterface shaderInterface,
1428 vk::VkBufferView viewA,
1429 vk::VkBufferView viewB)
1431 const vk::VkDescriptorInfo bufferInfos[2] =
1433 createDescriptorInfo(viewA),
1434 createDescriptorInfo(viewB),
1437 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(vki, device, descriptorPool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, descriptorSetLayout);
1438 vk::DescriptorSetUpdateBuilder builder;
1440 switch (shaderInterface)
1442 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1443 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1446 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1447 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1448 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1451 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1452 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1456 DE_FATAL("Impossible");
1459 builder.update(vki, device);
1460 return descriptorSet;
1463 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1464 vk::VkDevice device,
1465 vk::VkDescriptorSetLayout descriptorSetLayout)
1467 const vk::VkPipelineLayoutCreateInfo createInfo =
1469 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1471 1, // descriptorSetCount
1472 &descriptorSetLayout, // pSetLayouts
1473 0u, // pushConstantRangeCount
1474 DE_NULL, // pPushConstantRanges
1477 return vk::createPipelineLayout(vki, device, &createInfo);
1480 void BufferRenderInstance::logTestPlan (void) const
1482 std::ostringstream msg;
1484 msg << "Rendering 2x2 yellow-green grid.\n"
1485 << "Single descriptor set. Descriptor set contains "
1486 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1487 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
1488 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1489 (const char*)DE_NULL)
1490 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1491 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1493 if (isDynamicDescriptorType(m_descriptorType))
1495 if (m_setDynamicOffset)
1497 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1498 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1502 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1506 if (m_stageFlags == 0u)
1508 msg << "Descriptors are not accessed in any shader stage.\n";
1512 msg << "Descriptors are accessed in {"
1513 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1514 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1515 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1516 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1517 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1521 m_context.getTestContext().getLog()
1522 << tcu::TestLog::Message
1524 << tcu::TestLog::EndMessage;
1527 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1529 return *m_pipelineLayout;
1532 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const
1534 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1536 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1537 const deUint32 dynamicOffsets[] =
1542 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1543 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1545 // make host writes device-visible
1546 const vk::VkMemoryInputFlags inputBit = (isUniformBuffer) ? (vk::VK_MEMORY_INPUT_UNIFORM_READ_BIT) : (vk::VK_MEMORY_INPUT_SHADER_READ_BIT);
1547 const vk::VkBufferMemoryBarrier memoryBarrierA =
1549 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1551 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
1552 inputBit, // inputMask
1553 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1554 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1555 *m_sourceBufferA, // buffer
1557 (vk::VkDeviceSize)m_bufferSizeA, // size
1559 const vk::VkBufferMemoryBarrier memoryBarrierB =
1561 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1563 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
1564 inputBit, // inputMask
1565 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1566 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1567 *m_sourceBufferB, // buffer
1569 (vk::VkDeviceSize)m_bufferSizeB, // size
1571 const void* const memoryBarriers[2] =
1576 const deUint32 numMemoryBarriers = getInterfaceNumResources(m_shaderInterface);
1578 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1579 m_vki.cmdPipelineBarrier(cmd, 0u, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS, vk::VK_FALSE, numMemoryBarriers, memoryBarriers);
1580 m_vki.cmdDraw(cmd, 0, 6 * 4, 0, 1); // render four quads (two separate triangles)
1583 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1585 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1586 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1587 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1589 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1591 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1592 return tcu::TestStatus::fail("Image verification failed");
1594 return tcu::TestStatus::pass("Pass");
1597 class ComputeInstanceResultBuffer
1602 DATA_SIZE = sizeof(tcu::Vec4[4])
1605 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1606 vk::VkDevice device,
1607 vk::Allocator& allocator);
1609 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1611 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1612 inline vk::VkBufferView getBufferView (void) const { return *m_bufferView; }
1613 inline const void* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1616 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1617 vk::VkDevice device,
1618 vk::Allocator& allocator,
1619 de::MovePtr<vk::Allocation>* outAllocation);
1621 static vk::Move<vk::VkBufferView> createResultBufferView (const vk::DeviceInterface& vki,
1622 vk::VkDevice device,
1623 vk::VkBuffer buffer);
1625 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1627 const vk::DeviceInterface& m_vki;
1628 const vk::VkDevice m_device;
1630 de::MovePtr<vk::Allocation> m_bufferMem;
1631 const vk::Unique<vk::VkBuffer> m_buffer;
1632 const vk::Unique<vk::VkBufferView> m_bufferView;
1633 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1636 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1637 vk::VkDevice device,
1638 vk::Allocator& allocator)
1641 , m_bufferMem (DE_NULL)
1642 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1643 , m_bufferView (createResultBufferView(m_vki, m_device, *m_buffer))
1644 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1648 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1650 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1651 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1654 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1655 vk::VkDevice device,
1656 vk::Allocator& allocator,
1657 de::MovePtr<vk::Allocation>* outAllocation)
1659 const vk::VkBufferCreateInfo createInfo =
1661 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1663 (vk::VkDeviceSize)DATA_SIZE, // size
1664 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1666 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1667 0u, // queueFamilyCount
1668 DE_NULL, // pQueueFamilyIndices
1670 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1671 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1672 const float clearValue = -1.0f;
1673 void* mapPtr = allocation->getHostPtr();
1675 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1676 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1678 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1680 *outAllocation = allocation;
1684 vk::Move<vk::VkBufferView> ComputeInstanceResultBuffer::createResultBufferView (const vk::DeviceInterface& vki,
1685 vk::VkDevice device,
1686 vk::VkBuffer buffer)
1688 const vk::VkBufferViewCreateInfo createInfo =
1690 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
1693 vk::VK_BUFFER_VIEW_TYPE_RAW, // viewType
1694 vk::VK_FORMAT_UNDEFINED, // format
1695 (vk::VkDeviceSize)0u, // offset
1696 (vk::VkDeviceSize)DATA_SIZE // range
1698 return vk::createBufferView(vki, device, &createInfo);
1701 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1703 const vk::VkBufferMemoryBarrier bufferBarrier =
1705 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1707 vk::VK_MEMORY_OUTPUT_SHADER_WRITE_BIT, // outputMask
1708 vk::VK_MEMORY_INPUT_HOST_READ_BIT, // inputMask
1709 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1710 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1712 (vk::VkDeviceSize)0u, // offset
1715 return bufferBarrier;
1718 class ComputePipeline
1721 ComputePipeline (const vk::DeviceInterface& vki,
1722 vk::VkDevice device,
1723 const vk::BinaryCollection& programCollection,
1724 deUint32 numDescriptorSets,
1725 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1727 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1728 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1731 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1732 vk::VkDevice device,
1733 deUint32 numDescriptorSets,
1734 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1736 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1737 vk::VkDevice device,
1738 const vk::BinaryCollection& programCollection,
1739 vk::VkPipelineLayout layout);
1741 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1742 const vk::Unique<vk::VkPipeline> m_pipeline;
1745 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1746 vk::VkDevice device,
1747 const vk::BinaryCollection& programCollection,
1748 deUint32 numDescriptorSets,
1749 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1750 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
1751 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
1755 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
1756 vk::VkDevice device,
1757 deUint32 numDescriptorSets,
1758 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1760 const vk::VkPipelineLayoutCreateInfo createInfo =
1762 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1764 numDescriptorSets, // descriptorSetCount
1765 descriptorSetLayouts, // pSetLayouts
1766 0u, // pushConstantRangeCount
1767 DE_NULL, // pPushConstantRanges
1769 return vk::createPipelineLayout(vki, device, &createInfo);
1772 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
1773 vk::VkDevice device,
1774 const vk::BinaryCollection& programCollection,
1775 vk::VkPipelineLayout layout)
1777 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
1778 const vk::VkShaderCreateInfo shaderCreateInfo =
1780 vk::VK_STRUCTURE_TYPE_SHADER_CREATE_INFO,
1782 *computeModule, // module
1786 const vk::Unique<vk::VkShader> computeShader (vk::createShader(vki, device, &shaderCreateInfo));
1787 const vk::VkPipelineShaderStageCreateInfo cs =
1789 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1791 vk::VK_SHADER_STAGE_COMPUTE, // stage
1792 *computeShader, // shader
1793 DE_NULL, // pSpecializationInfo
1795 const vk::VkComputePipelineCreateInfo createInfo =
1797 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1802 (vk::VkPipeline)0, // basePipelineHandle
1803 0u, // basePipelineIndex
1805 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
1808 class ComputeCommand
1811 ComputeCommand (const vk::DeviceInterface& vki,
1812 vk::VkDevice device,
1813 vk::VkPipeline pipeline,
1814 vk::VkPipelineLayout pipelineLayout,
1815 const tcu::UVec3& numWorkGroups,
1816 int numDescriptorSets,
1817 const vk::VkDescriptorSet* descriptorSets,
1818 int numDynamicOffsets,
1819 const deUint32* dynamicOffsets,
1821 const void* const* preBarriers,
1822 int numPostBarriers,
1823 const void* const* postBarriers);
1825 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const;
1828 const vk::DeviceInterface& m_vki;
1829 const vk::VkDevice m_device;
1830 const vk::VkPipeline m_pipeline;
1831 const vk::VkPipelineLayout m_pipelineLayout;
1832 const tcu::UVec3& m_numWorkGroups;
1833 const int m_numDescriptorSets;
1834 const vk::VkDescriptorSet* const m_descriptorSets;
1835 const int m_numDynamicOffsets;
1836 const deUint32* const m_dynamicOffsets;
1837 const int m_numPreBarriers;
1838 const void* const* const m_preBarriers;
1839 const int m_numPostBarriers;
1840 const void* const* const m_postBarriers;
1843 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
1844 vk::VkDevice device,
1845 vk::VkPipeline pipeline,
1846 vk::VkPipelineLayout pipelineLayout,
1847 const tcu::UVec3& numWorkGroups,
1848 int numDescriptorSets,
1849 const vk::VkDescriptorSet* descriptorSets,
1850 int numDynamicOffsets,
1851 const deUint32* dynamicOffsets,
1853 const void* const* preBarriers,
1854 int numPostBarriers,
1855 const void* const* postBarriers)
1858 , m_pipeline (pipeline)
1859 , m_pipelineLayout (pipelineLayout)
1860 , m_numWorkGroups (numWorkGroups)
1861 , m_numDescriptorSets (numDescriptorSets)
1862 , m_descriptorSets (descriptorSets)
1863 , m_numDynamicOffsets (numDynamicOffsets)
1864 , m_dynamicOffsets (dynamicOffsets)
1865 , m_numPreBarriers (numPreBarriers)
1866 , m_preBarriers (preBarriers)
1867 , m_numPostBarriers (numPostBarriers)
1868 , m_postBarriers (postBarriers)
1872 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const
1874 const vk::VkCmdPoolCreateInfo cmdPoolCreateInfo =
1876 vk::VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,
1878 queueFamilyIndex, // queueFamilyIndex
1879 vk::VK_CMD_POOL_CREATE_TRANSIENT_BIT, // flags
1881 const vk::Unique<vk::VkCmdPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
1883 const vk::VkFenceCreateInfo fenceCreateInfo =
1885 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1890 const vk::VkCmdBufferCreateInfo cmdBufCreateInfo =
1892 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
1894 *cmdPool, // cmdPool
1895 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
1898 const vk::VkCmdBufferBeginInfo cmdBufBeginInfo =
1900 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
1902 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
1903 (vk::VkRenderPass)0u, // renderPass
1904 (vk::VkFramebuffer)0u, // framebuffer
1907 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1908 const vk::Unique<vk::VkCmdBuffer> cmd (vk::createCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
1909 const deUint64 infiniteTimeout = ~(deUint64)0u;
1911 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
1913 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
1914 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
1916 if (m_numPreBarriers)
1917 m_vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_FALSE, m_numPreBarriers, m_preBarriers);
1919 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
1920 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, m_numPostBarriers, m_postBarriers);
1921 VK_CHECK(m_vki.endCommandBuffer(*cmd));
1924 VK_CHECK(m_vki.queueSubmit(queue, 1, &cmd.get(), *cmdCompleteFence));
1925 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1928 class BufferComputeInstance : public vkt::TestInstance
1931 BufferComputeInstance (Context& context,
1932 vk::VkDescriptorType descriptorType,
1933 ShaderInputInterface shaderInterface,
1936 bool dynamicOffsetNonZero);
1939 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
1940 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
1941 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
1942 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
1943 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBufferView viewA, vk::VkBufferView viewB, vk::VkBufferView viewRes) const;
1945 tcu::TestStatus iterate (void);
1946 void logTestPlan (void) const;
1947 tcu::TestStatus testResourceAccess (void);
1951 STATIC_OFFSET_VALUE_A = 256,
1952 DYNAMIC_OFFSET_VALUE_A = 512,
1953 STATIC_OFFSET_VALUE_B = 1024,
1954 DYNAMIC_OFFSET_VALUE_B = 768,
1957 const vk::VkDescriptorType m_descriptorType;
1958 const ShaderInputInterface m_shaderInterface;
1959 const bool m_setViewOffset;
1960 const bool m_setDynamicOffset;
1961 const bool m_dynamicOffsetNonZero;
1963 const vk::DeviceInterface& m_vki;
1964 const vk::VkDevice m_device;
1965 const vk::VkQueue m_queue;
1966 const deUint32 m_queueFamilyIndex;
1967 vk::Allocator& m_allocator;
1969 const ComputeInstanceResultBuffer m_result;
1972 BufferComputeInstance::BufferComputeInstance (Context& context,
1973 vk::VkDescriptorType descriptorType,
1974 ShaderInputInterface shaderInterface,
1977 bool dynamicOffsetNonZero)
1978 : vkt::TestInstance (context)
1979 , m_descriptorType (descriptorType)
1980 , m_shaderInterface (shaderInterface)
1981 , m_setViewOffset (viewOffset)
1982 , m_setDynamicOffset (dynamicOffset)
1983 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1984 , m_vki (context.getDeviceInterface())
1985 , m_device (context.getDevice())
1986 , m_queue (context.getUniversalQueue())
1987 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
1988 , m_allocator (context.getDefaultAllocator())
1989 , m_result (m_vki, m_device, m_allocator)
1991 if (m_dynamicOffsetNonZero)
1992 DE_ASSERT(m_setDynamicOffset);
1995 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
1997 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
1999 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2000 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
2001 const vk::VkBufferCreateInfo createInfo =
2003 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
2005 (vk::VkDeviceSize)bufferSize, // size
2006 usageFlags, // usage
2008 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2009 0u, // queueFamilyCount
2010 DE_NULL, // pQueueFamilyIndices
2012 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
2013 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
2014 void* mapPtr = allocation->getHostPtr();
2017 deMemset(mapPtr, 0x5A, (size_t)offset);
2018 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
2019 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
2020 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
2022 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
2024 *outAllocation = allocation;
2028 vk::Move<vk::VkBufferView> BufferComputeInstance::createBufferView (vk::VkBuffer buffer, deUint32 offset) const
2030 const vk::VkBufferViewCreateInfo createInfo =
2032 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
2035 vk::VK_BUFFER_VIEW_TYPE_RAW, // viewType
2036 vk::VK_FORMAT_UNDEFINED, // format
2037 (vk::VkDeviceSize)offset, // offset
2038 (vk::VkDeviceSize)sizeof(tcu::Vec4[2]) // range
2040 return vk::createBufferView(m_vki, m_device, &createInfo);
2043 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
2045 vk::DescriptorSetLayoutBuilder builder;
2047 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2049 switch (m_shaderInterface)
2051 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2052 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2055 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2056 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2057 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2060 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2061 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
2065 DE_FATAL("Impossible");
2068 return builder.build(m_vki, m_device);
2071 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
2073 return vk::DescriptorPoolBuilder()
2074 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
2075 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
2076 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
2079 vk::Move<vk::VkDescriptorSet> BufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBufferView viewA, vk::VkBufferView viewB, vk::VkBufferView viewRes) const
2081 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(viewRes);
2082 const vk::VkDescriptorInfo bufferInfos[2] =
2084 createDescriptorInfo(viewA),
2085 createDescriptorInfo(viewB),
2088 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
2089 vk::DescriptorSetUpdateBuilder builder;
2092 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
2095 switch (m_shaderInterface)
2097 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2098 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2101 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2102 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2103 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
2106 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2107 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
2111 DE_FATAL("Impossible");
2114 builder.update(m_vki, m_device);
2115 return descriptorSet;
2118 tcu::TestStatus BufferComputeInstance::iterate (void)
2121 return testResourceAccess();
2124 void BufferComputeInstance::logTestPlan (void) const
2126 std::ostringstream msg;
2128 msg << "Accessing resource in a compute program.\n"
2129 << "Single descriptor set. Descriptor set contains "
2130 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2131 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
2132 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2133 (const char*)DE_NULL)
2134 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2135 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2136 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2138 if (isDynamicDescriptorType(m_descriptorType))
2140 if (m_setDynamicOffset)
2142 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2143 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2147 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2151 msg << "Destination buffer is pre-initialized to -1.\n";
2153 m_context.getTestContext().getLog()
2154 << tcu::TestLog::Message
2156 << tcu::TestLog::EndMessage;
2159 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2163 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2166 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2167 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2168 const deUint32 bindTimeOffsets[] =
2170 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2171 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2174 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2175 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2176 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2177 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2179 const deUint32 dataOffsetA = (isDynamicCase) ? (bindTimeOffsets[0]) : (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2180 const deUint32 dataOffsetB = (isDynamicCase) ? (bindTimeOffsets[1]) : (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2181 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2182 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2183 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2184 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2186 de::MovePtr<vk::Allocation> bufferMemA;
2187 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2188 const vk::Unique<vk::VkBufferView> bufferViewA (createBufferView(*bufferA, viewOffsetA));
2190 de::MovePtr<vk::Allocation> bufferMemB;
2191 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2192 ? (vk::Move<vk::VkBuffer>())
2193 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2194 const vk::Unique<vk::VkBufferView> bufferViewB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2195 ? (vk::Move<vk::VkBufferView>())
2196 : (createBufferView(*bufferB, viewOffsetB)));
2198 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2199 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2200 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferViewA, *bufferViewB, m_result.getBufferView()));
2201 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2203 const vk::VkMemoryInputFlags inputBit = (isUniformBuffer) ? (vk::VK_MEMORY_INPUT_UNIFORM_READ_BIT) : (vk::VK_MEMORY_INPUT_SHADER_READ_BIT);
2204 const vk::VkBufferMemoryBarrier bufferBarrierA =
2206 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2208 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
2209 inputBit, // inputMask
2210 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2211 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2213 (vk::VkDeviceSize)0u, // offset
2214 (vk::VkDeviceSize)bufferSizeA, // size
2216 const vk::VkBufferMemoryBarrier bufferBarrierB =
2218 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2220 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
2221 inputBit, // inputMask
2222 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2223 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2225 (vk::VkDeviceSize)0u, // offset
2226 (vk::VkDeviceSize)bufferSizeB, // size
2229 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2231 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2232 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2233 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2234 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2235 const void* const preBarriers[] = { &bufferBarrierA, &bufferBarrierB };
2236 const int numPreBarriers = numSrcBuffers;
2237 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
2238 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
2240 const ComputeCommand compute (m_vki,
2242 pipeline.getPipeline(),
2243 pipeline.getPipelineLayout(),
2244 tcu::UVec3(4, 1, 1),
2245 numDescriptorSets, descriptorSets,
2246 numDynamicOffsets, dynamicOffsets,
2247 numPreBarriers, preBarriers,
2248 numPostBarriers, postBarriers);
2250 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2251 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorB2) :
2252 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2254 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2255 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorA1) :
2256 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2258 const tcu::Vec4 references[4] =
2265 tcu::Vec4 results[4];
2267 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2268 m_result.readResultContentsTo(&results);
2271 if (results[0] == references[0] &&
2272 results[1] == references[1] &&
2273 results[2] == references[2] &&
2274 results[3] == references[3])
2276 return tcu::TestStatus::pass("Pass");
2278 else if (results[0] == tcu::Vec4(-1.0f) &&
2279 results[1] == tcu::Vec4(-1.0f) &&
2280 results[2] == tcu::Vec4(-1.0f) &&
2281 results[3] == tcu::Vec4(-1.0f))
2283 m_context.getTestContext().getLog()
2284 << tcu::TestLog::Message
2285 << "Result buffer was not written to."
2286 << tcu::TestLog::EndMessage;
2287 return tcu::TestStatus::fail("Result buffer was not written to");
2291 m_context.getTestContext().getLog()
2292 << tcu::TestLog::Message
2293 << "Error expected ["
2294 << references[0] << ", "
2295 << references[1] << ", "
2296 << references[2] << ", "
2297 << references[3] << "], got ["
2298 << results[0] << ", "
2299 << results[1] << ", "
2300 << results[2] << ", "
2301 << results[3] << "]"
2302 << tcu::TestLog::EndMessage;
2303 return tcu::TestStatus::fail("Invalid result values");
2307 class QuadrantRendederCase : public vkt::TestCase
2310 QuadrantRendederCase (tcu::TestContext& testCtx,
2312 const char* description,
2313 glu::GLSLVersion glslVersion,
2314 vk::VkShaderStageFlags exitingStages,
2315 vk::VkShaderStageFlags activeStages);
2317 virtual std::string genExtensionDeclarations (vk::VkShaderStage stage) const = 0;
2318 virtual std::string genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const = 0;
2319 virtual std::string genResourceAccessSource (vk::VkShaderStage stage) const = 0;
2320 virtual std::string genNoAccessSource (void) const = 0;
2322 std::string genVertexSource (void) const;
2323 std::string genTessCtrlSource (void) const;
2324 std::string genTessEvalSource (void) const;
2325 std::string genGeometrySource (void) const;
2326 std::string genFragmentSource (void) const;
2327 std::string genComputeSource (void) const;
2329 void initPrograms (vk::SourceCollections& programCollection) const;
2332 const glu::GLSLVersion m_glslVersion;
2333 const vk::VkShaderStageFlags m_exitingStages;
2334 const vk::VkShaderStageFlags m_activeStages;
2337 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2339 const char* description,
2340 glu::GLSLVersion glslVersion,
2341 vk::VkShaderStageFlags exitingStages,
2342 vk::VkShaderStageFlags activeStages)
2343 : vkt::TestCase (testCtx, name, description)
2344 , m_glslVersion (glslVersion)
2345 , m_exitingStages (exitingStages)
2346 , m_activeStages (activeStages)
2348 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2351 std::string QuadrantRendederCase::genVertexSource (void) const
2353 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0u) ? ("tsc")
2354 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2355 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2357 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2358 std::ostringstream buf;
2360 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2362 // active vertex shader
2363 buf << versionDecl << "\n"
2364 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX)
2365 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX, 0)
2366 << "layout(location = 0) out highp vec4 " << nextStageName << "_color;\n"
2367 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2368 << "void main (void)\n"
2370 << " highp vec4 result_position;\n"
2371 << " highp int quadrant_id;\n"
2372 << s_quadrantGenVertexPosSource
2373 << " gl_Position = result_position;\n"
2374 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2376 << " highp vec4 result_color;\n"
2377 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX)
2378 << " " << nextStageName << "_color = result_color;\n"
2384 buf << versionDecl << "\n"
2385 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX)
2386 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2387 << "void main (void)\n"
2389 << " highp vec4 result_position;\n"
2390 << " highp int quadrant_id;\n"
2391 << s_quadrantGenVertexPosSource
2392 << " gl_Position = result_position;\n"
2393 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2400 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2402 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2403 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2404 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2405 std::ostringstream buf;
2407 if ((m_activeStages & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0u)
2409 // contributing not implemented
2410 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESS_CONTROL_BIT);
2413 buf << versionDecl << "\n"
2415 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESS_CONTROL)
2416 << "layout(vertices=3) out;\n"
2417 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESS_CONTROL, 0)
2418 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2419 << "layout(location = 0) out highp vec4 tes_color[];\n"
2420 << "void main (void)\n"
2422 << " highp vec4 result_color;\n"
2423 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2424 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESS_CONTROL)
2426 << " tes_color[gl_InvocationID] = result_color;\n"
2428 << " // no dynamic input block indexing\n"
2429 << " highp vec4 position;\n"
2430 << " if (gl_InvocationID == 0)\n"
2431 << " position = gl_in[0].gl_Position;\n"
2432 << " else if (gl_InvocationID == 1)\n"
2433 << " position = gl_in[1].gl_Position;\n"
2435 << " position = gl_in[2].gl_Position;\n"
2436 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2437 << " gl_TessLevelInner[0] = 2.8;\n"
2438 << " gl_TessLevelInner[1] = 2.8;\n"
2439 << " gl_TessLevelOuter[0] = 2.8;\n"
2440 << " gl_TessLevelOuter[1] = 2.8;\n"
2441 << " gl_TessLevelOuter[2] = 2.8;\n"
2442 << " gl_TessLevelOuter[3] = 2.8;\n"
2445 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0u)
2447 // active te shader, tc passthru
2448 buf << versionDecl << "\n"
2450 << "layout(vertices=3) out;\n"
2451 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2452 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2453 << "void main (void)\n"
2455 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2457 << " // no dynamic input block indexing\n"
2458 << " highp vec4 position;\n"
2459 << " if (gl_InvocationID == 0)\n"
2460 << " position = gl_in[0].gl_Position;\n"
2461 << " else if (gl_InvocationID == 1)\n"
2462 << " position = gl_in[1].gl_Position;\n"
2464 << " position = gl_in[2].gl_Position;\n"
2465 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2466 << " gl_TessLevelInner[0] = 2.8;\n"
2467 << " gl_TessLevelInner[1] = 2.8;\n"
2468 << " gl_TessLevelOuter[0] = 2.8;\n"
2469 << " gl_TessLevelOuter[1] = 2.8;\n"
2470 << " gl_TessLevelOuter[2] = 2.8;\n"
2471 << " gl_TessLevelOuter[3] = 2.8;\n"
2476 // passthrough not implemented
2477 DE_FATAL("not implemented");
2483 std::string QuadrantRendederCase::genTessEvalSource (void) const
2485 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2486 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2487 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2488 std::ostringstream buf;
2490 if ((m_activeStages & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0u)
2492 // contributing not implemented
2493 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT);
2496 buf << versionDecl << "\n"
2498 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESS_EVALUATION)
2499 << "layout(triangles) in;\n"
2500 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESS_EVALUATION, 0)
2501 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2502 << "layout(location = 0) out highp vec4 frag_color;\n"
2503 << "void main (void)\n"
2505 << " highp vec4 result_color;\n"
2506 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2507 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESS_EVALUATION)
2509 << " frag_color = result_color;\n"
2510 << " 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"
2513 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0u)
2515 // contributing not implemented
2516 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESS_CONTROL_BIT);
2518 // active tc shader, te is passthru
2519 buf << versionDecl << "\n"
2521 << "layout(triangles) in;\n"
2522 << "layout(location = 0) in highp vec4 tes_color[];\n"
2523 << "layout(location = 0) out highp vec4 frag_color;\n"
2524 << "void main (void)\n"
2526 << " frag_color = tes_color[0];\n"
2527 << " 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"
2532 // passthrough not implemented
2533 DE_FATAL("not implemented");
2539 std::string QuadrantRendederCase::genGeometrySource (void) const
2541 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2542 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2543 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
2544 std::ostringstream buf;
2546 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2548 // contributing not implemented
2549 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
2551 // active geometry shader
2552 buf << versionDecl << "\n"
2554 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY)
2555 << "layout(triangles) in;\n"
2556 << "layout(triangle_strip, max_vertices=4) out;\n"
2557 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY, 0)
2558 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
2559 << "layout(location = 0) out highp vec4 frag_color;\n"
2560 << "void main (void)\n"
2562 << " highp int quadrant_id;\n"
2563 << " highp vec4 result_color;\n"
2565 << " quadrant_id = geo_quadrant_id[0];\n"
2566 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY)
2567 << " frag_color = result_color;\n"
2568 << " gl_Position = gl_in[0].gl_Position;\n"
2569 << " EmitVertex();\n"
2571 << " quadrant_id = geo_quadrant_id[1];\n"
2572 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY)
2573 << " frag_color = result_color;\n"
2574 << " gl_Position = gl_in[1].gl_Position;\n"
2575 << " EmitVertex();\n"
2577 << " quadrant_id = geo_quadrant_id[2];\n"
2578 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY)
2579 << " frag_color = result_color;\n"
2580 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
2581 << " EmitVertex();\n"
2583 << " quadrant_id = geo_quadrant_id[0];\n"
2584 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY)
2585 << " frag_color = result_color;\n"
2586 << " gl_Position = gl_in[2].gl_Position;\n"
2587 << " EmitVertex();\n"
2592 // passthrough not implemented
2593 DE_FATAL("not implemented");
2599 std::string QuadrantRendederCase::genFragmentSource (void) const
2601 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2602 std::ostringstream buf;
2604 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2606 buf << versionDecl << "\n"
2607 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY)
2608 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT, 0);
2610 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2612 // there are other stages, this is just a contributor
2613 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
2616 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2617 << "layout(location = 0) out mediump vec4 o_color;\n"
2618 << "void main (void)\n"
2620 << " highp int quadrant_id = frag_quadrant_id;\n"
2621 << " highp vec4 result_color;\n"
2622 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT);
2624 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2627 buf << " if (frag_quadrant_id < 2)\n"
2628 << " o_color = result_color;\n"
2630 << " o_color = frag_color;\n";
2633 buf << " o_color = result_color;\n";
2637 else if (m_activeStages == 0u)
2639 // special case, no active stages
2640 buf << versionDecl << "\n"
2641 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2642 << "layout(location = 0) out mediump vec4 o_color;\n"
2643 << "void main (void)\n"
2645 << " highp int quadrant_id = frag_quadrant_id;\n"
2646 << " highp vec4 result_color;\n"
2647 << genNoAccessSource()
2648 << " o_color = result_color;\n"
2654 buf << versionDecl << "\n"
2655 << "layout(location = 0) in mediump vec4 frag_color;\n"
2656 "layout(location = 0) out mediump vec4 o_color;\n"
2657 "void main (void)\n"
2659 " o_color = frag_color;\n"
2666 std::string QuadrantRendederCase::genComputeSource (void) const
2668 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2669 std::ostringstream buf;
2671 buf << versionDecl << "\n"
2672 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE)
2673 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2674 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE, 1)
2675 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
2677 << " highp vec4 read_colors[4];\n"
2679 << "void main(void)\n"
2681 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
2682 << " highp vec4 result_color;\n"
2683 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE)
2684 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
2690 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
2692 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2693 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
2695 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0u)
2696 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
2698 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0u)
2699 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
2701 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2702 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
2704 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2705 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
2707 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
2708 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
2711 class BufferDescriptorCase : public QuadrantRendederCase
2716 FLAG_VIEW_OFFSET = (1u << 1u),
2717 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
2718 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
2720 // enum continues where resource flags ends
2721 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
2723 BufferDescriptorCase (tcu::TestContext& testCtx,
2725 const char* description,
2726 bool isPrimaryCmdBuf,
2727 vk::VkDescriptorType descriptorType,
2728 vk::VkShaderStageFlags exitingStages,
2729 vk::VkShaderStageFlags activeStages,
2730 ShaderInputInterface shaderInterface,
2734 std::string genExtensionDeclarations (vk::VkShaderStage stage) const;
2735 std::string genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const;
2736 std::string genResourceAccessSource (vk::VkShaderStage stage) const;
2737 std::string genNoAccessSource (void) const;
2739 vkt::TestInstance* createInstance (vkt::Context& context) const;
2741 const bool m_viewOffset;
2742 const bool m_dynamicOffsetSet;
2743 const bool m_dynamicOffsetNonZero;
2744 const bool m_isPrimaryCmdBuf;
2745 const vk::VkDescriptorType m_descriptorType;
2746 const ShaderInputInterface m_shaderInterface;
2749 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
2751 const char* description,
2752 bool isPrimaryCmdBuf,
2753 vk::VkDescriptorType descriptorType,
2754 vk::VkShaderStageFlags exitingStages,
2755 vk::VkShaderStageFlags activeStages,
2756 ShaderInputInterface shaderInterface,
2758 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
2759 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
2760 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
2761 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
2762 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
2763 , m_descriptorType (descriptorType)
2764 , m_shaderInterface (shaderInterface)
2768 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStage stage) const
2774 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const
2778 const bool isUniform = isUniformDescriptorType(m_descriptorType);
2779 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
2780 std::ostringstream buf;
2782 switch (m_shaderInterface)
2784 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2785 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2787 << " highp vec4 colorA;\n"
2788 << " highp vec4 colorB;\n"
2789 << "} b_instance;\n";
2792 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2793 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
2795 << " highp vec4 colorA;\n"
2796 << " highp vec4 colorB;\n"
2797 << "} b_instanceA;\n"
2798 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
2800 << " highp vec4 colorA;\n"
2801 << " highp vec4 colorB;\n"
2802 << "} b_instanceB;\n";
2805 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2806 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2808 << " highp vec4 colorA;\n"
2809 << " highp vec4 colorB;\n"
2810 << "} b_instances[2];\n";
2814 DE_FATAL("Impossible");
2820 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStage stage) const
2824 std::ostringstream buf;
2826 switch (m_shaderInterface)
2828 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2829 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2830 << " result_color = b_instance.colorA;\n"
2832 << " result_color = b_instance.colorB;\n";
2835 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2836 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2837 << " result_color = b_instanceA.colorA;\n"
2839 << " result_color = b_instanceB.colorB;\n";
2842 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2843 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2844 << " result_color = b_instances[0].colorA;\n"
2846 << " result_color = b_instances[1].colorB;\n";
2850 DE_FATAL("Impossible");
2856 std::string BufferDescriptorCase::genNoAccessSource (void) const
2858 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
2859 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2861 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
2864 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
2866 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
2868 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
2869 return new BufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2872 return new BufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2875 class ImageInstanceImages
2878 ImageInstanceImages (const vk::DeviceInterface& vki,
2879 vk::VkDevice device,
2880 deUint32 queueFamilyIndex,
2882 vk::Allocator& allocator,
2883 vk::VkDescriptorType descriptorType,
2884 vk::VkImageViewType viewType,
2886 deUint32 baseMipLevel,
2887 deUint32 baseArraySlice);
2890 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
2891 vk::VkDevice device,
2892 vk::Allocator& allocator,
2893 vk::VkDescriptorType descriptorType,
2894 vk::VkImageViewType viewType,
2895 const tcu::TextureLevelPyramid& sourceImage,
2896 de::MovePtr<vk::Allocation>* outAllocation);
2898 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
2899 vk::VkDevice device,
2900 vk::VkImageViewType viewType,
2901 const tcu::TextureLevelPyramid& sourceImage,
2903 deUint32 baseMipLevel,
2904 deUint32 baseArraySlice);
2906 void populateSourceImage (tcu::TextureLevelPyramid* dst,
2907 bool isFirst) const;
2909 void uploadImage (const vk::DeviceInterface& vki,
2910 vk::VkDevice device,
2911 deUint32 queueFamilyIndex,
2913 vk::Allocator& allocator,
2915 const tcu::TextureLevelPyramid& data);
2925 const vk::VkImageViewType m_viewType;
2926 const deUint32 m_baseMipLevel;
2927 const deUint32 m_baseArraySlice;
2929 const tcu::TextureFormat m_imageFormat;
2930 tcu::TextureLevelPyramid m_sourceImageA;
2931 tcu::TextureLevelPyramid m_sourceImageB;
2933 de::MovePtr<vk::Allocation> m_imageMemoryA;
2934 de::MovePtr<vk::Allocation> m_imageMemoryB;
2935 vk::Move<vk::VkImage> m_imageA;
2936 vk::Move<vk::VkImage> m_imageB;
2937 vk::Move<vk::VkImageView> m_imageViewA;
2938 vk::Move<vk::VkImageView> m_imageViewB;
2941 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
2942 vk::VkDevice device,
2943 deUint32 queueFamilyIndex,
2945 vk::Allocator& allocator,
2946 vk::VkDescriptorType descriptorType,
2947 vk::VkImageViewType viewType,
2949 deUint32 baseMipLevel,
2950 deUint32 baseArraySlice)
2951 : m_viewType (viewType)
2952 , m_baseMipLevel (baseMipLevel)
2953 , m_baseArraySlice (baseArraySlice)
2954 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
2955 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
2956 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
2957 , m_imageMemoryA (DE_NULL)
2958 , m_imageMemoryB (DE_NULL)
2959 , m_imageA (vk::Move<vk::VkImage>())
2960 , m_imageB (vk::Move<vk::VkImage>())
2961 , m_imageViewA (vk::Move<vk::VkImageView>())
2962 , m_imageViewB (vk::Move<vk::VkImageView>())
2964 DE_ASSERT(numImages == 1 || numImages == 2);
2966 populateSourceImage(&m_sourceImageA, true);
2967 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
2968 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
2969 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, m_sourceImageA);
2973 populateSourceImage(&m_sourceImageB, false);
2974 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
2975 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
2976 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, m_sourceImageB);
2980 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
2981 vk::VkDevice device,
2982 vk::Allocator& allocator,
2983 vk::VkDescriptorType descriptorType,
2984 vk::VkImageViewType viewType,
2985 const tcu::TextureLevelPyramid& sourceImage,
2986 de::MovePtr<vk::Allocation>* outAllocation)
2988 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2989 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
2990 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
2991 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
2992 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
2993 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
2994 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2995 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
2997 const vk::VkExtent3D extent =
3000 (deInt32)baseLevel.getWidth(),
3003 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (deInt32)baseLevel.getHeight(),
3006 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deInt32)baseLevel.getDepth()) : (1),
3008 const vk::VkImageCreateInfo createInfo =
3010 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
3012 viewTypeToImageType(viewType), // imageType
3013 mapToVkTextureFormat(baseLevel.getFormat()), // format
3015 (deUint32)sourceImage.getNumLevels(), // mipLevels
3016 arraySize, // arraySize
3018 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
3019 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT, // usage
3020 isCube ? ((deUint32)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) : (0u), // flags
3021 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3022 0u, // queueFamilyCount
3023 DE_NULL, // pQueueFamilyIndices
3025 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
3027 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
3031 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
3032 vk::VkDevice device,
3033 vk::VkImageViewType viewType,
3034 const tcu::TextureLevelPyramid& sourceImage,
3036 deUint32 baseMipLevel,
3037 deUint32 baseArraySlice)
3039 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
3040 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
3041 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
3042 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
3043 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
3044 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
3045 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
3046 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
3047 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
3050 DE_ASSERT(viewArraySize > 0);
3052 const vk::VkImageSubresourceRange resourceRange =
3054 vk::VK_IMAGE_ASPECT_COLOR, // aspect
3055 baseMipLevel, // baseMipLevel
3056 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
3057 viewTypeBaseSlice, // baseArraySlice
3058 viewArraySize, // arraySize
3060 const vk::VkImageViewCreateInfo createInfo =
3062 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
3065 viewType, // viewType
3066 mapToVkTextureFormat(baseLevel.getFormat()), // format
3068 vk::VK_CHANNEL_SWIZZLE_R,
3069 vk::VK_CHANNEL_SWIZZLE_G,
3070 vk::VK_CHANNEL_SWIZZLE_B,
3071 vk::VK_CHANNEL_SWIZZLE_A
3073 resourceRange, // subresourceRange
3075 return vk::createImageView(vki, device, &createInfo);
3078 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
3080 const int numLevels = dst->getNumLevels();
3082 for (int level = 0; level < numLevels; ++level)
3084 const int width = IMAGE_SIZE >> level;
3085 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
3086 : (IMAGE_SIZE >> level);
3087 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
3088 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
3089 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
3090 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
3093 dst->allocLevel(level, width, height, depth);
3096 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
3098 for (int z = 0; z < depth; ++z)
3099 for (int y = 0; y < height; ++y)
3100 for (int x = 0; x < width; ++x)
3102 const int gradPos = x + y + z;
3103 const int gradMax = width + height + depth - 3;
3105 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
3106 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
3107 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
3109 DE_ASSERT(de::inRange(red, 0, 255));
3110 DE_ASSERT(de::inRange(green, 0, 255));
3111 DE_ASSERT(de::inRange(blue, 0, 255));
3113 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3119 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3120 vk::VkDevice device,
3121 deUint32 queueFamilyIndex,
3123 vk::Allocator& allocator,
3125 const tcu::TextureLevelPyramid& data)
3127 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3128 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3129 ((deUint32)ARRAY_SIZE);
3130 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3131 const vk::VkBufferCreateInfo bufferCreateInfo =
3133 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3135 dataBufferSize, // size
3136 vk::VK_BUFFER_USAGE_TRANSFER_SOURCE_BIT, // usage
3138 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3139 0u, // queueFamilyCount
3140 DE_NULL, // pQueueFamilyIndices
3142 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3143 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3144 const vk::VkFenceCreateInfo fenceCreateInfo =
3146 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3150 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3152 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3154 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
3155 vk::VK_MEMORY_INPUT_TRANSFER_BIT, // inputMask
3156 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3157 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3158 *dataBuffer, // buffer
3160 dataBufferSize, // size
3162 const vk::VkImageSubresourceRange fullSubrange =
3164 vk::VK_IMAGE_ASPECT_COLOR, // aspect
3166 (deUint32)data.getNumLevels(), // mipLevels
3167 0u, // baseArraySlice
3168 arraySize, // arraySize
3170 const vk::VkImageMemoryBarrier preImageBarrier =
3172 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3176 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3177 vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, // newLayout
3178 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3179 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3181 fullSubrange // subresourceRange
3183 const vk::VkImageMemoryBarrier postImageBarrier =
3185 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3187 vk::VK_MEMORY_OUTPUT_TRANSFER_BIT, // outputMask
3188 vk::VK_MEMORY_INPUT_SHADER_READ_BIT, // inputMask
3189 vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, // oldLayout
3190 vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, // newLayout
3191 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3192 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3194 fullSubrange // subresourceRange
3196 const vk::VkCmdPoolCreateInfo cmdPoolCreateInfo =
3198 vk::VK_STRUCTURE_TYPE_CMD_POOL_CREATE_INFO,
3200 queueFamilyIndex, // queueFamilyIndex
3201 vk::VK_CMD_POOL_CREATE_TRANSIENT_BIT, // flags
3203 const vk::Unique<vk::VkCmdPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3204 const vk::VkCmdBufferCreateInfo cmdBufCreateInfo =
3206 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_CREATE_INFO,
3208 *cmdPool, // cmdPool
3209 vk::VK_CMD_BUFFER_LEVEL_PRIMARY, // level
3212 const vk::VkCmdBufferBeginInfo cmdBufBeginInfo =
3214 vk::VK_STRUCTURE_TYPE_CMD_BUFFER_BEGIN_INFO,
3216 vk::VK_CMD_BUFFER_OPTIMIZE_SMALL_BATCH_BIT | vk::VK_CMD_BUFFER_OPTIMIZE_ONE_TIME_SUBMIT_BIT, // flags
3217 (vk::VkRenderPass)0u, // renderPass
3218 (vk::VkFramebuffer)0u, // framebuffer
3221 const vk::Unique<vk::VkCmdBuffer> cmd (vk::createCommandBuffer(vki, device, &cmdBufCreateInfo));
3222 const void* const preBarriers[2] = { &preMemoryBarrier, &preImageBarrier };
3223 const void* const postBarriers[1] = { &postImageBarrier };
3224 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device, &fenceCreateInfo));
3225 const deUint64 infiniteTimeout = ~(deUint64)0u;
3226 std::vector<vk::VkBufferImageCopy> copySlices;
3228 // copy data to buffer
3229 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3230 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3232 // record command buffer
3233 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3234 vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_FALSE, DE_LENGTH_OF_ARRAY(preBarriers), preBarriers);
3235 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DESTINATION_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3236 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_FALSE, DE_LENGTH_OF_ARRAY(postBarriers), postBarriers);
3237 VK_CHECK(vki.endCommandBuffer(*cmd));
3239 // submit and wait for command buffer to complete before killing it
3240 VK_CHECK(vki.queueSubmit(queue, 1, &cmd.get(), *cmdCompleteFence));
3241 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3244 class ImageFetchInstanceImages : private ImageInstanceImages
3247 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3248 vk::VkDevice device,
3249 deUint32 queueFamilyIndex,
3251 vk::Allocator& allocator,
3252 vk::VkDescriptorType descriptorType,
3253 ShaderInputInterface shaderInterface,
3254 vk::VkImageViewType viewType,
3255 deUint32 baseMipLevel,
3256 deUint32 baseArraySlice);
3258 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3259 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3261 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3262 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3267 // some arbitrary sample points for all four quadrants
3268 SAMPLE_POINT_0_X = 6,
3269 SAMPLE_POINT_0_Y = 13,
3270 SAMPLE_POINT_0_Z = 49,
3272 SAMPLE_POINT_1_X = 51,
3273 SAMPLE_POINT_1_Y = 40,
3274 SAMPLE_POINT_1_Z = 44,
3276 SAMPLE_POINT_2_X = 42,
3277 SAMPLE_POINT_2_Y = 26,
3278 SAMPLE_POINT_2_Z = 19,
3280 SAMPLE_POINT_3_X = 25,
3281 SAMPLE_POINT_3_Y = 25,
3282 SAMPLE_POINT_3_Z = 18,
3285 const ShaderInputInterface m_shaderInterface;
3288 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3289 vk::VkDevice device,
3290 deUint32 queueFamilyIndex,
3292 vk::Allocator& allocator,
3293 vk::VkDescriptorType descriptorType,
3294 ShaderInputInterface shaderInterface,
3295 vk::VkImageViewType viewType,
3296 deUint32 baseMipLevel,
3297 deUint32 baseArraySlice)
3298 : ImageInstanceImages (vki,
3305 getInterfaceNumResources(shaderInterface), // numImages
3308 , m_shaderInterface (shaderInterface)
3312 bool isImageViewTypeArray (vk::VkImageViewType type)
3314 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;
3317 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3319 const tcu::IVec3 fetchPositions[4] =
3321 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3322 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3323 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3324 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3326 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3327 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3328 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3332 case vk::VK_IMAGE_VIEW_TYPE_1D:
3333 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3334 case vk::VK_IMAGE_VIEW_TYPE_2D:
3335 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3336 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3337 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3338 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3340 DE_FATAL("Impossible");
3341 return tcu::IVec3();
3345 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3347 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3349 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3350 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3351 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3352 const tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3354 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3357 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3360 ImageFetchRenderInstance (vkt::Context& context,
3361 bool isPrimaryCmdBuf,
3362 vk::VkDescriptorType descriptorType,
3363 vk::VkShaderStageFlags stageFlags,
3364 ShaderInputInterface shaderInterface,
3365 vk::VkImageViewType viewType,
3366 deUint32 baseMipLevel,
3367 deUint32 baseArraySlice);
3370 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3371 vk::VkDevice device,
3372 vk::VkDescriptorType descriptorType,
3373 ShaderInputInterface shaderInterface,
3374 vk::VkShaderStageFlags stageFlags);
3376 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3377 vk::VkDevice device,
3378 vk::VkDescriptorSetLayout descriptorSetLayout);
3380 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3381 vk::VkDevice device,
3382 vk::VkDescriptorType descriptorType,
3383 ShaderInputInterface shaderInterface);
3385 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3386 vk::VkDevice device,
3387 vk::VkDescriptorType descriptorType,
3388 ShaderInputInterface shaderInterface,
3389 vk::VkDescriptorSetLayout layout,
3390 vk::VkDescriptorPool pool,
3391 vk::VkImageView viewA,
3392 vk::VkImageView viewB);
3394 void logTestPlan (void) const;
3395 vk::VkPipelineLayout getPipelineLayout (void) const;
3396 void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const;
3397 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3404 const vk::VkDescriptorType m_descriptorType;
3405 const vk::VkShaderStageFlags m_stageFlags;
3406 const ShaderInputInterface m_shaderInterface;
3407 const vk::VkImageViewType m_viewType;
3408 const deUint32 m_baseMipLevel;
3409 const deUint32 m_baseArraySlice;
3411 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3412 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3413 const ImageFetchInstanceImages m_images;
3414 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3415 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3418 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3419 bool isPrimaryCmdBuf,
3420 vk::VkDescriptorType descriptorType,
3421 vk::VkShaderStageFlags stageFlags,
3422 ShaderInputInterface shaderInterface,
3423 vk::VkImageViewType viewType,
3424 deUint32 baseMipLevel,
3425 deUint32 baseArraySlice)
3426 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3427 , m_descriptorType (descriptorType)
3428 , m_stageFlags (stageFlags)
3429 , m_shaderInterface (shaderInterface)
3430 , m_viewType (viewType)
3431 , m_baseMipLevel (baseMipLevel)
3432 , m_baseArraySlice (baseArraySlice)
3433 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
3434 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3435 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3436 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3437 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_images.getImageViewA(), m_images.getImageViewB()))
3441 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3442 vk::VkDevice device,
3443 vk::VkDescriptorType descriptorType,
3444 ShaderInputInterface shaderInterface,
3445 vk::VkShaderStageFlags stageFlags)
3447 vk::DescriptorSetLayoutBuilder builder;
3449 switch (shaderInterface)
3451 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3452 builder.addSingleBinding(descriptorType, stageFlags);
3455 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3456 builder.addSingleBinding(descriptorType, stageFlags);
3457 builder.addSingleBinding(descriptorType, stageFlags);
3460 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3461 builder.addArrayBinding(descriptorType, 2u, stageFlags);
3465 DE_FATAL("Impossible");
3468 return builder.build(vki, device);
3471 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
3472 vk::VkDevice device,
3473 vk::VkDescriptorSetLayout descriptorSetLayout)
3475 const vk::VkPipelineLayoutCreateInfo createInfo =
3477 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3479 1, // descriptorSetCount
3480 &descriptorSetLayout, // pSetLayouts
3481 0u, // pushConstantRangeCount
3482 DE_NULL, // pPushConstantRanges
3484 return vk::createPipelineLayout(vki, device, &createInfo);
3487 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
3488 vk::VkDevice device,
3489 vk::VkDescriptorType descriptorType,
3490 ShaderInputInterface shaderInterface)
3492 return vk::DescriptorPoolBuilder()
3493 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
3494 .build(vki, device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
3497 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
3498 vk::VkDevice device,
3499 vk::VkDescriptorType descriptorType,
3500 ShaderInputInterface shaderInterface,
3501 vk::VkDescriptorSetLayout layout,
3502 vk::VkDescriptorPool pool,
3503 vk::VkImageView viewA,
3504 vk::VkImageView viewB)
3506 const vk::VkDescriptorInfo imageInfos[2] =
3508 createDescriptorInfo(viewA, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3509 createDescriptorInfo(viewB, vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3512 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(vki, device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
3513 vk::DescriptorSetUpdateBuilder builder;
3515 switch (shaderInterface)
3517 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3518 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3521 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3522 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3523 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
3526 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3527 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
3531 DE_FATAL("Impossible");
3534 builder.update(vki, device);
3535 return descriptorSet;
3538 void ImageFetchRenderInstance::logTestPlan (void) const
3540 std::ostringstream msg;
3542 msg << "Rendering 2x2 grid.\n"
3543 << "Single descriptor set. Descriptor set contains "
3544 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3545 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3546 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3547 (const char*)DE_NULL)
3548 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3549 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3552 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3553 if (m_baseArraySlice)
3554 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3556 if (m_stageFlags == 0u)
3558 msg << "Descriptors are not accessed in any shader stage.\n";
3562 msg << "Color in each cell is fetched using the descriptor(s):\n";
3564 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3566 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3568 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3570 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3571 msg << " from descriptor " << srcResourceNdx;
3577 msg << "Descriptors are accessed in {"
3578 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
3579 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0) ? (" tess_control") : (""))
3580 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
3581 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
3582 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
3586 m_context.getTestContext().getLog()
3587 << tcu::TestLog::Message
3589 << tcu::TestLog::EndMessage;
3592 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
3594 return *m_pipelineLayout;
3597 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const
3599 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
3600 m_vki.cmdDraw(cmd, 0, 6 * 4, 0, 1); // render four quads (two separate triangles)
3603 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
3605 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3606 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
3607 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
3608 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
3609 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
3610 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
3611 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
3612 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
3614 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
3616 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
3617 return tcu::TestStatus::fail("Image verification failed");
3619 return tcu::TestStatus::pass("Pass");
3622 class ImageFetchComputeInstance : public vkt::TestInstance
3625 ImageFetchComputeInstance (vkt::Context& context,
3626 vk::VkDescriptorType descriptorType,
3627 ShaderInputInterface shaderInterface,
3628 vk::VkImageViewType viewType,
3629 deUint32 baseMipLevel,
3630 deUint32 baseArraySlice);
3633 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
3634 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
3635 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
3637 tcu::TestStatus iterate (void);
3638 void logTestPlan (void) const;
3639 tcu::TestStatus testResourceAccess (void);
3641 const vk::VkDescriptorType m_descriptorType;
3642 const ShaderInputInterface m_shaderInterface;
3643 const vk::VkImageViewType m_viewType;
3644 const deUint32 m_baseMipLevel;
3645 const deUint32 m_baseArraySlice;
3647 const vk::DeviceInterface& m_vki;
3648 const vk::VkDevice m_device;
3649 const vk::VkQueue m_queue;
3650 const deUint32 m_queueFamilyIndex;
3651 vk::Allocator& m_allocator;
3653 const ComputeInstanceResultBuffer m_result;
3654 const ImageFetchInstanceImages m_images;
3657 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
3658 vk::VkDescriptorType descriptorType,
3659 ShaderInputInterface shaderInterface,
3660 vk::VkImageViewType viewType,
3661 deUint32 baseMipLevel,
3662 deUint32 baseArraySlice)
3663 : vkt::TestInstance (context)
3664 , m_descriptorType (descriptorType)
3665 , m_shaderInterface (shaderInterface)
3666 , m_viewType (viewType)
3667 , m_baseMipLevel (baseMipLevel)
3668 , m_baseArraySlice (baseArraySlice)
3669 , m_vki (context.getDeviceInterface())
3670 , m_device (context.getDevice())
3671 , m_queue (context.getUniversalQueue())
3672 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
3673 , m_allocator (context.getDefaultAllocator())
3674 , m_result (m_vki, m_device, m_allocator)
3675 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3679 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
3681 vk::DescriptorSetLayoutBuilder builder;
3683 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3685 switch (m_shaderInterface)
3687 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3688 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3691 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3692 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3693 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3696 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3697 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3701 DE_FATAL("Impossible");
3704 return builder.build(m_vki, m_device);
3707 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
3709 return vk::DescriptorPoolBuilder()
3710 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3711 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
3712 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
3715 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
3717 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(m_result.getBufferView());
3718 const vk::VkDescriptorInfo imageInfos[2] =
3720 createDescriptorInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3721 createDescriptorInfo(m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
3724 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
3725 vk::DescriptorSetUpdateBuilder builder;
3728 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
3731 switch (m_shaderInterface)
3733 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3734 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3737 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3738 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3739 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
3742 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3743 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
3747 DE_FATAL("Impossible");
3750 builder.update(m_vki, m_device);
3751 return descriptorSet;
3754 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
3757 return testResourceAccess();
3760 void ImageFetchComputeInstance::logTestPlan (void) const
3762 std::ostringstream msg;
3764 msg << "Fetching 4 values from image in compute shader.\n"
3765 << "Single descriptor set. Descriptor set contains "
3766 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3767 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3768 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3769 (const char*)DE_NULL)
3770 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3771 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3774 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3775 if (m_baseArraySlice)
3776 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3778 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3780 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3782 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3784 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3785 msg << " from descriptor " << srcResourceNdx;
3791 m_context.getTestContext().getLog()
3792 << tcu::TestLog::Message
3794 << tcu::TestLog::EndMessage;
3797 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
3799 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
3800 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
3801 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
3802 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
3804 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
3805 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
3806 const deUint32* const dynamicOffsets = DE_NULL;
3807 const int numDynamicOffsets = 0;
3808 const void* const* preBarriers = DE_NULL;
3809 const int numPreBarriers = 0;
3810 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
3811 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
3813 const ComputeCommand compute (m_vki,
3815 pipeline.getPipeline(),
3816 pipeline.getPipelineLayout(),
3817 tcu::UVec3(4, 1, 1),
3818 numDescriptorSets, descriptorSets,
3819 numDynamicOffsets, dynamicOffsets,
3820 numPreBarriers, preBarriers,
3821 numPostBarriers, postBarriers);
3823 tcu::Vec4 results[4];
3824 bool anyResultSet = false;
3825 bool allResultsOk = true;
3827 compute.submitAndWait(m_queueFamilyIndex, m_queue);
3828 m_result.readResultContentsTo(&results);
3831 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3833 const tcu::Vec4 result = results[resultNdx];
3834 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
3835 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
3837 if (result != tcu::Vec4(-1.0f))
3838 anyResultSet = true;
3840 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
3842 allResultsOk = false;
3844 m_context.getTestContext().getLog()
3845 << tcu::TestLog::Message
3846 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
3847 << tcu::TestLog::EndMessage;
3851 // read back and verify
3853 return tcu::TestStatus::pass("Pass");
3854 else if (anyResultSet)
3855 return tcu::TestStatus::fail("Invalid result values");
3858 m_context.getTestContext().getLog()
3859 << tcu::TestLog::Message
3860 << "Result buffer was not written to."
3861 << tcu::TestLog::EndMessage;
3862 return tcu::TestStatus::fail("Result buffer was not written to");
3866 class ImageSampleInstanceImages : private ImageInstanceImages
3869 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3870 vk::VkDevice device,
3871 deUint32 queueFamilyIndex,
3873 vk::Allocator& allocator,
3874 vk::VkDescriptorType descriptorType,
3875 ShaderInputInterface shaderInterface,
3876 vk::VkImageViewType viewType,
3877 deUint32 baseMipLevel,
3878 deUint32 baseArraySlice,
3881 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
3882 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
3884 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3885 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3886 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
3887 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
3888 inline bool isImmutable (void) const { return m_isImmutable; }
3891 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
3892 static tcu::Sampler createRefSampler (bool isFirst);
3893 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
3895 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3896 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3897 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3898 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3900 const vk::VkDescriptorType m_descriptorType;
3901 const ShaderInputInterface m_shaderInterface;
3902 const bool m_isImmutable;
3904 const tcu::Sampler m_refSamplerA;
3905 const tcu::Sampler m_refSamplerB;
3906 const vk::Unique<vk::VkSampler> m_samplerA;
3907 const vk::Unique<vk::VkSampler> m_samplerB;
3910 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3911 vk::VkDevice device,
3912 deUint32 queueFamilyIndex,
3914 vk::Allocator& allocator,
3915 vk::VkDescriptorType descriptorType,
3916 ShaderInputInterface shaderInterface,
3917 vk::VkImageViewType viewType,
3918 deUint32 baseMipLevel,
3919 deUint32 baseArraySlice,
3921 : ImageInstanceImages (vki,
3928 getNumImages(descriptorType, shaderInterface),
3931 , m_descriptorType (descriptorType)
3932 , m_shaderInterface (shaderInterface)
3933 , m_isImmutable (immutable)
3934 , m_refSamplerA (createRefSampler(true))
3935 , m_refSamplerB (createRefSampler(false))
3936 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
3937 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
3938 ? vk::Move<vk::VkSampler>()
3939 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
3943 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
3945 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3947 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3948 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3950 // choose arbitrary values that are not ambiguous with NEAREST filtering
3954 case vk::VK_IMAGE_VIEW_TYPE_1D:
3955 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
3956 case vk::VK_IMAGE_VIEW_TYPE_2D:
3957 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
3958 case vk::VK_IMAGE_VIEW_TYPE_3D:
3960 const tcu::Vec3 coords[4] =
3964 (float)(12u % imageSize) + 0.25f),
3966 tcu::Vec3((float)(23u % imageSize) + 0.25f,
3967 (float)(73u % imageSize) + 0.5f,
3968 (float)(16u % imageSize) + 0.5f + (float)imageSize),
3970 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
3971 (float)(84u % imageSize) + 0.5f + (float)imageSize,
3972 (float)(117u % imageSize) + 0.75f),
3974 tcu::Vec3((float)imageSize + 0.5f,
3975 (float)(75u % imageSize) + 0.25f,
3976 (float)(83u % imageSize) + 0.25f + (float)imageSize),
3978 const deUint32 slices[4] =
3986 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3987 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3988 (float)slices[samplePosNdx],
3991 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
3992 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3993 coords[samplePosNdx].y() / (float)imageSize,
3994 (float)slices[samplePosNdx],
3996 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
3997 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3998 coords[samplePosNdx].y() / (float)imageSize,
3999 coords[samplePosNdx].z() / (float)imageSize,
4003 DE_FATAL("Impossible");
4008 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4009 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
4011 // \note these values are in [0, texSize]*3 space for convenience
4012 const tcu::Vec3 coords[4] =
4018 tcu::Vec3((float)(13u % imageSize) + 0.25f,
4020 (float)(16u % imageSize) + 0.5f),
4023 (float)(84u % imageSize) + 0.5f,
4024 (float)(10u % imageSize) + 0.75f),
4026 tcu::Vec3((float)imageSize,
4027 (float)(75u % imageSize) + 0.25f,
4028 (float)(83u % imageSize) + 0.75f),
4030 const deUint32 slices[4] =
4038 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
4039 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
4040 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
4042 // map to [-1, 1]*3 space
4043 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
4044 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
4045 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
4046 (float)slices[samplePosNdx]);
4050 DE_FATAL("Impossible");
4055 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
4057 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
4059 // texture order is ABAB
4060 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
4061 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
4062 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
4063 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
4065 // sampler order is ABAB
4066 const tcu::Sampler& samplerA = m_refSamplerA;
4067 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
4068 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
4070 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
4071 const float lod = 0.0f;
4072 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
4076 case vk::VK_IMAGE_VIEW_TYPE_1D:
4077 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
4078 case vk::VK_IMAGE_VIEW_TYPE_2D:
4079 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);
4080 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
4081 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4082 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);
4086 DE_FATAL("Impossible");
4092 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
4094 // If we are testing separate samplers, just one image is enough
4095 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4097 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4099 // combined: numImages == numSamplers
4100 return getInterfaceNumResources(shaderInterface);
4104 DE_FATAL("Impossible");
4109 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4114 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4118 // nearest, clamping
4119 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4123 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4125 const bool compareEnabled = (sampler.compare != tcu::Sampler::COMPAREMODE_NONE);
4126 const vk::VkCompareOp compareOp = (compareEnabled) ? (mapToVkCompareOp(sampler.compare)) : (vk::VK_COMPARE_OP_ALWAYS);
4127 const tcu::TextureChannelClass channelClass = tcu::getTextureChannelClass(format.type);
4128 const bool isIntTexture = channelClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER || channelClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER;
4129 const vk::VkBorderColor borderColor = (isIntTexture) ? (vk::VK_BORDER_COLOR_INT_OPAQUE_WHITE) : (vk::VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE);
4130 const vk::VkSamplerCreateInfo createInfo =
4132 vk::VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
4134 mapMagFilterToVkTexFilter(sampler.magFilter), // magFilter
4135 mapMinFilterToVkTexFilter(sampler.minFilter), // minFilter
4136 mapMinFilterToVkTexMipmapMode(sampler.minFilter), // mipMode
4137 mapToVkTexAddress(sampler.wrapS), // addressU
4138 mapToVkTexAddress(sampler.wrapT), // addressV
4139 mapToVkTexAddress(sampler.wrapR), // addressW
4142 (compareEnabled) ? (vk::VkBool32)(vk::VK_TRUE) : (vk::VkBool32)(vk::VK_FALSE), // compareEnable
4143 compareOp, // compareOp
4146 borderColor, // borderColor
4148 return vk::createSampler(vki, device, &createInfo);
4151 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4153 DE_ASSERT(levelStorage->empty());
4155 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4156 const deUint32 numLevels = (deUint32)source.getNumLevels();
4158 // cut pyramid from baseMipLevel
4159 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4161 // cut levels from baseArraySlice
4162 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4163 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4164 levelStorage->push_back(cutLevel);
4167 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4170 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4172 DE_ASSERT(levelStorage->empty());
4174 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4175 const deUint32 numLevels = (deUint32)source.getNumLevels();
4177 // cut pyramid from baseMipLevel
4178 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4180 // cut levels from baseArraySlice
4181 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4182 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4183 levelStorage->push_back(cutLevel);
4186 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4189 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4191 DE_ASSERT(levelStorage->empty());
4192 DE_ASSERT(baseArraySlice == 0);
4193 DE_UNREF(baseArraySlice);
4195 const deUint32 numLevels = (deUint32)source.getNumLevels();
4197 // cut pyramid from baseMipLevel
4198 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4199 levelStorage->push_back(source.getLevel(level));
4201 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
4204 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4206 DE_ASSERT(levelStorage->empty());
4208 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
4209 const deUint32 numLevels = (deUint32)source.getNumLevels();
4211 // cut pyramid from baseMipLevel
4212 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4214 // cut levels from baseArraySlice
4215 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4216 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
4217 levelStorage->push_back(cutLevel);
4220 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
4223 class ImageSampleRenderInstance : public SingleCmdRenderInstance
4226 ImageSampleRenderInstance (vkt::Context& context,
4227 bool isPrimaryCmdBuf,
4228 vk::VkDescriptorType descriptorType,
4229 vk::VkShaderStageFlags stageFlags,
4230 ShaderInputInterface shaderInterface,
4231 vk::VkImageViewType viewType,
4232 deUint32 baseMipLevel,
4233 deUint32 baseArraySlice,
4237 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
4238 vk::VkDevice device,
4239 vk::VkDescriptorType descriptorType,
4240 ShaderInputInterface shaderInterface,
4241 vk::VkShaderStageFlags stageFlags,
4242 const ImageSampleInstanceImages& images);
4244 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4245 vk::VkDevice device,
4246 vk::VkDescriptorSetLayout descriptorSetLayout);
4248 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4249 vk::VkDevice device,
4250 vk::VkDescriptorType descriptorType,
4251 ShaderInputInterface shaderInterface,
4254 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
4255 vk::VkDevice device,
4256 vk::VkDescriptorType descriptorType,
4257 ShaderInputInterface shaderInterface,
4258 vk::VkDescriptorSetLayout layout,
4259 vk::VkDescriptorPool pool,
4261 const ImageSampleInstanceImages& images);
4263 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4264 vk::VkDevice device,
4265 ShaderInputInterface shaderInterface,
4267 const ImageSampleInstanceImages& images,
4268 vk::VkDescriptorSet descriptorSet);
4270 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4271 vk::VkDevice device,
4272 ShaderInputInterface shaderInterface,
4274 const ImageSampleInstanceImages& images,
4275 vk::VkDescriptorSet descriptorSet);
4277 void logTestPlan (void) const;
4278 vk::VkPipelineLayout getPipelineLayout (void) const;
4279 void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const;
4280 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4287 const vk::VkDescriptorType m_descriptorType;
4288 const vk::VkShaderStageFlags m_stageFlags;
4289 const ShaderInputInterface m_shaderInterface;
4290 const vk::VkImageViewType m_viewType;
4291 const deUint32 m_baseMipLevel;
4292 const deUint32 m_baseArraySlice;
4294 const ImageSampleInstanceImages m_images;
4295 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
4296 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4297 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4298 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
4301 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
4302 bool isPrimaryCmdBuf,
4303 vk::VkDescriptorType descriptorType,
4304 vk::VkShaderStageFlags stageFlags,
4305 ShaderInputInterface shaderInterface,
4306 vk::VkImageViewType viewType,
4307 deUint32 baseMipLevel,
4308 deUint32 baseArraySlice,
4310 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4311 , m_descriptorType (descriptorType)
4312 , m_stageFlags (stageFlags)
4313 , m_shaderInterface (shaderInterface)
4314 , m_viewType (viewType)
4315 , m_baseMipLevel (baseMipLevel)
4316 , m_baseArraySlice (baseArraySlice)
4317 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
4318 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images))
4319 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
4320 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface, isImmutable))
4321 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, isImmutable, m_images))
4325 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
4326 vk::VkDevice device,
4327 vk::VkDescriptorType descriptorType,
4328 ShaderInputInterface shaderInterface,
4329 vk::VkShaderStageFlags stageFlags,
4330 const ImageSampleInstanceImages& images)
4332 const vk::VkSampler samplers[2] =
4334 images.getSamplerA(),
4335 images.getSamplerB(),
4338 vk::DescriptorSetLayoutBuilder builder;
4340 // with samplers, separate texture at binding 0
4341 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4342 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4344 // (combined)samplers follow
4345 switch (shaderInterface)
4347 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4348 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4351 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4352 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4353 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4356 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4357 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
4361 DE_FATAL("Impossible");
4364 return builder.build(vki, device);
4367 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4368 vk::VkDevice device,
4369 vk::VkDescriptorSetLayout descriptorSetLayout)
4371 const vk::VkPipelineLayoutCreateInfo createInfo =
4373 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4375 1, // descriptorSetCount
4376 &descriptorSetLayout, // pSetLayouts
4377 0u, // pushConstantRangeCount
4378 DE_NULL, // pPushConstantRanges
4380 return vk::createPipelineLayout(vki, device, &createInfo);
4383 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4384 vk::VkDevice device,
4385 vk::VkDescriptorType descriptorType,
4386 ShaderInputInterface shaderInterface,
4389 vk::DescriptorPoolBuilder builder;
4391 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4393 // separate samplers need image to sample
4394 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4396 // samplers needed only if they are specified in the descriptor set
4398 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
4400 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4402 // combined image samplers
4403 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
4406 DE_FATAL("Impossible");
4408 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
4411 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
4412 vk::VkDevice device,
4413 vk::VkDescriptorType descriptorType,
4414 ShaderInputInterface shaderInterface,
4415 vk::VkDescriptorSetLayout layout,
4416 vk::VkDescriptorPool pool,
4418 const ImageSampleInstanceImages& images)
4420 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(vki, device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
4422 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4423 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4424 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4425 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4427 DE_FATAL("Impossible");
4429 return descriptorSet;
4432 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4433 vk::VkDevice device,
4434 ShaderInputInterface shaderInterface,
4436 const ImageSampleInstanceImages& images,
4437 vk::VkDescriptorSet descriptorSet)
4439 const vk::VkDescriptorInfo imageInfo = createDescriptorInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4440 const vk::VkDescriptorInfo samplersInfos[2] =
4442 createDescriptorInfo(images.getSamplerA()),
4443 createDescriptorInfo(images.getSamplerB()),
4446 vk::DescriptorSetUpdateBuilder builder;
4448 // stand alone texture
4449 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4454 switch (shaderInterface)
4456 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4457 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4460 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4461 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4462 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4465 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4466 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4470 DE_FATAL("Impossible");
4474 builder.update(vki, device);
4477 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4478 vk::VkDevice device,
4479 ShaderInputInterface shaderInterface,
4481 const ImageSampleInstanceImages& images,
4482 vk::VkDescriptorSet descriptorSet)
4484 const vk::VkSampler samplers[2] =
4486 (isImmutable) ? (0) : (images.getSamplerA()),
4487 (isImmutable) ? (0) : (images.getSamplerB()),
4489 const vk::VkDescriptorInfo imageSamplers[2] =
4491 createDescriptorInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4492 createDescriptorInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4495 vk::DescriptorSetUpdateBuilder builder;
4497 // combined image samplers
4498 switch (shaderInterface)
4500 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4501 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4504 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4505 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4506 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4509 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4510 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4514 DE_FATAL("Impossible");
4517 builder.update(vki, device);
4520 void ImageSampleRenderInstance::logTestPlan (void) const
4522 std::ostringstream msg;
4524 msg << "Rendering 2x2 grid.\n";
4526 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4528 msg << "Single descriptor set. Descriptor set contains "
4529 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4530 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4531 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4532 (const char*)DE_NULL)
4533 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4535 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4537 msg << "Single descriptor set. Descriptor set contains "
4538 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4539 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4540 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4541 (const char*)DE_NULL)
4542 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4545 DE_FATAL("Impossible");
4547 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4550 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4551 if (m_baseArraySlice)
4552 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4554 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4555 msg << "Sampler mode is LINEAR, with WRAP\n";
4557 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4559 if (m_stageFlags == 0u)
4561 msg << "Descriptors are not accessed in any shader stage.\n";
4565 msg << "Color in each cell is fetched using the descriptor(s):\n";
4567 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4569 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4571 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4573 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4575 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4576 msg << " using sampler " << srcResourceNdx;
4577 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4578 msg << " from combined image sampler " << srcResourceNdx;
4580 DE_FATAL("Impossible");
4585 msg << "Descriptors are accessed in {"
4586 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4587 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4588 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4589 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4590 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4594 m_context.getTestContext().getLog()
4595 << tcu::TestLog::Message
4597 << tcu::TestLog::EndMessage;
4600 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
4602 return *m_pipelineLayout;
4605 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const
4607 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4608 m_vki.cmdDraw(cmd, 0u, 6u * 4u, 0u, 1u); // render four quads (two separate triangles)
4611 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4613 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4614 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4615 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4616 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
4617 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
4618 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
4619 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
4620 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
4621 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4623 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4625 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
4626 return tcu::TestStatus::fail("Image verification failed");
4628 return tcu::TestStatus::pass("Pass");
4631 class ImageSampleComputeInstance : public vkt::TestInstance
4634 ImageSampleComputeInstance (vkt::Context& context,
4635 vk::VkDescriptorType descriptorType,
4636 ShaderInputInterface shaderInterface,
4637 vk::VkImageViewType viewType,
4638 deUint32 baseMipLevel,
4639 deUint32 baseArraySlice,
4640 bool isImmutableSampler);
4643 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4644 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4645 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
4646 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4647 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4649 tcu::TestStatus iterate (void);
4650 void logTestPlan (void) const;
4651 tcu::TestStatus testResourceAccess (void);
4653 const vk::VkDescriptorType m_descriptorType;
4654 const ShaderInputInterface m_shaderInterface;
4655 const vk::VkImageViewType m_viewType;
4656 const deUint32 m_baseMipLevel;
4657 const deUint32 m_baseArraySlice;
4658 const bool m_isImmutableSampler;
4660 const vk::DeviceInterface& m_vki;
4661 const vk::VkDevice m_device;
4662 const vk::VkQueue m_queue;
4663 const deUint32 m_queueFamilyIndex;
4664 vk::Allocator& m_allocator;
4666 const ComputeInstanceResultBuffer m_result;
4667 const ImageSampleInstanceImages m_images;
4670 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
4671 vk::VkDescriptorType descriptorType,
4672 ShaderInputInterface shaderInterface,
4673 vk::VkImageViewType viewType,
4674 deUint32 baseMipLevel,
4675 deUint32 baseArraySlice,
4676 bool isImmutableSampler)
4677 : vkt::TestInstance (context)
4678 , m_descriptorType (descriptorType)
4679 , m_shaderInterface (shaderInterface)
4680 , m_viewType (viewType)
4681 , m_baseMipLevel (baseMipLevel)
4682 , m_baseArraySlice (baseArraySlice)
4683 , m_isImmutableSampler (isImmutableSampler)
4684 , m_vki (context.getDeviceInterface())
4685 , m_device (context.getDevice())
4686 , m_queue (context.getUniversalQueue())
4687 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4688 , m_allocator (context.getDefaultAllocator())
4689 , m_result (m_vki, m_device, m_allocator)
4690 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
4694 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
4696 const vk::VkSampler samplers[2] =
4698 m_images.getSamplerA(),
4699 m_images.getSamplerB(),
4702 vk::DescriptorSetLayoutBuilder builder;
4705 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4707 // with samplers, separate texture at binding 0
4708 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4709 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4711 // (combined)samplers follow
4712 switch (m_shaderInterface)
4714 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4715 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4718 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4719 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4720 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4723 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4724 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
4728 DE_FATAL("Impossible");
4731 return builder.build(m_vki, m_device);
4734 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
4736 vk::DescriptorPoolBuilder builder;
4738 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
4739 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
4741 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4742 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4744 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
4747 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
4749 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
4751 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4752 writeSamplerDescriptorSet(*descriptorSet);
4753 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4754 writeImageSamplerDescriptorSet(*descriptorSet);
4756 DE_FATAL("Impossible");
4758 return descriptorSet;
4761 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4763 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(m_result.getBufferView());
4764 const vk::VkDescriptorInfo imageInfo = createDescriptorInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4765 const vk::VkDescriptorInfo samplersInfos[2] =
4767 createDescriptorInfo(m_images.getSamplerA()),
4768 createDescriptorInfo(m_images.getSamplerB()),
4771 vk::DescriptorSetUpdateBuilder builder;
4774 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4776 // stand alone texture
4777 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4780 if (!m_isImmutableSampler)
4782 switch (m_shaderInterface)
4784 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4785 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4788 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4789 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4790 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4793 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4794 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4798 DE_FATAL("Impossible");
4802 builder.update(m_vki, m_device);
4805 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4807 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(m_result.getBufferView());
4808 const vk::VkSampler samplers[2] =
4810 (m_isImmutableSampler) ? (0) : (m_images.getSamplerA()),
4811 (m_isImmutableSampler) ? (0) : (m_images.getSamplerB()),
4813 const vk::VkDescriptorInfo imageSamplers[2] =
4815 createDescriptorInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4816 createDescriptorInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4819 vk::DescriptorSetUpdateBuilder builder;
4822 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4824 // combined image samplers
4825 switch (m_shaderInterface)
4827 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4828 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4831 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4832 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4833 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4836 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4837 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4841 DE_FATAL("Impossible");
4844 builder.update(m_vki, m_device);
4847 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
4850 return testResourceAccess();
4853 void ImageSampleComputeInstance::logTestPlan (void) const
4855 std::ostringstream msg;
4857 msg << "Accessing resource in a compute program.\n";
4859 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4861 msg << "Single descriptor set. Descriptor set contains "
4862 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4863 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4864 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4865 (const char*)DE_NULL)
4866 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4868 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4870 msg << "Single descriptor set. Descriptor set contains "
4871 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4872 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4873 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4874 (const char*)DE_NULL)
4875 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4878 DE_FATAL("Impossible");
4880 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4883 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4884 if (m_baseArraySlice)
4885 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4887 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4888 msg << "Sampler mode is LINEAR, with WRAP\n";
4890 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4892 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4894 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4896 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4898 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4900 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4901 msg << " using sampler " << srcResourceNdx;
4902 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4903 msg << " from combined image sampler " << srcResourceNdx;
4905 DE_FATAL("Impossible");
4910 m_context.getTestContext().getLog()
4911 << tcu::TestLog::Message
4913 << tcu::TestLog::EndMessage;
4916 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
4918 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4919 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4920 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4921 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4923 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4924 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
4925 const deUint32* const dynamicOffsets = DE_NULL;
4926 const int numDynamicOffsets = 0;
4927 const void* const* preBarriers = DE_NULL;
4928 const int numPreBarriers = 0;
4929 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
4930 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
4932 const ComputeCommand compute (m_vki,
4934 pipeline.getPipeline(),
4935 pipeline.getPipelineLayout(),
4936 tcu::UVec3(4, 1, 1),
4937 numDescriptorSets, descriptorSets,
4938 numDynamicOffsets, dynamicOffsets,
4939 numPreBarriers, preBarriers,
4940 numPostBarriers, postBarriers);
4942 tcu::Vec4 results[4];
4943 bool anyResultSet = false;
4944 bool allResultsOk = true;
4946 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4947 m_result.readResultContentsTo(&results);
4950 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4952 const tcu::Vec4 result = results[resultNdx];
4953 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
4955 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
4956 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
4958 if (result != tcu::Vec4(-1.0f))
4959 anyResultSet = true;
4961 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
4963 allResultsOk = false;
4965 m_context.getTestContext().getLog()
4966 << tcu::TestLog::Message
4967 << "Test sample " << resultNdx << ":\n"
4968 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
4969 << "\tError expected " << reference << ", got " << result
4970 << tcu::TestLog::EndMessage;
4974 // read back and verify
4976 return tcu::TestStatus::pass("Pass");
4977 else if (anyResultSet)
4978 return tcu::TestStatus::fail("Invalid result values");
4981 m_context.getTestContext().getLog()
4982 << tcu::TestLog::Message
4983 << "Result buffer was not written to."
4984 << tcu::TestLog::EndMessage;
4985 return tcu::TestStatus::fail("Result buffer was not written to");
4989 class ImageDescriptorCase : public QuadrantRendederCase
4994 FLAG_BASE_MIP = (1u << 1u),
4995 FLAG_BASE_SLICE = (1u << 2u),
4997 // enum continues where resource flags ends
4998 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
5000 ImageDescriptorCase (tcu::TestContext& testCtx,
5002 const char* description,
5003 bool isPrimaryCmdBuf,
5004 vk::VkDescriptorType descriptorType,
5005 vk::VkShaderStageFlags exitingStages,
5006 vk::VkShaderStageFlags activeStages,
5007 ShaderInputInterface shaderInterface,
5008 vk::VkImageViewType viewType,
5012 std::string genExtensionDeclarations (vk::VkShaderStage stage) const;
5013 std::string genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const;
5014 std::string genFetchCoordStr (int fetchPosNdx) const;
5015 std::string genSampleCoordStr (int samplePosNdx) const;
5016 std::string genResourceAccessSource (vk::VkShaderStage stage) const;
5017 std::string genNoAccessSource (void) const;
5019 vkt::TestInstance* createInstance (vkt::Context& context) const;
5022 const bool m_isPrimaryCmdBuf;
5023 const vk::VkDescriptorType m_descriptorType;
5024 const ShaderInputInterface m_shaderInterface;
5025 const vk::VkImageViewType m_viewType;
5026 const deUint32 m_baseMipLevel;
5027 const deUint32 m_baseArraySlice;
5028 const bool m_isImmutableSampler;
5031 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
5033 const char* description,
5034 bool isPrimaryCmdBuf,
5035 vk::VkDescriptorType descriptorType,
5036 vk::VkShaderStageFlags exitingStages,
5037 vk::VkShaderStageFlags activeStages,
5038 ShaderInputInterface shaderInterface,
5039 vk::VkImageViewType viewType,
5041 : QuadrantRendederCase (testCtx, name, description,
5042 // \note 1D textures are not supported in ES
5043 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
5044 exitingStages, activeStages)
5045 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
5046 , m_descriptorType (descriptorType)
5047 , m_shaderInterface (shaderInterface)
5048 , m_viewType (viewType)
5049 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
5050 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
5051 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
5055 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStage stage) const
5059 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5060 return "#extension GL_OES_texture_cube_map_array : require\n";
5065 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const
5069 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
5070 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
5071 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
5072 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5073 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
5075 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5076 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5077 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5078 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5080 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
5082 switch (m_shaderInterface)
5084 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5086 switch (m_descriptorType)
5088 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5089 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n"
5090 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
5091 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5092 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
5093 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5094 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
5095 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5096 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
5098 DE_FATAL("invalid descriptor");
5103 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5104 switch (m_descriptorType)
5106 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5107 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n"
5108 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
5109 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5110 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5111 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
5112 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
5113 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5114 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
5115 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
5116 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5117 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
5118 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
5120 DE_FATAL("invalid descriptor");
5124 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5125 switch (m_descriptorType)
5127 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5128 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n"
5129 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplers[2];\n";
5130 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5131 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
5132 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5133 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
5134 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5135 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
5137 DE_FATAL("invalid descriptor");
5142 DE_FATAL("Impossible");
5147 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
5149 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
5150 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
5152 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5154 return de::toString(fetchPos.x());
5156 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5158 std::ostringstream buf;
5159 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
5164 std::ostringstream buf;
5165 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
5170 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
5172 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
5173 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5175 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5177 std::ostringstream buf;
5178 buf << "float(" << fetchPos.x() << ")";
5181 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5183 std::ostringstream buf;
5184 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
5187 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5189 std::ostringstream buf;
5190 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
5195 std::ostringstream buf;
5196 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
5201 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStage stage) const
5205 const char* const dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5206 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5207 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5208 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5210 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5211 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
5212 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
5214 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5215 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
5216 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
5219 switch (m_descriptorType)
5221 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5222 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5224 const std::string coodStr[4] =
5226 genSampleCoordStr(0),
5227 genSampleCoordStr(1),
5228 genSampleCoordStr(2),
5229 genSampleCoordStr(3),
5231 std::ostringstream buf;
5233 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5235 buf << " if (quadrant_id == 0)\n"
5236 << " result_color = textureLod(sampler" << dimensionArray << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
5237 << " else if (quadrant_id == 1)\n"
5238 << " result_color = textureLod(sampler" << dimensionArray << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
5239 << " else if (quadrant_id == 2)\n"
5240 << " result_color = textureLod(sampler" << dimensionArray << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
5242 << " result_color = textureLod(sampler" << dimensionArray << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
5246 buf << " if (quadrant_id == 0)\n"
5247 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
5248 << " else if (quadrant_id == 1)\n"
5249 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
5250 << " else if (quadrant_id == 2)\n"
5251 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
5253 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
5259 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5260 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5262 const std::string coodStr[4] =
5264 genFetchCoordStr(0),
5265 genFetchCoordStr(1),
5266 genFetchCoordStr(2),
5267 genFetchCoordStr(3),
5269 std::ostringstream buf;
5271 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
5273 buf << " if (quadrant_id == 0)\n"
5274 << " result_color = textureFetch(u_separateTexture" << accessPostfixA << ", " << coodStr[0] << ", 0);\n"
5275 << " else if (quadrant_id == 1)\n"
5276 << " result_color = textureFetch(u_separateTexture" << accessPostfixB << ", " << coodStr[1] << ", 0);\n"
5277 << " else if (quadrant_id == 2)\n"
5278 << " result_color = textureFetch(u_separateTexture" << accessPostfixA << ", " << coodStr[2] << ", 0);\n"
5280 << " result_color = textureFetch(u_separateTexture" << accessPostfixB << ", " << coodStr[3] << ", 0);\n";
5284 buf << " if (quadrant_id == 0)\n"
5285 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
5286 << " else if (quadrant_id == 1)\n"
5287 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
5288 << " else if (quadrant_id == 2)\n"
5289 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
5291 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
5298 DE_FATAL("invalid descriptor");
5303 std::string ImageDescriptorCase::genNoAccessSource (void) const
5305 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
5306 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5308 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
5311 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
5313 switch (m_descriptorType)
5315 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5316 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5317 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5319 DE_ASSERT(m_isPrimaryCmdBuf);
5320 return new ImageSampleComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5323 return new ImageSampleRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5325 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5326 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5327 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5329 DE_ASSERT(m_isPrimaryCmdBuf);
5330 return new ImageFetchComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5333 return new ImageFetchRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5336 DE_FATAL("Impossible");
5341 class TexelBufferInstanceBuffers
5344 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5345 vk::VkDevice device,
5346 vk::Allocator& allocator,
5347 vk::VkDescriptorType descriptorType,
5348 int numTexelBuffers,
5349 bool hasViewOffset);
5352 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
5353 vk::VkDevice device,
5354 vk::Allocator& allocator,
5355 vk::VkDescriptorType descriptorType,
5356 de::MovePtr<vk::Allocation> *outAllocation);
5358 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
5359 vk::VkDevice device,
5360 const tcu::TextureFormat& textureFormat,
5362 vk::VkBuffer buffer);
5364 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
5366 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
5367 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
5370 static int getFetchPos (int fetchPosNdx);
5371 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
5373 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
5374 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
5375 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
5376 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
5377 inline const void* getBufferInitBarrierA (void) const { return &m_bufferBarrierA; }
5378 inline const void* getBufferInitBarrierB (void) const { return &m_bufferBarrierB; }
5384 VIEW_OFFSET_VALUE = 256,
5385 VIEW_DATA_SIZE = 256, //!< size in bytes
5386 VIEW_WIDTH = 64, //!< size in pixels
5390 // some arbitrary points
5392 SAMPLE_POINT_1 = 51,
5393 SAMPLE_POINT_2 = 42,
5394 SAMPLE_POINT_3 = 25,
5397 const deUint32 m_numTexelBuffers;
5398 const tcu::TextureFormat m_imageFormat;
5399 const deUint32 m_viewOffset;
5401 de::ArrayBuffer<deUint8> m_sourceBufferA;
5402 de::ArrayBuffer<deUint8> m_sourceBufferB;
5403 const tcu::ConstPixelBufferAccess m_sourceViewA;
5404 const tcu::ConstPixelBufferAccess m_sourceViewB;
5406 de::MovePtr<vk::Allocation> m_bufferMemoryA;
5407 de::MovePtr<vk::Allocation> m_bufferMemoryB;
5408 const vk::Unique<vk::VkBuffer> m_bufferA;
5409 const vk::Unique<vk::VkBuffer> m_bufferB;
5410 const vk::Unique<vk::VkBufferView> m_bufferViewA;
5411 const vk::Unique<vk::VkBufferView> m_bufferViewB;
5412 const vk::VkBufferMemoryBarrier m_bufferBarrierA;
5413 const vk::VkBufferMemoryBarrier m_bufferBarrierB;
5416 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5417 vk::VkDevice device,
5418 vk::Allocator& allocator,
5419 vk::VkDescriptorType descriptorType,
5420 int numTexelBuffers,
5422 : m_numTexelBuffers (numTexelBuffers)
5423 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
5424 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
5425 , m_sourceBufferA (BUFFER_SIZE)
5426 , m_sourceBufferB ((numTexelBuffers == 1)
5428 : ((size_t)BUFFER_SIZE))
5429 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
5430 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
5431 , m_bufferMemoryA (DE_NULL)
5432 , m_bufferMemoryB (DE_NULL)
5433 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
5434 , m_bufferB ((numTexelBuffers == 1)
5435 ? vk::Move<vk::VkBuffer>()
5436 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
5437 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
5438 , m_bufferViewB ((numTexelBuffers == 1)
5439 ? vk::Move<vk::VkBufferView>()
5440 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
5441 , m_bufferBarrierA (createBarrier(descriptorType, *m_bufferA))
5442 , m_bufferBarrierB (createBarrier(descriptorType, *m_bufferB))
5444 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
5445 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
5446 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
5448 // specify and upload
5450 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
5451 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
5453 if (numTexelBuffers == 2)
5455 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
5456 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
5460 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
5461 vk::VkDevice device,
5462 vk::Allocator& allocator,
5463 vk::VkDescriptorType descriptorType,
5464 de::MovePtr<vk::Allocation> *outAllocation)
5466 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
5467 const vk::VkBufferCreateInfo createInfo =
5469 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
5471 (vk::VkDeviceSize)BUFFER_SIZE, // size
5474 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
5475 0u, // queueFamilyCount
5476 DE_NULL, // pQueueFamilyIndices
5478 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
5479 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
5481 *outAllocation = allocation;
5485 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
5486 vk::VkDevice device,
5487 const tcu::TextureFormat& textureFormat,
5489 vk::VkBuffer buffer)
5491 const vk::VkBufferViewCreateInfo createInfo =
5493 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
5496 vk::VK_BUFFER_VIEW_TYPE_FORMATTED, // viewType
5497 mapToVkTextureFormat(textureFormat), // format
5498 (vk::VkDeviceSize)offset, // offset
5499 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
5501 return vk::createBufferView(vki, device, &createInfo);
5504 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
5506 const vk::VkMemoryInputFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_MEMORY_INPUT_UNIFORM_READ_BIT) : (vk::VK_MEMORY_INPUT_SHADER_READ_BIT);
5507 const vk::VkBufferMemoryBarrier barrier =
5509 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
5511 vk::VK_MEMORY_OUTPUT_HOST_WRITE_BIT, // outputMask
5512 inputBit, // inputMask
5513 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
5514 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
5517 (vk::VkDeviceSize)BUFFER_SIZE // size
5522 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
5524 DE_ASSERT(access.getHeight() == 1);
5525 DE_ASSERT(access.getDepth() == 1);
5527 const deInt32 width = access.getWidth();
5529 for (int x = 0; x < width; ++x)
5531 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
5532 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
5533 const int blue = 16 * (x % 16); //!< 16-long triangle wave
5535 DE_ASSERT(de::inRange(red, 0, 255));
5536 DE_ASSERT(de::inRange(green, 0, 255));
5537 DE_ASSERT(de::inRange(blue, 0, 255));
5539 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
5543 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
5545 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
5546 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
5549 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
5551 static const int fetchPositions[4] =
5558 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
5561 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
5563 // source order is ABAB
5564 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
5565 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
5566 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
5568 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
5571 class TexelBufferRenderInstance : public SingleCmdRenderInstance
5574 TexelBufferRenderInstance (vkt::Context& context,
5575 bool isPrimaryCmdBuf,
5576 vk::VkDescriptorType descriptorType,
5577 vk::VkShaderStageFlags stageFlags,
5578 ShaderInputInterface shaderInterface,
5579 bool nonzeroViewOffset);
5582 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
5583 vk::VkDevice device,
5584 vk::VkDescriptorType descriptorType,
5585 ShaderInputInterface shaderInterface,
5586 vk::VkShaderStageFlags stageFlags);
5588 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5589 vk::VkDevice device,
5590 vk::VkDescriptorSetLayout descriptorSetLayout);
5592 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5593 vk::VkDevice device,
5594 vk::VkDescriptorType descriptorType,
5595 ShaderInputInterface shaderInterface);
5597 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
5598 vk::VkDevice device,
5599 vk::VkDescriptorType descriptorType,
5600 ShaderInputInterface shaderInterface,
5601 vk::VkDescriptorSetLayout layout,
5602 vk::VkDescriptorPool pool,
5603 vk::VkBufferView viewA,
5604 vk::VkBufferView viewB);
5606 void logTestPlan (void) const;
5607 vk::VkPipelineLayout getPipelineLayout (void) const;
5608 void writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const;
5609 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5616 const vk::VkDescriptorType m_descriptorType;
5617 const vk::VkShaderStageFlags m_stageFlags;
5618 const ShaderInputInterface m_shaderInterface;
5619 const bool m_nonzeroViewOffset;
5621 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5622 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5623 const TexelBufferInstanceBuffers m_texelBuffers;
5624 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5625 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5628 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
5629 bool isPrimaryCmdBuf,
5630 vk::VkDescriptorType descriptorType,
5631 vk::VkShaderStageFlags stageFlags,
5632 ShaderInputInterface shaderInterface,
5633 bool nonzeroViewOffset)
5634 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5635 , m_descriptorType (descriptorType)
5636 , m_stageFlags (stageFlags)
5637 , m_shaderInterface (shaderInterface)
5638 , m_nonzeroViewOffset (nonzeroViewOffset)
5639 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
5640 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5641 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5642 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5643 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_texelBuffers.getBufferViewA(), m_texelBuffers.getBufferViewB()))
5647 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5648 vk::VkDevice device,
5649 vk::VkDescriptorType descriptorType,
5650 ShaderInputInterface shaderInterface,
5651 vk::VkShaderStageFlags stageFlags)
5653 vk::DescriptorSetLayoutBuilder builder;
5655 switch (shaderInterface)
5657 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5658 builder.addSingleBinding(descriptorType, stageFlags);
5661 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5662 builder.addSingleBinding(descriptorType, stageFlags);
5663 builder.addSingleBinding(descriptorType, stageFlags);
5666 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5667 builder.addArrayBinding(descriptorType, 2u, stageFlags);
5671 DE_FATAL("Impossible");
5674 return builder.build(vki, device);
5677 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5678 vk::VkDevice device,
5679 vk::VkDescriptorSetLayout descriptorSetLayout)
5681 const vk::VkPipelineLayoutCreateInfo createInfo =
5683 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5685 1, // descriptorSetCount
5686 &descriptorSetLayout, // pSetLayouts
5687 0u, // pushConstantRangeCount
5688 DE_NULL, // pPushConstantRanges
5690 return vk::createPipelineLayout(vki, device, &createInfo);
5693 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5694 vk::VkDevice device,
5695 vk::VkDescriptorType descriptorType,
5696 ShaderInputInterface shaderInterface)
5698 return vk::DescriptorPoolBuilder()
5699 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
5700 .build(vki, device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
5703 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5704 vk::VkDevice device,
5705 vk::VkDescriptorType descriptorType,
5706 ShaderInputInterface shaderInterface,
5707 vk::VkDescriptorSetLayout layout,
5708 vk::VkDescriptorPool pool,
5709 vk::VkBufferView viewA,
5710 vk::VkBufferView viewB)
5712 const vk::VkDescriptorInfo texelBufferInfos[2] =
5714 createDescriptorInfo(viewA),
5715 createDescriptorInfo(viewB),
5718 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(vki, device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
5719 vk::DescriptorSetUpdateBuilder builder;
5721 switch (shaderInterface)
5723 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5724 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5727 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5728 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5729 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
5732 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5733 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
5737 DE_FATAL("Impossible");
5740 builder.update(vki, device);
5741 return descriptorSet;
5744 void TexelBufferRenderInstance::logTestPlan (void) const
5746 std::ostringstream msg;
5748 msg << "Rendering 2x2 grid.\n"
5749 << "Single descriptor set. Descriptor set contains "
5750 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5751 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5752 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5753 (const char*)DE_NULL)
5754 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5755 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5756 << "Buffer format is " << vk::getFormatName(mapToVkTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5758 if (m_stageFlags == 0u)
5760 msg << "Descriptors are not accessed in any shader stage.\n";
5764 msg << "Color in each cell is fetched using the descriptor(s):\n";
5766 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5768 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5770 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5772 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5773 msg << " from texelBuffer " << srcResourceNdx;
5779 msg << "Descriptors are accessed in {"
5780 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5781 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5782 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5783 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5784 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5788 m_context.getTestContext().getLog()
5789 << tcu::TestLog::Message
5791 << tcu::TestLog::EndMessage;
5794 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
5796 return *m_pipelineLayout;
5799 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCmdBuffer cmd) const
5801 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
5802 m_vki.cmdDraw(cmd, 0, 6 * 4, 0, 1); // render four quads (two separate triangles)
5805 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5807 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5808 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5809 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5810 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
5811 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
5812 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
5813 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
5814 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5816 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5818 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
5819 return tcu::TestStatus::fail("Image verification failed");
5821 return tcu::TestStatus::pass("Pass");
5824 class TexelBufferComputeInstance : public vkt::TestInstance
5827 TexelBufferComputeInstance (vkt::Context& context,
5828 vk::VkDescriptorType descriptorType,
5829 ShaderInputInterface shaderInterface,
5830 bool nonzeroViewOffset);
5833 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5834 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5835 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
5837 tcu::TestStatus iterate (void);
5838 void logTestPlan (void) const;
5839 tcu::TestStatus testResourceAccess (void);
5841 const vk::VkDescriptorType m_descriptorType;
5842 const ShaderInputInterface m_shaderInterface;
5843 const bool m_nonzeroViewOffset;
5845 const vk::DeviceInterface& m_vki;
5846 const vk::VkDevice m_device;
5847 const vk::VkQueue m_queue;
5848 const deUint32 m_queueFamilyIndex;
5849 vk::Allocator& m_allocator;
5851 const ComputeInstanceResultBuffer m_result;
5852 const TexelBufferInstanceBuffers m_texelBuffers;
5855 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
5856 vk::VkDescriptorType descriptorType,
5857 ShaderInputInterface shaderInterface,
5858 bool nonzeroViewOffset)
5859 : vkt::TestInstance (context)
5860 , m_descriptorType (descriptorType)
5861 , m_shaderInterface (shaderInterface)
5862 , m_nonzeroViewOffset (nonzeroViewOffset)
5863 , m_vki (context.getDeviceInterface())
5864 , m_device (context.getDevice())
5865 , m_queue (context.getUniversalQueue())
5866 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5867 , m_allocator (context.getDefaultAllocator())
5868 , m_result (m_vki, m_device, m_allocator)
5869 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5873 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
5875 vk::DescriptorSetLayoutBuilder builder;
5877 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5879 switch (m_shaderInterface)
5881 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5882 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5885 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5886 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5887 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5890 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5891 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5895 DE_FATAL("Impossible");
5898 return builder.build(m_vki, m_device);
5901 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
5903 return vk::DescriptorPoolBuilder()
5904 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
5905 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
5906 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_USAGE_ONE_SHOT, 1);
5909 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
5911 const vk::VkDescriptorInfo resultInfo = createDescriptorInfo(m_result.getBufferView());
5912 const vk::VkDescriptorInfo texelBufferInfos[2] =
5914 createDescriptorInfo(m_texelBuffers.getBufferViewA()),
5915 createDescriptorInfo(m_texelBuffers.getBufferViewB()),
5918 vk::Move<vk::VkDescriptorSet> descriptorSet = allocDescriptorSet(m_vki, m_device, pool, vk::VK_DESCRIPTOR_SET_USAGE_ONE_SHOT, layout);
5919 vk::DescriptorSetUpdateBuilder builder;
5922 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5925 switch (m_shaderInterface)
5927 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5928 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5931 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5932 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5933 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
5936 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5937 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
5941 DE_FATAL("Impossible");
5944 builder.update(m_vki, m_device);
5945 return descriptorSet;
5948 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
5951 return testResourceAccess();
5954 void TexelBufferComputeInstance::logTestPlan (void) const
5956 std::ostringstream msg;
5958 msg << "Fetching 4 values from image in compute shader.\n"
5959 << "Single descriptor set. Descriptor set contains "
5960 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5961 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5962 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5963 (const char*)DE_NULL)
5964 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5965 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5966 << "Buffer format is " << vk::getFormatName(mapToVkTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5968 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5970 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5972 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5974 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5975 msg << " from texelBuffer " << srcResourceNdx;
5981 m_context.getTestContext().getLog()
5982 << tcu::TestLog::Message
5984 << tcu::TestLog::EndMessage;
5987 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
5989 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
5990 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5991 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
5992 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
5994 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
5995 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
5996 const deUint32* const dynamicOffsets = DE_NULL;
5997 const int numDynamicOffsets = 0;
5998 const void* const preBarriers[] = { m_texelBuffers.getBufferInitBarrierA(), m_texelBuffers.getBufferInitBarrierB() };
5999 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
6000 const void* const postBarriers[] = { m_result.getResultReadBarrier() };
6001 const int numPostBarriers = DE_LENGTH_OF_ARRAY(postBarriers);
6003 const ComputeCommand compute (m_vki,
6005 pipeline.getPipeline(),
6006 pipeline.getPipelineLayout(),
6007 tcu::UVec3(4, 1, 1),
6008 numDescriptorSets, descriptorSets,
6009 numDynamicOffsets, dynamicOffsets,
6010 numPreBarriers, preBarriers,
6011 numPostBarriers, postBarriers);
6013 tcu::Vec4 results[4];
6014 bool anyResultSet = false;
6015 bool allResultsOk = true;
6017 compute.submitAndWait(m_queueFamilyIndex, m_queue);
6018 m_result.readResultContentsTo(&results);
6021 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6023 const tcu::Vec4 result = results[resultNdx];
6024 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
6025 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
6027 if (result != tcu::Vec4(-1.0f))
6028 anyResultSet = true;
6030 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
6032 allResultsOk = false;
6034 m_context.getTestContext().getLog()
6035 << tcu::TestLog::Message
6036 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
6037 << tcu::TestLog::EndMessage;
6041 // read back and verify
6043 return tcu::TestStatus::pass("Pass");
6044 else if (anyResultSet)
6045 return tcu::TestStatus::fail("Invalid result values");
6048 m_context.getTestContext().getLog()
6049 << tcu::TestLog::Message
6050 << "Result buffer was not written to."
6051 << tcu::TestLog::EndMessage;
6052 return tcu::TestStatus::fail("Result buffer was not written to");
6056 class TexelBufferDescriptorCase : public QuadrantRendederCase
6061 FLAG_VIEW_OFFSET = (1u << 1u),
6063 // enum continues where resource flags ends
6064 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
6066 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6068 const char* description,
6069 bool isPrimaryCmdBuf,
6070 vk::VkDescriptorType descriptorType,
6071 vk::VkShaderStageFlags exitingStages,
6072 vk::VkShaderStageFlags activeStages,
6073 ShaderInputInterface shaderInterface,
6077 std::string genExtensionDeclarations (vk::VkShaderStage stage) const;
6078 std::string genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const;
6079 std::string genResourceAccessSource (vk::VkShaderStage stage) const;
6080 std::string genNoAccessSource (void) const;
6082 vkt::TestInstance* createInstance (vkt::Context& context) const;
6084 const bool m_isPrimaryCmdBuf;
6085 const vk::VkDescriptorType m_descriptorType;
6086 const ShaderInputInterface m_shaderInterface;
6087 const bool m_nonzeroViewOffset;
6090 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6092 const char* description,
6093 bool isPrimaryCmdBuf,
6094 vk::VkDescriptorType descriptorType,
6095 vk::VkShaderStageFlags exitingStages,
6096 vk::VkShaderStageFlags activeStages,
6097 ShaderInputInterface shaderInterface,
6099 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
6100 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6101 , m_descriptorType (descriptorType)
6102 , m_shaderInterface (shaderInterface)
6103 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
6107 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStage stage) const
6110 return "#extension GL_EXT_texture_buffer : require\n";
6113 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStage stage, int numUsedBindings) const
6117 const bool isUniform = isUniformDescriptorType(m_descriptorType);
6118 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
6119 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
6121 switch (m_shaderInterface)
6123 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6124 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
6126 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
6127 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
6128 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
6130 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6131 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
6134 DE_FATAL("Impossible");
6139 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStage stage) const
6143 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6144 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
6145 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6147 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6148 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
6149 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6151 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
6152 std::ostringstream buf;
6154 buf << " if (quadrant_id == 0)\n"
6155 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
6156 << " else if (quadrant_id == 1)\n"
6157 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
6158 << " else if (quadrant_id == 2)\n"
6159 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
6161 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
6166 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
6168 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6169 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6171 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6174 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
6176 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6178 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
6179 return new TexelBufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
6182 return new TexelBufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
6185 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
6186 bool isPrimaryCmdBuf,
6187 vk::VkDescriptorType descriptorType,
6188 vk::VkShaderStageFlags exitingStages,
6189 vk::VkShaderStageFlags activeStages,
6190 ShaderInputInterface dimension,
6191 deUint32 resourceFlags)
6195 vk::VkImageViewType viewType;
6197 const char* description;
6201 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
6202 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6203 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6205 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
6206 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6207 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6209 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
6210 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6211 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6213 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
6214 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6215 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6217 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
6218 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6219 // no 3d array textures
6221 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
6222 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6223 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6225 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
6226 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6227 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6230 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
6233 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
6235 group->addChild(new ImageDescriptorCase(group->getTestContext(),
6236 s_imageTypes[ndx].name,
6237 s_imageTypes[ndx].description,
6243 s_imageTypes[ndx].viewType,
6244 s_imageTypes[ndx].flags | resourceFlags));
6248 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
6249 bool isPrimaryCmdBuf,
6250 vk::VkDescriptorType descriptorType,
6251 vk::VkShaderStageFlags exitingStages,
6252 vk::VkShaderStageFlags activeStages,
6253 ShaderInputInterface dimension,
6254 deUint32 resourceFlags)
6256 DE_ASSERT(resourceFlags == 0);
6257 DE_UNREF(resourceFlags);
6262 const char* description;
6264 } s_texelBufferTypes[] =
6266 { "offset_zero", "View offset is zero", 0u },
6267 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
6270 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
6272 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
6273 s_texelBufferTypes[ndx].name,
6274 s_texelBufferTypes[ndx].description,
6280 s_texelBufferTypes[ndx].flags));
6284 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
6285 bool isPrimaryCmdBuf,
6286 vk::VkDescriptorType descriptorType,
6287 vk::VkShaderStageFlags exitingStages,
6288 vk::VkShaderStageFlags activeStages,
6289 ShaderInputInterface dimension,
6290 deUint32 resourceFlags)
6292 DE_ASSERT(resourceFlags == 0u);
6293 DE_UNREF(resourceFlags);
6298 const char* description;
6299 bool isForDynamicCases;
6303 { "offset_view_zero", "View offset is zero", false, 0u },
6304 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6306 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6307 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
6308 { "offset_view_zero_dynamic_not_set", "View offset is zero, dynamic offset is not supplied", true, 0u },
6309 // \note no case for offset_view_nonzero_dynamic_zero since it doesn't produce any additional coverage
6310 { "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 },
6311 { "offset_view_nonzero_dynamic_not_set", "View offset is non-zero, dynamic offset is not supplied", true, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6314 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
6316 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
6318 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
6319 group->addChild(new BufferDescriptorCase(group->getTestContext(),
6320 s_bufferTypes[ndx].name,
6321 s_bufferTypes[ndx].description,
6327 s_bufferTypes[ndx].flags));
6333 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
6337 const bool isPrimary;
6339 const char* description;
6342 { true, "primary_cmd_buf", "Bind in primary command buffer" },
6343 { false, "seconday_cmd_buf", "Bind in secondary command buffer" },
6347 const vk::VkDescriptorType descriptorType;
6349 const char* description;
6351 } s_descriptorTypes[] =
6353 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
6354 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6355 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
6356 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6357 { vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
6358 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
6359 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
6360 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
6361 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
6362 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
6363 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
6364 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
6369 const char* description;
6370 vk::VkShaderStageFlags existingStages; //!< stages that exists
6371 vk::VkShaderStageFlags activeStages; //!< stages that access resource
6372 bool supportsSecondaryCmdBufs;
6373 } s_shaderStages[] =
6377 "No accessing stages",
6378 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6385 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6386 vk::VK_SHADER_STAGE_VERTEX_BIT,
6391 "Tessellation control stage",
6392 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESS_CONTROL_BIT | vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6393 vk::VK_SHADER_STAGE_TESS_CONTROL_BIT,
6398 "Tessellation evaluation stage",
6399 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESS_CONTROL_BIT | vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6400 vk::VK_SHADER_STAGE_TESS_EVALUATION_BIT,
6406 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6407 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
6413 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6414 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6420 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6421 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6426 "Vertex and fragment stages",
6427 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6428 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6434 ShaderInputInterface dimension;
6436 const char* description;
6437 } s_variableDimensions[] =
6439 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
6440 { SHADER_INPUT_MULTIPLE_DESCRIPTORS, "multiple_descriptors", "Multiple descriptors" },
6441 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
6444 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
6446 // .primary_cmd_buf...
6447 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
6449 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
6451 // .sampler, .combined_image_sampler, other resource types ...
6452 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
6454 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
6456 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
6458 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
6460 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
6462 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
6464 de::MovePtr<tcu::TestCaseGroup> dimensionGroup(new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
6465 void (*createTestsFunc)(tcu::TestCaseGroup* group,
6466 bool isPrimaryCmdBuf,
6467 vk::VkDescriptorType descriptorType,
6468 vk::VkShaderStageFlags existingStages,
6469 vk::VkShaderStageFlags activeStages,
6470 ShaderInputInterface dimension,
6471 deUint32 resourceFlags);
6473 switch (s_descriptorTypes[descriptorNdx].descriptorType)
6475 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6476 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6477 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
6478 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6479 createTestsFunc = createShaderAccessImageTests;
6482 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
6483 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
6484 createTestsFunc = createShaderAccessTexelBufferTests;
6487 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
6488 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
6489 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
6490 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
6491 createTestsFunc = createShaderAccessBufferTests;
6495 createTestsFunc = DE_NULL;
6496 DE_FATAL("Impossible");
6499 if (createTestsFunc)
6501 createTestsFunc(dimensionGroup.get(),
6502 s_bindTypes[bindTypeNdx].isPrimary,
6503 s_descriptorTypes[descriptorNdx].descriptorType,
6504 s_shaderStages[stageNdx].existingStages,
6505 s_shaderStages[stageNdx].activeStages,
6506 s_variableDimensions[dimensionNdx].dimension,
6507 s_descriptorTypes[descriptorNdx].flags);
6510 DE_FATAL("Impossible");
6512 stageGroup->addChild(dimensionGroup.release());
6515 typeGroup->addChild(stageGroup.release());
6519 bindGroup->addChild(typeGroup.release());
6522 group->addChild(bindGroup.release());
6525 return group.release();