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"
47 #include "vkImageUtil.hpp"
48 #include "vkTypeUtil.hpp"
50 #include "tcuVector.hpp"
51 #include "tcuVectorUtil.hpp"
52 #include "tcuTexture.hpp"
53 #include "tcuTextureUtil.hpp"
54 #include "tcuResultCollector.hpp"
55 #include "tcuTestLog.hpp"
56 #include "tcuRGBA.hpp"
57 #include "tcuSurface.hpp"
58 #include "tcuImageCompare.hpp"
60 #include "deUniquePtr.hpp"
61 #include "deSharedPtr.hpp"
62 #include "deStringUtil.hpp"
63 #include "deArrayUtil.hpp"
69 namespace BindingModel
76 RESOURCE_FLAG_IMMUTABLE_SAMPLER = (1u << 0u),
78 RESOURCE_FLAG_LAST = (1u << 1u)
81 static const char* const s_quadrantGenVertexPosSource = " highp int quadPhase = gl_VertexIndex % 6;\n"
82 " highp int quadXcoord = int(quadPhase == 1 || quadPhase == 4 || quadPhase == 5);\n"
83 " highp int quadYcoord = int(quadPhase == 2 || quadPhase == 3 || quadPhase == 5);\n"
84 " highp int quadOriginX = (gl_VertexIndex / 6) % 2;\n"
85 " highp int quadOriginY = (gl_VertexIndex / 6) / 2;\n"
86 " quadrant_id = gl_VertexIndex / 6;\n"
87 " result_position = vec4(float(quadOriginX + quadXcoord - 1), float(quadOriginY + quadYcoord - 1), 0.0, 1.0);\n";
89 bool isUniformDescriptorType (vk::VkDescriptorType type)
91 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
92 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
93 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
96 bool isDynamicDescriptorType (vk::VkDescriptorType type)
98 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || type == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
101 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type)
105 case vk::VK_IMAGE_VIEW_TYPE_1D:
106 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return vk::VK_IMAGE_TYPE_1D;
107 case vk::VK_IMAGE_VIEW_TYPE_2D:
108 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return vk::VK_IMAGE_TYPE_2D;
109 case vk::VK_IMAGE_VIEW_TYPE_3D: return vk::VK_IMAGE_TYPE_3D;
110 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
111 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return vk::VK_IMAGE_TYPE_2D;
114 DE_FATAL("Impossible");
115 return (vk::VkImageType)0;
119 vk::VkImageLayout getImageLayoutForDescriptorType (vk::VkDescriptorType descType)
121 if (descType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
122 return vk::VK_IMAGE_LAYOUT_GENERAL;
124 return vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
127 deUint32 getTextureLevelPyramidDataSize (const tcu::TextureLevelPyramid& srcImage)
129 deUint32 dataSize = 0;
130 for (int level = 0; level < srcImage.getNumLevels(); ++level)
132 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
135 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
137 dataSize += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
142 void writeTextureLevelPyramidData (void* dst, deUint32 dstLen, const tcu::TextureLevelPyramid& srcImage, vk::VkImageViewType viewType, std::vector<vk::VkBufferImageCopy>* copySlices)
144 // \note cube is copied face-by-face
145 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (srcImage.getLevel(0).getHeight()) :
146 (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
147 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
148 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
150 deUint32 levelOffset = 0;
152 DE_ASSERT(arraySize != 0);
154 for (int level = 0; level < srcImage.getNumLevels(); ++level)
156 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
157 const tcu::PixelBufferAccess dstAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), (deUint8*)dst + levelOffset);
158 const deUint32 dataSize = srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
159 const deUint32 sliceDataSize = dataSize / arraySize;
160 const deInt32 sliceHeight = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (srcAccess.getHeight());
161 const deInt32 sliceDepth = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (srcAccess.getDepth()) : (1);
162 const tcu::IVec3 sliceSize (srcAccess.getWidth(), sliceHeight, sliceDepth);
165 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
167 for (int sliceNdx = 0; sliceNdx < (int)arraySize; ++sliceNdx)
169 const vk::VkBufferImageCopy copySlice =
171 (vk::VkDeviceSize)levelOffset + sliceNdx * sliceDataSize, // bufferOffset
172 (deUint32)sliceSize.x(), // bufferRowLength
173 (deUint32)sliceSize.y(), // bufferImageHeight
175 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
176 (deUint32)level, // mipLevel
177 (deUint32)sliceNdx, // arrayLayer
179 }, // imageSubresource
186 (deUint32)sliceSize.x(),
187 (deUint32)sliceSize.y(),
188 (deUint32)sliceSize.z(),
191 copySlices->push_back(copySlice);
194 DE_ASSERT(arraySize * sliceDataSize == dataSize);
196 tcu::copy(dstAccess, srcAccess);
197 levelOffset += dataSize;
200 DE_ASSERT(dstLen == levelOffset);
204 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement)
206 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer);
207 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
209 VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
213 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkImage image, vk::MemoryRequirement requirement)
215 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vki, device, image);
216 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
218 VK_CHECK(vki.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
222 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkSampler sampler)
224 return vk::makeDescriptorImageInfo(sampler, (vk::VkImageView)0, (vk::VkImageLayout)0);
227 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkImageView imageView, vk::VkImageLayout layout)
229 return vk::makeDescriptorImageInfo((vk::VkSampler)0, imageView, layout);
232 void drawQuadrantReferenceResult (const tcu::PixelBufferAccess& dst, const tcu::Vec4& c1, const tcu::Vec4& c2, const tcu::Vec4& c3, const tcu::Vec4& c4)
234 tcu::clear(tcu::getSubregion(dst, 0, 0, dst.getWidth() / 2, dst.getHeight() / 2), c1);
235 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, 0, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() / 2), c2);
236 tcu::clear(tcu::getSubregion(dst, 0, dst.getHeight() / 2, dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c3);
237 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, dst.getHeight() / 2, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c4);
240 class SingleTargetRenderInstance : public vkt::TestInstance
243 SingleTargetRenderInstance (Context& context,
244 const tcu::UVec2& size);
247 static vk::Move<vk::VkImage> createColorAttachment (const vk::DeviceInterface& vki,
249 vk::Allocator& allocator,
250 const tcu::TextureFormat& format,
251 const tcu::UVec2& size,
252 de::MovePtr<vk::Allocation>* outAllocation);
254 static vk::Move<vk::VkImageView> createColorAttachmentView (const vk::DeviceInterface& vki,
256 const tcu::TextureFormat& format,
259 static vk::Move<vk::VkRenderPass> createRenderPass (const vk::DeviceInterface& vki,
261 const tcu::TextureFormat& format);
263 static vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vki,
265 vk::VkRenderPass renderpass,
266 vk::VkImageView colorAttachmentView,
267 const tcu::UVec2& size);
269 static vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vki,
271 deUint32 queueFamilyIndex);
273 virtual void logTestPlan (void) const = 0;
274 virtual void renderToTarget (void) = 0;
275 virtual tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const = 0;
277 void readRenderTarget (tcu::TextureLevel& dst);
278 tcu::TestStatus iterate (void);
281 const tcu::TextureFormat m_targetFormat;
282 const tcu::UVec2 m_targetSize;
284 const vk::DeviceInterface& m_vki;
285 const vk::VkDevice m_device;
286 const vk::VkQueue m_queue;
287 const deUint32 m_queueFamilyIndex;
288 vk::Allocator& m_allocator;
289 de::MovePtr<vk::Allocation> m_colorAttachmentMemory;
290 const vk::Unique<vk::VkImage> m_colorAttachmentImage;
291 const vk::Unique<vk::VkImageView> m_colorAttachmentView;
292 const vk::Unique<vk::VkRenderPass> m_renderPass;
293 const vk::Unique<vk::VkFramebuffer> m_framebuffer;
294 const vk::Unique<vk::VkCommandPool> m_cmdPool;
296 bool m_firstIteration;
299 SingleTargetRenderInstance::SingleTargetRenderInstance (Context& context,
300 const tcu::UVec2& size)
301 : vkt::TestInstance (context)
302 , m_targetFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
303 , m_targetSize (size)
304 , m_vki (context.getDeviceInterface())
305 , m_device (context.getDevice())
306 , m_queue (context.getUniversalQueue())
307 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
308 , m_allocator (context.getDefaultAllocator())
309 , m_colorAttachmentMemory (DE_NULL)
310 , m_colorAttachmentImage (createColorAttachment(m_vki, m_device, m_allocator, m_targetFormat, m_targetSize, &m_colorAttachmentMemory))
311 , m_colorAttachmentView (createColorAttachmentView(m_vki, m_device, m_targetFormat, *m_colorAttachmentImage))
312 , m_renderPass (createRenderPass(m_vki, m_device, m_targetFormat))
313 , m_framebuffer (createFramebuffer(m_vki, m_device, *m_renderPass, *m_colorAttachmentView, m_targetSize))
314 , m_cmdPool (createCommandPool(m_vki, m_device, context.getUniversalQueueFamilyIndex()))
315 , m_firstIteration (true)
319 vk::Move<vk::VkImage> SingleTargetRenderInstance::createColorAttachment (const vk::DeviceInterface& vki,
321 vk::Allocator& allocator,
322 const tcu::TextureFormat& format,
323 const tcu::UVec2& size,
324 de::MovePtr<vk::Allocation>* outAllocation)
326 const vk::VkImageCreateInfo imageInfo =
328 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
330 (vk::VkImageCreateFlags)0,
331 vk::VK_IMAGE_TYPE_2D, // imageType
332 vk::mapTextureFormat(format), // format
333 { size.x(), size.y(), 1u }, // extent
336 vk::VK_SAMPLE_COUNT_1_BIT, // samples
337 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
338 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
339 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
340 0u, // queueFamilyCount
341 DE_NULL, // pQueueFamilyIndices
342 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
345 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &imageInfo));
346 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any));
348 *outAllocation = allocation;
352 vk::Move<vk::VkImageView> SingleTargetRenderInstance::createColorAttachmentView (const vk::DeviceInterface& vki,
354 const tcu::TextureFormat& format,
357 const vk::VkImageViewCreateInfo createInfo =
359 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
361 (vk::VkImageViewCreateFlags)0,
363 vk::VK_IMAGE_VIEW_TYPE_2D, // viewType
364 vk::mapTextureFormat(format), // format
365 vk::makeComponentMappingRGBA(),
367 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
370 0u, // baseArrayLayer
375 return vk::createImageView(vki, device, &createInfo);
378 vk::Move<vk::VkRenderPass> SingleTargetRenderInstance::createRenderPass (const vk::DeviceInterface& vki,
380 const tcu::TextureFormat& format)
382 const vk::VkAttachmentDescription attachmentDescription =
384 (vk::VkAttachmentDescriptionFlags)0,
385 vk::mapTextureFormat(format), // format
386 vk::VK_SAMPLE_COUNT_1_BIT, // samples
387 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp
388 vk::VK_ATTACHMENT_STORE_OP_STORE, // storeOp
389 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
390 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
391 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
392 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout
394 const vk::VkAttachmentReference colorAttachment =
397 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
399 const vk::VkAttachmentReference depthStencilAttachment =
401 vk::VK_NO_ATTACHMENT, // attachment
402 vk::VK_IMAGE_LAYOUT_UNDEFINED // layout
404 const vk::VkSubpassDescription subpass =
406 (vk::VkSubpassDescriptionFlags)0,
407 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
408 0u, // inputAttachmentCount
409 DE_NULL, // pInputAttachments
410 1u, // colorAttachmentCount
411 &colorAttachment, // pColorAttachments
412 DE_NULL, // pResolveAttachments
413 &depthStencilAttachment, // pDepthStencilAttachment
414 0u, // preserveAttachmentCount
415 DE_NULL // pPreserveAttachments
417 const vk::VkRenderPassCreateInfo renderPassCreateInfo =
419 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
421 (vk::VkRenderPassCreateFlags)0,
422 1u, // attachmentCount
423 &attachmentDescription, // pAttachments
425 &subpass, // pSubpasses
426 0u, // dependencyCount
427 DE_NULL, // pDependencies
430 return vk::createRenderPass(vki, device, &renderPassCreateInfo);
433 vk::Move<vk::VkFramebuffer> SingleTargetRenderInstance::createFramebuffer (const vk::DeviceInterface& vki,
435 vk::VkRenderPass renderpass,
436 vk::VkImageView colorAttachmentView,
437 const tcu::UVec2& size)
439 const vk::VkFramebufferCreateInfo framebufferCreateInfo =
441 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
443 (vk::VkFramebufferCreateFlags)0,
444 renderpass, // renderPass
445 1u, // attachmentCount
446 &colorAttachmentView, // pAttachments
452 return vk::createFramebuffer(vki, device, &framebufferCreateInfo);
455 vk::Move<vk::VkCommandPool> SingleTargetRenderInstance::createCommandPool (const vk::DeviceInterface& vki,
457 deUint32 queueFamilyIndex)
459 const vk::VkCommandPoolCreateInfo createInfo =
461 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
463 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
464 queueFamilyIndex, // queueFamilyIndex
466 return vk::createCommandPool(vki, device, &createInfo);
469 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
471 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
472 const vk::VkBufferCreateInfo bufferCreateInfo =
474 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
477 pixelDataSize, // size
478 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
479 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
480 0u, // queueFamilyCount
481 DE_NULL, // pQueueFamilyIndices
483 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
484 const vk::VkImageSubresourceRange fullSubrange =
486 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
489 0u, // baseArraySlice
492 const vk::VkImageMemoryBarrier imageBarrier =
494 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
496 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
497 vk::VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
498 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
499 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
500 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
501 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
502 *m_colorAttachmentImage, // image
503 fullSubrange, // subresourceRange
505 const vk::VkBufferMemoryBarrier memoryBarrier =
507 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
509 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
510 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
511 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
512 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
515 (vk::VkDeviceSize)pixelDataSize // size
517 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
519 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
521 *m_cmdPool, // cmdPool
522 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
525 const vk::VkFenceCreateInfo fenceCreateInfo =
527 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
531 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
533 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
535 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
536 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
538 const vk::VkImageSubresourceLayers firstSlice =
540 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspect
545 const vk::VkBufferImageCopy copyRegion =
548 m_targetSize.x(), // bufferRowLength
549 m_targetSize.y(), // bufferImageHeight
550 firstSlice, // imageSubresource
551 { 0, 0, 0 }, // imageOffset
552 { m_targetSize.x(), m_targetSize.y(), 1u } // imageExtent
555 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
557 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
558 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
559 const deUint64 infiniteTimeout = ~(deUint64)0u;
561 // copy content to buffer
562 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
563 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
564 0, (const vk::VkMemoryBarrier*)DE_NULL,
565 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
567 m_vki.cmdCopyImageToBuffer(*cmd, *m_colorAttachmentImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
568 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
569 0, (const vk::VkMemoryBarrier*)DE_NULL,
571 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
572 VK_CHECK(m_vki.endCommandBuffer(*cmd));
574 // wait for transfer to complete
576 const vk::VkSubmitInfo submitInfo =
578 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
581 (const vk::VkSemaphore*)0,
582 (const vk::VkPipelineStageFlags*)DE_NULL,
586 (const vk::VkSemaphore*)0,
589 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *cmdCompleteFence));
591 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
593 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
596 invalidateMappedMemoryRange(m_vki, m_device, bufferMemory->getMemory(), bufferMemory->getOffset(), pixelDataSize);
597 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
600 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
602 tcu::TextureLevel resultImage;
605 if (m_firstIteration)
608 m_firstIteration = false;
613 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
614 const vk::VkImageSubresourceRange fullSubrange =
616 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
619 0u, // baseArraySlice
622 const vk::VkImageMemoryBarrier imageBarrier =
624 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
627 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
628 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
629 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
630 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
631 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
632 *m_colorAttachmentImage, // image
633 fullSubrange, // subresourceRange
635 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
637 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
639 *m_cmdPool, // cmdPool
640 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
643 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
645 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
647 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
648 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
651 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
653 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
654 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
655 0, (const vk::VkMemoryBarrier*)DE_NULL,
656 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
658 VK_CHECK(m_vki.endCommandBuffer(*cmd));
661 const vk::VkSubmitInfo submitInfo =
663 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
666 (const vk::VkSemaphore*)0,
667 (const vk::VkPipelineStageFlags*)DE_NULL,
671 (const vk::VkSemaphore*)0,
674 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, (vk::VkFence)0));
677 // and then render to
682 readRenderTarget(resultImage);
683 return verifyResultImage(resultImage.getAccess());
686 class RenderInstanceShaders
689 RenderInstanceShaders (const vk::DeviceInterface& vki,
691 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
692 const vk::BinaryCollection& programCollection);
694 inline bool hasTessellationStage (void) const { return *m_tessCtrlShaderModule != 0 || *m_tessEvalShaderModule != 0; }
695 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
696 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
699 void addStage (const vk::DeviceInterface& vki,
701 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
702 const vk::BinaryCollection& programCollection,
704 vk::VkShaderStageFlagBits stage,
705 vk::Move<vk::VkShaderModule>* outModule);
707 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const;
709 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
710 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
711 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
712 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
713 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
714 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
717 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
719 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
720 const vk::BinaryCollection& programCollection)
722 addStage(vki, device, deviceFeatures, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX_BIT, &m_vertexShaderModule);
723 addStage(vki, device, deviceFeatures, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessCtrlShaderModule);
724 addStage(vki, device, deviceFeatures, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvalShaderModule);
725 addStage(vki, device, deviceFeatures, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule);
726 addStage(vki, device, deviceFeatures, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule);
728 DE_ASSERT(!m_stageInfos.empty());
731 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
733 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
734 const vk::BinaryCollection& programCollection,
736 vk::VkShaderStageFlagBits stage,
737 vk::Move<vk::VkShaderModule>* outModule)
739 if (programCollection.contains(name))
741 if (vk::isShaderStageSupported(deviceFeatures, stage))
743 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
745 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *module));
750 // Wait for the GPU to idle so that throwing the exception
751 // below doesn't free in-use GPU resource.
752 vki.deviceWaitIdle(device);
753 TCU_THROW(NotSupportedError, (de::toString(stage) + " is not supported").c_str());
758 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const
760 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
762 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
764 (vk::VkPipelineShaderStageCreateFlags)0,
768 DE_NULL, // pSpecializationInfo
770 return stageCreateInfo;
773 class SingleCmdRenderInstance : public SingleTargetRenderInstance
776 SingleCmdRenderInstance (Context& context,
777 bool isPrimaryCmdBuf,
778 const tcu::UVec2& renderSize);
781 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
783 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
784 virtual void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const = 0;
786 void renderToTarget (void);
788 const bool m_isPrimaryCmdBuf;
791 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
792 bool isPrimaryCmdBuf,
793 const tcu::UVec2& renderSize)
794 : SingleTargetRenderInstance (context, renderSize)
795 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
799 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
801 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getDeviceFeatures(), m_context.getBinaryCollection());
802 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
803 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
805 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
807 (vk::VkPipelineVertexInputStateCreateFlags)0,
809 DE_NULL, // pVertexBindingDescriptions
810 0u, // attributeCount
811 DE_NULL, // pVertexAttributeDescriptions
813 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
815 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
817 (vk::VkPipelineInputAssemblyStateCreateFlags)0,
818 topology, // topology
819 vk::VK_FALSE, // primitiveRestartEnable
821 const vk::VkPipelineTessellationStateCreateInfo tessState =
823 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
825 (vk::VkPipelineTessellationStateCreateFlags)0,
826 3u, // patchControlPoints
828 const vk::VkViewport viewport =
832 float(m_targetSize.x()), // width
833 float(m_targetSize.y()), // height
837 const vk::VkRect2D renderArea =
840 { m_targetSize.x(), m_targetSize.y() }, // extent
842 const vk::VkPipelineViewportStateCreateInfo vpState =
844 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
846 (vk::VkPipelineViewportStateCreateFlags)0,
852 const vk::VkPipelineRasterizationStateCreateInfo rsState =
854 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
856 (vk::VkPipelineRasterizationStateCreateFlags)0,
857 vk::VK_TRUE, // depthClipEnable
858 vk::VK_FALSE, // rasterizerDiscardEnable
859 vk::VK_POLYGON_MODE_FILL, // fillMode
860 vk::VK_CULL_MODE_NONE, // cullMode
861 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
862 vk::VK_FALSE, // depthBiasEnable
864 0.0f, // depthBiasClamp
865 0.0f, // slopeScaledDepthBias
868 const vk::VkSampleMask sampleMask = 0x01u;
869 const vk::VkPipelineMultisampleStateCreateInfo msState =
871 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
873 (vk::VkPipelineMultisampleStateCreateFlags)0,
874 vk::VK_SAMPLE_COUNT_1_BIT, // rasterSamples
875 vk::VK_FALSE, // sampleShadingEnable
876 0.0f, // minSampleShading
877 &sampleMask, // sampleMask
878 vk::VK_FALSE, // alphaToCoverageEnable
879 vk::VK_FALSE, // alphaToOneEnable
881 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
883 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
885 (vk::VkPipelineDepthStencilStateCreateFlags)0,
886 vk::VK_FALSE, // depthTestEnable
887 vk::VK_FALSE, // depthWriteEnable
888 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
889 vk::VK_FALSE, // depthBoundsTestEnable
890 vk::VK_FALSE, // stencilTestEnable
891 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
892 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
893 -1.0f, // minDepthBounds
894 +1.0f, // maxDepthBounds
896 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
898 vk::VK_FALSE, // blendEnable
899 vk::VK_BLEND_FACTOR_ZERO, // srcBlendColor
900 vk::VK_BLEND_FACTOR_ZERO, // destBlendColor
901 vk::VK_BLEND_OP_ADD, // blendOpColor
902 vk::VK_BLEND_FACTOR_ZERO, // srcBlendAlpha
903 vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha
904 vk::VK_BLEND_OP_ADD, // blendOpAlpha
905 (vk::VK_COLOR_COMPONENT_R_BIT |
906 vk::VK_COLOR_COMPONENT_G_BIT |
907 vk::VK_COLOR_COMPONENT_B_BIT |
908 vk::VK_COLOR_COMPONENT_A_BIT), // channelWriteMask
910 const vk::VkPipelineColorBlendStateCreateInfo cbState =
912 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
914 (vk::VkPipelineColorBlendStateCreateFlags)0,
915 vk::VK_FALSE, // logicOpEnable
916 vk::VK_LOGIC_OP_CLEAR, // logicOp
917 1u, // attachmentCount
918 &cbAttachment, // pAttachments
919 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
921 const vk::VkPipelineDynamicStateCreateInfo dynState =
923 vk::VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO,
925 (vk::VkPipelineDynamicStateCreateFlags)0,
926 0u, // dynamicStateCount
927 DE_NULL, // pDynamicStates
929 const vk::VkGraphicsPipelineCreateInfo createInfo =
931 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
933 (vk::VkPipelineCreateFlags)0,
934 shaderStages.getNumStages(), // stageCount
935 shaderStages.getStages(), // pStages
936 &vertexInputState, // pVertexInputState
937 &iaState, // pInputAssemblyState
938 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
939 &vpState, // pViewportState
940 &rsState, // pRasterState
941 &msState, // pMultisampleState
942 &dsState, // pDepthStencilState
943 &cbState, // pColorBlendState
944 &dynState, // pDynamicState
945 pipelineLayout, // layout
946 *m_renderPass, // renderPass
948 (vk::VkPipeline)0, // basePipelineHandle
949 0u, // basePipelineIndex
951 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
954 void SingleCmdRenderInstance::renderToTarget (void)
956 const vk::VkRect2D renderArea =
959 { m_targetSize.x(), m_targetSize.y() }, // extent
961 const vk::VkCommandBufferAllocateInfo mainCmdBufCreateInfo =
963 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
965 *m_cmdPool, // cmdPool
966 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
969 const vk::VkCommandBufferBeginInfo mainCmdBufBeginInfo =
971 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
973 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
974 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
976 const vk::VkCommandBufferAllocateInfo passCmdBufCreateInfo =
978 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
980 *m_cmdPool, // cmdPool
981 vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level
984 const vk::VkCommandBufferInheritanceInfo passCmdBufInheritInfo =
986 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
988 (vk::VkRenderPass)*m_renderPass, // renderPass
990 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
991 vk::VK_FALSE, // occlusionQueryEnable
992 (vk::VkQueryControlFlags)0,
993 (vk::VkQueryPipelineStatisticFlags)0,
995 const vk::VkCommandBufferBeginInfo passCmdBufBeginInfo =
997 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
999 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
1000 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // flags
1001 &passCmdBufInheritInfo,
1003 const vk::VkFenceCreateInfo fenceCreateInfo =
1005 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1009 const vk::VkClearValue clearValue = vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
1010 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1012 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1014 *m_renderPass, // renderPass
1015 *m_framebuffer, // framebuffer
1016 renderArea, // renderArea
1017 1u, // clearValueCount
1018 &clearValue, // pClearValues
1021 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1022 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1023 const vk::Unique<vk::VkCommandBuffer> mainCmd (vk::allocateCommandBuffer(m_vki, m_device, &mainCmdBufCreateInfo));
1024 const vk::Unique<vk::VkCommandBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCommandBuffer>()) : (vk::allocateCommandBuffer(m_vki, m_device, &passCmdBufCreateInfo)));
1025 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1026 const deUint64 infiniteTimeout = ~(deUint64)0u;
1027 const vk::VkSubpassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_SUBPASS_CONTENTS_INLINE) : (vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1029 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1030 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1032 if (m_isPrimaryCmdBuf)
1034 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1035 writeDrawCmdBuffer(*mainCmd);
1039 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1040 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1041 writeDrawCmdBuffer(*passCmd);
1042 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1044 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1047 m_vki.cmdEndRenderPass(*mainCmd);
1048 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1050 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1052 const vk::VkSubmitInfo submitInfo =
1054 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1057 (const vk::VkSemaphore*)0,
1058 (const vk::VkPipelineStageFlags*)DE_NULL,
1062 (const vk::VkSemaphore*)0,
1064 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *fence));
1066 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1069 enum ShaderInputInterface
1071 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1072 SHADER_INPUT_MULTIPLE_DESCRIPTORS, //!< multiple descriptors
1073 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1078 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1080 switch (shaderInterface)
1082 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1083 case SHADER_INPUT_MULTIPLE_DESCRIPTORS: return 2u;
1084 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1087 DE_FATAL("Impossible");
1092 class BufferRenderInstance : public SingleCmdRenderInstance
1095 BufferRenderInstance (Context& context,
1096 bool isPrimaryCmdBuf,
1097 vk::VkDescriptorType descriptorType,
1098 vk::VkShaderStageFlags stageFlags,
1099 ShaderInputInterface shaderInterface,
1102 bool dynamicOffsetNonZero);
1104 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1105 vk::VkDevice device,
1106 vk::Allocator& allocator,
1107 vk::VkDescriptorType descriptorType,
1109 deUint32 bufferSize,
1110 de::MovePtr<vk::Allocation>* outMemory);
1112 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1113 vk::VkDevice device,
1114 vk::VkDescriptorType descriptorType,
1115 ShaderInputInterface shaderInterface);
1117 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1118 vk::VkDevice device,
1119 vk::VkDescriptorType descriptorType,
1120 ShaderInputInterface shaderInterface,
1121 vk::VkShaderStageFlags stageFlags);
1123 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1124 vk::VkDevice device,
1125 vk::VkDescriptorSetLayout descriptorSetLayout,
1126 vk::VkDescriptorPool descriptorPool,
1127 vk::VkDescriptorType descriptorType,
1128 ShaderInputInterface shaderInterface,
1129 vk::VkBuffer sourceBufferA,
1130 const deUint32 viewOffsetA,
1131 vk::VkBuffer sourceBufferB,
1132 const deUint32 viewOffsetB);
1134 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1135 vk::VkDevice device,
1136 vk::VkDescriptorSetLayout descriptorSetLayout);
1138 void logTestPlan (void) const;
1139 vk::VkPipelineLayout getPipelineLayout (void) const;
1140 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1141 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1146 BUFFER_DATA_SIZE = 8 * sizeof(float),
1147 BUFFER_SIZE_A = 2048, //!< a lot more than required
1148 BUFFER_SIZE_B = 2560, //!< a lot more than required
1150 STATIC_OFFSET_VALUE_A = 256,
1151 DYNAMIC_OFFSET_VALUE_A = 512,
1152 STATIC_OFFSET_VALUE_B = 1024,
1153 DYNAMIC_OFFSET_VALUE_B = 768,
1156 const vk::VkDescriptorType m_descriptorType;
1157 const ShaderInputInterface m_shaderInterface;
1158 const bool m_setViewOffset;
1159 const bool m_setDynamicOffset;
1160 const bool m_dynamicOffsetNonZero;
1161 const vk::VkShaderStageFlags m_stageFlags;
1163 const deUint32 m_viewOffsetA;
1164 const deUint32 m_viewOffsetB;
1165 const deUint32 m_dynamicOffsetA;
1166 const deUint32 m_dynamicOffsetB;
1167 const deUint32 m_effectiveOffsetA;
1168 const deUint32 m_effectiveOffsetB;
1169 const deUint32 m_bufferSizeA;
1170 const deUint32 m_bufferSizeB;
1172 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1173 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1174 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1175 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1176 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1177 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1178 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1179 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1182 BufferRenderInstance::BufferRenderInstance (Context& context,
1183 bool isPrimaryCmdBuf,
1184 vk::VkDescriptorType descriptorType,
1185 vk::VkShaderStageFlags stageFlags,
1186 ShaderInputInterface shaderInterface,
1189 bool dynamicOffsetNonZero)
1190 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1191 , m_descriptorType (descriptorType)
1192 , m_shaderInterface (shaderInterface)
1193 , m_setViewOffset (viewOffset)
1194 , m_setDynamicOffset (dynamicOffset)
1195 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1196 , m_stageFlags (stageFlags)
1197 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1198 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1199 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1200 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1201 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetA + m_dynamicOffsetA) : (m_viewOffsetA))
1202 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetB + m_dynamicOffsetB) : (m_viewOffsetB))
1203 , m_bufferSizeA (BUFFER_SIZE_A)
1204 , m_bufferSizeB (BUFFER_SIZE_B)
1205 , m_bufferMemoryA (DE_NULL)
1206 , m_bufferMemoryB (DE_NULL)
1207 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1208 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1209 ? vk::Move<vk::VkBuffer>()
1210 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1211 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1212 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
1213 , m_descriptorSet (createDescriptorSet(m_vki, m_device, *m_descriptorSetLayout, *m_descriptorPool, m_descriptorType, m_shaderInterface, *m_sourceBufferA, m_viewOffsetA, *m_sourceBufferB, m_viewOffsetB))
1214 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1216 if (m_setDynamicOffset)
1217 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1218 if (m_dynamicOffsetNonZero)
1219 DE_ASSERT(m_setDynamicOffset);
1222 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1223 vk::VkDevice device,
1224 vk::Allocator& allocator,
1225 vk::VkDescriptorType descriptorType,
1227 deUint32 bufferSize,
1228 de::MovePtr<vk::Allocation>* outMemory)
1230 static const float s_colors[] =
1232 0.0f, 1.0f, 0.0f, 1.0f, // green
1233 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1235 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1236 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1237 DE_ASSERT(offset % sizeof(float) == 0);
1238 DE_ASSERT(bufferSize % sizeof(float) == 0);
1240 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1241 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1242 const float preGuardValue = 0.5f;
1243 const float postGuardValue = 0.75f;
1244 const vk::VkBufferCreateInfo bufferCreateInfo =
1246 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1250 usageFlags, // usage
1251 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1252 0u, // queueFamilyCount
1253 DE_NULL, // pQueueFamilyIndices
1255 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1256 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1257 void* const mapPtr = bufferMemory->getHostPtr();
1259 // guard with interesting values
1260 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1261 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1263 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1264 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1265 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1266 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
1268 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1270 *outMemory = bufferMemory;
1274 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1275 vk::VkDevice device,
1276 vk::VkDescriptorType descriptorType,
1277 ShaderInputInterface shaderInterface)
1279 return vk::DescriptorPoolBuilder()
1280 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1281 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1284 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1285 vk::VkDevice device,
1286 vk::VkDescriptorType descriptorType,
1287 ShaderInputInterface shaderInterface,
1288 vk::VkShaderStageFlags stageFlags)
1290 vk::DescriptorSetLayoutBuilder builder;
1292 switch (shaderInterface)
1294 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1295 builder.addSingleBinding(descriptorType, stageFlags);
1298 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1299 builder.addSingleBinding(descriptorType, stageFlags);
1300 builder.addSingleBinding(descriptorType, stageFlags);
1303 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1304 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1308 DE_FATAL("Impossible");
1311 return builder.build(vki, device);
1314 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1315 vk::VkDevice device,
1316 vk::VkDescriptorSetLayout descriptorSetLayout,
1317 vk::VkDescriptorPool descriptorPool,
1318 vk::VkDescriptorType descriptorType,
1319 ShaderInputInterface shaderInterface,
1320 vk::VkBuffer bufferA,
1322 vk::VkBuffer bufferB,
1325 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1327 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1328 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1330 const vk::VkDescriptorSetAllocateInfo allocInfo =
1332 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1336 &descriptorSetLayout
1339 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1340 vk::DescriptorSetUpdateBuilder builder;
1342 switch (shaderInterface)
1344 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1345 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1348 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1349 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1350 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1353 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1354 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1358 DE_FATAL("Impossible");
1361 builder.update(vki, device);
1362 return descriptorSet;
1365 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1366 vk::VkDevice device,
1367 vk::VkDescriptorSetLayout descriptorSetLayout)
1369 const vk::VkPipelineLayoutCreateInfo createInfo =
1371 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1373 (vk::VkPipelineLayoutCreateFlags)0,
1374 1, // descriptorSetCount
1375 &descriptorSetLayout, // pSetLayouts
1376 0u, // pushConstantRangeCount
1377 DE_NULL, // pPushConstantRanges
1380 return vk::createPipelineLayout(vki, device, &createInfo);
1383 void BufferRenderInstance::logTestPlan (void) const
1385 std::ostringstream msg;
1387 msg << "Rendering 2x2 yellow-green grid.\n"
1388 << "Single descriptor set. Descriptor set contains "
1389 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1390 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
1391 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1392 (const char*)DE_NULL)
1393 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1394 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1396 if (isDynamicDescriptorType(m_descriptorType))
1398 if (m_setDynamicOffset)
1400 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1401 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1405 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1409 if (m_stageFlags == 0u)
1411 msg << "Descriptors are not accessed in any shader stage.\n";
1415 msg << "Descriptors are accessed in {"
1416 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1417 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1418 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1419 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1420 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1424 m_context.getTestContext().getLog()
1425 << tcu::TestLog::Message
1427 << tcu::TestLog::EndMessage;
1430 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1432 return *m_pipelineLayout;
1435 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1437 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1439 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1440 const deUint32 dynamicOffsets[] =
1445 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1446 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1448 // make host writes device-visible
1449 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
1450 const vk::VkBufferMemoryBarrier memoryBarriers[] =
1453 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1455 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
1456 inputBit, // inputMask
1457 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1458 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1459 *m_sourceBufferA, // buffer
1461 (vk::VkDeviceSize)m_bufferSizeA, // size
1464 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1466 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
1467 inputBit, // inputMask
1468 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1469 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1470 *m_sourceBufferB, // buffer
1472 (vk::VkDeviceSize)m_bufferSizeB, // size
1475 const deUint32 numMemoryBarriers = getInterfaceNumResources(m_shaderInterface);
1477 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1478 m_vki.cmdPipelineBarrier(cmd, 0u, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (vk::VkDependencyFlags)0,
1479 0, (const vk::VkMemoryBarrier*)DE_NULL,
1480 numMemoryBarriers, memoryBarriers,
1481 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
1482 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1485 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1487 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1488 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1489 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1491 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1493 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1494 return tcu::TestStatus::fail("Image verification failed");
1496 return tcu::TestStatus::pass("Pass");
1499 class ComputeInstanceResultBuffer
1504 DATA_SIZE = sizeof(tcu::Vec4[4])
1507 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1508 vk::VkDevice device,
1509 vk::Allocator& allocator);
1511 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1513 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1514 inline const vk::VkBufferMemoryBarrier* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1517 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1518 vk::VkDevice device,
1519 vk::Allocator& allocator,
1520 de::MovePtr<vk::Allocation>* outAllocation);
1522 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1524 const vk::DeviceInterface& m_vki;
1525 const vk::VkDevice m_device;
1527 de::MovePtr<vk::Allocation> m_bufferMem;
1528 const vk::Unique<vk::VkBuffer> m_buffer;
1529 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1532 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1533 vk::VkDevice device,
1534 vk::Allocator& allocator)
1537 , m_bufferMem (DE_NULL)
1538 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1539 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1543 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1545 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1546 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1549 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1550 vk::VkDevice device,
1551 vk::Allocator& allocator,
1552 de::MovePtr<vk::Allocation>* outAllocation)
1554 const vk::VkBufferCreateInfo createInfo =
1556 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1559 (vk::VkDeviceSize)DATA_SIZE, // size
1560 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1561 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1562 0u, // queueFamilyCount
1563 DE_NULL, // pQueueFamilyIndices
1565 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1566 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1567 const float clearValue = -1.0f;
1568 void* mapPtr = allocation->getHostPtr();
1570 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1571 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1573 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1575 *outAllocation = allocation;
1579 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1581 const vk::VkBufferMemoryBarrier bufferBarrier =
1583 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1585 vk::VK_ACCESS_SHADER_WRITE_BIT, // outputMask
1586 vk::VK_ACCESS_HOST_READ_BIT, // inputMask
1587 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1588 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1590 (vk::VkDeviceSize)0u, // offset
1593 return bufferBarrier;
1596 class ComputePipeline
1599 ComputePipeline (const vk::DeviceInterface& vki,
1600 vk::VkDevice device,
1601 const vk::BinaryCollection& programCollection,
1602 deUint32 numDescriptorSets,
1603 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1605 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1606 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1609 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1610 vk::VkDevice device,
1611 deUint32 numDescriptorSets,
1612 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1614 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1615 vk::VkDevice device,
1616 const vk::BinaryCollection& programCollection,
1617 vk::VkPipelineLayout layout);
1619 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1620 const vk::Unique<vk::VkPipeline> m_pipeline;
1623 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1624 vk::VkDevice device,
1625 const vk::BinaryCollection& programCollection,
1626 deUint32 numDescriptorSets,
1627 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1628 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
1629 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
1633 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
1634 vk::VkDevice device,
1635 deUint32 numDescriptorSets,
1636 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1638 const vk::VkPipelineLayoutCreateInfo createInfo =
1640 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1642 (vk::VkPipelineLayoutCreateFlags)0,
1643 numDescriptorSets, // descriptorSetCount
1644 descriptorSetLayouts, // pSetLayouts
1645 0u, // pushConstantRangeCount
1646 DE_NULL, // pPushConstantRanges
1648 return vk::createPipelineLayout(vki, device, &createInfo);
1651 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
1652 vk::VkDevice device,
1653 const vk::BinaryCollection& programCollection,
1654 vk::VkPipelineLayout layout)
1656 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
1657 const vk::VkPipelineShaderStageCreateInfo cs =
1659 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1661 (vk::VkPipelineShaderStageCreateFlags)0,
1662 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
1663 *computeModule, // shader
1665 DE_NULL, // pSpecializationInfo
1667 const vk::VkComputePipelineCreateInfo createInfo =
1669 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1674 (vk::VkPipeline)0, // basePipelineHandle
1675 0u, // basePipelineIndex
1677 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
1680 class ComputeCommand
1683 ComputeCommand (const vk::DeviceInterface& vki,
1684 vk::VkDevice device,
1685 vk::VkPipeline pipeline,
1686 vk::VkPipelineLayout pipelineLayout,
1687 const tcu::UVec3& numWorkGroups,
1688 int numDescriptorSets,
1689 const vk::VkDescriptorSet* descriptorSets,
1690 int numDynamicOffsets,
1691 const deUint32* dynamicOffsets,
1693 const vk::VkBufferMemoryBarrier* preBarriers,
1694 int numPostBarriers,
1695 const vk::VkBufferMemoryBarrier* postBarriers);
1697 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const;
1700 const vk::DeviceInterface& m_vki;
1701 const vk::VkDevice m_device;
1702 const vk::VkPipeline m_pipeline;
1703 const vk::VkPipelineLayout m_pipelineLayout;
1704 const tcu::UVec3 m_numWorkGroups;
1705 const int m_numDescriptorSets;
1706 const vk::VkDescriptorSet* const m_descriptorSets;
1707 const int m_numDynamicOffsets;
1708 const deUint32* const m_dynamicOffsets;
1709 const int m_numPreBarriers;
1710 const vk::VkBufferMemoryBarrier* const m_preBarriers;
1711 const int m_numPostBarriers;
1712 const vk::VkBufferMemoryBarrier* const m_postBarriers;
1715 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
1716 vk::VkDevice device,
1717 vk::VkPipeline pipeline,
1718 vk::VkPipelineLayout pipelineLayout,
1719 const tcu::UVec3& numWorkGroups,
1720 int numDescriptorSets,
1721 const vk::VkDescriptorSet* descriptorSets,
1722 int numDynamicOffsets,
1723 const deUint32* dynamicOffsets,
1725 const vk::VkBufferMemoryBarrier* preBarriers,
1726 int numPostBarriers,
1727 const vk::VkBufferMemoryBarrier* postBarriers)
1730 , m_pipeline (pipeline)
1731 , m_pipelineLayout (pipelineLayout)
1732 , m_numWorkGroups (numWorkGroups)
1733 , m_numDescriptorSets (numDescriptorSets)
1734 , m_descriptorSets (descriptorSets)
1735 , m_numDynamicOffsets (numDynamicOffsets)
1736 , m_dynamicOffsets (dynamicOffsets)
1737 , m_numPreBarriers (numPreBarriers)
1738 , m_preBarriers (preBarriers)
1739 , m_numPostBarriers (numPostBarriers)
1740 , m_postBarriers (postBarriers)
1744 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const
1746 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
1748 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1750 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
1751 queueFamilyIndex, // queueFamilyIndex
1753 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
1755 const vk::VkFenceCreateInfo fenceCreateInfo =
1757 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1762 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
1764 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1766 *cmdPool, // cmdPool
1767 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1770 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
1772 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1774 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1775 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
1778 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1779 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
1780 const deUint64 infiniteTimeout = ~(deUint64)0u;
1782 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
1784 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
1785 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
1787 if (m_numPreBarriers)
1788 m_vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
1789 0, (const vk::VkMemoryBarrier*)DE_NULL,
1790 m_numPreBarriers, m_preBarriers,
1791 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
1793 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
1794 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
1795 0, (const vk::VkMemoryBarrier*)DE_NULL,
1796 m_numPostBarriers, m_postBarriers,
1797 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
1798 VK_CHECK(m_vki.endCommandBuffer(*cmd));
1802 const vk::VkSubmitInfo submitInfo =
1804 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1807 (const vk::VkSemaphore*)0,
1808 (const vk::VkPipelineStageFlags*)DE_NULL,
1812 (const vk::VkSemaphore*)0,
1814 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
1816 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1819 class BufferComputeInstance : public vkt::TestInstance
1822 BufferComputeInstance (Context& context,
1823 vk::VkDescriptorType descriptorType,
1824 ShaderInputInterface shaderInterface,
1827 bool dynamicOffsetNonZero);
1830 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
1831 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
1832 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
1833 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
1834 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf) const;
1836 tcu::TestStatus iterate (void);
1837 void logTestPlan (void) const;
1838 tcu::TestStatus testResourceAccess (void);
1842 STATIC_OFFSET_VALUE_A = 256,
1843 DYNAMIC_OFFSET_VALUE_A = 512,
1844 STATIC_OFFSET_VALUE_B = 1024,
1845 DYNAMIC_OFFSET_VALUE_B = 768,
1848 const vk::VkDescriptorType m_descriptorType;
1849 const ShaderInputInterface m_shaderInterface;
1850 const bool m_setViewOffset;
1851 const bool m_setDynamicOffset;
1852 const bool m_dynamicOffsetNonZero;
1854 const vk::DeviceInterface& m_vki;
1855 const vk::VkDevice m_device;
1856 const vk::VkQueue m_queue;
1857 const deUint32 m_queueFamilyIndex;
1858 vk::Allocator& m_allocator;
1860 const ComputeInstanceResultBuffer m_result;
1863 BufferComputeInstance::BufferComputeInstance (Context& context,
1864 vk::VkDescriptorType descriptorType,
1865 ShaderInputInterface shaderInterface,
1868 bool dynamicOffsetNonZero)
1869 : vkt::TestInstance (context)
1870 , m_descriptorType (descriptorType)
1871 , m_shaderInterface (shaderInterface)
1872 , m_setViewOffset (viewOffset)
1873 , m_setDynamicOffset (dynamicOffset)
1874 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1875 , m_vki (context.getDeviceInterface())
1876 , m_device (context.getDevice())
1877 , m_queue (context.getUniversalQueue())
1878 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
1879 , m_allocator (context.getDefaultAllocator())
1880 , m_result (m_vki, m_device, m_allocator)
1882 if (m_dynamicOffsetNonZero)
1883 DE_ASSERT(m_setDynamicOffset);
1886 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
1888 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
1890 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1891 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1892 const vk::VkBufferCreateInfo createInfo =
1894 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1897 (vk::VkDeviceSize)bufferSize, // size
1898 usageFlags, // usage
1899 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1900 0u, // queueFamilyCount
1901 DE_NULL, // pQueueFamilyIndices
1903 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
1904 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
1905 void* mapPtr = allocation->getHostPtr();
1908 deMemset(mapPtr, 0x5A, (size_t)offset);
1909 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
1910 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
1911 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
1913 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
1915 *outAllocation = allocation;
1919 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
1921 vk::DescriptorSetLayoutBuilder builder;
1923 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1925 switch (m_shaderInterface)
1927 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1928 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1931 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1932 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1933 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1936 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1937 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1941 DE_FATAL("Impossible");
1944 return builder.build(m_vki, m_device);
1947 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
1949 return vk::DescriptorPoolBuilder()
1950 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1951 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
1952 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1955 vk::Move<vk::VkDescriptorSet> BufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout, vk::VkBuffer viewA, deUint32 offsetA, vk::VkBuffer viewB, deUint32 offsetB, vk::VkBuffer resBuf) const
1957 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
1958 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1960 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1961 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1963 const vk::VkDescriptorSetAllocateInfo allocInfo =
1965 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1972 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
1973 vk::DescriptorSetUpdateBuilder builder;
1976 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
1979 switch (m_shaderInterface)
1981 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1982 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
1985 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
1986 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
1987 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
1990 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1991 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
1995 DE_FATAL("Impossible");
1998 builder.update(m_vki, m_device);
1999 return descriptorSet;
2002 tcu::TestStatus BufferComputeInstance::iterate (void)
2005 return testResourceAccess();
2008 void BufferComputeInstance::logTestPlan (void) const
2010 std::ostringstream msg;
2012 msg << "Accessing resource in a compute program.\n"
2013 << "Single descriptor set. Descriptor set contains "
2014 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2015 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
2016 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2017 (const char*)DE_NULL)
2018 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2019 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2020 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2022 if (isDynamicDescriptorType(m_descriptorType))
2024 if (m_setDynamicOffset)
2026 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2027 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2031 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2035 msg << "Destination buffer is pre-initialized to -1.\n";
2037 m_context.getTestContext().getLog()
2038 << tcu::TestLog::Message
2040 << tcu::TestLog::EndMessage;
2043 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2047 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2050 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2051 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2052 const deUint32 bindTimeOffsets[] =
2054 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2055 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2058 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2059 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2060 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2061 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2063 const deUint32 dataOffsetA = ((isDynamicCase) ? (bindTimeOffsets[0]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u));
2064 const deUint32 dataOffsetB = ((isDynamicCase) ? (bindTimeOffsets[1]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u));
2065 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2066 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2067 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2068 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2070 de::MovePtr<vk::Allocation> bufferMemA;
2071 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2073 de::MovePtr<vk::Allocation> bufferMemB;
2074 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2075 ? (vk::Move<vk::VkBuffer>())
2076 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2078 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2079 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2080 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer()));
2081 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2083 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2084 const vk::VkBufferMemoryBarrier bufferBarriers[] =
2087 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2089 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2090 inputBit, // inputMask
2091 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2092 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2094 (vk::VkDeviceSize)0u, // offset
2095 (vk::VkDeviceSize)bufferSizeA, // size
2098 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2100 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2101 inputBit, // inputMask
2102 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2103 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2105 (vk::VkDeviceSize)0u, // offset
2106 (vk::VkDeviceSize)bufferSizeB, // size
2110 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2112 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2113 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2114 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2115 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2116 const vk::VkBufferMemoryBarrier* const preBarriers = bufferBarriers;
2117 const int numPreBarriers = numSrcBuffers;
2118 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
2119 const int numPostBarriers = 1;
2121 const ComputeCommand compute (m_vki,
2123 pipeline.getPipeline(),
2124 pipeline.getPipelineLayout(),
2125 tcu::UVec3(4, 1, 1),
2126 numDescriptorSets, descriptorSets,
2127 numDynamicOffsets, dynamicOffsets,
2128 numPreBarriers, preBarriers,
2129 numPostBarriers, postBarriers);
2131 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2132 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorB2) :
2133 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2135 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2136 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? (colorA1) :
2137 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2139 const tcu::Vec4 references[4] =
2146 tcu::Vec4 results[4];
2148 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2149 m_result.readResultContentsTo(&results);
2152 if (results[0] == references[0] &&
2153 results[1] == references[1] &&
2154 results[2] == references[2] &&
2155 results[3] == references[3])
2157 return tcu::TestStatus::pass("Pass");
2159 else if (results[0] == tcu::Vec4(-1.0f) &&
2160 results[1] == tcu::Vec4(-1.0f) &&
2161 results[2] == tcu::Vec4(-1.0f) &&
2162 results[3] == tcu::Vec4(-1.0f))
2164 m_context.getTestContext().getLog()
2165 << tcu::TestLog::Message
2166 << "Result buffer was not written to."
2167 << tcu::TestLog::EndMessage;
2168 return tcu::TestStatus::fail("Result buffer was not written to");
2172 m_context.getTestContext().getLog()
2173 << tcu::TestLog::Message
2174 << "Error expected ["
2175 << references[0] << ", "
2176 << references[1] << ", "
2177 << references[2] << ", "
2178 << references[3] << "], got ["
2179 << results[0] << ", "
2180 << results[1] << ", "
2181 << results[2] << ", "
2182 << results[3] << "]"
2183 << tcu::TestLog::EndMessage;
2184 return tcu::TestStatus::fail("Invalid result values");
2188 class QuadrantRendederCase : public vkt::TestCase
2191 QuadrantRendederCase (tcu::TestContext& testCtx,
2193 const char* description,
2194 glu::GLSLVersion glslVersion,
2195 vk::VkShaderStageFlags exitingStages,
2196 vk::VkShaderStageFlags activeStages);
2198 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
2199 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
2200 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
2201 virtual std::string genNoAccessSource (void) const = 0;
2203 std::string genVertexSource (void) const;
2204 std::string genTessCtrlSource (void) const;
2205 std::string genTessEvalSource (void) const;
2206 std::string genGeometrySource (void) const;
2207 std::string genFragmentSource (void) const;
2208 std::string genComputeSource (void) const;
2210 void initPrograms (vk::SourceCollections& programCollection) const;
2213 const glu::GLSLVersion m_glslVersion;
2214 const vk::VkShaderStageFlags m_exitingStages;
2215 const vk::VkShaderStageFlags m_activeStages;
2218 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2220 const char* description,
2221 glu::GLSLVersion glslVersion,
2222 vk::VkShaderStageFlags exitingStages,
2223 vk::VkShaderStageFlags activeStages)
2224 : vkt::TestCase (testCtx, name, description)
2225 , m_glslVersion (glslVersion)
2226 , m_exitingStages (exitingStages)
2227 , m_activeStages (activeStages)
2229 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2232 std::string QuadrantRendederCase::genVertexSource (void) const
2234 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
2235 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2236 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2238 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2239 std::ostringstream buf;
2241 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2243 // active vertex shader
2244 buf << versionDecl << "\n"
2245 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2246 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0)
2247 << "layout(location = 0) out highp vec4 " << nextStageName << "_color;\n"
2248 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2249 << "void main (void)\n"
2251 << " highp vec4 result_position;\n"
2252 << " highp int quadrant_id;\n"
2253 << s_quadrantGenVertexPosSource
2254 << " gl_Position = result_position;\n"
2255 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2257 << " highp vec4 result_color;\n"
2258 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
2259 << " " << nextStageName << "_color = result_color;\n"
2265 buf << versionDecl << "\n"
2266 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2267 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2268 << "void main (void)\n"
2270 << " highp vec4 result_position;\n"
2271 << " highp int quadrant_id;\n"
2272 << s_quadrantGenVertexPosSource
2273 << " gl_Position = result_position;\n"
2274 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2281 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2283 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2284 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2285 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2286 std::ostringstream buf;
2288 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2290 // contributing not implemented
2291 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2294 buf << versionDecl << "\n"
2296 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2297 << "layout(vertices=3) out;\n"
2298 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
2299 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2300 << "layout(location = 0) out highp vec4 tes_color[];\n"
2301 << "void main (void)\n"
2303 << " highp vec4 result_color;\n"
2304 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2305 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2307 << " tes_color[gl_InvocationID] = result_color;\n"
2309 << " // no dynamic input block indexing\n"
2310 << " highp vec4 position;\n"
2311 << " if (gl_InvocationID == 0)\n"
2312 << " position = gl_in[0].gl_Position;\n"
2313 << " else if (gl_InvocationID == 1)\n"
2314 << " position = gl_in[1].gl_Position;\n"
2316 << " position = gl_in[2].gl_Position;\n"
2317 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2318 << " gl_TessLevelInner[0] = 2.8;\n"
2319 << " gl_TessLevelInner[1] = 2.8;\n"
2320 << " gl_TessLevelOuter[0] = 2.8;\n"
2321 << " gl_TessLevelOuter[1] = 2.8;\n"
2322 << " gl_TessLevelOuter[2] = 2.8;\n"
2323 << " gl_TessLevelOuter[3] = 2.8;\n"
2326 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2328 // active te shader, tc passthru
2329 buf << versionDecl << "\n"
2331 << "layout(vertices=3) out;\n"
2332 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2333 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2334 << "void main (void)\n"
2336 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2338 << " // no dynamic input block indexing\n"
2339 << " highp vec4 position;\n"
2340 << " if (gl_InvocationID == 0)\n"
2341 << " position = gl_in[0].gl_Position;\n"
2342 << " else if (gl_InvocationID == 1)\n"
2343 << " position = gl_in[1].gl_Position;\n"
2345 << " position = gl_in[2].gl_Position;\n"
2346 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2347 << " gl_TessLevelInner[0] = 2.8;\n"
2348 << " gl_TessLevelInner[1] = 2.8;\n"
2349 << " gl_TessLevelOuter[0] = 2.8;\n"
2350 << " gl_TessLevelOuter[1] = 2.8;\n"
2351 << " gl_TessLevelOuter[2] = 2.8;\n"
2352 << " gl_TessLevelOuter[3] = 2.8;\n"
2357 // passthrough not implemented
2358 DE_FATAL("not implemented");
2364 std::string QuadrantRendederCase::genTessEvalSource (void) const
2366 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2367 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2368 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2369 std::ostringstream buf;
2371 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2373 // contributing not implemented
2374 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
2377 buf << versionDecl << "\n"
2379 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2380 << "layout(triangles) in;\n"
2381 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
2382 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2383 << "layout(location = 0) out highp vec4 frag_color;\n"
2384 << "void main (void)\n"
2386 << " highp vec4 result_color;\n"
2387 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2388 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2390 << " frag_color = result_color;\n"
2391 << " 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"
2394 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2396 // contributing not implemented
2397 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2399 // active tc shader, te is passthru
2400 buf << versionDecl << "\n"
2402 << "layout(triangles) in;\n"
2403 << "layout(location = 0) in highp vec4 tes_color[];\n"
2404 << "layout(location = 0) out highp vec4 frag_color;\n"
2405 << "void main (void)\n"
2407 << " frag_color = tes_color[0];\n"
2408 << " 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"
2413 // passthrough not implemented
2414 DE_FATAL("not implemented");
2420 std::string QuadrantRendederCase::genGeometrySource (void) const
2422 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2423 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2424 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
2425 std::ostringstream buf;
2427 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2429 // contributing not implemented
2430 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
2432 // active geometry shader
2433 buf << versionDecl << "\n"
2435 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2436 << "layout(triangles) in;\n"
2437 << "layout(triangle_strip, max_vertices=4) out;\n"
2438 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
2439 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
2440 << "layout(location = 0) out highp vec4 frag_color;\n"
2441 << "void main (void)\n"
2443 << " highp int quadrant_id;\n"
2444 << " highp vec4 result_color;\n"
2446 << " quadrant_id = geo_quadrant_id[0];\n"
2447 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2448 << " frag_color = result_color;\n"
2449 << " gl_Position = gl_in[0].gl_Position;\n"
2450 << " EmitVertex();\n"
2452 << " quadrant_id = geo_quadrant_id[1];\n"
2453 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2454 << " frag_color = result_color;\n"
2455 << " gl_Position = gl_in[1].gl_Position;\n"
2456 << " EmitVertex();\n"
2458 << " quadrant_id = geo_quadrant_id[2];\n"
2459 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2460 << " frag_color = result_color;\n"
2461 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
2462 << " EmitVertex();\n"
2464 << " quadrant_id = geo_quadrant_id[0];\n"
2465 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2466 << " frag_color = result_color;\n"
2467 << " gl_Position = gl_in[2].gl_Position;\n"
2468 << " EmitVertex();\n"
2473 // passthrough not implemented
2474 DE_FATAL("not implemented");
2480 std::string QuadrantRendederCase::genFragmentSource (void) const
2482 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2483 std::ostringstream buf;
2485 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2487 buf << versionDecl << "\n"
2488 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2489 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
2491 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2493 // there are other stages, this is just a contributor
2494 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
2497 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2498 << "layout(location = 0) out mediump vec4 o_color;\n"
2499 << "void main (void)\n"
2501 << " highp int quadrant_id = frag_quadrant_id;\n"
2502 << " highp vec4 result_color;\n"
2503 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
2505 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2508 buf << " if (frag_quadrant_id < 2)\n"
2509 << " o_color = result_color;\n"
2511 << " o_color = frag_color;\n";
2514 buf << " o_color = result_color;\n";
2518 else if (m_activeStages == 0u)
2520 // special case, no active stages
2521 buf << versionDecl << "\n"
2522 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2523 << "layout(location = 0) out mediump vec4 o_color;\n"
2524 << "void main (void)\n"
2526 << " highp int quadrant_id = frag_quadrant_id;\n"
2527 << " highp vec4 result_color;\n"
2528 << genNoAccessSource()
2529 << " o_color = result_color;\n"
2535 buf << versionDecl << "\n"
2536 << "layout(location = 0) in mediump vec4 frag_color;\n"
2537 "layout(location = 0) out mediump vec4 o_color;\n"
2538 "void main (void)\n"
2540 " o_color = frag_color;\n"
2547 std::string QuadrantRendederCase::genComputeSource (void) const
2549 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2550 std::ostringstream buf;
2552 buf << versionDecl << "\n"
2553 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2554 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2555 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
2556 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
2558 << " highp vec4 read_colors[4];\n"
2560 << "void main(void)\n"
2562 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
2563 << " highp vec4 result_color;\n"
2564 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2565 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
2571 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
2573 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2574 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
2576 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2577 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
2579 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2580 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
2582 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2583 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
2585 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2586 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
2588 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
2589 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
2592 class BufferDescriptorCase : public QuadrantRendederCase
2597 FLAG_VIEW_OFFSET = (1u << 1u),
2598 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
2599 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
2601 // enum continues where resource flags ends
2602 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
2604 BufferDescriptorCase (tcu::TestContext& testCtx,
2606 const char* description,
2607 bool isPrimaryCmdBuf,
2608 vk::VkDescriptorType descriptorType,
2609 vk::VkShaderStageFlags exitingStages,
2610 vk::VkShaderStageFlags activeStages,
2611 ShaderInputInterface shaderInterface,
2615 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
2616 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
2617 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
2618 std::string genNoAccessSource (void) const;
2620 vkt::TestInstance* createInstance (vkt::Context& context) const;
2622 const bool m_viewOffset;
2623 const bool m_dynamicOffsetSet;
2624 const bool m_dynamicOffsetNonZero;
2625 const bool m_isPrimaryCmdBuf;
2626 const vk::VkDescriptorType m_descriptorType;
2627 const ShaderInputInterface m_shaderInterface;
2630 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
2632 const char* description,
2633 bool isPrimaryCmdBuf,
2634 vk::VkDescriptorType descriptorType,
2635 vk::VkShaderStageFlags exitingStages,
2636 vk::VkShaderStageFlags activeStages,
2637 ShaderInputInterface shaderInterface,
2639 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
2640 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
2641 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
2642 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
2643 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
2644 , m_descriptorType (descriptorType)
2645 , m_shaderInterface (shaderInterface)
2649 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
2655 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
2659 const bool isUniform = isUniformDescriptorType(m_descriptorType);
2660 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
2661 std::ostringstream buf;
2663 switch (m_shaderInterface)
2665 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2666 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2668 << " highp vec4 colorA;\n"
2669 << " highp vec4 colorB;\n"
2670 << "} b_instance;\n";
2673 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2674 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
2676 << " highp vec4 colorA;\n"
2677 << " highp vec4 colorB;\n"
2678 << "} b_instanceA;\n"
2679 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
2681 << " highp vec4 colorA;\n"
2682 << " highp vec4 colorB;\n"
2683 << "} b_instanceB;\n";
2686 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2687 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2689 << " highp vec4 colorA;\n"
2690 << " highp vec4 colorB;\n"
2691 << "} b_instances[2];\n";
2695 DE_FATAL("Impossible");
2701 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
2705 std::ostringstream buf;
2707 switch (m_shaderInterface)
2709 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2710 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2711 << " result_color = b_instance.colorA;\n"
2713 << " result_color = b_instance.colorB;\n";
2716 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
2717 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2718 << " result_color = b_instanceA.colorA;\n"
2720 << " result_color = b_instanceB.colorB;\n";
2723 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2724 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2725 << " result_color = b_instances[0].colorA;\n"
2727 << " result_color = b_instances[1].colorB;\n";
2731 DE_FATAL("Impossible");
2737 std::string BufferDescriptorCase::genNoAccessSource (void) const
2739 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
2740 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2742 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
2745 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
2747 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
2749 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
2750 return new BufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2753 return new BufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2756 class ImageInstanceImages
2759 ImageInstanceImages (const vk::DeviceInterface& vki,
2760 vk::VkDevice device,
2761 deUint32 queueFamilyIndex,
2763 vk::Allocator& allocator,
2764 vk::VkDescriptorType descriptorType,
2765 vk::VkImageViewType viewType,
2767 deUint32 baseMipLevel,
2768 deUint32 baseArraySlice);
2771 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
2772 vk::VkDevice device,
2773 vk::Allocator& allocator,
2774 vk::VkDescriptorType descriptorType,
2775 vk::VkImageViewType viewType,
2776 const tcu::TextureLevelPyramid& sourceImage,
2777 de::MovePtr<vk::Allocation>* outAllocation);
2779 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
2780 vk::VkDevice device,
2781 vk::VkImageViewType viewType,
2782 const tcu::TextureLevelPyramid& sourceImage,
2784 deUint32 baseMipLevel,
2785 deUint32 baseArraySlice);
2787 void populateSourceImage (tcu::TextureLevelPyramid* dst,
2788 bool isFirst) const;
2790 void uploadImage (const vk::DeviceInterface& vki,
2791 vk::VkDevice device,
2792 deUint32 queueFamilyIndex,
2794 vk::Allocator& allocator,
2796 vk::VkImageLayout layout,
2797 const tcu::TextureLevelPyramid& data);
2807 const vk::VkImageViewType m_viewType;
2808 const deUint32 m_baseMipLevel;
2809 const deUint32 m_baseArraySlice;
2811 const tcu::TextureFormat m_imageFormat;
2812 tcu::TextureLevelPyramid m_sourceImageA;
2813 tcu::TextureLevelPyramid m_sourceImageB;
2815 de::MovePtr<vk::Allocation> m_imageMemoryA;
2816 de::MovePtr<vk::Allocation> m_imageMemoryB;
2817 vk::Move<vk::VkImage> m_imageA;
2818 vk::Move<vk::VkImage> m_imageB;
2819 vk::Move<vk::VkImageView> m_imageViewA;
2820 vk::Move<vk::VkImageView> m_imageViewB;
2823 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
2824 vk::VkDevice device,
2825 deUint32 queueFamilyIndex,
2827 vk::Allocator& allocator,
2828 vk::VkDescriptorType descriptorType,
2829 vk::VkImageViewType viewType,
2831 deUint32 baseMipLevel,
2832 deUint32 baseArraySlice)
2833 : m_viewType (viewType)
2834 , m_baseMipLevel (baseMipLevel)
2835 , m_baseArraySlice (baseArraySlice)
2836 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
2837 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
2838 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
2839 , m_imageMemoryA (DE_NULL)
2840 , m_imageMemoryB (DE_NULL)
2841 , m_imageA (vk::Move<vk::VkImage>())
2842 , m_imageB (vk::Move<vk::VkImage>())
2843 , m_imageViewA (vk::Move<vk::VkImageView>())
2844 , m_imageViewB (vk::Move<vk::VkImageView>())
2846 const vk::VkImageLayout layout = getImageLayoutForDescriptorType(descriptorType);
2848 DE_ASSERT(numImages == 1 || numImages == 2);
2850 populateSourceImage(&m_sourceImageA, true);
2851 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
2852 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
2853 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, layout, m_sourceImageA);
2857 populateSourceImage(&m_sourceImageB, false);
2858 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
2859 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
2860 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, layout, m_sourceImageB);
2864 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
2865 vk::VkDevice device,
2866 vk::Allocator& allocator,
2867 vk::VkDescriptorType descriptorType,
2868 vk::VkImageViewType viewType,
2869 const tcu::TextureLevelPyramid& sourceImage,
2870 de::MovePtr<vk::Allocation>* outAllocation)
2872 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2873 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
2874 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
2875 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
2876 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
2877 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
2878 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2879 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
2881 const vk::VkExtent3D extent =
2884 (deUint32)baseLevel.getWidth(),
2887 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1u) : (deUint32)baseLevel.getHeight(),
2890 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deUint32)baseLevel.getDepth()) : (1u),
2892 const vk::VkImageCreateInfo createInfo =
2894 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2896 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
2897 viewTypeToImageType(viewType), // imageType
2898 vk::mapTextureFormat(baseLevel.getFormat()), // format
2900 (deUint32)sourceImage.getNumLevels(), // mipLevels
2901 arraySize, // arraySize
2902 vk::VK_SAMPLE_COUNT_1_BIT, // samples
2903 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
2904 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
2905 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2906 0u, // queueFamilyCount
2907 DE_NULL, // pQueueFamilyIndices
2908 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2910 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
2912 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
2916 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
2917 vk::VkDevice device,
2918 vk::VkImageViewType viewType,
2919 const tcu::TextureLevelPyramid& sourceImage,
2921 deUint32 baseMipLevel,
2922 deUint32 baseArraySlice)
2924 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2925 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
2926 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
2927 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
2928 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
2929 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
2930 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2931 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
2932 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
2935 DE_ASSERT(viewArraySize > 0);
2937 const vk::VkImageSubresourceRange resourceRange =
2939 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
2940 baseMipLevel, // baseMipLevel
2941 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
2942 viewTypeBaseSlice, // baseArraySlice
2943 viewArraySize, // arraySize
2945 const vk::VkImageViewCreateInfo createInfo =
2947 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
2949 (vk::VkImageViewCreateFlags)0,
2951 viewType, // viewType
2952 vk::mapTextureFormat(baseLevel.getFormat()), // format
2954 vk::VK_COMPONENT_SWIZZLE_R,
2955 vk::VK_COMPONENT_SWIZZLE_G,
2956 vk::VK_COMPONENT_SWIZZLE_B,
2957 vk::VK_COMPONENT_SWIZZLE_A
2959 resourceRange, // subresourceRange
2961 return vk::createImageView(vki, device, &createInfo);
2964 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
2966 const int numLevels = dst->getNumLevels();
2968 for (int level = 0; level < numLevels; ++level)
2970 const int width = IMAGE_SIZE >> level;
2971 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
2972 : (IMAGE_SIZE >> level);
2973 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
2974 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
2975 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
2976 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
2979 dst->allocLevel(level, width, height, depth);
2982 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
2984 for (int z = 0; z < depth; ++z)
2985 for (int y = 0; y < height; ++y)
2986 for (int x = 0; x < width; ++x)
2988 const int gradPos = x + y + z;
2989 const int gradMax = width + height + depth - 3;
2991 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
2992 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
2993 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
2995 DE_ASSERT(de::inRange(red, 0, 255));
2996 DE_ASSERT(de::inRange(green, 0, 255));
2997 DE_ASSERT(de::inRange(blue, 0, 255));
2999 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3005 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3006 vk::VkDevice device,
3007 deUint32 queueFamilyIndex,
3009 vk::Allocator& allocator,
3011 vk::VkImageLayout layout,
3012 const tcu::TextureLevelPyramid& data)
3014 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3015 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3016 ((deUint32)ARRAY_SIZE);
3017 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3018 const vk::VkBufferCreateInfo bufferCreateInfo =
3020 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3023 dataBufferSize, // size
3024 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
3025 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3026 0u, // queueFamilyCount
3027 DE_NULL, // pQueueFamilyIndices
3029 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3030 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3031 const vk::VkFenceCreateInfo fenceCreateInfo =
3033 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3037 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3039 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3041 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
3042 vk::VK_ACCESS_TRANSFER_READ_BIT, // inputMask
3043 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3044 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3045 *dataBuffer, // buffer
3047 dataBufferSize, // size
3049 const vk::VkImageSubresourceRange fullSubrange =
3051 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3053 (deUint32)data.getNumLevels(), // mipLevels
3054 0u, // baseArraySlice
3055 arraySize, // arraySize
3057 const vk::VkImageMemoryBarrier preImageBarrier =
3059 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3063 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3064 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout
3065 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3066 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3068 fullSubrange // subresourceRange
3070 const vk::VkImageMemoryBarrier postImageBarrier =
3072 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3074 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask
3075 vk::VK_ACCESS_SHADER_READ_BIT, // inputMask
3076 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout
3077 layout, // newLayout
3078 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3079 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3081 fullSubrange // subresourceRange
3083 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
3085 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
3087 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
3088 queueFamilyIndex, // queueFamilyIndex
3090 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3091 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
3093 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
3095 *cmdPool, // cmdPool
3096 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
3099 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
3101 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3103 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
3104 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
3107 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(vki, device, &cmdBufCreateInfo));
3108 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device, &fenceCreateInfo));
3109 const deUint64 infiniteTimeout = ~(deUint64)0u;
3110 std::vector<vk::VkBufferImageCopy> copySlices;
3112 // copy data to buffer
3113 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3114 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3116 // record command buffer
3117 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3118 vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
3119 0, (const vk::VkMemoryBarrier*)DE_NULL,
3120 1, &preMemoryBarrier,
3121 1, &preImageBarrier);
3122 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3123 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
3124 0, (const vk::VkMemoryBarrier*)DE_NULL,
3125 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
3126 1, &postImageBarrier);
3127 VK_CHECK(vki.endCommandBuffer(*cmd));
3129 // submit and wait for command buffer to complete before killing it
3131 const vk::VkSubmitInfo submitInfo =
3133 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
3136 (const vk::VkSemaphore*)0,
3137 (const vk::VkPipelineStageFlags*)DE_NULL,
3141 (const vk::VkSemaphore*)0,
3143 VK_CHECK(vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
3145 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3148 class ImageFetchInstanceImages : private ImageInstanceImages
3151 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3152 vk::VkDevice device,
3153 deUint32 queueFamilyIndex,
3155 vk::Allocator& allocator,
3156 vk::VkDescriptorType descriptorType,
3157 ShaderInputInterface shaderInterface,
3158 vk::VkImageViewType viewType,
3159 deUint32 baseMipLevel,
3160 deUint32 baseArraySlice);
3162 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3163 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3165 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3166 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3171 // some arbitrary sample points for all four quadrants
3172 SAMPLE_POINT_0_X = 6,
3173 SAMPLE_POINT_0_Y = 13,
3174 SAMPLE_POINT_0_Z = 49,
3176 SAMPLE_POINT_1_X = 51,
3177 SAMPLE_POINT_1_Y = 40,
3178 SAMPLE_POINT_1_Z = 44,
3180 SAMPLE_POINT_2_X = 42,
3181 SAMPLE_POINT_2_Y = 26,
3182 SAMPLE_POINT_2_Z = 19,
3184 SAMPLE_POINT_3_X = 25,
3185 SAMPLE_POINT_3_Y = 25,
3186 SAMPLE_POINT_3_Z = 18,
3189 const ShaderInputInterface m_shaderInterface;
3192 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3193 vk::VkDevice device,
3194 deUint32 queueFamilyIndex,
3196 vk::Allocator& allocator,
3197 vk::VkDescriptorType descriptorType,
3198 ShaderInputInterface shaderInterface,
3199 vk::VkImageViewType viewType,
3200 deUint32 baseMipLevel,
3201 deUint32 baseArraySlice)
3202 : ImageInstanceImages (vki,
3209 getInterfaceNumResources(shaderInterface), // numImages
3212 , m_shaderInterface (shaderInterface)
3216 bool isImageViewTypeArray (vk::VkImageViewType type)
3218 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;
3221 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3223 const tcu::IVec3 fetchPositions[4] =
3225 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3226 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3227 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3228 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3230 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3231 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3232 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3236 case vk::VK_IMAGE_VIEW_TYPE_1D:
3237 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3238 case vk::VK_IMAGE_VIEW_TYPE_2D:
3239 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3240 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3241 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3242 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3244 DE_FATAL("Impossible");
3245 return tcu::IVec3();
3249 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3251 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3253 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3254 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3255 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3256 tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3258 // add base array layer into the appropriate coordinate, based on the view type
3259 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
3260 fetchPos.z() += 6 * m_baseArraySlice;
3261 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3262 fetchPos.y() += m_baseArraySlice;
3264 fetchPos.z() += m_baseArraySlice;
3266 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3269 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3272 ImageFetchRenderInstance (vkt::Context& context,
3273 bool isPrimaryCmdBuf,
3274 vk::VkDescriptorType descriptorType,
3275 vk::VkShaderStageFlags stageFlags,
3276 ShaderInputInterface shaderInterface,
3277 vk::VkImageViewType viewType,
3278 deUint32 baseMipLevel,
3279 deUint32 baseArraySlice);
3282 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3283 vk::VkDevice device,
3284 vk::VkDescriptorType descriptorType,
3285 ShaderInputInterface shaderInterface,
3286 vk::VkShaderStageFlags stageFlags);
3288 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3289 vk::VkDevice device,
3290 vk::VkDescriptorSetLayout descriptorSetLayout);
3292 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3293 vk::VkDevice device,
3294 vk::VkDescriptorType descriptorType,
3295 ShaderInputInterface shaderInterface);
3297 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3298 vk::VkDevice device,
3299 vk::VkDescriptorType descriptorType,
3300 ShaderInputInterface shaderInterface,
3301 vk::VkDescriptorSetLayout layout,
3302 vk::VkDescriptorPool pool,
3303 vk::VkImageView viewA,
3304 vk::VkImageView viewB);
3306 void logTestPlan (void) const;
3307 vk::VkPipelineLayout getPipelineLayout (void) const;
3308 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
3309 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3316 const vk::VkDescriptorType m_descriptorType;
3317 const vk::VkShaderStageFlags m_stageFlags;
3318 const ShaderInputInterface m_shaderInterface;
3319 const vk::VkImageViewType m_viewType;
3320 const deUint32 m_baseMipLevel;
3321 const deUint32 m_baseArraySlice;
3323 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3324 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3325 const ImageFetchInstanceImages m_images;
3326 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3327 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3330 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3331 bool isPrimaryCmdBuf,
3332 vk::VkDescriptorType descriptorType,
3333 vk::VkShaderStageFlags stageFlags,
3334 ShaderInputInterface shaderInterface,
3335 vk::VkImageViewType viewType,
3336 deUint32 baseMipLevel,
3337 deUint32 baseArraySlice)
3338 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3339 , m_descriptorType (descriptorType)
3340 , m_stageFlags (stageFlags)
3341 , m_shaderInterface (shaderInterface)
3342 , m_viewType (viewType)
3343 , m_baseMipLevel (baseMipLevel)
3344 , m_baseArraySlice (baseArraySlice)
3345 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
3346 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3347 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3348 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3349 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_images.getImageViewA(), m_images.getImageViewB()))
3353 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3354 vk::VkDevice device,
3355 vk::VkDescriptorType descriptorType,
3356 ShaderInputInterface shaderInterface,
3357 vk::VkShaderStageFlags stageFlags)
3359 vk::DescriptorSetLayoutBuilder builder;
3361 switch (shaderInterface)
3363 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3364 builder.addSingleBinding(descriptorType, stageFlags);
3367 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3368 builder.addSingleBinding(descriptorType, stageFlags);
3369 builder.addSingleBinding(descriptorType, stageFlags);
3372 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3373 builder.addArrayBinding(descriptorType, 2u, stageFlags);
3377 DE_FATAL("Impossible");
3380 return builder.build(vki, device);
3383 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
3384 vk::VkDevice device,
3385 vk::VkDescriptorSetLayout descriptorSetLayout)
3387 const vk::VkPipelineLayoutCreateInfo createInfo =
3389 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3391 (vk::VkPipelineLayoutCreateFlags)0,
3392 1, // descriptorSetCount
3393 &descriptorSetLayout, // pSetLayouts
3394 0u, // pushConstantRangeCount
3395 DE_NULL, // pPushConstantRanges
3397 return vk::createPipelineLayout(vki, device, &createInfo);
3400 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
3401 vk::VkDevice device,
3402 vk::VkDescriptorType descriptorType,
3403 ShaderInputInterface shaderInterface)
3405 return vk::DescriptorPoolBuilder()
3406 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
3407 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3410 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
3411 vk::VkDevice device,
3412 vk::VkDescriptorType descriptorType,
3413 ShaderInputInterface shaderInterface,
3414 vk::VkDescriptorSetLayout layout,
3415 vk::VkDescriptorPool pool,
3416 vk::VkImageView viewA,
3417 vk::VkImageView viewB)
3419 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
3420 const vk::VkDescriptorImageInfo imageInfos[2] =
3422 makeDescriptorImageInfo(viewA, imageLayout),
3423 makeDescriptorImageInfo(viewB, imageLayout),
3425 const vk::VkDescriptorSetAllocateInfo allocInfo =
3427 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3434 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
3435 vk::DescriptorSetUpdateBuilder builder;
3437 switch (shaderInterface)
3439 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3440 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3443 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3444 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3445 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
3448 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3449 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
3453 DE_FATAL("Impossible");
3456 builder.update(vki, device);
3457 return descriptorSet;
3460 void ImageFetchRenderInstance::logTestPlan (void) const
3462 std::ostringstream msg;
3464 msg << "Rendering 2x2 grid.\n"
3465 << "Single descriptor set. Descriptor set contains "
3466 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3467 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3468 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3469 (const char*)DE_NULL)
3470 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3471 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3474 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3475 if (m_baseArraySlice)
3476 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3478 if (m_stageFlags == 0u)
3480 msg << "Descriptors are not accessed in any shader stage.\n";
3484 msg << "Color in each cell is fetched using the descriptor(s):\n";
3486 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3488 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3490 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3492 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3493 msg << " from descriptor " << srcResourceNdx;
3499 msg << "Descriptors are accessed in {"
3500 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
3501 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
3502 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
3503 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
3504 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
3508 m_context.getTestContext().getLog()
3509 << tcu::TestLog::Message
3511 << tcu::TestLog::EndMessage;
3514 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
3516 return *m_pipelineLayout;
3519 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
3521 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
3522 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
3525 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
3527 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3528 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
3529 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
3530 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
3531 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
3532 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
3533 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
3534 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
3536 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
3538 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
3539 return tcu::TestStatus::fail("Image verification failed");
3541 return tcu::TestStatus::pass("Pass");
3544 class ImageFetchComputeInstance : public vkt::TestInstance
3547 ImageFetchComputeInstance (vkt::Context& context,
3548 vk::VkDescriptorType descriptorType,
3549 ShaderInputInterface shaderInterface,
3550 vk::VkImageViewType viewType,
3551 deUint32 baseMipLevel,
3552 deUint32 baseArraySlice);
3555 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
3556 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
3557 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
3559 tcu::TestStatus iterate (void);
3560 void logTestPlan (void) const;
3561 tcu::TestStatus testResourceAccess (void);
3563 const vk::VkDescriptorType m_descriptorType;
3564 const ShaderInputInterface m_shaderInterface;
3565 const vk::VkImageViewType m_viewType;
3566 const deUint32 m_baseMipLevel;
3567 const deUint32 m_baseArraySlice;
3569 const vk::DeviceInterface& m_vki;
3570 const vk::VkDevice m_device;
3571 const vk::VkQueue m_queue;
3572 const deUint32 m_queueFamilyIndex;
3573 vk::Allocator& m_allocator;
3575 const ComputeInstanceResultBuffer m_result;
3576 const ImageFetchInstanceImages m_images;
3579 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
3580 vk::VkDescriptorType descriptorType,
3581 ShaderInputInterface shaderInterface,
3582 vk::VkImageViewType viewType,
3583 deUint32 baseMipLevel,
3584 deUint32 baseArraySlice)
3585 : vkt::TestInstance (context)
3586 , m_descriptorType (descriptorType)
3587 , m_shaderInterface (shaderInterface)
3588 , m_viewType (viewType)
3589 , m_baseMipLevel (baseMipLevel)
3590 , m_baseArraySlice (baseArraySlice)
3591 , m_vki (context.getDeviceInterface())
3592 , m_device (context.getDevice())
3593 , m_queue (context.getUniversalQueue())
3594 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
3595 , m_allocator (context.getDefaultAllocator())
3596 , m_result (m_vki, m_device, m_allocator)
3597 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3601 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
3603 vk::DescriptorSetLayoutBuilder builder;
3605 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3607 switch (m_shaderInterface)
3609 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3610 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3613 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3614 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3615 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3618 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3619 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3623 DE_FATAL("Impossible");
3626 return builder.build(m_vki, m_device);
3629 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
3631 return vk::DescriptorPoolBuilder()
3632 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3633 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
3634 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3637 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
3639 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
3640 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
3641 const vk::VkDescriptorImageInfo imageInfos[2] =
3643 makeDescriptorImageInfo(m_images.getImageViewA(), imageLayout),
3644 makeDescriptorImageInfo(m_images.getImageViewB(), imageLayout),
3646 const vk::VkDescriptorSetAllocateInfo allocInfo =
3648 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3655 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
3656 vk::DescriptorSetUpdateBuilder builder;
3659 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
3662 switch (m_shaderInterface)
3664 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3665 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3668 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
3669 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3670 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
3673 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3674 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
3678 DE_FATAL("Impossible");
3681 builder.update(m_vki, m_device);
3682 return descriptorSet;
3685 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
3688 return testResourceAccess();
3691 void ImageFetchComputeInstance::logTestPlan (void) const
3693 std::ostringstream msg;
3695 msg << "Fetching 4 values from image in compute shader.\n"
3696 << "Single descriptor set. Descriptor set contains "
3697 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3698 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
3699 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3700 (const char*)DE_NULL)
3701 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3702 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3705 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3706 if (m_baseArraySlice)
3707 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3709 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3711 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3713 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3715 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3716 msg << " from descriptor " << srcResourceNdx;
3722 m_context.getTestContext().getLog()
3723 << tcu::TestLog::Message
3725 << tcu::TestLog::EndMessage;
3728 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
3730 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
3731 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
3732 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
3733 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
3735 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
3736 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
3737 const deUint32* const dynamicOffsets = DE_NULL;
3738 const int numDynamicOffsets = 0;
3739 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
3740 const int numPreBarriers = 0;
3741 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
3742 const int numPostBarriers = 1;
3744 const ComputeCommand compute (m_vki,
3746 pipeline.getPipeline(),
3747 pipeline.getPipelineLayout(),
3748 tcu::UVec3(4, 1, 1),
3749 numDescriptorSets, descriptorSets,
3750 numDynamicOffsets, dynamicOffsets,
3751 numPreBarriers, preBarriers,
3752 numPostBarriers, postBarriers);
3754 tcu::Vec4 results[4];
3755 bool anyResultSet = false;
3756 bool allResultsOk = true;
3758 compute.submitAndWait(m_queueFamilyIndex, m_queue);
3759 m_result.readResultContentsTo(&results);
3762 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3764 const tcu::Vec4 result = results[resultNdx];
3765 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
3766 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
3768 if (result != tcu::Vec4(-1.0f))
3769 anyResultSet = true;
3771 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
3773 allResultsOk = false;
3775 m_context.getTestContext().getLog()
3776 << tcu::TestLog::Message
3777 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
3778 << tcu::TestLog::EndMessage;
3782 // read back and verify
3784 return tcu::TestStatus::pass("Pass");
3785 else if (anyResultSet)
3786 return tcu::TestStatus::fail("Invalid result values");
3789 m_context.getTestContext().getLog()
3790 << tcu::TestLog::Message
3791 << "Result buffer was not written to."
3792 << tcu::TestLog::EndMessage;
3793 return tcu::TestStatus::fail("Result buffer was not written to");
3797 class ImageSampleInstanceImages : private ImageInstanceImages
3800 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3801 vk::VkDevice device,
3802 deUint32 queueFamilyIndex,
3804 vk::Allocator& allocator,
3805 vk::VkDescriptorType descriptorType,
3806 ShaderInputInterface shaderInterface,
3807 vk::VkImageViewType viewType,
3808 deUint32 baseMipLevel,
3809 deUint32 baseArraySlice,
3812 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
3813 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
3815 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3816 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3817 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
3818 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
3819 inline bool isImmutable (void) const { return m_isImmutable; }
3822 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
3823 static tcu::Sampler createRefSampler (bool isFirst);
3824 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
3826 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3827 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3828 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3829 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3831 const vk::VkDescriptorType m_descriptorType;
3832 const ShaderInputInterface m_shaderInterface;
3833 const bool m_isImmutable;
3835 const tcu::Sampler m_refSamplerA;
3836 const tcu::Sampler m_refSamplerB;
3837 const vk::Unique<vk::VkSampler> m_samplerA;
3838 const vk::Unique<vk::VkSampler> m_samplerB;
3841 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3842 vk::VkDevice device,
3843 deUint32 queueFamilyIndex,
3845 vk::Allocator& allocator,
3846 vk::VkDescriptorType descriptorType,
3847 ShaderInputInterface shaderInterface,
3848 vk::VkImageViewType viewType,
3849 deUint32 baseMipLevel,
3850 deUint32 baseArraySlice,
3852 : ImageInstanceImages (vki,
3859 getNumImages(descriptorType, shaderInterface),
3862 , m_descriptorType (descriptorType)
3863 , m_shaderInterface (shaderInterface)
3864 , m_isImmutable (immutable)
3865 , m_refSamplerA (createRefSampler(true))
3866 , m_refSamplerB (createRefSampler(false))
3867 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
3868 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
3869 ? vk::Move<vk::VkSampler>()
3870 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
3874 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
3876 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3878 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3879 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3881 // choose arbitrary values that are not ambiguous with NEAREST filtering
3885 case vk::VK_IMAGE_VIEW_TYPE_1D:
3886 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
3887 case vk::VK_IMAGE_VIEW_TYPE_2D:
3888 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
3889 case vk::VK_IMAGE_VIEW_TYPE_3D:
3891 const tcu::Vec3 coords[4] =
3895 (float)(12u % imageSize) + 0.25f),
3897 tcu::Vec3((float)(23u % imageSize) + 0.25f,
3898 (float)(73u % imageSize) + 0.5f,
3899 (float)(16u % imageSize) + 0.5f + (float)imageSize),
3901 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
3902 (float)(84u % imageSize) + 0.5f + (float)imageSize,
3903 (float)(117u % imageSize) + 0.75f),
3905 tcu::Vec3((float)imageSize + 0.5f,
3906 (float)(75u % imageSize) + 0.25f,
3907 (float)(83u % imageSize) + 0.25f + (float)imageSize),
3909 const deUint32 slices[4] =
3917 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3918 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3919 (float)slices[samplePosNdx],
3922 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
3923 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3924 coords[samplePosNdx].y() / (float)imageSize,
3925 (float)slices[samplePosNdx],
3927 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
3928 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3929 coords[samplePosNdx].y() / (float)imageSize,
3930 coords[samplePosNdx].z() / (float)imageSize,
3934 DE_FATAL("Impossible");
3939 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3940 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
3942 // \note these values are in [0, texSize]*3 space for convenience
3943 const tcu::Vec3 coords[4] =
3949 tcu::Vec3((float)(13u % imageSize) + 0.25f,
3951 (float)(16u % imageSize) + 0.5f),
3954 (float)(84u % imageSize) + 0.5f,
3955 (float)(10u % imageSize) + 0.75f),
3957 tcu::Vec3((float)imageSize,
3958 (float)(75u % imageSize) + 0.25f,
3959 (float)(83u % imageSize) + 0.75f),
3961 const deUint32 slices[4] =
3969 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
3970 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
3971 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
3973 // map to [-1, 1]*3 space
3974 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
3975 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
3976 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
3977 (float)slices[samplePosNdx]);
3981 DE_FATAL("Impossible");
3986 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
3988 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3990 // texture order is ABAB
3991 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
3992 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
3993 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3994 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
3996 // sampler order is ABAB
3997 const tcu::Sampler& samplerA = m_refSamplerA;
3998 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
3999 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
4001 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
4002 const float lod = 0.0f;
4003 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
4007 case vk::VK_IMAGE_VIEW_TYPE_1D:
4008 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
4009 case vk::VK_IMAGE_VIEW_TYPE_2D:
4010 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);
4011 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
4012 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4013 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);
4017 DE_FATAL("Impossible");
4023 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
4025 // If we are testing separate samplers, just one image is enough
4026 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4028 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4030 // combined: numImages == numSamplers
4031 return getInterfaceNumResources(shaderInterface);
4035 DE_FATAL("Impossible");
4040 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4045 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4049 // nearest, clamping
4050 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4054 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4056 const vk::VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, format);
4058 return vk::createSampler(vki, device, &createInfo);
4061 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4063 DE_ASSERT(levelStorage->empty());
4065 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4066 const deUint32 numLevels = (deUint32)source.getNumLevels();
4068 // cut pyramid from baseMipLevel
4069 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4071 // cut levels from baseArraySlice
4072 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4073 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4074 levelStorage->push_back(cutLevel);
4077 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4080 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4082 DE_ASSERT(levelStorage->empty());
4084 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4085 const deUint32 numLevels = (deUint32)source.getNumLevels();
4087 // cut pyramid from baseMipLevel
4088 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4090 // cut levels from baseArraySlice
4091 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4092 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4093 levelStorage->push_back(cutLevel);
4096 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4099 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4101 DE_ASSERT(levelStorage->empty());
4102 DE_ASSERT(baseArraySlice == 0);
4103 DE_UNREF(baseArraySlice);
4105 const deUint32 numLevels = (deUint32)source.getNumLevels();
4107 // cut pyramid from baseMipLevel
4108 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4109 levelStorage->push_back(source.getLevel(level));
4111 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
4114 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4116 DE_ASSERT(levelStorage->empty());
4118 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
4119 const deUint32 numLevels = (deUint32)source.getNumLevels();
4121 // cut pyramid from baseMipLevel
4122 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4124 // cut levels from baseArraySlice
4125 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4126 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
4127 levelStorage->push_back(cutLevel);
4130 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
4133 class ImageSampleRenderInstance : public SingleCmdRenderInstance
4136 ImageSampleRenderInstance (vkt::Context& context,
4137 bool isPrimaryCmdBuf,
4138 vk::VkDescriptorType descriptorType,
4139 vk::VkShaderStageFlags stageFlags,
4140 ShaderInputInterface shaderInterface,
4141 vk::VkImageViewType viewType,
4142 deUint32 baseMipLevel,
4143 deUint32 baseArraySlice,
4147 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
4148 vk::VkDevice device,
4149 vk::VkDescriptorType descriptorType,
4150 ShaderInputInterface shaderInterface,
4151 vk::VkShaderStageFlags stageFlags,
4152 const ImageSampleInstanceImages& images);
4154 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4155 vk::VkDevice device,
4156 vk::VkDescriptorSetLayout descriptorSetLayout);
4158 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4159 vk::VkDevice device,
4160 vk::VkDescriptorType descriptorType,
4161 ShaderInputInterface shaderInterface);
4163 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
4164 vk::VkDevice device,
4165 vk::VkDescriptorType descriptorType,
4166 ShaderInputInterface shaderInterface,
4167 vk::VkDescriptorSetLayout layout,
4168 vk::VkDescriptorPool pool,
4170 const ImageSampleInstanceImages& images);
4172 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4173 vk::VkDevice device,
4174 ShaderInputInterface shaderInterface,
4176 const ImageSampleInstanceImages& images,
4177 vk::VkDescriptorSet descriptorSet);
4179 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4180 vk::VkDevice device,
4181 ShaderInputInterface shaderInterface,
4183 const ImageSampleInstanceImages& images,
4184 vk::VkDescriptorSet descriptorSet);
4186 void logTestPlan (void) const;
4187 vk::VkPipelineLayout getPipelineLayout (void) const;
4188 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
4189 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4196 const vk::VkDescriptorType m_descriptorType;
4197 const vk::VkShaderStageFlags m_stageFlags;
4198 const ShaderInputInterface m_shaderInterface;
4199 const vk::VkImageViewType m_viewType;
4200 const deUint32 m_baseMipLevel;
4201 const deUint32 m_baseArraySlice;
4203 const ImageSampleInstanceImages m_images;
4204 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
4205 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4206 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4207 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
4210 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
4211 bool isPrimaryCmdBuf,
4212 vk::VkDescriptorType descriptorType,
4213 vk::VkShaderStageFlags stageFlags,
4214 ShaderInputInterface shaderInterface,
4215 vk::VkImageViewType viewType,
4216 deUint32 baseMipLevel,
4217 deUint32 baseArraySlice,
4219 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4220 , m_descriptorType (descriptorType)
4221 , m_stageFlags (stageFlags)
4222 , m_shaderInterface (shaderInterface)
4223 , m_viewType (viewType)
4224 , m_baseMipLevel (baseMipLevel)
4225 , m_baseArraySlice (baseArraySlice)
4226 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
4227 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images))
4228 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
4229 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
4230 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, isImmutable, m_images))
4234 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
4235 vk::VkDevice device,
4236 vk::VkDescriptorType descriptorType,
4237 ShaderInputInterface shaderInterface,
4238 vk::VkShaderStageFlags stageFlags,
4239 const ImageSampleInstanceImages& images)
4241 const vk::VkSampler samplers[2] =
4243 images.getSamplerA(),
4244 images.getSamplerB(),
4247 vk::DescriptorSetLayoutBuilder builder;
4249 // with samplers, separate texture at binding 0
4250 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4251 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4253 // (combined)samplers follow
4254 switch (shaderInterface)
4256 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4257 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4260 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4261 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4262 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4265 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4266 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
4270 DE_FATAL("Impossible");
4273 return builder.build(vki, device);
4276 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4277 vk::VkDevice device,
4278 vk::VkDescriptorSetLayout descriptorSetLayout)
4280 const vk::VkPipelineLayoutCreateInfo createInfo =
4282 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4284 (vk::VkPipelineLayoutCreateFlags)0,
4285 1, // descriptorSetCount
4286 &descriptorSetLayout, // pSetLayouts
4287 0u, // pushConstantRangeCount
4288 DE_NULL, // pPushConstantRanges
4290 return vk::createPipelineLayout(vki, device, &createInfo);
4293 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4294 vk::VkDevice device,
4295 vk::VkDescriptorType descriptorType,
4296 ShaderInputInterface shaderInterface)
4298 vk::DescriptorPoolBuilder builder;
4300 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4302 // separate samplers need image to sample
4303 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4305 // also need sample to use, indifferent of whether immutable or not
4306 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
4308 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4310 // combined image samplers
4311 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
4314 DE_FATAL("Impossible");
4316 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4319 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
4320 vk::VkDevice device,
4321 vk::VkDescriptorType descriptorType,
4322 ShaderInputInterface shaderInterface,
4323 vk::VkDescriptorSetLayout layout,
4324 vk::VkDescriptorPool pool,
4326 const ImageSampleInstanceImages& images)
4328 const vk::VkDescriptorSetAllocateInfo allocInfo =
4330 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4337 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4339 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4340 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4341 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4342 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4344 DE_FATAL("Impossible");
4346 return descriptorSet;
4349 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4350 vk::VkDevice device,
4351 ShaderInputInterface shaderInterface,
4353 const ImageSampleInstanceImages& images,
4354 vk::VkDescriptorSet descriptorSet)
4356 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4357 const vk::VkDescriptorImageInfo samplersInfos[2] =
4359 makeDescriptorImageInfo(images.getSamplerA()),
4360 makeDescriptorImageInfo(images.getSamplerB()),
4363 vk::DescriptorSetUpdateBuilder builder;
4365 // stand alone texture
4366 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4371 switch (shaderInterface)
4373 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4374 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4377 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4378 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4379 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4382 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4383 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4387 DE_FATAL("Impossible");
4391 builder.update(vki, device);
4394 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4395 vk::VkDevice device,
4396 ShaderInputInterface shaderInterface,
4398 const ImageSampleInstanceImages& images,
4399 vk::VkDescriptorSet descriptorSet)
4401 const vk::VkSampler samplers[2] =
4403 (isImmutable) ? (0) : (images.getSamplerA()),
4404 (isImmutable) ? (0) : (images.getSamplerB()),
4406 const vk::VkDescriptorImageInfo imageSamplers[2] =
4408 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4409 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4412 vk::DescriptorSetUpdateBuilder builder;
4414 // combined image samplers
4415 switch (shaderInterface)
4417 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4418 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4421 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4422 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4423 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4426 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4427 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4431 DE_FATAL("Impossible");
4434 builder.update(vki, device);
4437 void ImageSampleRenderInstance::logTestPlan (void) const
4439 std::ostringstream msg;
4441 msg << "Rendering 2x2 grid.\n";
4443 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4445 msg << "Single descriptor set. Descriptor set contains "
4446 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4447 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4448 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4449 (const char*)DE_NULL)
4450 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4452 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4454 msg << "Single descriptor set. Descriptor set contains "
4455 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4456 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4457 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4458 (const char*)DE_NULL)
4459 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4462 DE_FATAL("Impossible");
4464 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4467 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4468 if (m_baseArraySlice)
4469 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4471 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4472 msg << "Sampler mode is LINEAR, with WRAP\n";
4474 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4476 if (m_stageFlags == 0u)
4478 msg << "Descriptors are not accessed in any shader stage.\n";
4482 msg << "Color in each cell is fetched using the descriptor(s):\n";
4484 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4486 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4488 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4490 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4492 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4493 msg << " using sampler " << srcResourceNdx;
4494 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4495 msg << " from combined image sampler " << srcResourceNdx;
4497 DE_FATAL("Impossible");
4502 msg << "Descriptors are accessed in {"
4503 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4504 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4505 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4506 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4507 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4511 m_context.getTestContext().getLog()
4512 << tcu::TestLog::Message
4514 << tcu::TestLog::EndMessage;
4517 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
4519 return *m_pipelineLayout;
4522 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4524 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4525 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
4528 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4530 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4531 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4532 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4533 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
4534 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
4535 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
4536 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
4537 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
4538 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4540 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4542 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
4543 return tcu::TestStatus::fail("Image verification failed");
4545 return tcu::TestStatus::pass("Pass");
4548 class ImageSampleComputeInstance : public vkt::TestInstance
4551 ImageSampleComputeInstance (vkt::Context& context,
4552 vk::VkDescriptorType descriptorType,
4553 ShaderInputInterface shaderInterface,
4554 vk::VkImageViewType viewType,
4555 deUint32 baseMipLevel,
4556 deUint32 baseArraySlice,
4557 bool isImmutableSampler);
4560 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4561 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4562 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
4563 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4564 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4566 tcu::TestStatus iterate (void);
4567 void logTestPlan (void) const;
4568 tcu::TestStatus testResourceAccess (void);
4570 const vk::VkDescriptorType m_descriptorType;
4571 const ShaderInputInterface m_shaderInterface;
4572 const vk::VkImageViewType m_viewType;
4573 const deUint32 m_baseMipLevel;
4574 const deUint32 m_baseArraySlice;
4575 const bool m_isImmutableSampler;
4577 const vk::DeviceInterface& m_vki;
4578 const vk::VkDevice m_device;
4579 const vk::VkQueue m_queue;
4580 const deUint32 m_queueFamilyIndex;
4581 vk::Allocator& m_allocator;
4583 const ComputeInstanceResultBuffer m_result;
4584 const ImageSampleInstanceImages m_images;
4587 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
4588 vk::VkDescriptorType descriptorType,
4589 ShaderInputInterface shaderInterface,
4590 vk::VkImageViewType viewType,
4591 deUint32 baseMipLevel,
4592 deUint32 baseArraySlice,
4593 bool isImmutableSampler)
4594 : vkt::TestInstance (context)
4595 , m_descriptorType (descriptorType)
4596 , m_shaderInterface (shaderInterface)
4597 , m_viewType (viewType)
4598 , m_baseMipLevel (baseMipLevel)
4599 , m_baseArraySlice (baseArraySlice)
4600 , m_isImmutableSampler (isImmutableSampler)
4601 , m_vki (context.getDeviceInterface())
4602 , m_device (context.getDevice())
4603 , m_queue (context.getUniversalQueue())
4604 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4605 , m_allocator (context.getDefaultAllocator())
4606 , m_result (m_vki, m_device, m_allocator)
4607 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
4611 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
4613 const vk::VkSampler samplers[2] =
4615 m_images.getSamplerA(),
4616 m_images.getSamplerB(),
4619 vk::DescriptorSetLayoutBuilder builder;
4622 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4624 // with samplers, separate texture at binding 0
4625 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4626 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4628 // (combined)samplers follow
4629 switch (m_shaderInterface)
4631 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4632 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4635 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4636 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4637 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4640 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4641 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
4645 DE_FATAL("Impossible");
4648 return builder.build(m_vki, m_device);
4651 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
4653 vk::DescriptorPoolBuilder builder;
4655 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
4656 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
4658 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4659 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4661 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4664 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
4666 const vk::VkDescriptorSetAllocateInfo allocInfo =
4668 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4675 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4677 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4678 writeSamplerDescriptorSet(*descriptorSet);
4679 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4680 writeImageSamplerDescriptorSet(*descriptorSet);
4682 DE_FATAL("Impossible");
4684 return descriptorSet;
4687 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4689 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4690 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4691 const vk::VkDescriptorImageInfo samplersInfos[2] =
4693 makeDescriptorImageInfo(m_images.getSamplerA()),
4694 makeDescriptorImageInfo(m_images.getSamplerB()),
4697 vk::DescriptorSetUpdateBuilder builder;
4700 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4702 // stand alone texture
4703 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4706 if (!m_isImmutableSampler)
4708 switch (m_shaderInterface)
4710 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4711 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4714 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4715 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4716 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4719 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4720 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4724 DE_FATAL("Impossible");
4728 builder.update(m_vki, m_device);
4731 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4733 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4734 const vk::VkSampler samplers[2] =
4736 (m_isImmutableSampler) ? (0) : (m_images.getSamplerA()),
4737 (m_isImmutableSampler) ? (0) : (m_images.getSamplerB()),
4739 const vk::VkDescriptorImageInfo imageSamplers[2] =
4741 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4742 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4745 vk::DescriptorSetUpdateBuilder builder;
4748 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4750 // combined image samplers
4751 switch (m_shaderInterface)
4753 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4754 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4757 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
4758 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4759 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4762 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4763 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4767 DE_FATAL("Impossible");
4770 builder.update(m_vki, m_device);
4773 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
4776 return testResourceAccess();
4779 void ImageSampleComputeInstance::logTestPlan (void) const
4781 std::ostringstream msg;
4783 msg << "Accessing resource in a compute program.\n";
4785 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4787 msg << "Single descriptor set. Descriptor set contains "
4788 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4789 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4790 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4791 (const char*)DE_NULL)
4792 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4794 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4796 msg << "Single descriptor set. Descriptor set contains "
4797 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4798 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
4799 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4800 (const char*)DE_NULL)
4801 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4804 DE_FATAL("Impossible");
4806 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4809 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4810 if (m_baseArraySlice)
4811 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4813 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4814 msg << "Sampler mode is LINEAR, with WRAP\n";
4816 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4818 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4820 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4822 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4824 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4826 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4827 msg << " using sampler " << srcResourceNdx;
4828 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4829 msg << " from combined image sampler " << srcResourceNdx;
4831 DE_FATAL("Impossible");
4836 m_context.getTestContext().getLog()
4837 << tcu::TestLog::Message
4839 << tcu::TestLog::EndMessage;
4842 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
4844 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4845 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4846 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4847 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4849 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4850 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
4851 const deUint32* const dynamicOffsets = DE_NULL;
4852 const int numDynamicOffsets = 0;
4853 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
4854 const int numPreBarriers = 0;
4855 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
4856 const int numPostBarriers = 1;
4858 const ComputeCommand compute (m_vki,
4860 pipeline.getPipeline(),
4861 pipeline.getPipelineLayout(),
4862 tcu::UVec3(4, 1, 1),
4863 numDescriptorSets, descriptorSets,
4864 numDynamicOffsets, dynamicOffsets,
4865 numPreBarriers, preBarriers,
4866 numPostBarriers, postBarriers);
4868 tcu::Vec4 results[4];
4869 bool anyResultSet = false;
4870 bool allResultsOk = true;
4872 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4873 m_result.readResultContentsTo(&results);
4876 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4878 const tcu::Vec4 result = results[resultNdx];
4879 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
4881 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
4882 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
4884 if (result != tcu::Vec4(-1.0f))
4885 anyResultSet = true;
4887 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
4889 allResultsOk = false;
4891 m_context.getTestContext().getLog()
4892 << tcu::TestLog::Message
4893 << "Test sample " << resultNdx << ":\n"
4894 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
4895 << "\tError expected " << reference << ", got " << result
4896 << tcu::TestLog::EndMessage;
4900 // read back and verify
4902 return tcu::TestStatus::pass("Pass");
4903 else if (anyResultSet)
4904 return tcu::TestStatus::fail("Invalid result values");
4907 m_context.getTestContext().getLog()
4908 << tcu::TestLog::Message
4909 << "Result buffer was not written to."
4910 << tcu::TestLog::EndMessage;
4911 return tcu::TestStatus::fail("Result buffer was not written to");
4915 class ImageDescriptorCase : public QuadrantRendederCase
4920 FLAG_BASE_MIP = (1u << 1u),
4921 FLAG_BASE_SLICE = (1u << 2u),
4923 // enum continues where resource flags ends
4924 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
4926 ImageDescriptorCase (tcu::TestContext& testCtx,
4928 const char* description,
4929 bool isPrimaryCmdBuf,
4930 vk::VkDescriptorType descriptorType,
4931 vk::VkShaderStageFlags exitingStages,
4932 vk::VkShaderStageFlags activeStages,
4933 ShaderInputInterface shaderInterface,
4934 vk::VkImageViewType viewType,
4938 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
4939 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
4940 std::string genFetchCoordStr (int fetchPosNdx) const;
4941 std::string genSampleCoordStr (int samplePosNdx) const;
4942 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
4943 std::string genNoAccessSource (void) const;
4945 vkt::TestInstance* createInstance (vkt::Context& context) const;
4948 const bool m_isPrimaryCmdBuf;
4949 const vk::VkDescriptorType m_descriptorType;
4950 const ShaderInputInterface m_shaderInterface;
4951 const vk::VkImageViewType m_viewType;
4952 const deUint32 m_baseMipLevel;
4953 const deUint32 m_baseArraySlice;
4954 const bool m_isImmutableSampler;
4957 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
4959 const char* description,
4960 bool isPrimaryCmdBuf,
4961 vk::VkDescriptorType descriptorType,
4962 vk::VkShaderStageFlags exitingStages,
4963 vk::VkShaderStageFlags activeStages,
4964 ShaderInputInterface shaderInterface,
4965 vk::VkImageViewType viewType,
4967 : QuadrantRendederCase (testCtx, name, description,
4968 // \note 1D textures are not supported in ES
4969 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
4970 exitingStages, activeStages)
4971 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
4972 , m_descriptorType (descriptorType)
4973 , m_shaderInterface (shaderInterface)
4974 , m_viewType (viewType)
4975 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
4976 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
4977 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
4981 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
4985 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
4986 return "#extension GL_OES_texture_cube_map_array : require\n";
4991 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
4995 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
4996 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
4997 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
4998 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
4999 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
5001 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5002 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5003 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5004 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5006 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
5008 switch (m_shaderInterface)
5010 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5012 switch (m_descriptorType)
5014 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5015 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5016 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
5017 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5018 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
5019 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5020 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
5021 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5022 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
5024 DE_FATAL("invalid descriptor");
5029 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5030 switch (m_descriptorType)
5032 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5033 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5034 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
5035 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5036 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5037 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
5038 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
5039 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5040 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
5041 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
5042 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5043 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
5044 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
5046 DE_FATAL("invalid descriptor");
5050 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5051 switch (m_descriptorType)
5053 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5054 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5055 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler[2];\n";
5056 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5057 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
5058 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5059 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
5060 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5061 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
5063 DE_FATAL("invalid descriptor");
5068 DE_FATAL("Impossible");
5073 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
5075 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
5076 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
5078 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5080 return de::toString(fetchPos.x());
5082 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5084 std::ostringstream buf;
5085 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
5090 std::ostringstream buf;
5091 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
5096 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
5098 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
5099 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5101 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5103 std::ostringstream buf;
5104 buf << "float(" << fetchPos.x() << ")";
5107 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5109 std::ostringstream buf;
5110 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
5113 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5115 std::ostringstream buf;
5116 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
5121 std::ostringstream buf;
5122 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
5127 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
5131 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
5132 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5133 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
5134 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5135 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5136 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
5137 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5139 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5140 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
5141 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
5143 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5144 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
5145 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
5148 switch (m_descriptorType)
5150 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5151 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5153 const std::string coodStr[4] =
5155 genSampleCoordStr(0),
5156 genSampleCoordStr(1),
5157 genSampleCoordStr(2),
5158 genSampleCoordStr(3),
5160 std::ostringstream buf;
5162 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5164 buf << " if (quadrant_id == 0)\n"
5165 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
5166 << " else if (quadrant_id == 1)\n"
5167 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
5168 << " else if (quadrant_id == 2)\n"
5169 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
5171 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
5175 buf << " if (quadrant_id == 0)\n"
5176 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
5177 << " else if (quadrant_id == 1)\n"
5178 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
5179 << " else if (quadrant_id == 2)\n"
5180 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
5182 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
5188 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5190 const std::string coodStr[4] =
5192 genFetchCoordStr(0),
5193 genFetchCoordStr(1),
5194 genFetchCoordStr(2),
5195 genFetchCoordStr(3),
5197 std::ostringstream buf;
5199 buf << " if (quadrant_id == 0)\n"
5200 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
5201 << " else if (quadrant_id == 1)\n"
5202 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
5203 << " else if (quadrant_id == 2)\n"
5204 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
5206 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
5212 DE_FATAL("invalid descriptor");
5217 std::string ImageDescriptorCase::genNoAccessSource (void) const
5219 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
5220 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5222 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
5225 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
5227 switch (m_descriptorType)
5229 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5230 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5231 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5233 DE_ASSERT(m_isPrimaryCmdBuf);
5234 return new ImageSampleComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5237 return new ImageSampleRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5239 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5240 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5241 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5243 DE_ASSERT(m_isPrimaryCmdBuf);
5244 return new ImageFetchComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5247 return new ImageFetchRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5250 DE_FATAL("Impossible");
5255 class TexelBufferInstanceBuffers
5258 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5259 vk::VkDevice device,
5260 vk::Allocator& allocator,
5261 vk::VkDescriptorType descriptorType,
5262 int numTexelBuffers,
5263 bool hasViewOffset);
5266 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
5267 vk::VkDevice device,
5268 vk::Allocator& allocator,
5269 vk::VkDescriptorType descriptorType,
5270 de::MovePtr<vk::Allocation> *outAllocation);
5272 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
5273 vk::VkDevice device,
5274 const tcu::TextureFormat& textureFormat,
5276 vk::VkBuffer buffer);
5278 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
5280 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
5281 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
5284 static int getFetchPos (int fetchPosNdx);
5285 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
5287 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
5288 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
5289 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
5290 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
5291 inline const vk::VkBufferMemoryBarrier* getBufferInitBarriers (void) const { return m_bufferBarriers; }
5297 VIEW_OFFSET_VALUE = 256,
5298 VIEW_DATA_SIZE = 256, //!< size in bytes
5299 VIEW_WIDTH = 64, //!< size in pixels
5303 // some arbitrary points
5305 SAMPLE_POINT_1 = 51,
5306 SAMPLE_POINT_2 = 42,
5307 SAMPLE_POINT_3 = 25,
5310 const deUint32 m_numTexelBuffers;
5311 const tcu::TextureFormat m_imageFormat;
5312 const deUint32 m_viewOffset;
5314 de::ArrayBuffer<deUint8> m_sourceBufferA;
5315 de::ArrayBuffer<deUint8> m_sourceBufferB;
5316 const tcu::ConstPixelBufferAccess m_sourceViewA;
5317 const tcu::ConstPixelBufferAccess m_sourceViewB;
5319 de::MovePtr<vk::Allocation> m_bufferMemoryA;
5320 de::MovePtr<vk::Allocation> m_bufferMemoryB;
5321 const vk::Unique<vk::VkBuffer> m_bufferA;
5322 const vk::Unique<vk::VkBuffer> m_bufferB;
5323 const vk::Unique<vk::VkBufferView> m_bufferViewA;
5324 const vk::Unique<vk::VkBufferView> m_bufferViewB;
5325 vk::VkBufferMemoryBarrier m_bufferBarriers[2];
5328 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5329 vk::VkDevice device,
5330 vk::Allocator& allocator,
5331 vk::VkDescriptorType descriptorType,
5332 int numTexelBuffers,
5334 : m_numTexelBuffers (numTexelBuffers)
5335 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
5336 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
5337 , m_sourceBufferA (BUFFER_SIZE)
5338 , m_sourceBufferB ((numTexelBuffers == 1)
5340 : ((size_t)BUFFER_SIZE))
5341 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
5342 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
5343 , m_bufferMemoryA (DE_NULL)
5344 , m_bufferMemoryB (DE_NULL)
5345 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
5346 , m_bufferB ((numTexelBuffers == 1)
5347 ? vk::Move<vk::VkBuffer>()
5348 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
5349 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
5350 , m_bufferViewB ((numTexelBuffers == 1)
5351 ? vk::Move<vk::VkBufferView>()
5352 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
5354 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
5355 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
5356 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
5358 // specify and upload
5360 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
5361 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
5363 if (numTexelBuffers == 2)
5365 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
5366 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
5369 m_bufferBarriers[0] = createBarrier(descriptorType, *m_bufferA);
5370 m_bufferBarriers[1] = createBarrier(descriptorType, *m_bufferB);
5373 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
5374 vk::VkDevice device,
5375 vk::Allocator& allocator,
5376 vk::VkDescriptorType descriptorType,
5377 de::MovePtr<vk::Allocation> *outAllocation)
5379 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
5380 const vk::VkBufferCreateInfo createInfo =
5382 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
5385 (vk::VkDeviceSize)BUFFER_SIZE, // size
5387 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
5388 0u, // queueFamilyCount
5389 DE_NULL, // pQueueFamilyIndices
5391 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
5392 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
5394 *outAllocation = allocation;
5398 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
5399 vk::VkDevice device,
5400 const tcu::TextureFormat& textureFormat,
5402 vk::VkBuffer buffer)
5404 const vk::VkBufferViewCreateInfo createInfo =
5406 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
5408 (vk::VkBufferViewCreateFlags)0,
5410 vk::mapTextureFormat(textureFormat), // format
5411 (vk::VkDeviceSize)offset, // offset
5412 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
5414 return vk::createBufferView(vki, device, &createInfo);
5417 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
5419 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
5420 const vk::VkBufferMemoryBarrier barrier =
5422 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
5424 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
5425 inputBit, // inputMask
5426 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
5427 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
5430 (vk::VkDeviceSize)BUFFER_SIZE // size
5435 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
5437 DE_ASSERT(access.getHeight() == 1);
5438 DE_ASSERT(access.getDepth() == 1);
5440 const deInt32 width = access.getWidth();
5442 for (int x = 0; x < width; ++x)
5444 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
5445 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
5446 const int blue = 16 * (x % 16); //!< 16-long triangle wave
5448 DE_ASSERT(de::inRange(red, 0, 255));
5449 DE_ASSERT(de::inRange(green, 0, 255));
5450 DE_ASSERT(de::inRange(blue, 0, 255));
5452 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
5456 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
5458 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
5459 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
5462 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
5464 static const int fetchPositions[4] =
5471 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
5474 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
5476 // source order is ABAB
5477 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
5478 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
5479 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
5481 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
5484 class TexelBufferRenderInstance : public SingleCmdRenderInstance
5487 TexelBufferRenderInstance (vkt::Context& context,
5488 bool isPrimaryCmdBuf,
5489 vk::VkDescriptorType descriptorType,
5490 vk::VkShaderStageFlags stageFlags,
5491 ShaderInputInterface shaderInterface,
5492 bool nonzeroViewOffset);
5495 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
5496 vk::VkDevice device,
5497 vk::VkDescriptorType descriptorType,
5498 ShaderInputInterface shaderInterface,
5499 vk::VkShaderStageFlags stageFlags);
5501 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5502 vk::VkDevice device,
5503 vk::VkDescriptorSetLayout descriptorSetLayout);
5505 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5506 vk::VkDevice device,
5507 vk::VkDescriptorType descriptorType,
5508 ShaderInputInterface shaderInterface);
5510 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
5511 vk::VkDevice device,
5512 vk::VkDescriptorType descriptorType,
5513 ShaderInputInterface shaderInterface,
5514 vk::VkDescriptorSetLayout layout,
5515 vk::VkDescriptorPool pool,
5516 vk::VkBufferView viewA,
5517 vk::VkBufferView viewB);
5519 void logTestPlan (void) const;
5520 vk::VkPipelineLayout getPipelineLayout (void) const;
5521 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5522 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5529 const vk::VkDescriptorType m_descriptorType;
5530 const vk::VkShaderStageFlags m_stageFlags;
5531 const ShaderInputInterface m_shaderInterface;
5532 const bool m_nonzeroViewOffset;
5534 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5535 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5536 const TexelBufferInstanceBuffers m_texelBuffers;
5537 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5538 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5541 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
5542 bool isPrimaryCmdBuf,
5543 vk::VkDescriptorType descriptorType,
5544 vk::VkShaderStageFlags stageFlags,
5545 ShaderInputInterface shaderInterface,
5546 bool nonzeroViewOffset)
5547 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5548 , m_descriptorType (descriptorType)
5549 , m_stageFlags (stageFlags)
5550 , m_shaderInterface (shaderInterface)
5551 , m_nonzeroViewOffset (nonzeroViewOffset)
5552 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
5553 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5554 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5555 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5556 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_texelBuffers.getBufferViewA(), m_texelBuffers.getBufferViewB()))
5560 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5561 vk::VkDevice device,
5562 vk::VkDescriptorType descriptorType,
5563 ShaderInputInterface shaderInterface,
5564 vk::VkShaderStageFlags stageFlags)
5566 vk::DescriptorSetLayoutBuilder builder;
5568 switch (shaderInterface)
5570 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5571 builder.addSingleBinding(descriptorType, stageFlags);
5574 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5575 builder.addSingleBinding(descriptorType, stageFlags);
5576 builder.addSingleBinding(descriptorType, stageFlags);
5579 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5580 builder.addArrayBinding(descriptorType, 2u, stageFlags);
5584 DE_FATAL("Impossible");
5587 return builder.build(vki, device);
5590 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5591 vk::VkDevice device,
5592 vk::VkDescriptorSetLayout descriptorSetLayout)
5594 const vk::VkPipelineLayoutCreateInfo createInfo =
5596 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5598 (vk::VkPipelineLayoutCreateFlags)0,
5599 1, // descriptorSetCount
5600 &descriptorSetLayout, // pSetLayouts
5601 0u, // pushConstantRangeCount
5602 DE_NULL, // pPushConstantRanges
5604 return vk::createPipelineLayout(vki, device, &createInfo);
5607 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5608 vk::VkDevice device,
5609 vk::VkDescriptorType descriptorType,
5610 ShaderInputInterface shaderInterface)
5612 return vk::DescriptorPoolBuilder()
5613 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
5614 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5617 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5618 vk::VkDevice device,
5619 vk::VkDescriptorType descriptorType,
5620 ShaderInputInterface shaderInterface,
5621 vk::VkDescriptorSetLayout layout,
5622 vk::VkDescriptorPool pool,
5623 vk::VkBufferView viewA,
5624 vk::VkBufferView viewB)
5626 const vk::VkBufferView texelBufferInfos[2] =
5631 const vk::VkDescriptorSetAllocateInfo allocInfo =
5633 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5640 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5641 vk::DescriptorSetUpdateBuilder builder;
5643 switch (shaderInterface)
5645 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5646 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5649 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5650 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5651 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
5654 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5655 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
5659 DE_FATAL("Impossible");
5662 builder.update(vki, device);
5663 return descriptorSet;
5666 void TexelBufferRenderInstance::logTestPlan (void) const
5668 std::ostringstream msg;
5670 msg << "Rendering 2x2 grid.\n"
5671 << "Single descriptor set. Descriptor set contains "
5672 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5673 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5674 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5675 (const char*)DE_NULL)
5676 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5677 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5678 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5680 if (m_stageFlags == 0u)
5682 msg << "Descriptors are not accessed in any shader stage.\n";
5686 msg << "Color in each cell is fetched using the descriptor(s):\n";
5688 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5690 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5692 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5694 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5695 msg << " from texelBuffer " << srcResourceNdx;
5701 msg << "Descriptors are accessed in {"
5702 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5703 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5704 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5705 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5706 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5710 m_context.getTestContext().getLog()
5711 << tcu::TestLog::Message
5713 << tcu::TestLog::EndMessage;
5716 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
5718 return *m_pipelineLayout;
5721 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
5723 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
5724 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
5727 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5729 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5730 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5731 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5732 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
5733 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
5734 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
5735 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
5736 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5738 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5740 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
5741 return tcu::TestStatus::fail("Image verification failed");
5743 return tcu::TestStatus::pass("Pass");
5746 class TexelBufferComputeInstance : public vkt::TestInstance
5749 TexelBufferComputeInstance (vkt::Context& context,
5750 vk::VkDescriptorType descriptorType,
5751 ShaderInputInterface shaderInterface,
5752 bool nonzeroViewOffset);
5755 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5756 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5757 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
5759 tcu::TestStatus iterate (void);
5760 void logTestPlan (void) const;
5761 tcu::TestStatus testResourceAccess (void);
5763 const vk::VkDescriptorType m_descriptorType;
5764 const ShaderInputInterface m_shaderInterface;
5765 const bool m_nonzeroViewOffset;
5767 const vk::DeviceInterface& m_vki;
5768 const vk::VkDevice m_device;
5769 const vk::VkQueue m_queue;
5770 const deUint32 m_queueFamilyIndex;
5771 vk::Allocator& m_allocator;
5773 const ComputeInstanceResultBuffer m_result;
5774 const TexelBufferInstanceBuffers m_texelBuffers;
5777 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
5778 vk::VkDescriptorType descriptorType,
5779 ShaderInputInterface shaderInterface,
5780 bool nonzeroViewOffset)
5781 : vkt::TestInstance (context)
5782 , m_descriptorType (descriptorType)
5783 , m_shaderInterface (shaderInterface)
5784 , m_nonzeroViewOffset (nonzeroViewOffset)
5785 , m_vki (context.getDeviceInterface())
5786 , m_device (context.getDevice())
5787 , m_queue (context.getUniversalQueue())
5788 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5789 , m_allocator (context.getDefaultAllocator())
5790 , m_result (m_vki, m_device, m_allocator)
5791 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5795 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
5797 vk::DescriptorSetLayoutBuilder builder;
5799 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5801 switch (m_shaderInterface)
5803 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5804 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5807 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5808 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5809 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5812 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5813 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5817 DE_FATAL("Impossible");
5820 return builder.build(m_vki, m_device);
5823 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
5825 return vk::DescriptorPoolBuilder()
5826 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
5827 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
5828 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5831 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
5833 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5834 const vk::VkBufferView texelBufferInfos[2] =
5836 m_texelBuffers.getBufferViewA(),
5837 m_texelBuffers.getBufferViewB(),
5839 const vk::VkDescriptorSetAllocateInfo allocInfo =
5841 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5848 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
5849 vk::DescriptorSetUpdateBuilder builder;
5852 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5855 switch (m_shaderInterface)
5857 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5858 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5861 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
5862 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5863 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
5866 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5867 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
5871 DE_FATAL("Impossible");
5874 builder.update(m_vki, m_device);
5875 return descriptorSet;
5878 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
5881 return testResourceAccess();
5884 void TexelBufferComputeInstance::logTestPlan (void) const
5886 std::ostringstream msg;
5888 msg << "Fetching 4 values from image in compute shader.\n"
5889 << "Single descriptor set. Descriptor set contains "
5890 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5891 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? "two" :
5892 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5893 (const char*)DE_NULL)
5894 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5895 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5896 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5898 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5900 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5902 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5904 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5905 msg << " from texelBuffer " << srcResourceNdx;
5911 m_context.getTestContext().getLog()
5912 << tcu::TestLog::Message
5914 << tcu::TestLog::EndMessage;
5917 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
5919 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
5920 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5921 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
5922 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
5924 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
5925 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
5926 const deUint32* const dynamicOffsets = DE_NULL;
5927 const int numDynamicOffsets = 0;
5928 const vk::VkBufferMemoryBarrier* const preBarriers = m_texelBuffers.getBufferInitBarriers();
5929 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
5930 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
5931 const int numPostBarriers = 1;
5933 const ComputeCommand compute (m_vki,
5935 pipeline.getPipeline(),
5936 pipeline.getPipelineLayout(),
5937 tcu::UVec3(4, 1, 1),
5938 numDescriptorSets, descriptorSets,
5939 numDynamicOffsets, dynamicOffsets,
5940 numPreBarriers, preBarriers,
5941 numPostBarriers, postBarriers);
5943 tcu::Vec4 results[4];
5944 bool anyResultSet = false;
5945 bool allResultsOk = true;
5947 compute.submitAndWait(m_queueFamilyIndex, m_queue);
5948 m_result.readResultContentsTo(&results);
5951 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5953 const tcu::Vec4 result = results[resultNdx];
5954 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
5955 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
5957 if (result != tcu::Vec4(-1.0f))
5958 anyResultSet = true;
5960 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
5962 allResultsOk = false;
5964 m_context.getTestContext().getLog()
5965 << tcu::TestLog::Message
5966 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
5967 << tcu::TestLog::EndMessage;
5971 // read back and verify
5973 return tcu::TestStatus::pass("Pass");
5974 else if (anyResultSet)
5975 return tcu::TestStatus::fail("Invalid result values");
5978 m_context.getTestContext().getLog()
5979 << tcu::TestLog::Message
5980 << "Result buffer was not written to."
5981 << tcu::TestLog::EndMessage;
5982 return tcu::TestStatus::fail("Result buffer was not written to");
5986 class TexelBufferDescriptorCase : public QuadrantRendederCase
5991 FLAG_VIEW_OFFSET = (1u << 1u),
5993 // enum continues where resource flags ends
5994 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
5996 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
5998 const char* description,
5999 bool isPrimaryCmdBuf,
6000 vk::VkDescriptorType descriptorType,
6001 vk::VkShaderStageFlags exitingStages,
6002 vk::VkShaderStageFlags activeStages,
6003 ShaderInputInterface shaderInterface,
6007 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
6008 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
6009 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
6010 std::string genNoAccessSource (void) const;
6012 vkt::TestInstance* createInstance (vkt::Context& context) const;
6014 const bool m_isPrimaryCmdBuf;
6015 const vk::VkDescriptorType m_descriptorType;
6016 const ShaderInputInterface m_shaderInterface;
6017 const bool m_nonzeroViewOffset;
6020 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6022 const char* description,
6023 bool isPrimaryCmdBuf,
6024 vk::VkDescriptorType descriptorType,
6025 vk::VkShaderStageFlags exitingStages,
6026 vk::VkShaderStageFlags activeStages,
6027 ShaderInputInterface shaderInterface,
6029 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
6030 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6031 , m_descriptorType (descriptorType)
6032 , m_shaderInterface (shaderInterface)
6033 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
6037 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
6040 return "#extension GL_EXT_texture_buffer : require\n";
6043 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
6047 const bool isUniform = isUniformDescriptorType(m_descriptorType);
6048 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
6049 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
6051 switch (m_shaderInterface)
6053 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6054 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
6056 case SHADER_INPUT_MULTIPLE_DESCRIPTORS:
6057 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
6058 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
6060 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6061 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
6064 DE_FATAL("Impossible");
6069 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
6073 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6074 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("A")
6075 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6077 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6078 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DESCRIPTORS) ? ("B")
6079 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6081 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
6082 std::ostringstream buf;
6084 buf << " if (quadrant_id == 0)\n"
6085 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
6086 << " else if (quadrant_id == 1)\n"
6087 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
6088 << " else if (quadrant_id == 2)\n"
6089 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
6091 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
6096 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
6098 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6099 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6101 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6104 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
6106 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6108 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
6109 return new TexelBufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
6112 return new TexelBufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
6115 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
6116 bool isPrimaryCmdBuf,
6117 vk::VkDescriptorType descriptorType,
6118 vk::VkShaderStageFlags exitingStages,
6119 vk::VkShaderStageFlags activeStages,
6120 ShaderInputInterface dimension,
6121 deUint32 resourceFlags)
6125 vk::VkImageViewType viewType;
6127 const char* description;
6131 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
6132 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6133 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6135 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
6136 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6137 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6139 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
6140 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6141 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6143 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
6144 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6145 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6147 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
6148 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6149 // no 3d array textures
6151 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
6152 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6153 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6155 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
6156 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6157 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6160 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
6163 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
6165 group->addChild(new ImageDescriptorCase(group->getTestContext(),
6166 s_imageTypes[ndx].name,
6167 s_imageTypes[ndx].description,
6173 s_imageTypes[ndx].viewType,
6174 s_imageTypes[ndx].flags | resourceFlags));
6178 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
6179 bool isPrimaryCmdBuf,
6180 vk::VkDescriptorType descriptorType,
6181 vk::VkShaderStageFlags exitingStages,
6182 vk::VkShaderStageFlags activeStages,
6183 ShaderInputInterface dimension,
6184 deUint32 resourceFlags)
6186 DE_ASSERT(resourceFlags == 0);
6187 DE_UNREF(resourceFlags);
6192 const char* description;
6194 } s_texelBufferTypes[] =
6196 { "offset_zero", "View offset is zero", 0u },
6197 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
6200 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
6202 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
6203 s_texelBufferTypes[ndx].name,
6204 s_texelBufferTypes[ndx].description,
6210 s_texelBufferTypes[ndx].flags));
6214 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
6215 bool isPrimaryCmdBuf,
6216 vk::VkDescriptorType descriptorType,
6217 vk::VkShaderStageFlags exitingStages,
6218 vk::VkShaderStageFlags activeStages,
6219 ShaderInputInterface dimension,
6220 deUint32 resourceFlags)
6222 DE_ASSERT(resourceFlags == 0u);
6223 DE_UNREF(resourceFlags);
6228 const char* description;
6229 bool isForDynamicCases;
6233 { "offset_view_zero", "View offset is zero", false, 0u },
6234 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6236 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6237 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
6238 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6239 { "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 },
6242 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
6244 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
6246 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
6247 group->addChild(new BufferDescriptorCase(group->getTestContext(),
6248 s_bufferTypes[ndx].name,
6249 s_bufferTypes[ndx].description,
6255 s_bufferTypes[ndx].flags));
6261 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
6265 const bool isPrimary;
6267 const char* description;
6270 { true, "primary_cmd_buf", "Bind in primary command buffer" },
6271 { false, "secondary_cmd_buf", "Bind in secondary command buffer" },
6275 const vk::VkDescriptorType descriptorType;
6277 const char* description;
6279 } s_descriptorTypes[] =
6281 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
6282 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6283 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
6284 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6285 // \note No way to access SAMPLED_IMAGE without a sampler
6286 // { vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
6287 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
6288 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
6289 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
6290 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
6291 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
6292 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
6293 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
6298 const char* description;
6299 vk::VkShaderStageFlags existingStages; //!< stages that exists
6300 vk::VkShaderStageFlags activeStages; //!< stages that access resource
6301 bool supportsSecondaryCmdBufs;
6302 } s_shaderStages[] =
6306 "No accessing stages",
6307 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6314 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6315 vk::VK_SHADER_STAGE_VERTEX_BIT,
6320 "Tessellation control stage",
6321 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6322 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
6327 "Tessellation evaluation stage",
6328 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT | vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6329 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
6335 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6336 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
6342 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6343 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6349 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6350 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6355 "Vertex and fragment stages",
6356 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6357 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6363 ShaderInputInterface dimension;
6365 const char* description;
6366 } s_variableDimensions[] =
6368 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
6369 { SHADER_INPUT_MULTIPLE_DESCRIPTORS, "multiple_descriptors", "Multiple descriptors" },
6370 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
6373 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
6375 // .primary_cmd_buf...
6376 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
6378 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
6380 // .sampler, .combined_image_sampler, other resource types ...
6381 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
6383 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
6385 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
6387 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
6389 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
6391 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
6393 de::MovePtr<tcu::TestCaseGroup> dimensionGroup(new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
6394 void (*createTestsFunc)(tcu::TestCaseGroup* group,
6395 bool isPrimaryCmdBuf,
6396 vk::VkDescriptorType descriptorType,
6397 vk::VkShaderStageFlags existingStages,
6398 vk::VkShaderStageFlags activeStages,
6399 ShaderInputInterface dimension,
6400 deUint32 resourceFlags);
6402 switch (s_descriptorTypes[descriptorNdx].descriptorType)
6404 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6405 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6406 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6407 createTestsFunc = createShaderAccessImageTests;
6410 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
6411 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
6412 createTestsFunc = createShaderAccessTexelBufferTests;
6415 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
6416 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
6417 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
6418 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
6419 createTestsFunc = createShaderAccessBufferTests;
6423 createTestsFunc = DE_NULL;
6424 DE_FATAL("Impossible");
6427 if (createTestsFunc)
6429 createTestsFunc(dimensionGroup.get(),
6430 s_bindTypes[bindTypeNdx].isPrimary,
6431 s_descriptorTypes[descriptorNdx].descriptorType,
6432 s_shaderStages[stageNdx].existingStages,
6433 s_shaderStages[stageNdx].activeStages,
6434 s_variableDimensions[dimensionNdx].dimension,
6435 s_descriptorTypes[descriptorNdx].flags);
6438 DE_FATAL("Impossible");
6440 stageGroup->addChild(dimensionGroup.release());
6443 typeGroup->addChild(stageGroup.release());
6447 bindGroup->addChild(typeGroup.release());
6450 group->addChild(bindGroup.release());
6453 return group.release();