1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 Google Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Binding shader access tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktBindingShaderAccessTests.hpp"
26 #include "vktTestCase.hpp"
30 #include "vkRefUtil.hpp"
31 #include "vkPlatform.hpp"
32 #include "vkPrograms.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkBuilderUtil.hpp"
35 #include "vkQueryUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkTypeUtil.hpp"
39 #include "tcuVector.hpp"
40 #include "tcuVectorUtil.hpp"
41 #include "tcuTexture.hpp"
42 #include "tcuTextureUtil.hpp"
43 #include "tcuResultCollector.hpp"
44 #include "tcuTestLog.hpp"
45 #include "tcuRGBA.hpp"
46 #include "tcuSurface.hpp"
47 #include "tcuImageCompare.hpp"
49 #include "deUniquePtr.hpp"
50 #include "deSharedPtr.hpp"
51 #include "deStringUtil.hpp"
52 #include "deArrayUtil.hpp"
58 namespace BindingModel
65 RESOURCE_FLAG_IMMUTABLE_SAMPLER = (1u << 0u),
67 RESOURCE_FLAG_LAST = (1u << 1u)
70 static const char* const s_quadrantGenVertexPosSource = " highp int quadPhase = gl_VertexIndex % 6;\n"
71 " highp int quadXcoord = int(quadPhase == 1 || quadPhase == 4 || quadPhase == 5);\n"
72 " highp int quadYcoord = int(quadPhase == 2 || quadPhase == 3 || quadPhase == 5);\n"
73 " highp int quadOriginX = (gl_VertexIndex / 6) % 2;\n"
74 " highp int quadOriginY = (gl_VertexIndex / 6) / 2;\n"
75 " quadrant_id = gl_VertexIndex / 6;\n"
76 " result_position = vec4(float(quadOriginX + quadXcoord - 1), float(quadOriginY + quadYcoord - 1), 0.0, 1.0);\n";
78 bool isUniformDescriptorType (vk::VkDescriptorType type)
80 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
81 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
82 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
85 bool isDynamicDescriptorType (vk::VkDescriptorType type)
87 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || type == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
90 void verifyDriverSupport(const vk::VkPhysicalDeviceFeatures& deviceFeatures,
91 vk::VkDescriptorType descType,
92 vk::VkShaderStageFlags activeStages)
96 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
97 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
98 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
99 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
100 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
101 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
102 // These are supported in all stages
105 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
106 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
107 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
108 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
109 if (activeStages & (vk::VK_SHADER_STAGE_VERTEX_BIT |
110 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
111 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT |
112 vk::VK_SHADER_STAGE_GEOMETRY_BIT))
114 if (!deviceFeatures.vertexPipelineStoresAndAtomics)
115 TCU_THROW(NotSupportedError, (de::toString(descType) + " is not supported in the vertex pipeline").c_str());
118 if (activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT)
120 if (!deviceFeatures.fragmentStoresAndAtomics)
121 TCU_THROW(NotSupportedError, (de::toString(descType) + " is not supported in fragment shaders").c_str());
126 DE_FATAL("Impossible");
130 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type)
134 case vk::VK_IMAGE_VIEW_TYPE_1D:
135 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return vk::VK_IMAGE_TYPE_1D;
136 case vk::VK_IMAGE_VIEW_TYPE_2D:
137 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return vk::VK_IMAGE_TYPE_2D;
138 case vk::VK_IMAGE_VIEW_TYPE_3D: return vk::VK_IMAGE_TYPE_3D;
139 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
140 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return vk::VK_IMAGE_TYPE_2D;
143 DE_FATAL("Impossible");
144 return (vk::VkImageType)0;
148 vk::VkImageLayout getImageLayoutForDescriptorType (vk::VkDescriptorType descType)
150 if (descType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
151 return vk::VK_IMAGE_LAYOUT_GENERAL;
153 return vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
156 deUint32 getTextureLevelPyramidDataSize (const tcu::TextureLevelPyramid& srcImage)
158 deUint32 dataSize = 0;
159 for (int level = 0; level < srcImage.getNumLevels(); ++level)
161 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
164 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
166 dataSize += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
171 void writeTextureLevelPyramidData (void* dst, deUint32 dstLen, const tcu::TextureLevelPyramid& srcImage, vk::VkImageViewType viewType, std::vector<vk::VkBufferImageCopy>* copySlices)
173 // \note cube is copied face-by-face
174 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (srcImage.getLevel(0).getHeight()) :
175 (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
176 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
177 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
179 deUint32 levelOffset = 0;
181 DE_ASSERT(arraySize != 0);
183 for (int level = 0; level < srcImage.getNumLevels(); ++level)
185 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
186 const tcu::PixelBufferAccess dstAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), (deUint8*)dst + levelOffset);
187 const deUint32 dataSize = srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
188 const deUint32 sliceDataSize = dataSize / arraySize;
189 const deInt32 sliceHeight = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (srcAccess.getHeight());
190 const deInt32 sliceDepth = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (srcAccess.getDepth()) : (1);
191 const tcu::IVec3 sliceSize (srcAccess.getWidth(), sliceHeight, sliceDepth);
194 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
196 for (int sliceNdx = 0; sliceNdx < (int)arraySize; ++sliceNdx)
198 const vk::VkBufferImageCopy copySlice =
200 (vk::VkDeviceSize)levelOffset + sliceNdx * sliceDataSize, // bufferOffset
201 (deUint32)sliceSize.x(), // bufferRowLength
202 (deUint32)sliceSize.y(), // bufferImageHeight
204 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
205 (deUint32)level, // mipLevel
206 (deUint32)sliceNdx, // arrayLayer
208 }, // imageSubresource
215 (deUint32)sliceSize.x(),
216 (deUint32)sliceSize.y(),
217 (deUint32)sliceSize.z(),
220 copySlices->push_back(copySlice);
223 DE_ASSERT(arraySize * sliceDataSize == dataSize);
225 tcu::copy(dstAccess, srcAccess);
226 levelOffset += dataSize;
229 DE_ASSERT(dstLen == levelOffset);
233 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement)
235 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer);
236 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
238 VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
242 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkImage image, vk::MemoryRequirement requirement)
244 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vki, device, image);
245 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
247 VK_CHECK(vki.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
251 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkSampler sampler)
253 return vk::makeDescriptorImageInfo(sampler, (vk::VkImageView)0, (vk::VkImageLayout)0);
256 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkImageView imageView, vk::VkImageLayout layout)
258 return vk::makeDescriptorImageInfo((vk::VkSampler)0, imageView, layout);
261 void drawQuadrantReferenceResult (const tcu::PixelBufferAccess& dst, const tcu::Vec4& c1, const tcu::Vec4& c2, const tcu::Vec4& c3, const tcu::Vec4& c4)
263 tcu::clear(tcu::getSubregion(dst, 0, 0, dst.getWidth() / 2, dst.getHeight() / 2), c1);
264 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, 0, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() / 2), c2);
265 tcu::clear(tcu::getSubregion(dst, 0, dst.getHeight() / 2, dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c3);
266 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, dst.getHeight() / 2, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c4);
269 class SingleTargetRenderInstance : public vkt::TestInstance
272 SingleTargetRenderInstance (Context& context,
273 const tcu::UVec2& size);
276 static vk::Move<vk::VkImage> createColorAttachment (const vk::DeviceInterface& vki,
278 vk::Allocator& allocator,
279 const tcu::TextureFormat& format,
280 const tcu::UVec2& size,
281 de::MovePtr<vk::Allocation>* outAllocation);
283 static vk::Move<vk::VkImageView> createColorAttachmentView (const vk::DeviceInterface& vki,
285 const tcu::TextureFormat& format,
288 static vk::Move<vk::VkRenderPass> createRenderPass (const vk::DeviceInterface& vki,
290 const tcu::TextureFormat& format);
292 static vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vki,
294 vk::VkRenderPass renderpass,
295 vk::VkImageView colorAttachmentView,
296 const tcu::UVec2& size);
298 static vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vki,
300 deUint32 queueFamilyIndex);
302 virtual void logTestPlan (void) const = 0;
303 virtual void renderToTarget (void) = 0;
304 virtual tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const = 0;
306 void readRenderTarget (tcu::TextureLevel& dst);
307 tcu::TestStatus iterate (void);
310 const tcu::TextureFormat m_targetFormat;
311 const tcu::UVec2 m_targetSize;
313 const vk::DeviceInterface& m_vki;
314 const vk::VkDevice m_device;
315 const vk::VkQueue m_queue;
316 const deUint32 m_queueFamilyIndex;
317 vk::Allocator& m_allocator;
318 de::MovePtr<vk::Allocation> m_colorAttachmentMemory;
319 const vk::Unique<vk::VkImage> m_colorAttachmentImage;
320 const vk::Unique<vk::VkImageView> m_colorAttachmentView;
321 const vk::Unique<vk::VkRenderPass> m_renderPass;
322 const vk::Unique<vk::VkFramebuffer> m_framebuffer;
323 const vk::Unique<vk::VkCommandPool> m_cmdPool;
325 bool m_firstIteration;
328 SingleTargetRenderInstance::SingleTargetRenderInstance (Context& context,
329 const tcu::UVec2& size)
330 : vkt::TestInstance (context)
331 , m_targetFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
332 , m_targetSize (size)
333 , m_vki (context.getDeviceInterface())
334 , m_device (context.getDevice())
335 , m_queue (context.getUniversalQueue())
336 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
337 , m_allocator (context.getDefaultAllocator())
338 , m_colorAttachmentMemory (DE_NULL)
339 , m_colorAttachmentImage (createColorAttachment(m_vki, m_device, m_allocator, m_targetFormat, m_targetSize, &m_colorAttachmentMemory))
340 , m_colorAttachmentView (createColorAttachmentView(m_vki, m_device, m_targetFormat, *m_colorAttachmentImage))
341 , m_renderPass (createRenderPass(m_vki, m_device, m_targetFormat))
342 , m_framebuffer (createFramebuffer(m_vki, m_device, *m_renderPass, *m_colorAttachmentView, m_targetSize))
343 , m_cmdPool (createCommandPool(m_vki, m_device, context.getUniversalQueueFamilyIndex()))
344 , m_firstIteration (true)
348 vk::Move<vk::VkImage> SingleTargetRenderInstance::createColorAttachment (const vk::DeviceInterface& vki,
350 vk::Allocator& allocator,
351 const tcu::TextureFormat& format,
352 const tcu::UVec2& size,
353 de::MovePtr<vk::Allocation>* outAllocation)
355 const vk::VkImageCreateInfo imageInfo =
357 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
359 (vk::VkImageCreateFlags)0,
360 vk::VK_IMAGE_TYPE_2D, // imageType
361 vk::mapTextureFormat(format), // format
362 { size.x(), size.y(), 1u }, // extent
365 vk::VK_SAMPLE_COUNT_1_BIT, // samples
366 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
367 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
368 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
369 0u, // queueFamilyCount
370 DE_NULL, // pQueueFamilyIndices
371 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
374 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &imageInfo));
375 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any));
377 *outAllocation = allocation;
381 vk::Move<vk::VkImageView> SingleTargetRenderInstance::createColorAttachmentView (const vk::DeviceInterface& vki,
383 const tcu::TextureFormat& format,
386 const vk::VkImageViewCreateInfo createInfo =
388 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
390 (vk::VkImageViewCreateFlags)0,
392 vk::VK_IMAGE_VIEW_TYPE_2D, // viewType
393 vk::mapTextureFormat(format), // format
394 vk::makeComponentMappingRGBA(),
396 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
399 0u, // baseArrayLayer
404 return vk::createImageView(vki, device, &createInfo);
407 vk::Move<vk::VkRenderPass> SingleTargetRenderInstance::createRenderPass (const vk::DeviceInterface& vki,
409 const tcu::TextureFormat& format)
411 const vk::VkAttachmentDescription attachmentDescription =
413 (vk::VkAttachmentDescriptionFlags)0,
414 vk::mapTextureFormat(format), // format
415 vk::VK_SAMPLE_COUNT_1_BIT, // samples
416 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp
417 vk::VK_ATTACHMENT_STORE_OP_STORE, // storeOp
418 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
419 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
420 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
421 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout
423 const vk::VkAttachmentReference colorAttachment =
426 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
428 const vk::VkAttachmentReference depthStencilAttachment =
430 vk::VK_NO_ATTACHMENT, // attachment
431 vk::VK_IMAGE_LAYOUT_UNDEFINED // layout
433 const vk::VkSubpassDescription subpass =
435 (vk::VkSubpassDescriptionFlags)0,
436 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
437 0u, // inputAttachmentCount
438 DE_NULL, // pInputAttachments
439 1u, // colorAttachmentCount
440 &colorAttachment, // pColorAttachments
441 DE_NULL, // pResolveAttachments
442 &depthStencilAttachment, // pDepthStencilAttachment
443 0u, // preserveAttachmentCount
444 DE_NULL // pPreserveAttachments
446 const vk::VkRenderPassCreateInfo renderPassCreateInfo =
448 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
450 (vk::VkRenderPassCreateFlags)0,
451 1u, // attachmentCount
452 &attachmentDescription, // pAttachments
454 &subpass, // pSubpasses
455 0u, // dependencyCount
456 DE_NULL, // pDependencies
459 return vk::createRenderPass(vki, device, &renderPassCreateInfo);
462 vk::Move<vk::VkFramebuffer> SingleTargetRenderInstance::createFramebuffer (const vk::DeviceInterface& vki,
464 vk::VkRenderPass renderpass,
465 vk::VkImageView colorAttachmentView,
466 const tcu::UVec2& size)
468 const vk::VkFramebufferCreateInfo framebufferCreateInfo =
470 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
472 (vk::VkFramebufferCreateFlags)0,
473 renderpass, // renderPass
474 1u, // attachmentCount
475 &colorAttachmentView, // pAttachments
481 return vk::createFramebuffer(vki, device, &framebufferCreateInfo);
484 vk::Move<vk::VkCommandPool> SingleTargetRenderInstance::createCommandPool (const vk::DeviceInterface& vki,
486 deUint32 queueFamilyIndex)
488 const vk::VkCommandPoolCreateInfo createInfo =
490 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
492 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
493 queueFamilyIndex, // queueFamilyIndex
495 return vk::createCommandPool(vki, device, &createInfo);
498 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
500 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
501 const vk::VkBufferCreateInfo bufferCreateInfo =
503 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
506 pixelDataSize, // size
507 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
508 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
509 0u, // queueFamilyCount
510 DE_NULL, // pQueueFamilyIndices
512 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
513 const vk::VkImageSubresourceRange fullSubrange =
515 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
518 0u, // baseArraySlice
521 const vk::VkImageMemoryBarrier imageBarrier =
523 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
525 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
526 vk::VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
527 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
528 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
529 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
530 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
531 *m_colorAttachmentImage, // image
532 fullSubrange, // subresourceRange
534 const vk::VkBufferMemoryBarrier memoryBarrier =
536 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
538 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
539 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
540 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
541 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
544 (vk::VkDeviceSize)pixelDataSize // size
546 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
548 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
550 *m_cmdPool, // cmdPool
551 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
554 const vk::VkFenceCreateInfo fenceCreateInfo =
556 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
560 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
562 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
564 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
565 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
567 const vk::VkImageSubresourceLayers firstSlice =
569 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspect
574 const vk::VkBufferImageCopy copyRegion =
577 m_targetSize.x(), // bufferRowLength
578 m_targetSize.y(), // bufferImageHeight
579 firstSlice, // imageSubresource
580 { 0, 0, 0 }, // imageOffset
581 { m_targetSize.x(), m_targetSize.y(), 1u } // imageExtent
584 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
586 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
587 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
588 const deUint64 infiniteTimeout = ~(deUint64)0u;
590 // copy content to buffer
591 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
592 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
593 0, (const vk::VkMemoryBarrier*)DE_NULL,
594 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
596 m_vki.cmdCopyImageToBuffer(*cmd, *m_colorAttachmentImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
597 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
598 0, (const vk::VkMemoryBarrier*)DE_NULL,
600 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
601 VK_CHECK(m_vki.endCommandBuffer(*cmd));
603 // wait for transfer to complete
605 const vk::VkSubmitInfo submitInfo =
607 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
610 (const vk::VkSemaphore*)0,
611 (const vk::VkPipelineStageFlags*)DE_NULL,
615 (const vk::VkSemaphore*)0,
618 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *cmdCompleteFence));
620 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
622 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
625 invalidateMappedMemoryRange(m_vki, m_device, bufferMemory->getMemory(), bufferMemory->getOffset(), pixelDataSize);
626 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
629 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
631 tcu::TextureLevel resultImage;
634 if (m_firstIteration)
637 m_firstIteration = false;
642 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
643 const vk::VkImageSubresourceRange fullSubrange =
645 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
648 0u, // baseArraySlice
651 const vk::VkImageMemoryBarrier imageBarrier =
653 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
656 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
657 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
658 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
659 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
660 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
661 *m_colorAttachmentImage, // image
662 fullSubrange, // subresourceRange
664 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
666 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
668 *m_cmdPool, // cmdPool
669 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
672 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
674 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
676 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
677 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
680 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
682 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
683 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
684 0, (const vk::VkMemoryBarrier*)DE_NULL,
685 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
687 VK_CHECK(m_vki.endCommandBuffer(*cmd));
690 const vk::VkSubmitInfo submitInfo =
692 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
695 (const vk::VkSemaphore*)0,
696 (const vk::VkPipelineStageFlags*)DE_NULL,
700 (const vk::VkSemaphore*)0,
703 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, (vk::VkFence)0));
706 // and then render to
711 readRenderTarget(resultImage);
712 return verifyResultImage(resultImage.getAccess());
715 class RenderInstanceShaders
718 RenderInstanceShaders (const vk::DeviceInterface& vki,
720 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
721 const vk::BinaryCollection& programCollection);
723 inline bool hasTessellationStage (void) const { return *m_tessCtrlShaderModule != 0 || *m_tessEvalShaderModule != 0; }
724 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
725 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
728 void addStage (const vk::DeviceInterface& vki,
730 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
731 const vk::BinaryCollection& programCollection,
733 vk::VkShaderStageFlagBits stage,
734 vk::Move<vk::VkShaderModule>* outModule);
736 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const;
738 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
739 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
740 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
741 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
742 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
743 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
746 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
748 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
749 const vk::BinaryCollection& programCollection)
751 addStage(vki, device, deviceFeatures, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX_BIT, &m_vertexShaderModule);
752 addStage(vki, device, deviceFeatures, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessCtrlShaderModule);
753 addStage(vki, device, deviceFeatures, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvalShaderModule);
754 addStage(vki, device, deviceFeatures, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule);
755 addStage(vki, device, deviceFeatures, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule);
757 DE_ASSERT(!m_stageInfos.empty());
760 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
762 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
763 const vk::BinaryCollection& programCollection,
765 vk::VkShaderStageFlagBits stage,
766 vk::Move<vk::VkShaderModule>* outModule)
768 if (programCollection.contains(name))
770 if (vk::isShaderStageSupported(deviceFeatures, stage))
772 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
774 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *module));
779 // Wait for the GPU to idle so that throwing the exception
780 // below doesn't free in-use GPU resource.
781 vki.deviceWaitIdle(device);
782 TCU_THROW(NotSupportedError, (de::toString(stage) + " is not supported").c_str());
787 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const
789 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
791 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
793 (vk::VkPipelineShaderStageCreateFlags)0,
797 DE_NULL, // pSpecializationInfo
799 return stageCreateInfo;
802 class SingleCmdRenderInstance : public SingleTargetRenderInstance
805 SingleCmdRenderInstance (Context& context,
806 bool isPrimaryCmdBuf,
807 const tcu::UVec2& renderSize);
810 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
812 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
813 virtual void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const = 0;
815 void renderToTarget (void);
817 const bool m_isPrimaryCmdBuf;
820 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
821 bool isPrimaryCmdBuf,
822 const tcu::UVec2& renderSize)
823 : SingleTargetRenderInstance (context, renderSize)
824 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
828 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
830 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getDeviceFeatures(), m_context.getBinaryCollection());
831 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
832 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
834 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
836 (vk::VkPipelineVertexInputStateCreateFlags)0,
838 DE_NULL, // pVertexBindingDescriptions
839 0u, // attributeCount
840 DE_NULL, // pVertexAttributeDescriptions
842 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
844 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
846 (vk::VkPipelineInputAssemblyStateCreateFlags)0,
847 topology, // topology
848 vk::VK_FALSE, // primitiveRestartEnable
850 const vk::VkPipelineTessellationStateCreateInfo tessState =
852 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
854 (vk::VkPipelineTessellationStateCreateFlags)0,
855 3u, // patchControlPoints
857 const vk::VkViewport viewport =
861 float(m_targetSize.x()), // width
862 float(m_targetSize.y()), // height
866 const vk::VkRect2D renderArea =
869 { m_targetSize.x(), m_targetSize.y() }, // extent
871 const vk::VkPipelineViewportStateCreateInfo vpState =
873 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
875 (vk::VkPipelineViewportStateCreateFlags)0,
881 const vk::VkPipelineRasterizationStateCreateInfo rsState =
883 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
885 (vk::VkPipelineRasterizationStateCreateFlags)0,
886 vk::VK_TRUE, // depthClipEnable
887 vk::VK_FALSE, // rasterizerDiscardEnable
888 vk::VK_POLYGON_MODE_FILL, // fillMode
889 vk::VK_CULL_MODE_NONE, // cullMode
890 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
891 vk::VK_FALSE, // depthBiasEnable
893 0.0f, // depthBiasClamp
894 0.0f, // slopeScaledDepthBias
897 const vk::VkSampleMask sampleMask = 0x01u;
898 const vk::VkPipelineMultisampleStateCreateInfo msState =
900 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
902 (vk::VkPipelineMultisampleStateCreateFlags)0,
903 vk::VK_SAMPLE_COUNT_1_BIT, // rasterSamples
904 vk::VK_FALSE, // sampleShadingEnable
905 0.0f, // minSampleShading
906 &sampleMask, // sampleMask
907 vk::VK_FALSE, // alphaToCoverageEnable
908 vk::VK_FALSE, // alphaToOneEnable
910 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
912 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
914 (vk::VkPipelineDepthStencilStateCreateFlags)0,
915 vk::VK_FALSE, // depthTestEnable
916 vk::VK_FALSE, // depthWriteEnable
917 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
918 vk::VK_FALSE, // depthBoundsTestEnable
919 vk::VK_FALSE, // stencilTestEnable
920 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
921 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
922 -1.0f, // minDepthBounds
923 +1.0f, // maxDepthBounds
925 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
927 vk::VK_FALSE, // blendEnable
928 vk::VK_BLEND_FACTOR_ZERO, // srcBlendColor
929 vk::VK_BLEND_FACTOR_ZERO, // destBlendColor
930 vk::VK_BLEND_OP_ADD, // blendOpColor
931 vk::VK_BLEND_FACTOR_ZERO, // srcBlendAlpha
932 vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha
933 vk::VK_BLEND_OP_ADD, // blendOpAlpha
934 (vk::VK_COLOR_COMPONENT_R_BIT |
935 vk::VK_COLOR_COMPONENT_G_BIT |
936 vk::VK_COLOR_COMPONENT_B_BIT |
937 vk::VK_COLOR_COMPONENT_A_BIT), // channelWriteMask
939 const vk::VkPipelineColorBlendStateCreateInfo cbState =
941 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
943 (vk::VkPipelineColorBlendStateCreateFlags)0,
944 vk::VK_FALSE, // logicOpEnable
945 vk::VK_LOGIC_OP_CLEAR, // logicOp
946 1u, // attachmentCount
947 &cbAttachment, // pAttachments
948 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
950 const vk::VkGraphicsPipelineCreateInfo createInfo =
952 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
954 (vk::VkPipelineCreateFlags)0,
955 shaderStages.getNumStages(), // stageCount
956 shaderStages.getStages(), // pStages
957 &vertexInputState, // pVertexInputState
958 &iaState, // pInputAssemblyState
959 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
960 &vpState, // pViewportState
961 &rsState, // pRasterState
962 &msState, // pMultisampleState
963 &dsState, // pDepthStencilState
964 &cbState, // pColorBlendState
965 (const vk::VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
966 pipelineLayout, // layout
967 *m_renderPass, // renderPass
969 (vk::VkPipeline)0, // basePipelineHandle
970 0u, // basePipelineIndex
972 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
975 void SingleCmdRenderInstance::renderToTarget (void)
977 const vk::VkRect2D renderArea =
980 { m_targetSize.x(), m_targetSize.y() }, // extent
982 const vk::VkCommandBufferAllocateInfo mainCmdBufCreateInfo =
984 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
986 *m_cmdPool, // cmdPool
987 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
990 const vk::VkCommandBufferBeginInfo mainCmdBufBeginInfo =
992 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
994 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
995 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
997 const vk::VkCommandBufferAllocateInfo passCmdBufCreateInfo =
999 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1001 *m_cmdPool, // cmdPool
1002 vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level
1005 const vk::VkCommandBufferInheritanceInfo passCmdBufInheritInfo =
1007 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1009 (vk::VkRenderPass)*m_renderPass, // renderPass
1011 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
1012 vk::VK_FALSE, // occlusionQueryEnable
1013 (vk::VkQueryControlFlags)0,
1014 (vk::VkQueryPipelineStatisticFlags)0,
1016 const vk::VkCommandBufferBeginInfo passCmdBufBeginInfo =
1018 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1020 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
1021 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // flags
1022 &passCmdBufInheritInfo,
1024 const vk::VkFenceCreateInfo fenceCreateInfo =
1026 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1030 const vk::VkClearValue clearValue = vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
1031 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1033 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1035 *m_renderPass, // renderPass
1036 *m_framebuffer, // framebuffer
1037 renderArea, // renderArea
1038 1u, // clearValueCount
1039 &clearValue, // pClearValues
1042 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1043 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1044 const vk::Unique<vk::VkCommandBuffer> mainCmd (vk::allocateCommandBuffer(m_vki, m_device, &mainCmdBufCreateInfo));
1045 const vk::Unique<vk::VkCommandBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCommandBuffer>()) : (vk::allocateCommandBuffer(m_vki, m_device, &passCmdBufCreateInfo)));
1046 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1047 const deUint64 infiniteTimeout = ~(deUint64)0u;
1048 const vk::VkSubpassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_SUBPASS_CONTENTS_INLINE) : (vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1050 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1051 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1053 if (m_isPrimaryCmdBuf)
1055 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1056 writeDrawCmdBuffer(*mainCmd);
1060 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1061 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1062 writeDrawCmdBuffer(*passCmd);
1063 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1065 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1068 m_vki.cmdEndRenderPass(*mainCmd);
1069 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1071 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1073 const vk::VkSubmitInfo submitInfo =
1075 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1078 (const vk::VkSemaphore*)0,
1079 (const vk::VkPipelineStageFlags*)DE_NULL,
1083 (const vk::VkSemaphore*)0,
1085 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *fence));
1087 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1090 enum ShaderInputInterface
1092 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1093 SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with contiguous binding id's
1094 SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with discontiguous binding id's
1095 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1100 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1102 switch (shaderInterface)
1104 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1105 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS: return 2u;
1106 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS: return 2u;
1107 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1110 DE_FATAL("Impossible");
1115 class BufferRenderInstance : public SingleCmdRenderInstance
1118 BufferRenderInstance (Context& context,
1119 bool isPrimaryCmdBuf,
1120 vk::VkDescriptorType descriptorType,
1121 vk::VkShaderStageFlags stageFlags,
1122 ShaderInputInterface shaderInterface,
1125 bool dynamicOffsetNonZero);
1127 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1128 vk::VkDevice device,
1129 vk::Allocator& allocator,
1130 vk::VkDescriptorType descriptorType,
1132 deUint32 bufferSize,
1133 de::MovePtr<vk::Allocation>* outMemory);
1135 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1136 vk::VkDevice device,
1137 vk::VkDescriptorType descriptorType,
1138 ShaderInputInterface shaderInterface);
1140 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1141 vk::VkDevice device,
1142 vk::VkDescriptorType descriptorType,
1143 ShaderInputInterface shaderInterface,
1144 vk::VkShaderStageFlags stageFlags);
1146 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1147 vk::VkDevice device,
1148 vk::VkDescriptorSetLayout descriptorSetLayout,
1149 vk::VkDescriptorPool descriptorPool,
1150 vk::VkDescriptorType descriptorType,
1151 ShaderInputInterface shaderInterface,
1152 vk::VkBuffer sourceBufferA,
1153 const deUint32 viewOffsetA,
1154 vk::VkBuffer sourceBufferB,
1155 const deUint32 viewOffsetB);
1157 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1158 vk::VkDevice device,
1159 vk::VkDescriptorSetLayout descriptorSetLayout);
1161 void logTestPlan (void) const;
1162 vk::VkPipelineLayout getPipelineLayout (void) const;
1163 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1164 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1169 BUFFER_DATA_SIZE = 8 * sizeof(float),
1170 BUFFER_SIZE_A = 2048, //!< a lot more than required
1171 BUFFER_SIZE_B = 2560, //!< a lot more than required
1173 STATIC_OFFSET_VALUE_A = 256,
1174 DYNAMIC_OFFSET_VALUE_A = 512,
1175 STATIC_OFFSET_VALUE_B = 1024,
1176 DYNAMIC_OFFSET_VALUE_B = 768,
1179 const vk::VkDescriptorType m_descriptorType;
1180 const ShaderInputInterface m_shaderInterface;
1181 const bool m_setViewOffset;
1182 const bool m_setDynamicOffset;
1183 const bool m_dynamicOffsetNonZero;
1184 const vk::VkShaderStageFlags m_stageFlags;
1186 const deUint32 m_viewOffsetA;
1187 const deUint32 m_viewOffsetB;
1188 const deUint32 m_dynamicOffsetA;
1189 const deUint32 m_dynamicOffsetB;
1190 const deUint32 m_effectiveOffsetA;
1191 const deUint32 m_effectiveOffsetB;
1192 const deUint32 m_bufferSizeA;
1193 const deUint32 m_bufferSizeB;
1195 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1196 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1197 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1198 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1199 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1200 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1201 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1202 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1205 BufferRenderInstance::BufferRenderInstance (Context& context,
1206 bool isPrimaryCmdBuf,
1207 vk::VkDescriptorType descriptorType,
1208 vk::VkShaderStageFlags stageFlags,
1209 ShaderInputInterface shaderInterface,
1212 bool dynamicOffsetNonZero)
1213 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1214 , m_descriptorType (descriptorType)
1215 , m_shaderInterface (shaderInterface)
1216 , m_setViewOffset (viewOffset)
1217 , m_setDynamicOffset (dynamicOffset)
1218 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1219 , m_stageFlags (stageFlags)
1220 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1221 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1222 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1223 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1224 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetA + m_dynamicOffsetA) : (m_viewOffsetA))
1225 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetB + m_dynamicOffsetB) : (m_viewOffsetB))
1226 , m_bufferSizeA (BUFFER_SIZE_A)
1227 , m_bufferSizeB (BUFFER_SIZE_B)
1228 , m_bufferMemoryA (DE_NULL)
1229 , m_bufferMemoryB (DE_NULL)
1230 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1231 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1232 ? vk::Move<vk::VkBuffer>()
1233 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1234 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1235 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
1236 , m_descriptorSet (createDescriptorSet(m_vki, m_device, *m_descriptorSetLayout, *m_descriptorPool, m_descriptorType, m_shaderInterface, *m_sourceBufferA, m_viewOffsetA, *m_sourceBufferB, m_viewOffsetB))
1237 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1239 if (m_setDynamicOffset)
1240 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1241 if (m_dynamicOffsetNonZero)
1242 DE_ASSERT(m_setDynamicOffset);
1245 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1246 vk::VkDevice device,
1247 vk::Allocator& allocator,
1248 vk::VkDescriptorType descriptorType,
1250 deUint32 bufferSize,
1251 de::MovePtr<vk::Allocation>* outMemory)
1253 static const float s_colors[] =
1255 0.0f, 1.0f, 0.0f, 1.0f, // green
1256 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1258 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1259 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1260 DE_ASSERT(offset % sizeof(float) == 0);
1261 DE_ASSERT(bufferSize % sizeof(float) == 0);
1263 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1264 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1265 const float preGuardValue = 0.5f;
1266 const float postGuardValue = 0.75f;
1267 const vk::VkBufferCreateInfo bufferCreateInfo =
1269 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1273 usageFlags, // usage
1274 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1275 0u, // queueFamilyCount
1276 DE_NULL, // pQueueFamilyIndices
1278 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1279 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1280 void* const mapPtr = bufferMemory->getHostPtr();
1282 // guard with interesting values
1283 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1284 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1286 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1287 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1288 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1289 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
1291 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1293 *outMemory = bufferMemory;
1297 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1298 vk::VkDevice device,
1299 vk::VkDescriptorType descriptorType,
1300 ShaderInputInterface shaderInterface)
1302 return vk::DescriptorPoolBuilder()
1303 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1304 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1307 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1308 vk::VkDevice device,
1309 vk::VkDescriptorType descriptorType,
1310 ShaderInputInterface shaderInterface,
1311 vk::VkShaderStageFlags stageFlags)
1313 vk::DescriptorSetLayoutBuilder builder;
1315 switch (shaderInterface)
1317 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1318 builder.addSingleBinding(descriptorType, stageFlags);
1321 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1322 builder.addSingleBinding(descriptorType, stageFlags);
1323 builder.addSingleBinding(descriptorType, stageFlags);
1326 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1327 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1331 DE_FATAL("Impossible");
1334 return builder.build(vki, device);
1337 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1338 vk::VkDevice device,
1339 vk::VkDescriptorSetLayout descriptorSetLayout,
1340 vk::VkDescriptorPool descriptorPool,
1341 vk::VkDescriptorType descriptorType,
1342 ShaderInputInterface shaderInterface,
1343 vk::VkBuffer bufferA,
1345 vk::VkBuffer bufferB,
1348 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1350 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1351 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1353 const vk::VkDescriptorSetAllocateInfo allocInfo =
1355 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1359 &descriptorSetLayout
1362 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1363 vk::DescriptorSetUpdateBuilder builder;
1365 switch (shaderInterface)
1367 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1368 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1371 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1372 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1373 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1376 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1377 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1381 DE_FATAL("Impossible");
1384 builder.update(vki, device);
1385 return descriptorSet;
1388 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1389 vk::VkDevice device,
1390 vk::VkDescriptorSetLayout descriptorSetLayout)
1392 const vk::VkPipelineLayoutCreateInfo createInfo =
1394 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1396 (vk::VkPipelineLayoutCreateFlags)0,
1397 1, // descriptorSetCount
1398 &descriptorSetLayout, // pSetLayouts
1399 0u, // pushConstantRangeCount
1400 DE_NULL, // pPushConstantRanges
1403 return vk::createPipelineLayout(vki, device, &createInfo);
1406 void BufferRenderInstance::logTestPlan (void) const
1408 std::ostringstream msg;
1410 msg << "Rendering 2x2 yellow-green grid.\n"
1411 << "Single descriptor set. Descriptor set contains "
1412 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1413 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
1414 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1415 (const char*)DE_NULL)
1416 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1417 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1419 if (isDynamicDescriptorType(m_descriptorType))
1421 if (m_setDynamicOffset)
1423 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1424 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1428 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1432 if (m_stageFlags == 0u)
1434 msg << "Descriptors are not accessed in any shader stage.\n";
1438 msg << "Descriptors are accessed in {"
1439 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1440 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1441 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1442 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1443 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1447 m_context.getTestContext().getLog()
1448 << tcu::TestLog::Message
1450 << tcu::TestLog::EndMessage;
1453 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1455 return *m_pipelineLayout;
1458 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1460 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1462 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1463 const deUint32 dynamicOffsets[] =
1468 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1469 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1471 // make host writes device-visible
1472 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
1473 const vk::VkBufferMemoryBarrier memoryBarriers[] =
1476 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1478 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
1479 inputBit, // inputMask
1480 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1481 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1482 *m_sourceBufferA, // buffer
1484 (vk::VkDeviceSize)m_bufferSizeA, // size
1487 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1489 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
1490 inputBit, // inputMask
1491 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1492 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1493 *m_sourceBufferB, // buffer
1495 (vk::VkDeviceSize)m_bufferSizeB, // size
1498 const deUint32 numMemoryBarriers = getInterfaceNumResources(m_shaderInterface);
1500 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1501 m_vki.cmdPipelineBarrier(cmd, 0u, vk::VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT, (vk::VkDependencyFlags)0,
1502 0, (const vk::VkMemoryBarrier*)DE_NULL,
1503 numMemoryBarriers, memoryBarriers,
1504 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
1505 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1508 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1510 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1511 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1512 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1514 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1516 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1517 return tcu::TestStatus::fail("Image verification failed");
1519 return tcu::TestStatus::pass("Pass");
1522 class ComputeInstanceResultBuffer
1527 DATA_SIZE = sizeof(tcu::Vec4[4])
1530 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1531 vk::VkDevice device,
1532 vk::Allocator& allocator);
1534 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1536 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1537 inline const vk::VkBufferMemoryBarrier* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1540 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1541 vk::VkDevice device,
1542 vk::Allocator& allocator,
1543 de::MovePtr<vk::Allocation>* outAllocation);
1545 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1547 const vk::DeviceInterface& m_vki;
1548 const vk::VkDevice m_device;
1550 de::MovePtr<vk::Allocation> m_bufferMem;
1551 const vk::Unique<vk::VkBuffer> m_buffer;
1552 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1555 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1556 vk::VkDevice device,
1557 vk::Allocator& allocator)
1560 , m_bufferMem (DE_NULL)
1561 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1562 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1566 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1568 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1569 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1572 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1573 vk::VkDevice device,
1574 vk::Allocator& allocator,
1575 de::MovePtr<vk::Allocation>* outAllocation)
1577 const vk::VkBufferCreateInfo createInfo =
1579 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1582 (vk::VkDeviceSize)DATA_SIZE, // size
1583 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1584 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1585 0u, // queueFamilyCount
1586 DE_NULL, // pQueueFamilyIndices
1588 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1589 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1590 const float clearValue = -1.0f;
1591 void* mapPtr = allocation->getHostPtr();
1593 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1594 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1596 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1598 *outAllocation = allocation;
1602 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1604 const vk::VkBufferMemoryBarrier bufferBarrier =
1606 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1608 vk::VK_ACCESS_SHADER_WRITE_BIT, // outputMask
1609 vk::VK_ACCESS_HOST_READ_BIT, // inputMask
1610 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1611 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1613 (vk::VkDeviceSize)0u, // offset
1616 return bufferBarrier;
1619 class ComputePipeline
1622 ComputePipeline (const vk::DeviceInterface& vki,
1623 vk::VkDevice device,
1624 const vk::BinaryCollection& programCollection,
1625 deUint32 numDescriptorSets,
1626 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1628 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1629 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1632 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1633 vk::VkDevice device,
1634 deUint32 numDescriptorSets,
1635 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1637 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1638 vk::VkDevice device,
1639 const vk::BinaryCollection& programCollection,
1640 vk::VkPipelineLayout layout);
1642 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1643 const vk::Unique<vk::VkPipeline> m_pipeline;
1646 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1647 vk::VkDevice device,
1648 const vk::BinaryCollection& programCollection,
1649 deUint32 numDescriptorSets,
1650 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1651 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
1652 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
1656 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
1657 vk::VkDevice device,
1658 deUint32 numDescriptorSets,
1659 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1661 const vk::VkPipelineLayoutCreateInfo createInfo =
1663 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1665 (vk::VkPipelineLayoutCreateFlags)0,
1666 numDescriptorSets, // descriptorSetCount
1667 descriptorSetLayouts, // pSetLayouts
1668 0u, // pushConstantRangeCount
1669 DE_NULL, // pPushConstantRanges
1671 return vk::createPipelineLayout(vki, device, &createInfo);
1674 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
1675 vk::VkDevice device,
1676 const vk::BinaryCollection& programCollection,
1677 vk::VkPipelineLayout layout)
1679 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
1680 const vk::VkPipelineShaderStageCreateInfo cs =
1682 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1684 (vk::VkPipelineShaderStageCreateFlags)0,
1685 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
1686 *computeModule, // shader
1688 DE_NULL, // pSpecializationInfo
1690 const vk::VkComputePipelineCreateInfo createInfo =
1692 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1697 (vk::VkPipeline)0, // basePipelineHandle
1698 0u, // basePipelineIndex
1700 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
1703 class ComputeCommand
1706 ComputeCommand (const vk::DeviceInterface& vki,
1707 vk::VkDevice device,
1708 vk::VkPipeline pipeline,
1709 vk::VkPipelineLayout pipelineLayout,
1710 const tcu::UVec3& numWorkGroups,
1711 int numDescriptorSets,
1712 const vk::VkDescriptorSet* descriptorSets,
1713 int numDynamicOffsets,
1714 const deUint32* dynamicOffsets,
1716 const vk::VkBufferMemoryBarrier* preBarriers,
1717 int numPostBarriers,
1718 const vk::VkBufferMemoryBarrier* postBarriers);
1720 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const;
1723 const vk::DeviceInterface& m_vki;
1724 const vk::VkDevice m_device;
1725 const vk::VkPipeline m_pipeline;
1726 const vk::VkPipelineLayout m_pipelineLayout;
1727 const tcu::UVec3 m_numWorkGroups;
1728 const int m_numDescriptorSets;
1729 const vk::VkDescriptorSet* const m_descriptorSets;
1730 const int m_numDynamicOffsets;
1731 const deUint32* const m_dynamicOffsets;
1732 const int m_numPreBarriers;
1733 const vk::VkBufferMemoryBarrier* const m_preBarriers;
1734 const int m_numPostBarriers;
1735 const vk::VkBufferMemoryBarrier* const m_postBarriers;
1738 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
1739 vk::VkDevice device,
1740 vk::VkPipeline pipeline,
1741 vk::VkPipelineLayout pipelineLayout,
1742 const tcu::UVec3& numWorkGroups,
1743 int numDescriptorSets,
1744 const vk::VkDescriptorSet* descriptorSets,
1745 int numDynamicOffsets,
1746 const deUint32* dynamicOffsets,
1748 const vk::VkBufferMemoryBarrier* preBarriers,
1749 int numPostBarriers,
1750 const vk::VkBufferMemoryBarrier* postBarriers)
1753 , m_pipeline (pipeline)
1754 , m_pipelineLayout (pipelineLayout)
1755 , m_numWorkGroups (numWorkGroups)
1756 , m_numDescriptorSets (numDescriptorSets)
1757 , m_descriptorSets (descriptorSets)
1758 , m_numDynamicOffsets (numDynamicOffsets)
1759 , m_dynamicOffsets (dynamicOffsets)
1760 , m_numPreBarriers (numPreBarriers)
1761 , m_preBarriers (preBarriers)
1762 , m_numPostBarriers (numPostBarriers)
1763 , m_postBarriers (postBarriers)
1767 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const
1769 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
1771 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1773 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
1774 queueFamilyIndex, // queueFamilyIndex
1776 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
1778 const vk::VkFenceCreateInfo fenceCreateInfo =
1780 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1785 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
1787 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1789 *cmdPool, // cmdPool
1790 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1793 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
1795 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1797 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1798 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
1801 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1802 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
1803 const deUint64 infiniteTimeout = ~(deUint64)0u;
1805 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
1807 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
1808 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
1810 if (m_numPreBarriers)
1811 m_vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
1812 0, (const vk::VkMemoryBarrier*)DE_NULL,
1813 m_numPreBarriers, m_preBarriers,
1814 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
1816 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
1817 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
1818 0, (const vk::VkMemoryBarrier*)DE_NULL,
1819 m_numPostBarriers, m_postBarriers,
1820 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
1821 VK_CHECK(m_vki.endCommandBuffer(*cmd));
1825 const vk::VkSubmitInfo submitInfo =
1827 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1830 (const vk::VkSemaphore*)0,
1831 (const vk::VkPipelineStageFlags*)DE_NULL,
1835 (const vk::VkSemaphore*)0,
1837 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
1839 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1842 class BufferComputeInstance : public vkt::TestInstance
1845 BufferComputeInstance (Context& context,
1846 vk::VkDescriptorType descriptorType,
1847 ShaderInputInterface shaderInterface,
1850 bool dynamicOffsetNonZero);
1853 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
1854 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
1855 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
1856 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
1857 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;
1859 tcu::TestStatus iterate (void);
1860 void logTestPlan (void) const;
1861 tcu::TestStatus testResourceAccess (void);
1865 STATIC_OFFSET_VALUE_A = 256,
1866 DYNAMIC_OFFSET_VALUE_A = 512,
1867 STATIC_OFFSET_VALUE_B = 1024,
1868 DYNAMIC_OFFSET_VALUE_B = 768,
1871 const vk::VkDescriptorType m_descriptorType;
1872 const ShaderInputInterface m_shaderInterface;
1873 const bool m_setViewOffset;
1874 const bool m_setDynamicOffset;
1875 const bool m_dynamicOffsetNonZero;
1877 const vk::DeviceInterface& m_vki;
1878 const vk::VkDevice m_device;
1879 const vk::VkQueue m_queue;
1880 const deUint32 m_queueFamilyIndex;
1881 vk::Allocator& m_allocator;
1883 const ComputeInstanceResultBuffer m_result;
1886 BufferComputeInstance::BufferComputeInstance (Context& context,
1887 vk::VkDescriptorType descriptorType,
1888 ShaderInputInterface shaderInterface,
1891 bool dynamicOffsetNonZero)
1892 : vkt::TestInstance (context)
1893 , m_descriptorType (descriptorType)
1894 , m_shaderInterface (shaderInterface)
1895 , m_setViewOffset (viewOffset)
1896 , m_setDynamicOffset (dynamicOffset)
1897 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1898 , m_vki (context.getDeviceInterface())
1899 , m_device (context.getDevice())
1900 , m_queue (context.getUniversalQueue())
1901 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
1902 , m_allocator (context.getDefaultAllocator())
1903 , m_result (m_vki, m_device, m_allocator)
1905 if (m_dynamicOffsetNonZero)
1906 DE_ASSERT(m_setDynamicOffset);
1909 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
1911 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
1913 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1914 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1915 const vk::VkBufferCreateInfo createInfo =
1917 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1920 (vk::VkDeviceSize)bufferSize, // size
1921 usageFlags, // usage
1922 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1923 0u, // queueFamilyCount
1924 DE_NULL, // pQueueFamilyIndices
1926 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
1927 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
1928 void* mapPtr = allocation->getHostPtr();
1931 deMemset(mapPtr, 0x5A, (size_t)offset);
1932 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
1933 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
1934 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
1936 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
1938 *outAllocation = allocation;
1942 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
1944 vk::DescriptorSetLayoutBuilder builder;
1946 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1948 switch (m_shaderInterface)
1950 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1951 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1954 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1955 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1956 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1959 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1960 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1964 DE_FATAL("Impossible");
1967 return builder.build(m_vki, m_device);
1970 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
1972 return vk::DescriptorPoolBuilder()
1973 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1974 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
1975 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1978 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
1980 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
1981 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1983 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1984 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1986 const vk::VkDescriptorSetAllocateInfo allocInfo =
1988 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1995 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
1996 vk::DescriptorSetUpdateBuilder builder;
1999 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
2002 switch (m_shaderInterface)
2004 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2005 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2008 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2009 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2010 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
2013 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2014 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
2018 DE_FATAL("Impossible");
2021 builder.update(m_vki, m_device);
2022 return descriptorSet;
2025 tcu::TestStatus BufferComputeInstance::iterate (void)
2028 return testResourceAccess();
2031 void BufferComputeInstance::logTestPlan (void) const
2033 std::ostringstream msg;
2035 msg << "Accessing resource in a compute program.\n"
2036 << "Single descriptor set. Descriptor set contains "
2037 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2038 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
2039 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2040 (const char*)DE_NULL)
2041 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2042 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2043 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2045 if (isDynamicDescriptorType(m_descriptorType))
2047 if (m_setDynamicOffset)
2049 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2050 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2054 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2058 msg << "Destination buffer is pre-initialized to -1.\n";
2060 m_context.getTestContext().getLog()
2061 << tcu::TestLog::Message
2063 << tcu::TestLog::EndMessage;
2066 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2070 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2073 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2074 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2075 const deUint32 bindTimeOffsets[] =
2077 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2078 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2081 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2082 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2083 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2084 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2086 const deUint32 dataOffsetA = ((isDynamicCase) ? (bindTimeOffsets[0]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u));
2087 const deUint32 dataOffsetB = ((isDynamicCase) ? (bindTimeOffsets[1]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u));
2088 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2089 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2090 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2091 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2093 de::MovePtr<vk::Allocation> bufferMemA;
2094 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2096 de::MovePtr<vk::Allocation> bufferMemB;
2097 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2098 ? (vk::Move<vk::VkBuffer>())
2099 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2101 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2102 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2103 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer()));
2104 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2106 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2107 const vk::VkBufferMemoryBarrier bufferBarriers[] =
2110 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2112 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2113 inputBit, // inputMask
2114 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2115 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2117 (vk::VkDeviceSize)0u, // offset
2118 (vk::VkDeviceSize)bufferSizeA, // size
2121 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2123 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2124 inputBit, // inputMask
2125 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2126 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2128 (vk::VkDeviceSize)0u, // offset
2129 (vk::VkDeviceSize)bufferSizeB, // size
2133 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2135 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2136 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2137 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2138 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2139 const vk::VkBufferMemoryBarrier* const preBarriers = bufferBarriers;
2140 const int numPreBarriers = numSrcBuffers;
2141 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
2142 const int numPostBarriers = 1;
2144 const ComputeCommand compute (m_vki,
2146 pipeline.getPipeline(),
2147 pipeline.getPipelineLayout(),
2148 tcu::UVec3(4, 1, 1),
2149 numDescriptorSets, descriptorSets,
2150 numDynamicOffsets, dynamicOffsets,
2151 numPreBarriers, preBarriers,
2152 numPostBarriers, postBarriers);
2154 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2155 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? (colorB2) :
2156 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2158 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2159 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? (colorA1) :
2160 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2162 const tcu::Vec4 references[4] =
2169 tcu::Vec4 results[4];
2171 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2172 m_result.readResultContentsTo(&results);
2175 if (results[0] == references[0] &&
2176 results[1] == references[1] &&
2177 results[2] == references[2] &&
2178 results[3] == references[3])
2180 return tcu::TestStatus::pass("Pass");
2182 else if (results[0] == tcu::Vec4(-1.0f) &&
2183 results[1] == tcu::Vec4(-1.0f) &&
2184 results[2] == tcu::Vec4(-1.0f) &&
2185 results[3] == tcu::Vec4(-1.0f))
2187 m_context.getTestContext().getLog()
2188 << tcu::TestLog::Message
2189 << "Result buffer was not written to."
2190 << tcu::TestLog::EndMessage;
2191 return tcu::TestStatus::fail("Result buffer was not written to");
2195 m_context.getTestContext().getLog()
2196 << tcu::TestLog::Message
2197 << "Error expected ["
2198 << references[0] << ", "
2199 << references[1] << ", "
2200 << references[2] << ", "
2201 << references[3] << "], got ["
2202 << results[0] << ", "
2203 << results[1] << ", "
2204 << results[2] << ", "
2205 << results[3] << "]"
2206 << tcu::TestLog::EndMessage;
2207 return tcu::TestStatus::fail("Invalid result values");
2211 class QuadrantRendederCase : public vkt::TestCase
2214 QuadrantRendederCase (tcu::TestContext& testCtx,
2216 const char* description,
2217 glu::GLSLVersion glslVersion,
2218 vk::VkShaderStageFlags exitingStages,
2219 vk::VkShaderStageFlags activeStages);
2221 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
2222 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
2223 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
2224 virtual std::string genNoAccessSource (void) const = 0;
2226 std::string genVertexSource (void) const;
2227 std::string genTessCtrlSource (void) const;
2228 std::string genTessEvalSource (void) const;
2229 std::string genGeometrySource (void) const;
2230 std::string genFragmentSource (void) const;
2231 std::string genComputeSource (void) const;
2233 void initPrograms (vk::SourceCollections& programCollection) const;
2236 const glu::GLSLVersion m_glslVersion;
2237 const vk::VkShaderStageFlags m_exitingStages;
2238 const vk::VkShaderStageFlags m_activeStages;
2241 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2243 const char* description,
2244 glu::GLSLVersion glslVersion,
2245 vk::VkShaderStageFlags exitingStages,
2246 vk::VkShaderStageFlags activeStages)
2247 : vkt::TestCase (testCtx, name, description)
2248 , m_glslVersion (glslVersion)
2249 , m_exitingStages (exitingStages)
2250 , m_activeStages (activeStages)
2252 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2255 std::string QuadrantRendederCase::genVertexSource (void) const
2257 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
2258 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2259 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2261 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2262 std::ostringstream buf;
2264 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2266 // active vertex shader
2267 buf << versionDecl << "\n"
2268 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2269 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0)
2270 << "layout(location = 0) out highp vec4 " << nextStageName << "_color;\n"
2271 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2272 << "void main (void)\n"
2274 << " highp vec4 result_position;\n"
2275 << " highp int quadrant_id;\n"
2276 << s_quadrantGenVertexPosSource
2277 << " gl_Position = result_position;\n"
2278 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2280 << " highp vec4 result_color;\n"
2281 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
2282 << " " << nextStageName << "_color = result_color;\n"
2288 buf << versionDecl << "\n"
2289 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2290 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2291 << "void main (void)\n"
2293 << " highp vec4 result_position;\n"
2294 << " highp int quadrant_id;\n"
2295 << s_quadrantGenVertexPosSource
2296 << " gl_Position = result_position;\n"
2297 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2304 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2306 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2307 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2308 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2309 std::ostringstream buf;
2311 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2313 // contributing not implemented
2314 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2317 buf << versionDecl << "\n"
2319 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2320 << "layout(vertices=3) out;\n"
2321 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
2322 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2323 << "layout(location = 0) out highp vec4 tes_color[];\n"
2324 << "void main (void)\n"
2326 << " highp vec4 result_color;\n"
2327 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2328 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2330 << " tes_color[gl_InvocationID] = result_color;\n"
2332 << " // no dynamic input block indexing\n"
2333 << " highp vec4 position;\n"
2334 << " if (gl_InvocationID == 0)\n"
2335 << " position = gl_in[0].gl_Position;\n"
2336 << " else if (gl_InvocationID == 1)\n"
2337 << " position = gl_in[1].gl_Position;\n"
2339 << " position = gl_in[2].gl_Position;\n"
2340 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2341 << " gl_TessLevelInner[0] = 2.8;\n"
2342 << " gl_TessLevelInner[1] = 2.8;\n"
2343 << " gl_TessLevelOuter[0] = 2.8;\n"
2344 << " gl_TessLevelOuter[1] = 2.8;\n"
2345 << " gl_TessLevelOuter[2] = 2.8;\n"
2346 << " gl_TessLevelOuter[3] = 2.8;\n"
2349 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2351 // active te shader, tc passthru
2352 buf << versionDecl << "\n"
2354 << "layout(vertices=3) out;\n"
2355 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2356 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2357 << "void main (void)\n"
2359 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2361 << " // no dynamic input block indexing\n"
2362 << " highp vec4 position;\n"
2363 << " if (gl_InvocationID == 0)\n"
2364 << " position = gl_in[0].gl_Position;\n"
2365 << " else if (gl_InvocationID == 1)\n"
2366 << " position = gl_in[1].gl_Position;\n"
2368 << " position = gl_in[2].gl_Position;\n"
2369 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2370 << " gl_TessLevelInner[0] = 2.8;\n"
2371 << " gl_TessLevelInner[1] = 2.8;\n"
2372 << " gl_TessLevelOuter[0] = 2.8;\n"
2373 << " gl_TessLevelOuter[1] = 2.8;\n"
2374 << " gl_TessLevelOuter[2] = 2.8;\n"
2375 << " gl_TessLevelOuter[3] = 2.8;\n"
2380 // passthrough not implemented
2381 DE_FATAL("not implemented");
2387 std::string QuadrantRendederCase::genTessEvalSource (void) const
2389 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2390 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2391 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2392 std::ostringstream buf;
2394 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2396 // contributing not implemented
2397 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
2400 buf << versionDecl << "\n"
2402 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2403 << "layout(triangles) in;\n"
2404 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
2405 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2406 << "layout(location = 0) out highp vec4 frag_color;\n"
2407 << "void main (void)\n"
2409 << " highp vec4 result_color;\n"
2410 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2411 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2413 << " frag_color = result_color;\n"
2414 << " 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"
2417 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2419 // contributing not implemented
2420 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2422 // active tc shader, te is passthru
2423 buf << versionDecl << "\n"
2425 << "layout(triangles) in;\n"
2426 << "layout(location = 0) in highp vec4 tes_color[];\n"
2427 << "layout(location = 0) out highp vec4 frag_color;\n"
2428 << "void main (void)\n"
2430 << " frag_color = tes_color[0];\n"
2431 << " 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"
2436 // passthrough not implemented
2437 DE_FATAL("not implemented");
2443 std::string QuadrantRendederCase::genGeometrySource (void) const
2445 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2446 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2447 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
2448 std::ostringstream buf;
2450 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2452 // contributing not implemented
2453 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
2455 // active geometry shader
2456 buf << versionDecl << "\n"
2458 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2459 << "layout(triangles) in;\n"
2460 << "layout(triangle_strip, max_vertices=4) out;\n"
2461 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
2462 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
2463 << "layout(location = 0) out highp vec4 frag_color;\n"
2464 << "void main (void)\n"
2466 << " highp int quadrant_id;\n"
2467 << " highp vec4 result_color;\n"
2469 << " quadrant_id = geo_quadrant_id[0];\n"
2470 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2471 << " frag_color = result_color;\n"
2472 << " gl_Position = gl_in[0].gl_Position;\n"
2473 << " EmitVertex();\n"
2475 << " quadrant_id = geo_quadrant_id[1];\n"
2476 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2477 << " frag_color = result_color;\n"
2478 << " gl_Position = gl_in[1].gl_Position;\n"
2479 << " EmitVertex();\n"
2481 << " quadrant_id = geo_quadrant_id[2];\n"
2482 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2483 << " frag_color = result_color;\n"
2484 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
2485 << " EmitVertex();\n"
2487 << " quadrant_id = geo_quadrant_id[0];\n"
2488 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2489 << " frag_color = result_color;\n"
2490 << " gl_Position = gl_in[2].gl_Position;\n"
2491 << " EmitVertex();\n"
2496 // passthrough not implemented
2497 DE_FATAL("not implemented");
2503 std::string QuadrantRendederCase::genFragmentSource (void) const
2505 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2506 std::ostringstream buf;
2508 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2510 buf << versionDecl << "\n"
2511 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2512 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
2514 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2516 // there are other stages, this is just a contributor
2517 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
2520 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2521 << "layout(location = 0) out mediump vec4 o_color;\n"
2522 << "void main (void)\n"
2524 << " highp int quadrant_id = frag_quadrant_id;\n"
2525 << " highp vec4 result_color;\n"
2526 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
2528 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2531 buf << " if (frag_quadrant_id < 2)\n"
2532 << " o_color = result_color;\n"
2534 << " o_color = frag_color;\n";
2537 buf << " o_color = result_color;\n";
2541 else if (m_activeStages == 0u)
2543 // special case, no active stages
2544 buf << versionDecl << "\n"
2545 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2546 << "layout(location = 0) out mediump vec4 o_color;\n"
2547 << "void main (void)\n"
2549 << " highp int quadrant_id = frag_quadrant_id;\n"
2550 << " highp vec4 result_color;\n"
2551 << genNoAccessSource()
2552 << " o_color = result_color;\n"
2558 buf << versionDecl << "\n"
2559 << "layout(location = 0) in mediump vec4 frag_color;\n"
2560 "layout(location = 0) out mediump vec4 o_color;\n"
2561 "void main (void)\n"
2563 " o_color = frag_color;\n"
2570 std::string QuadrantRendederCase::genComputeSource (void) const
2572 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2573 std::ostringstream buf;
2575 buf << versionDecl << "\n"
2576 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2577 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2578 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
2579 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
2581 << " highp vec4 read_colors[4];\n"
2583 << "void main(void)\n"
2585 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
2586 << " highp vec4 result_color;\n"
2587 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2588 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
2594 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
2596 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2597 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
2599 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2600 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
2602 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2603 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
2605 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2606 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
2608 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2609 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
2611 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
2612 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
2615 class BufferDescriptorCase : public QuadrantRendederCase
2620 FLAG_VIEW_OFFSET = (1u << 1u),
2621 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
2622 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
2624 // enum continues where resource flags ends
2625 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
2627 BufferDescriptorCase (tcu::TestContext& testCtx,
2629 const char* description,
2630 bool isPrimaryCmdBuf,
2631 vk::VkDescriptorType descriptorType,
2632 vk::VkShaderStageFlags exitingStages,
2633 vk::VkShaderStageFlags activeStages,
2634 ShaderInputInterface shaderInterface,
2638 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
2639 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
2640 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
2641 std::string genNoAccessSource (void) const;
2643 vkt::TestInstance* createInstance (vkt::Context& context) const;
2645 const bool m_viewOffset;
2646 const bool m_dynamicOffsetSet;
2647 const bool m_dynamicOffsetNonZero;
2648 const bool m_isPrimaryCmdBuf;
2649 const vk::VkDescriptorType m_descriptorType;
2650 const ShaderInputInterface m_shaderInterface;
2653 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
2655 const char* description,
2656 bool isPrimaryCmdBuf,
2657 vk::VkDescriptorType descriptorType,
2658 vk::VkShaderStageFlags exitingStages,
2659 vk::VkShaderStageFlags activeStages,
2660 ShaderInputInterface shaderInterface,
2662 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
2663 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
2664 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
2665 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
2666 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
2667 , m_descriptorType (descriptorType)
2668 , m_shaderInterface (shaderInterface)
2672 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
2678 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
2682 const bool isUniform = isUniformDescriptorType(m_descriptorType);
2683 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
2684 std::ostringstream buf;
2686 switch (m_shaderInterface)
2688 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2689 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2691 << " highp vec4 colorA;\n"
2692 << " highp vec4 colorB;\n"
2693 << "} b_instance;\n";
2696 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2697 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
2699 << " highp vec4 colorA;\n"
2700 << " highp vec4 colorB;\n"
2701 << "} b_instanceA;\n"
2702 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
2704 << " highp vec4 colorA;\n"
2705 << " highp vec4 colorB;\n"
2706 << "} b_instanceB;\n";
2709 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2710 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2712 << " highp vec4 colorA;\n"
2713 << " highp vec4 colorB;\n"
2714 << "} b_instances[2];\n";
2718 DE_FATAL("Impossible");
2724 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
2728 std::ostringstream buf;
2730 switch (m_shaderInterface)
2732 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2733 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2734 << " result_color = b_instance.colorA;\n"
2736 << " result_color = b_instance.colorB;\n";
2739 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2740 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2741 << " result_color = b_instanceA.colorA;\n"
2743 << " result_color = b_instanceB.colorB;\n";
2746 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2747 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2748 << " result_color = b_instances[0].colorA;\n"
2750 << " result_color = b_instances[1].colorB;\n";
2754 DE_FATAL("Impossible");
2760 std::string BufferDescriptorCase::genNoAccessSource (void) const
2762 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
2763 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2765 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
2768 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
2770 verifyDriverSupport(context.getDeviceFeatures(), m_descriptorType, m_activeStages);
2772 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
2774 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
2775 return new BufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2778 return new BufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2781 class ImageInstanceImages
2784 ImageInstanceImages (const vk::DeviceInterface& vki,
2785 vk::VkDevice device,
2786 deUint32 queueFamilyIndex,
2788 vk::Allocator& allocator,
2789 vk::VkDescriptorType descriptorType,
2790 vk::VkImageViewType viewType,
2792 deUint32 baseMipLevel,
2793 deUint32 baseArraySlice);
2796 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
2797 vk::VkDevice device,
2798 vk::Allocator& allocator,
2799 vk::VkDescriptorType descriptorType,
2800 vk::VkImageViewType viewType,
2801 const tcu::TextureLevelPyramid& sourceImage,
2802 de::MovePtr<vk::Allocation>* outAllocation);
2804 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
2805 vk::VkDevice device,
2806 vk::VkImageViewType viewType,
2807 const tcu::TextureLevelPyramid& sourceImage,
2809 deUint32 baseMipLevel,
2810 deUint32 baseArraySlice);
2812 void populateSourceImage (tcu::TextureLevelPyramid* dst,
2813 bool isFirst) const;
2815 void uploadImage (const vk::DeviceInterface& vki,
2816 vk::VkDevice device,
2817 deUint32 queueFamilyIndex,
2819 vk::Allocator& allocator,
2821 vk::VkImageLayout layout,
2822 const tcu::TextureLevelPyramid& data);
2832 const vk::VkImageViewType m_viewType;
2833 const deUint32 m_baseMipLevel;
2834 const deUint32 m_baseArraySlice;
2836 const tcu::TextureFormat m_imageFormat;
2837 tcu::TextureLevelPyramid m_sourceImageA;
2838 tcu::TextureLevelPyramid m_sourceImageB;
2840 de::MovePtr<vk::Allocation> m_imageMemoryA;
2841 de::MovePtr<vk::Allocation> m_imageMemoryB;
2842 vk::Move<vk::VkImage> m_imageA;
2843 vk::Move<vk::VkImage> m_imageB;
2844 vk::Move<vk::VkImageView> m_imageViewA;
2845 vk::Move<vk::VkImageView> m_imageViewB;
2848 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
2849 vk::VkDevice device,
2850 deUint32 queueFamilyIndex,
2852 vk::Allocator& allocator,
2853 vk::VkDescriptorType descriptorType,
2854 vk::VkImageViewType viewType,
2856 deUint32 baseMipLevel,
2857 deUint32 baseArraySlice)
2858 : m_viewType (viewType)
2859 , m_baseMipLevel (baseMipLevel)
2860 , m_baseArraySlice (baseArraySlice)
2861 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
2862 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
2863 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
2864 , m_imageMemoryA (DE_NULL)
2865 , m_imageMemoryB (DE_NULL)
2866 , m_imageA (vk::Move<vk::VkImage>())
2867 , m_imageB (vk::Move<vk::VkImage>())
2868 , m_imageViewA (vk::Move<vk::VkImageView>())
2869 , m_imageViewB (vk::Move<vk::VkImageView>())
2871 const vk::VkImageLayout layout = getImageLayoutForDescriptorType(descriptorType);
2873 DE_ASSERT(numImages == 1 || numImages == 2);
2875 populateSourceImage(&m_sourceImageA, true);
2876 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
2877 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
2878 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, layout, m_sourceImageA);
2882 populateSourceImage(&m_sourceImageB, false);
2883 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
2884 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
2885 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, layout, m_sourceImageB);
2889 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
2890 vk::VkDevice device,
2891 vk::Allocator& allocator,
2892 vk::VkDescriptorType descriptorType,
2893 vk::VkImageViewType viewType,
2894 const tcu::TextureLevelPyramid& sourceImage,
2895 de::MovePtr<vk::Allocation>* outAllocation)
2897 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2898 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
2899 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
2900 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
2901 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
2902 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
2903 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2904 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
2906 const vk::VkExtent3D extent =
2909 (deUint32)baseLevel.getWidth(),
2912 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1u) : (deUint32)baseLevel.getHeight(),
2915 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deUint32)baseLevel.getDepth()) : (1u),
2917 const vk::VkImageCreateInfo createInfo =
2919 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2921 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
2922 viewTypeToImageType(viewType), // imageType
2923 vk::mapTextureFormat(baseLevel.getFormat()), // format
2925 (deUint32)sourceImage.getNumLevels(), // mipLevels
2926 arraySize, // arraySize
2927 vk::VK_SAMPLE_COUNT_1_BIT, // samples
2928 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
2929 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
2930 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2931 0u, // queueFamilyCount
2932 DE_NULL, // pQueueFamilyIndices
2933 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2935 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
2937 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
2941 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
2942 vk::VkDevice device,
2943 vk::VkImageViewType viewType,
2944 const tcu::TextureLevelPyramid& sourceImage,
2946 deUint32 baseMipLevel,
2947 deUint32 baseArraySlice)
2949 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2950 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
2951 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
2952 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
2953 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
2954 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
2955 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2956 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
2957 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
2960 DE_ASSERT(viewArraySize > 0);
2962 const vk::VkImageSubresourceRange resourceRange =
2964 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
2965 baseMipLevel, // baseMipLevel
2966 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
2967 viewTypeBaseSlice, // baseArraySlice
2968 viewArraySize, // arraySize
2970 const vk::VkImageViewCreateInfo createInfo =
2972 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
2974 (vk::VkImageViewCreateFlags)0,
2976 viewType, // viewType
2977 vk::mapTextureFormat(baseLevel.getFormat()), // format
2979 vk::VK_COMPONENT_SWIZZLE_R,
2980 vk::VK_COMPONENT_SWIZZLE_G,
2981 vk::VK_COMPONENT_SWIZZLE_B,
2982 vk::VK_COMPONENT_SWIZZLE_A
2984 resourceRange, // subresourceRange
2986 return vk::createImageView(vki, device, &createInfo);
2989 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
2991 const int numLevels = dst->getNumLevels();
2993 for (int level = 0; level < numLevels; ++level)
2995 const int width = IMAGE_SIZE >> level;
2996 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
2997 : (IMAGE_SIZE >> level);
2998 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
2999 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
3000 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
3001 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
3004 dst->allocLevel(level, width, height, depth);
3007 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
3009 for (int z = 0; z < depth; ++z)
3010 for (int y = 0; y < height; ++y)
3011 for (int x = 0; x < width; ++x)
3013 const int gradPos = x + y + z;
3014 const int gradMax = width + height + depth - 3;
3016 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
3017 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
3018 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
3020 DE_ASSERT(de::inRange(red, 0, 255));
3021 DE_ASSERT(de::inRange(green, 0, 255));
3022 DE_ASSERT(de::inRange(blue, 0, 255));
3024 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3030 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3031 vk::VkDevice device,
3032 deUint32 queueFamilyIndex,
3034 vk::Allocator& allocator,
3036 vk::VkImageLayout layout,
3037 const tcu::TextureLevelPyramid& data)
3039 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3040 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3041 ((deUint32)ARRAY_SIZE);
3042 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3043 const vk::VkBufferCreateInfo bufferCreateInfo =
3045 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3048 dataBufferSize, // size
3049 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
3050 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3051 0u, // queueFamilyCount
3052 DE_NULL, // pQueueFamilyIndices
3054 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3055 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3056 const vk::VkFenceCreateInfo fenceCreateInfo =
3058 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3062 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3064 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3066 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
3067 vk::VK_ACCESS_TRANSFER_READ_BIT, // inputMask
3068 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3069 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3070 *dataBuffer, // buffer
3072 dataBufferSize, // size
3074 const vk::VkImageSubresourceRange fullSubrange =
3076 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3078 (deUint32)data.getNumLevels(), // mipLevels
3079 0u, // baseArraySlice
3080 arraySize, // arraySize
3082 const vk::VkImageMemoryBarrier preImageBarrier =
3084 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3088 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3089 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout
3090 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3091 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3093 fullSubrange // subresourceRange
3095 const vk::VkImageMemoryBarrier postImageBarrier =
3097 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3099 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask
3100 vk::VK_ACCESS_SHADER_READ_BIT, // inputMask
3101 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout
3102 layout, // newLayout
3103 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3104 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3106 fullSubrange // subresourceRange
3108 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
3110 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
3112 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
3113 queueFamilyIndex, // queueFamilyIndex
3115 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3116 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
3118 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
3120 *cmdPool, // cmdPool
3121 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
3124 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
3126 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3128 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
3129 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
3132 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(vki, device, &cmdBufCreateInfo));
3133 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device, &fenceCreateInfo));
3134 const deUint64 infiniteTimeout = ~(deUint64)0u;
3135 std::vector<vk::VkBufferImageCopy> copySlices;
3137 // copy data to buffer
3138 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3139 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3141 // record command buffer
3142 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3143 vki.cmdPipelineBarrier(*cmd, 0u, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
3144 0, (const vk::VkMemoryBarrier*)DE_NULL,
3145 1, &preMemoryBarrier,
3146 1, &preImageBarrier);
3147 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3148 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
3149 0, (const vk::VkMemoryBarrier*)DE_NULL,
3150 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
3151 1, &postImageBarrier);
3152 VK_CHECK(vki.endCommandBuffer(*cmd));
3154 // submit and wait for command buffer to complete before killing it
3156 const vk::VkSubmitInfo submitInfo =
3158 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
3161 (const vk::VkSemaphore*)0,
3162 (const vk::VkPipelineStageFlags*)DE_NULL,
3166 (const vk::VkSemaphore*)0,
3168 VK_CHECK(vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
3170 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3173 class ImageFetchInstanceImages : private ImageInstanceImages
3176 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3177 vk::VkDevice device,
3178 deUint32 queueFamilyIndex,
3180 vk::Allocator& allocator,
3181 vk::VkDescriptorType descriptorType,
3182 ShaderInputInterface shaderInterface,
3183 vk::VkImageViewType viewType,
3184 deUint32 baseMipLevel,
3185 deUint32 baseArraySlice);
3187 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3188 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3190 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3191 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3196 // some arbitrary sample points for all four quadrants
3197 SAMPLE_POINT_0_X = 6,
3198 SAMPLE_POINT_0_Y = 13,
3199 SAMPLE_POINT_0_Z = 49,
3201 SAMPLE_POINT_1_X = 51,
3202 SAMPLE_POINT_1_Y = 40,
3203 SAMPLE_POINT_1_Z = 44,
3205 SAMPLE_POINT_2_X = 42,
3206 SAMPLE_POINT_2_Y = 26,
3207 SAMPLE_POINT_2_Z = 19,
3209 SAMPLE_POINT_3_X = 25,
3210 SAMPLE_POINT_3_Y = 25,
3211 SAMPLE_POINT_3_Z = 18,
3214 const ShaderInputInterface m_shaderInterface;
3217 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3218 vk::VkDevice device,
3219 deUint32 queueFamilyIndex,
3221 vk::Allocator& allocator,
3222 vk::VkDescriptorType descriptorType,
3223 ShaderInputInterface shaderInterface,
3224 vk::VkImageViewType viewType,
3225 deUint32 baseMipLevel,
3226 deUint32 baseArraySlice)
3227 : ImageInstanceImages (vki,
3234 getInterfaceNumResources(shaderInterface), // numImages
3237 , m_shaderInterface (shaderInterface)
3241 bool isImageViewTypeArray (vk::VkImageViewType type)
3243 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;
3246 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3248 const tcu::IVec3 fetchPositions[4] =
3250 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3251 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3252 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3253 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3255 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3256 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3257 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3261 case vk::VK_IMAGE_VIEW_TYPE_1D:
3262 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3263 case vk::VK_IMAGE_VIEW_TYPE_2D:
3264 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3265 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3266 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3267 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3269 DE_FATAL("Impossible");
3270 return tcu::IVec3();
3274 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3276 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3278 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3279 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3280 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3281 tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3283 // add base array layer into the appropriate coordinate, based on the view type
3284 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
3285 fetchPos.z() += 6 * m_baseArraySlice;
3286 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3287 fetchPos.y() += m_baseArraySlice;
3289 fetchPos.z() += m_baseArraySlice;
3291 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3294 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3297 ImageFetchRenderInstance (vkt::Context& context,
3298 bool isPrimaryCmdBuf,
3299 vk::VkDescriptorType descriptorType,
3300 vk::VkShaderStageFlags stageFlags,
3301 ShaderInputInterface shaderInterface,
3302 vk::VkImageViewType viewType,
3303 deUint32 baseMipLevel,
3304 deUint32 baseArraySlice);
3307 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3308 vk::VkDevice device,
3309 vk::VkDescriptorType descriptorType,
3310 ShaderInputInterface shaderInterface,
3311 vk::VkShaderStageFlags stageFlags);
3313 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3314 vk::VkDevice device,
3315 vk::VkDescriptorSetLayout descriptorSetLayout);
3317 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3318 vk::VkDevice device,
3319 vk::VkDescriptorType descriptorType,
3320 ShaderInputInterface shaderInterface);
3322 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3323 vk::VkDevice device,
3324 vk::VkDescriptorType descriptorType,
3325 ShaderInputInterface shaderInterface,
3326 vk::VkDescriptorSetLayout layout,
3327 vk::VkDescriptorPool pool,
3328 vk::VkImageView viewA,
3329 vk::VkImageView viewB);
3331 void logTestPlan (void) const;
3332 vk::VkPipelineLayout getPipelineLayout (void) const;
3333 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
3334 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3341 const vk::VkDescriptorType m_descriptorType;
3342 const vk::VkShaderStageFlags m_stageFlags;
3343 const ShaderInputInterface m_shaderInterface;
3344 const vk::VkImageViewType m_viewType;
3345 const deUint32 m_baseMipLevel;
3346 const deUint32 m_baseArraySlice;
3348 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3349 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3350 const ImageFetchInstanceImages m_images;
3351 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3352 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3355 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3356 bool isPrimaryCmdBuf,
3357 vk::VkDescriptorType descriptorType,
3358 vk::VkShaderStageFlags stageFlags,
3359 ShaderInputInterface shaderInterface,
3360 vk::VkImageViewType viewType,
3361 deUint32 baseMipLevel,
3362 deUint32 baseArraySlice)
3363 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3364 , m_descriptorType (descriptorType)
3365 , m_stageFlags (stageFlags)
3366 , m_shaderInterface (shaderInterface)
3367 , m_viewType (viewType)
3368 , m_baseMipLevel (baseMipLevel)
3369 , m_baseArraySlice (baseArraySlice)
3370 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
3371 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3372 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3373 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3374 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_images.getImageViewA(), m_images.getImageViewB()))
3378 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3379 vk::VkDevice device,
3380 vk::VkDescriptorType descriptorType,
3381 ShaderInputInterface shaderInterface,
3382 vk::VkShaderStageFlags stageFlags)
3384 vk::DescriptorSetLayoutBuilder builder;
3386 switch (shaderInterface)
3388 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3389 builder.addSingleBinding(descriptorType, stageFlags);
3392 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3393 builder.addSingleBinding(descriptorType, stageFlags);
3394 builder.addSingleBinding(descriptorType, stageFlags);
3397 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3398 builder.addArrayBinding(descriptorType, 2u, stageFlags);
3402 DE_FATAL("Impossible");
3405 return builder.build(vki, device);
3408 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
3409 vk::VkDevice device,
3410 vk::VkDescriptorSetLayout descriptorSetLayout)
3412 const vk::VkPipelineLayoutCreateInfo createInfo =
3414 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3416 (vk::VkPipelineLayoutCreateFlags)0,
3417 1, // descriptorSetCount
3418 &descriptorSetLayout, // pSetLayouts
3419 0u, // pushConstantRangeCount
3420 DE_NULL, // pPushConstantRanges
3422 return vk::createPipelineLayout(vki, device, &createInfo);
3425 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
3426 vk::VkDevice device,
3427 vk::VkDescriptorType descriptorType,
3428 ShaderInputInterface shaderInterface)
3430 return vk::DescriptorPoolBuilder()
3431 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
3432 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3435 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
3436 vk::VkDevice device,
3437 vk::VkDescriptorType descriptorType,
3438 ShaderInputInterface shaderInterface,
3439 vk::VkDescriptorSetLayout layout,
3440 vk::VkDescriptorPool pool,
3441 vk::VkImageView viewA,
3442 vk::VkImageView viewB)
3444 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
3445 const vk::VkDescriptorImageInfo imageInfos[2] =
3447 makeDescriptorImageInfo(viewA, imageLayout),
3448 makeDescriptorImageInfo(viewB, imageLayout),
3450 const vk::VkDescriptorSetAllocateInfo allocInfo =
3452 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3459 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
3460 vk::DescriptorSetUpdateBuilder builder;
3462 switch (shaderInterface)
3464 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3465 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3468 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3469 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3470 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
3473 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3474 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
3478 DE_FATAL("Impossible");
3481 builder.update(vki, device);
3482 return descriptorSet;
3485 void ImageFetchRenderInstance::logTestPlan (void) const
3487 std::ostringstream msg;
3489 msg << "Rendering 2x2 grid.\n"
3490 << "Single descriptor set. Descriptor set contains "
3491 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3492 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
3493 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3494 (const char*)DE_NULL)
3495 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3496 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3499 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3500 if (m_baseArraySlice)
3501 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3503 if (m_stageFlags == 0u)
3505 msg << "Descriptors are not accessed in any shader stage.\n";
3509 msg << "Color in each cell is fetched using the descriptor(s):\n";
3511 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3513 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3515 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3517 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3518 msg << " from descriptor " << srcResourceNdx;
3524 msg << "Descriptors are accessed in {"
3525 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
3526 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
3527 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
3528 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
3529 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
3533 m_context.getTestContext().getLog()
3534 << tcu::TestLog::Message
3536 << tcu::TestLog::EndMessage;
3539 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
3541 return *m_pipelineLayout;
3544 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
3546 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
3547 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
3550 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
3552 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3553 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
3554 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
3555 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
3556 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
3557 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
3558 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
3559 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
3561 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
3563 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
3564 return tcu::TestStatus::fail("Image verification failed");
3566 return tcu::TestStatus::pass("Pass");
3569 class ImageFetchComputeInstance : public vkt::TestInstance
3572 ImageFetchComputeInstance (vkt::Context& context,
3573 vk::VkDescriptorType descriptorType,
3574 ShaderInputInterface shaderInterface,
3575 vk::VkImageViewType viewType,
3576 deUint32 baseMipLevel,
3577 deUint32 baseArraySlice);
3580 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
3581 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
3582 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
3584 tcu::TestStatus iterate (void);
3585 void logTestPlan (void) const;
3586 tcu::TestStatus testResourceAccess (void);
3588 const vk::VkDescriptorType m_descriptorType;
3589 const ShaderInputInterface m_shaderInterface;
3590 const vk::VkImageViewType m_viewType;
3591 const deUint32 m_baseMipLevel;
3592 const deUint32 m_baseArraySlice;
3594 const vk::DeviceInterface& m_vki;
3595 const vk::VkDevice m_device;
3596 const vk::VkQueue m_queue;
3597 const deUint32 m_queueFamilyIndex;
3598 vk::Allocator& m_allocator;
3600 const ComputeInstanceResultBuffer m_result;
3601 const ImageFetchInstanceImages m_images;
3604 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
3605 vk::VkDescriptorType descriptorType,
3606 ShaderInputInterface shaderInterface,
3607 vk::VkImageViewType viewType,
3608 deUint32 baseMipLevel,
3609 deUint32 baseArraySlice)
3610 : vkt::TestInstance (context)
3611 , m_descriptorType (descriptorType)
3612 , m_shaderInterface (shaderInterface)
3613 , m_viewType (viewType)
3614 , m_baseMipLevel (baseMipLevel)
3615 , m_baseArraySlice (baseArraySlice)
3616 , m_vki (context.getDeviceInterface())
3617 , m_device (context.getDevice())
3618 , m_queue (context.getUniversalQueue())
3619 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
3620 , m_allocator (context.getDefaultAllocator())
3621 , m_result (m_vki, m_device, m_allocator)
3622 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3626 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
3628 vk::DescriptorSetLayoutBuilder builder;
3630 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3632 switch (m_shaderInterface)
3634 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3635 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3638 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3639 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3640 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3643 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3644 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3648 DE_FATAL("Impossible");
3651 return builder.build(m_vki, m_device);
3654 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
3656 return vk::DescriptorPoolBuilder()
3657 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3658 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
3659 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3662 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
3664 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
3665 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
3666 const vk::VkDescriptorImageInfo imageInfos[2] =
3668 makeDescriptorImageInfo(m_images.getImageViewA(), imageLayout),
3669 makeDescriptorImageInfo(m_images.getImageViewB(), imageLayout),
3671 const vk::VkDescriptorSetAllocateInfo allocInfo =
3673 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3680 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
3681 vk::DescriptorSetUpdateBuilder builder;
3684 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
3687 switch (m_shaderInterface)
3689 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3690 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3693 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3694 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3695 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
3698 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3699 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
3703 DE_FATAL("Impossible");
3706 builder.update(m_vki, m_device);
3707 return descriptorSet;
3710 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
3713 return testResourceAccess();
3716 void ImageFetchComputeInstance::logTestPlan (void) const
3718 std::ostringstream msg;
3720 msg << "Fetching 4 values from image in compute shader.\n"
3721 << "Single descriptor set. Descriptor set contains "
3722 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3723 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
3724 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3725 (const char*)DE_NULL)
3726 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3727 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3730 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3731 if (m_baseArraySlice)
3732 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3734 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3736 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3738 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3740 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3741 msg << " from descriptor " << srcResourceNdx;
3747 m_context.getTestContext().getLog()
3748 << tcu::TestLog::Message
3750 << tcu::TestLog::EndMessage;
3753 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
3755 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
3756 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
3757 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
3758 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
3760 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
3761 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
3762 const deUint32* const dynamicOffsets = DE_NULL;
3763 const int numDynamicOffsets = 0;
3764 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
3765 const int numPreBarriers = 0;
3766 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
3767 const int numPostBarriers = 1;
3769 const ComputeCommand compute (m_vki,
3771 pipeline.getPipeline(),
3772 pipeline.getPipelineLayout(),
3773 tcu::UVec3(4, 1, 1),
3774 numDescriptorSets, descriptorSets,
3775 numDynamicOffsets, dynamicOffsets,
3776 numPreBarriers, preBarriers,
3777 numPostBarriers, postBarriers);
3779 tcu::Vec4 results[4];
3780 bool anyResultSet = false;
3781 bool allResultsOk = true;
3783 compute.submitAndWait(m_queueFamilyIndex, m_queue);
3784 m_result.readResultContentsTo(&results);
3787 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3789 const tcu::Vec4 result = results[resultNdx];
3790 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
3791 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
3793 if (result != tcu::Vec4(-1.0f))
3794 anyResultSet = true;
3796 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
3798 allResultsOk = false;
3800 m_context.getTestContext().getLog()
3801 << tcu::TestLog::Message
3802 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
3803 << tcu::TestLog::EndMessage;
3807 // read back and verify
3809 return tcu::TestStatus::pass("Pass");
3810 else if (anyResultSet)
3811 return tcu::TestStatus::fail("Invalid result values");
3814 m_context.getTestContext().getLog()
3815 << tcu::TestLog::Message
3816 << "Result buffer was not written to."
3817 << tcu::TestLog::EndMessage;
3818 return tcu::TestStatus::fail("Result buffer was not written to");
3822 class ImageSampleInstanceImages : private ImageInstanceImages
3825 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3826 vk::VkDevice device,
3827 deUint32 queueFamilyIndex,
3829 vk::Allocator& allocator,
3830 vk::VkDescriptorType descriptorType,
3831 ShaderInputInterface shaderInterface,
3832 vk::VkImageViewType viewType,
3833 deUint32 baseMipLevel,
3834 deUint32 baseArraySlice,
3837 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
3838 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
3840 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3841 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3842 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
3843 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
3844 inline bool isImmutable (void) const { return m_isImmutable; }
3847 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
3848 static tcu::Sampler createRefSampler (bool isFirst);
3849 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
3851 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3852 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3853 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3854 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3856 const vk::VkDescriptorType m_descriptorType;
3857 const ShaderInputInterface m_shaderInterface;
3858 const bool m_isImmutable;
3860 const tcu::Sampler m_refSamplerA;
3861 const tcu::Sampler m_refSamplerB;
3862 const vk::Unique<vk::VkSampler> m_samplerA;
3863 const vk::Unique<vk::VkSampler> m_samplerB;
3866 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3867 vk::VkDevice device,
3868 deUint32 queueFamilyIndex,
3870 vk::Allocator& allocator,
3871 vk::VkDescriptorType descriptorType,
3872 ShaderInputInterface shaderInterface,
3873 vk::VkImageViewType viewType,
3874 deUint32 baseMipLevel,
3875 deUint32 baseArraySlice,
3877 : ImageInstanceImages (vki,
3884 getNumImages(descriptorType, shaderInterface),
3887 , m_descriptorType (descriptorType)
3888 , m_shaderInterface (shaderInterface)
3889 , m_isImmutable (immutable)
3890 , m_refSamplerA (createRefSampler(true))
3891 , m_refSamplerB (createRefSampler(false))
3892 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
3893 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
3894 ? vk::Move<vk::VkSampler>()
3895 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
3899 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
3901 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3903 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3904 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3906 // choose arbitrary values that are not ambiguous with NEAREST filtering
3910 case vk::VK_IMAGE_VIEW_TYPE_1D:
3911 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
3912 case vk::VK_IMAGE_VIEW_TYPE_2D:
3913 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
3914 case vk::VK_IMAGE_VIEW_TYPE_3D:
3916 const tcu::Vec3 coords[4] =
3920 (float)(12u % imageSize) + 0.25f),
3922 tcu::Vec3((float)(23u % imageSize) + 0.25f,
3923 (float)(73u % imageSize) + 0.5f,
3924 (float)(16u % imageSize) + 0.5f + (float)imageSize),
3926 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
3927 (float)(84u % imageSize) + 0.5f + (float)imageSize,
3928 (float)(117u % imageSize) + 0.75f),
3930 tcu::Vec3((float)imageSize + 0.5f,
3931 (float)(75u % imageSize) + 0.25f,
3932 (float)(83u % imageSize) + 0.25f + (float)imageSize),
3934 const deUint32 slices[4] =
3942 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3943 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3944 (float)slices[samplePosNdx],
3947 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
3948 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3949 coords[samplePosNdx].y() / (float)imageSize,
3950 (float)slices[samplePosNdx],
3952 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
3953 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3954 coords[samplePosNdx].y() / (float)imageSize,
3955 coords[samplePosNdx].z() / (float)imageSize,
3959 DE_FATAL("Impossible");
3964 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3965 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
3967 // \note these values are in [0, texSize]*3 space for convenience
3968 const tcu::Vec3 coords[4] =
3974 tcu::Vec3((float)(13u % imageSize) + 0.25f,
3976 (float)(16u % imageSize) + 0.5f),
3979 (float)(84u % imageSize) + 0.5f,
3980 (float)(10u % imageSize) + 0.75f),
3982 tcu::Vec3((float)imageSize,
3983 (float)(75u % imageSize) + 0.25f,
3984 (float)(83u % imageSize) + 0.75f),
3986 const deUint32 slices[4] =
3994 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
3995 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
3996 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
3998 // map to [-1, 1]*3 space
3999 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
4000 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
4001 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
4002 (float)slices[samplePosNdx]);
4006 DE_FATAL("Impossible");
4011 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
4013 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
4015 // texture order is ABAB
4016 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
4017 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
4018 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
4019 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
4021 // sampler order is ABAB
4022 const tcu::Sampler& samplerA = m_refSamplerA;
4023 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
4024 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
4026 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
4027 const float lod = 0.0f;
4028 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
4032 case vk::VK_IMAGE_VIEW_TYPE_1D:
4033 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
4034 case vk::VK_IMAGE_VIEW_TYPE_2D:
4035 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);
4036 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
4037 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4038 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);
4042 DE_FATAL("Impossible");
4048 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
4050 // If we are testing separate samplers, just one image is enough
4051 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4053 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4055 // combined: numImages == numSamplers
4056 return getInterfaceNumResources(shaderInterface);
4060 DE_FATAL("Impossible");
4065 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4070 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4074 // nearest, clamping
4075 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4079 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4081 const vk::VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, format);
4083 return vk::createSampler(vki, device, &createInfo);
4086 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4088 DE_ASSERT(levelStorage->empty());
4090 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4091 const deUint32 numLevels = (deUint32)source.getNumLevels();
4093 // cut pyramid from baseMipLevel
4094 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4096 // cut levels from baseArraySlice
4097 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4098 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4099 levelStorage->push_back(cutLevel);
4102 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4105 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4107 DE_ASSERT(levelStorage->empty());
4109 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4110 const deUint32 numLevels = (deUint32)source.getNumLevels();
4112 // cut pyramid from baseMipLevel
4113 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4115 // cut levels from baseArraySlice
4116 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4117 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4118 levelStorage->push_back(cutLevel);
4121 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4124 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4126 DE_ASSERT(levelStorage->empty());
4127 DE_ASSERT(baseArraySlice == 0);
4128 DE_UNREF(baseArraySlice);
4130 const deUint32 numLevels = (deUint32)source.getNumLevels();
4132 // cut pyramid from baseMipLevel
4133 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4134 levelStorage->push_back(source.getLevel(level));
4136 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
4139 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4141 DE_ASSERT(levelStorage->empty());
4143 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
4144 const deUint32 numLevels = (deUint32)source.getNumLevels();
4146 // cut pyramid from baseMipLevel
4147 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4149 // cut levels from baseArraySlice
4150 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4151 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
4152 levelStorage->push_back(cutLevel);
4155 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
4158 class ImageSampleRenderInstance : public SingleCmdRenderInstance
4161 ImageSampleRenderInstance (vkt::Context& context,
4162 bool isPrimaryCmdBuf,
4163 vk::VkDescriptorType descriptorType,
4164 vk::VkShaderStageFlags stageFlags,
4165 ShaderInputInterface shaderInterface,
4166 vk::VkImageViewType viewType,
4167 deUint32 baseMipLevel,
4168 deUint32 baseArraySlice,
4172 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
4173 vk::VkDevice device,
4174 vk::VkDescriptorType descriptorType,
4175 ShaderInputInterface shaderInterface,
4176 vk::VkShaderStageFlags stageFlags,
4177 const ImageSampleInstanceImages& images);
4179 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4180 vk::VkDevice device,
4181 vk::VkDescriptorSetLayout descriptorSetLayout);
4183 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4184 vk::VkDevice device,
4185 vk::VkDescriptorType descriptorType,
4186 ShaderInputInterface shaderInterface);
4188 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
4189 vk::VkDevice device,
4190 vk::VkDescriptorType descriptorType,
4191 ShaderInputInterface shaderInterface,
4192 vk::VkDescriptorSetLayout layout,
4193 vk::VkDescriptorPool pool,
4195 const ImageSampleInstanceImages& images);
4197 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4198 vk::VkDevice device,
4199 ShaderInputInterface shaderInterface,
4201 const ImageSampleInstanceImages& images,
4202 vk::VkDescriptorSet descriptorSet);
4204 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4205 vk::VkDevice device,
4206 ShaderInputInterface shaderInterface,
4208 const ImageSampleInstanceImages& images,
4209 vk::VkDescriptorSet descriptorSet);
4211 void logTestPlan (void) const;
4212 vk::VkPipelineLayout getPipelineLayout (void) const;
4213 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
4214 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4221 const vk::VkDescriptorType m_descriptorType;
4222 const vk::VkShaderStageFlags m_stageFlags;
4223 const ShaderInputInterface m_shaderInterface;
4224 const vk::VkImageViewType m_viewType;
4225 const deUint32 m_baseMipLevel;
4226 const deUint32 m_baseArraySlice;
4228 const ImageSampleInstanceImages m_images;
4229 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
4230 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4231 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4232 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
4235 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
4236 bool isPrimaryCmdBuf,
4237 vk::VkDescriptorType descriptorType,
4238 vk::VkShaderStageFlags stageFlags,
4239 ShaderInputInterface shaderInterface,
4240 vk::VkImageViewType viewType,
4241 deUint32 baseMipLevel,
4242 deUint32 baseArraySlice,
4244 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4245 , m_descriptorType (descriptorType)
4246 , m_stageFlags (stageFlags)
4247 , m_shaderInterface (shaderInterface)
4248 , m_viewType (viewType)
4249 , m_baseMipLevel (baseMipLevel)
4250 , m_baseArraySlice (baseArraySlice)
4251 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
4252 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images))
4253 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
4254 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
4255 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, isImmutable, m_images))
4259 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
4260 vk::VkDevice device,
4261 vk::VkDescriptorType descriptorType,
4262 ShaderInputInterface shaderInterface,
4263 vk::VkShaderStageFlags stageFlags,
4264 const ImageSampleInstanceImages& images)
4266 const vk::VkSampler samplers[2] =
4268 images.getSamplerA(),
4269 images.getSamplerB(),
4272 vk::DescriptorSetLayoutBuilder builder;
4273 const bool addSeparateImage = descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER;
4275 // (combined)samplers follow
4276 switch (shaderInterface)
4278 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4279 if (addSeparateImage)
4280 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4281 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4284 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4285 if (addSeparateImage)
4286 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4287 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4288 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4291 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4292 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4293 if (addSeparateImage)
4294 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4295 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4298 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4299 if (addSeparateImage)
4300 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4301 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
4305 DE_FATAL("Impossible");
4308 return builder.build(vki, device);
4311 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4312 vk::VkDevice device,
4313 vk::VkDescriptorSetLayout descriptorSetLayout)
4315 const vk::VkPipelineLayoutCreateInfo createInfo =
4317 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4319 (vk::VkPipelineLayoutCreateFlags)0,
4320 1, // descriptorSetCount
4321 &descriptorSetLayout, // pSetLayouts
4322 0u, // pushConstantRangeCount
4323 DE_NULL, // pPushConstantRanges
4325 return vk::createPipelineLayout(vki, device, &createInfo);
4328 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4329 vk::VkDevice device,
4330 vk::VkDescriptorType descriptorType,
4331 ShaderInputInterface shaderInterface)
4333 vk::DescriptorPoolBuilder builder;
4335 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4337 // separate samplers need image to sample
4338 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4340 // also need sample to use, indifferent of whether immutable or not
4341 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
4343 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4345 // combined image samplers
4346 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
4349 DE_FATAL("Impossible");
4351 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4354 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
4355 vk::VkDevice device,
4356 vk::VkDescriptorType descriptorType,
4357 ShaderInputInterface shaderInterface,
4358 vk::VkDescriptorSetLayout layout,
4359 vk::VkDescriptorPool pool,
4361 const ImageSampleInstanceImages& images)
4363 const vk::VkDescriptorSetAllocateInfo allocInfo =
4365 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4372 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4374 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4375 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4376 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4377 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4379 DE_FATAL("Impossible");
4381 return descriptorSet;
4384 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4385 vk::VkDevice device,
4386 ShaderInputInterface shaderInterface,
4388 const ImageSampleInstanceImages& images,
4389 vk::VkDescriptorSet descriptorSet)
4391 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4392 const vk::VkDescriptorImageInfo samplersInfos[2] =
4394 makeDescriptorImageInfo(images.getSamplerA()),
4395 makeDescriptorImageInfo(images.getSamplerB()),
4398 vk::DescriptorSetUpdateBuilder builder;
4399 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
4401 // stand alone texture
4402 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(samplerLocation), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4407 switch (shaderInterface)
4409 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4410 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4413 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4414 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4415 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4418 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4419 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4420 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4423 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4424 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4428 DE_FATAL("Impossible");
4432 builder.update(vki, device);
4435 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4436 vk::VkDevice device,
4437 ShaderInputInterface shaderInterface,
4439 const ImageSampleInstanceImages& images,
4440 vk::VkDescriptorSet descriptorSet)
4442 const vk::VkSampler samplers[2] =
4444 (isImmutable) ? (0) : (images.getSamplerA()),
4445 (isImmutable) ? (0) : (images.getSamplerB()),
4447 const vk::VkDescriptorImageInfo imageSamplers[2] =
4449 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4450 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4453 vk::DescriptorSetUpdateBuilder builder;
4455 // combined image samplers
4456 switch (shaderInterface)
4458 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4459 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4462 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4463 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4464 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4467 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4468 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4472 DE_FATAL("Impossible");
4475 builder.update(vki, device);
4478 void ImageSampleRenderInstance::logTestPlan (void) const
4480 std::ostringstream msg;
4482 msg << "Rendering 2x2 grid.\n";
4484 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4486 msg << "Single descriptor set. Descriptor set contains "
4487 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4488 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4489 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
4490 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4491 (const char*)DE_NULL)
4492 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4494 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4496 msg << "Single descriptor set. Descriptor set contains "
4497 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4498 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4499 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
4500 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4501 (const char*)DE_NULL)
4502 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4505 DE_FATAL("Impossible");
4507 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4510 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4511 if (m_baseArraySlice)
4512 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4514 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4515 msg << "Sampler mode is LINEAR, with WRAP\n";
4517 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4519 if (m_stageFlags == 0u)
4521 msg << "Descriptors are not accessed in any shader stage.\n";
4525 msg << "Color in each cell is fetched using the descriptor(s):\n";
4527 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4529 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4531 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4533 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4535 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4536 msg << " using sampler " << srcResourceNdx;
4537 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4538 msg << " from combined image sampler " << srcResourceNdx;
4540 DE_FATAL("Impossible");
4545 msg << "Descriptors are accessed in {"
4546 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4547 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4548 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4549 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4550 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4554 m_context.getTestContext().getLog()
4555 << tcu::TestLog::Message
4557 << tcu::TestLog::EndMessage;
4560 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
4562 return *m_pipelineLayout;
4565 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4567 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4568 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
4571 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4573 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4574 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4575 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4576 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
4577 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
4578 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
4579 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
4580 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
4581 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4583 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4585 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
4586 return tcu::TestStatus::fail("Image verification failed");
4588 return tcu::TestStatus::pass("Pass");
4591 class ImageSampleComputeInstance : public vkt::TestInstance
4594 ImageSampleComputeInstance (vkt::Context& context,
4595 vk::VkDescriptorType descriptorType,
4596 ShaderInputInterface shaderInterface,
4597 vk::VkImageViewType viewType,
4598 deUint32 baseMipLevel,
4599 deUint32 baseArraySlice,
4600 bool isImmutableSampler);
4603 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4604 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4605 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
4606 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4607 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4609 tcu::TestStatus iterate (void);
4610 void logTestPlan (void) const;
4611 tcu::TestStatus testResourceAccess (void);
4613 const vk::VkDescriptorType m_descriptorType;
4614 const ShaderInputInterface m_shaderInterface;
4615 const vk::VkImageViewType m_viewType;
4616 const deUint32 m_baseMipLevel;
4617 const deUint32 m_baseArraySlice;
4618 const bool m_isImmutableSampler;
4620 const vk::DeviceInterface& m_vki;
4621 const vk::VkDevice m_device;
4622 const vk::VkQueue m_queue;
4623 const deUint32 m_queueFamilyIndex;
4624 vk::Allocator& m_allocator;
4626 const ComputeInstanceResultBuffer m_result;
4627 const ImageSampleInstanceImages m_images;
4630 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
4631 vk::VkDescriptorType descriptorType,
4632 ShaderInputInterface shaderInterface,
4633 vk::VkImageViewType viewType,
4634 deUint32 baseMipLevel,
4635 deUint32 baseArraySlice,
4636 bool isImmutableSampler)
4637 : vkt::TestInstance (context)
4638 , m_descriptorType (descriptorType)
4639 , m_shaderInterface (shaderInterface)
4640 , m_viewType (viewType)
4641 , m_baseMipLevel (baseMipLevel)
4642 , m_baseArraySlice (baseArraySlice)
4643 , m_isImmutableSampler (isImmutableSampler)
4644 , m_vki (context.getDeviceInterface())
4645 , m_device (context.getDevice())
4646 , m_queue (context.getUniversalQueue())
4647 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4648 , m_allocator (context.getDefaultAllocator())
4649 , m_result (m_vki, m_device, m_allocator)
4650 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
4654 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
4656 const vk::VkSampler samplers[2] =
4658 m_images.getSamplerA(),
4659 m_images.getSamplerB(),
4662 vk::DescriptorSetLayoutBuilder builder;
4665 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4667 // with samplers, separate texture at binding 0
4668 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4669 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4671 // (combined)samplers follow
4672 switch (m_shaderInterface)
4674 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4675 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4678 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4679 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4680 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4683 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4684 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
4688 DE_FATAL("Impossible");
4691 return builder.build(m_vki, m_device);
4694 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
4696 vk::DescriptorPoolBuilder builder;
4698 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
4699 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
4701 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4702 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4704 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4707 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
4709 const vk::VkDescriptorSetAllocateInfo allocInfo =
4711 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4718 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4720 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4721 writeSamplerDescriptorSet(*descriptorSet);
4722 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4723 writeImageSamplerDescriptorSet(*descriptorSet);
4725 DE_FATAL("Impossible");
4727 return descriptorSet;
4730 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4732 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4733 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4734 const vk::VkDescriptorImageInfo samplersInfos[2] =
4736 makeDescriptorImageInfo(m_images.getSamplerA()),
4737 makeDescriptorImageInfo(m_images.getSamplerB()),
4740 vk::DescriptorSetUpdateBuilder builder;
4743 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4745 // stand alone texture
4746 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4749 if (!m_isImmutableSampler)
4751 switch (m_shaderInterface)
4753 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4754 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4757 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4758 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4759 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4762 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4763 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4767 DE_FATAL("Impossible");
4771 builder.update(m_vki, m_device);
4774 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4776 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4777 const vk::VkSampler samplers[2] =
4779 (m_isImmutableSampler) ? (0) : (m_images.getSamplerA()),
4780 (m_isImmutableSampler) ? (0) : (m_images.getSamplerB()),
4782 const vk::VkDescriptorImageInfo imageSamplers[2] =
4784 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4785 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4788 vk::DescriptorSetUpdateBuilder builder;
4791 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4793 // combined image samplers
4794 switch (m_shaderInterface)
4796 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4797 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4800 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4801 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4802 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4805 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4806 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4810 DE_FATAL("Impossible");
4813 builder.update(m_vki, m_device);
4816 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
4819 return testResourceAccess();
4822 void ImageSampleComputeInstance::logTestPlan (void) const
4824 std::ostringstream msg;
4826 msg << "Accessing resource in a compute program.\n";
4828 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4830 msg << "Single descriptor set. Descriptor set contains "
4831 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4832 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4833 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4834 (const char*)DE_NULL)
4835 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4837 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4839 msg << "Single descriptor set. Descriptor set contains "
4840 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4841 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4842 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4843 (const char*)DE_NULL)
4844 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4847 DE_FATAL("Impossible");
4849 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4852 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4853 if (m_baseArraySlice)
4854 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4856 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4857 msg << "Sampler mode is LINEAR, with WRAP\n";
4859 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4861 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4863 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4865 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4867 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4869 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4870 msg << " using sampler " << srcResourceNdx;
4871 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4872 msg << " from combined image sampler " << srcResourceNdx;
4874 DE_FATAL("Impossible");
4879 m_context.getTestContext().getLog()
4880 << tcu::TestLog::Message
4882 << tcu::TestLog::EndMessage;
4885 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
4887 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4888 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4889 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4890 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4892 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4893 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
4894 const deUint32* const dynamicOffsets = DE_NULL;
4895 const int numDynamicOffsets = 0;
4896 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
4897 const int numPreBarriers = 0;
4898 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
4899 const int numPostBarriers = 1;
4901 const ComputeCommand compute (m_vki,
4903 pipeline.getPipeline(),
4904 pipeline.getPipelineLayout(),
4905 tcu::UVec3(4, 1, 1),
4906 numDescriptorSets, descriptorSets,
4907 numDynamicOffsets, dynamicOffsets,
4908 numPreBarriers, preBarriers,
4909 numPostBarriers, postBarriers);
4911 tcu::Vec4 results[4];
4912 bool anyResultSet = false;
4913 bool allResultsOk = true;
4915 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4916 m_result.readResultContentsTo(&results);
4919 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4921 const tcu::Vec4 result = results[resultNdx];
4922 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
4924 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
4925 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
4927 if (result != tcu::Vec4(-1.0f))
4928 anyResultSet = true;
4930 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
4932 allResultsOk = false;
4934 m_context.getTestContext().getLog()
4935 << tcu::TestLog::Message
4936 << "Test sample " << resultNdx << ":\n"
4937 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
4938 << "\tError expected " << reference << ", got " << result
4939 << tcu::TestLog::EndMessage;
4943 // read back and verify
4945 return tcu::TestStatus::pass("Pass");
4946 else if (anyResultSet)
4947 return tcu::TestStatus::fail("Invalid result values");
4950 m_context.getTestContext().getLog()
4951 << tcu::TestLog::Message
4952 << "Result buffer was not written to."
4953 << tcu::TestLog::EndMessage;
4954 return tcu::TestStatus::fail("Result buffer was not written to");
4958 class ImageDescriptorCase : public QuadrantRendederCase
4963 FLAG_BASE_MIP = (1u << 1u),
4964 FLAG_BASE_SLICE = (1u << 2u),
4966 // enum continues where resource flags ends
4967 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
4969 ImageDescriptorCase (tcu::TestContext& testCtx,
4971 const char* description,
4972 bool isPrimaryCmdBuf,
4973 vk::VkDescriptorType descriptorType,
4974 vk::VkShaderStageFlags exitingStages,
4975 vk::VkShaderStageFlags activeStages,
4976 ShaderInputInterface shaderInterface,
4977 vk::VkImageViewType viewType,
4981 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
4982 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
4983 std::string genFetchCoordStr (int fetchPosNdx) const;
4984 std::string genSampleCoordStr (int samplePosNdx) const;
4985 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
4986 std::string genNoAccessSource (void) const;
4988 vkt::TestInstance* createInstance (vkt::Context& context) const;
4991 const bool m_isPrimaryCmdBuf;
4992 const vk::VkDescriptorType m_descriptorType;
4993 const ShaderInputInterface m_shaderInterface;
4994 const vk::VkImageViewType m_viewType;
4995 const deUint32 m_baseMipLevel;
4996 const deUint32 m_baseArraySlice;
4997 const bool m_isImmutableSampler;
5000 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
5002 const char* description,
5003 bool isPrimaryCmdBuf,
5004 vk::VkDescriptorType descriptorType,
5005 vk::VkShaderStageFlags exitingStages,
5006 vk::VkShaderStageFlags activeStages,
5007 ShaderInputInterface shaderInterface,
5008 vk::VkImageViewType viewType,
5010 : QuadrantRendederCase (testCtx, name, description,
5011 // \note 1D textures are not supported in ES
5012 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
5013 exitingStages, activeStages)
5014 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
5015 , m_descriptorType (descriptorType)
5016 , m_shaderInterface (shaderInterface)
5017 , m_viewType (viewType)
5018 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
5019 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
5020 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
5024 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
5028 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5029 return "#extension GL_OES_texture_cube_map_array : require\n";
5034 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
5038 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
5039 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
5040 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
5041 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5042 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
5044 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5045 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5046 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5047 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5049 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
5051 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
5052 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
5054 switch (m_shaderInterface)
5056 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5058 switch (m_descriptorType)
5060 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5061 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5062 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
5063 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5064 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
5065 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5066 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
5067 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5068 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
5070 DE_FATAL("invalid descriptor");
5075 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5076 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5077 switch (m_descriptorType)
5079 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5080 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS)
5081 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5082 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
5083 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5085 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler u_separateSamplerA;\n"
5086 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5087 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5088 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5089 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
5090 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
5091 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5092 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
5093 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
5094 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5095 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
5096 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
5098 DE_FATAL("invalid descriptor");
5102 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5103 switch (m_descriptorType)
5105 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5106 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5107 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler[2];\n";
5108 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5109 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
5110 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5111 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
5112 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5113 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
5115 DE_FATAL("invalid descriptor");
5120 DE_FATAL("Impossible");
5125 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
5127 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
5128 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
5130 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5132 return de::toString(fetchPos.x());
5134 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5136 std::ostringstream buf;
5137 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
5142 std::ostringstream buf;
5143 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
5148 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
5150 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
5151 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5153 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5155 std::ostringstream buf;
5156 buf << "float(" << fetchPos.x() << ")";
5159 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5161 std::ostringstream buf;
5162 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
5165 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5167 std::ostringstream buf;
5168 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
5173 std::ostringstream buf;
5174 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
5179 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
5183 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
5184 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5185 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
5186 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5187 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5188 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
5189 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5191 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5192 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
5193 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("A")
5194 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
5196 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5197 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
5198 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("B")
5199 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
5202 switch (m_descriptorType)
5204 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5205 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5207 const std::string coodStr[4] =
5209 genSampleCoordStr(0),
5210 genSampleCoordStr(1),
5211 genSampleCoordStr(2),
5212 genSampleCoordStr(3),
5214 std::ostringstream buf;
5216 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5218 buf << " if (quadrant_id == 0)\n"
5219 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
5220 << " else if (quadrant_id == 1)\n"
5221 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
5222 << " else if (quadrant_id == 2)\n"
5223 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
5225 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
5229 buf << " if (quadrant_id == 0)\n"
5230 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
5231 << " else if (quadrant_id == 1)\n"
5232 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
5233 << " else if (quadrant_id == 2)\n"
5234 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
5236 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
5242 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5244 const std::string coodStr[4] =
5246 genFetchCoordStr(0),
5247 genFetchCoordStr(1),
5248 genFetchCoordStr(2),
5249 genFetchCoordStr(3),
5251 std::ostringstream buf;
5253 buf << " if (quadrant_id == 0)\n"
5254 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
5255 << " else if (quadrant_id == 1)\n"
5256 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
5257 << " else if (quadrant_id == 2)\n"
5258 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
5260 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
5266 DE_FATAL("invalid descriptor");
5271 std::string ImageDescriptorCase::genNoAccessSource (void) const
5273 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
5274 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5276 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
5279 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
5281 verifyDriverSupport(context.getDeviceFeatures(), m_descriptorType, m_activeStages);
5283 switch (m_descriptorType)
5285 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5286 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5287 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5289 DE_ASSERT(m_isPrimaryCmdBuf);
5290 return new ImageSampleComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5293 return new ImageSampleRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5295 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5296 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5297 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5299 DE_ASSERT(m_isPrimaryCmdBuf);
5300 return new ImageFetchComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5303 return new ImageFetchRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5306 DE_FATAL("Impossible");
5311 class TexelBufferInstanceBuffers
5314 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5315 vk::VkDevice device,
5316 vk::Allocator& allocator,
5317 vk::VkDescriptorType descriptorType,
5318 int numTexelBuffers,
5319 bool hasViewOffset);
5322 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
5323 vk::VkDevice device,
5324 vk::Allocator& allocator,
5325 vk::VkDescriptorType descriptorType,
5326 de::MovePtr<vk::Allocation> *outAllocation);
5328 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
5329 vk::VkDevice device,
5330 const tcu::TextureFormat& textureFormat,
5332 vk::VkBuffer buffer);
5334 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
5336 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
5337 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
5340 static int getFetchPos (int fetchPosNdx);
5341 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
5343 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
5344 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
5345 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
5346 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
5347 inline const vk::VkBufferMemoryBarrier* getBufferInitBarriers (void) const { return m_bufferBarriers; }
5353 VIEW_OFFSET_VALUE = 256,
5354 VIEW_DATA_SIZE = 256, //!< size in bytes
5355 VIEW_WIDTH = 64, //!< size in pixels
5359 // some arbitrary points
5361 SAMPLE_POINT_1 = 51,
5362 SAMPLE_POINT_2 = 42,
5363 SAMPLE_POINT_3 = 25,
5366 const deUint32 m_numTexelBuffers;
5367 const tcu::TextureFormat m_imageFormat;
5368 const deUint32 m_viewOffset;
5370 de::ArrayBuffer<deUint8> m_sourceBufferA;
5371 de::ArrayBuffer<deUint8> m_sourceBufferB;
5372 const tcu::ConstPixelBufferAccess m_sourceViewA;
5373 const tcu::ConstPixelBufferAccess m_sourceViewB;
5375 de::MovePtr<vk::Allocation> m_bufferMemoryA;
5376 de::MovePtr<vk::Allocation> m_bufferMemoryB;
5377 const vk::Unique<vk::VkBuffer> m_bufferA;
5378 const vk::Unique<vk::VkBuffer> m_bufferB;
5379 const vk::Unique<vk::VkBufferView> m_bufferViewA;
5380 const vk::Unique<vk::VkBufferView> m_bufferViewB;
5381 vk::VkBufferMemoryBarrier m_bufferBarriers[2];
5384 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5385 vk::VkDevice device,
5386 vk::Allocator& allocator,
5387 vk::VkDescriptorType descriptorType,
5388 int numTexelBuffers,
5390 : m_numTexelBuffers (numTexelBuffers)
5391 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
5392 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
5393 , m_sourceBufferA (BUFFER_SIZE)
5394 , m_sourceBufferB ((numTexelBuffers == 1)
5396 : ((size_t)BUFFER_SIZE))
5397 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
5398 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
5399 , m_bufferMemoryA (DE_NULL)
5400 , m_bufferMemoryB (DE_NULL)
5401 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
5402 , m_bufferB ((numTexelBuffers == 1)
5403 ? vk::Move<vk::VkBuffer>()
5404 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
5405 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
5406 , m_bufferViewB ((numTexelBuffers == 1)
5407 ? vk::Move<vk::VkBufferView>()
5408 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
5410 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
5411 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
5412 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
5414 // specify and upload
5416 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
5417 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
5419 if (numTexelBuffers == 2)
5421 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
5422 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
5425 m_bufferBarriers[0] = createBarrier(descriptorType, *m_bufferA);
5426 m_bufferBarriers[1] = createBarrier(descriptorType, *m_bufferB);
5429 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
5430 vk::VkDevice device,
5431 vk::Allocator& allocator,
5432 vk::VkDescriptorType descriptorType,
5433 de::MovePtr<vk::Allocation> *outAllocation)
5435 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
5436 const vk::VkBufferCreateInfo createInfo =
5438 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
5441 (vk::VkDeviceSize)BUFFER_SIZE, // size
5443 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
5444 0u, // queueFamilyCount
5445 DE_NULL, // pQueueFamilyIndices
5447 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
5448 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
5450 *outAllocation = allocation;
5454 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
5455 vk::VkDevice device,
5456 const tcu::TextureFormat& textureFormat,
5458 vk::VkBuffer buffer)
5460 const vk::VkBufferViewCreateInfo createInfo =
5462 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
5464 (vk::VkBufferViewCreateFlags)0,
5466 vk::mapTextureFormat(textureFormat), // format
5467 (vk::VkDeviceSize)offset, // offset
5468 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
5470 return vk::createBufferView(vki, device, &createInfo);
5473 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
5475 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
5476 const vk::VkBufferMemoryBarrier barrier =
5478 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
5480 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
5481 inputBit, // inputMask
5482 vk::VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
5483 vk::VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
5486 (vk::VkDeviceSize)BUFFER_SIZE // size
5491 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
5493 DE_ASSERT(access.getHeight() == 1);
5494 DE_ASSERT(access.getDepth() == 1);
5496 const deInt32 width = access.getWidth();
5498 for (int x = 0; x < width; ++x)
5500 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
5501 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
5502 const int blue = 16 * (x % 16); //!< 16-long triangle wave
5504 DE_ASSERT(de::inRange(red, 0, 255));
5505 DE_ASSERT(de::inRange(green, 0, 255));
5506 DE_ASSERT(de::inRange(blue, 0, 255));
5508 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
5512 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
5514 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
5515 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
5518 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
5520 static const int fetchPositions[4] =
5527 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
5530 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
5532 // source order is ABAB
5533 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
5534 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
5535 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
5537 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
5540 class TexelBufferRenderInstance : public SingleCmdRenderInstance
5543 TexelBufferRenderInstance (vkt::Context& context,
5544 bool isPrimaryCmdBuf,
5545 vk::VkDescriptorType descriptorType,
5546 vk::VkShaderStageFlags stageFlags,
5547 ShaderInputInterface shaderInterface,
5548 bool nonzeroViewOffset);
5551 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
5552 vk::VkDevice device,
5553 vk::VkDescriptorType descriptorType,
5554 ShaderInputInterface shaderInterface,
5555 vk::VkShaderStageFlags stageFlags);
5557 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5558 vk::VkDevice device,
5559 vk::VkDescriptorSetLayout descriptorSetLayout);
5561 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5562 vk::VkDevice device,
5563 vk::VkDescriptorType descriptorType,
5564 ShaderInputInterface shaderInterface);
5566 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
5567 vk::VkDevice device,
5568 vk::VkDescriptorType descriptorType,
5569 ShaderInputInterface shaderInterface,
5570 vk::VkDescriptorSetLayout layout,
5571 vk::VkDescriptorPool pool,
5572 vk::VkBufferView viewA,
5573 vk::VkBufferView viewB);
5575 void logTestPlan (void) const;
5576 vk::VkPipelineLayout getPipelineLayout (void) const;
5577 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5578 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5585 const vk::VkDescriptorType m_descriptorType;
5586 const vk::VkShaderStageFlags m_stageFlags;
5587 const ShaderInputInterface m_shaderInterface;
5588 const bool m_nonzeroViewOffset;
5590 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5591 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5592 const TexelBufferInstanceBuffers m_texelBuffers;
5593 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5594 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5597 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
5598 bool isPrimaryCmdBuf,
5599 vk::VkDescriptorType descriptorType,
5600 vk::VkShaderStageFlags stageFlags,
5601 ShaderInputInterface shaderInterface,
5602 bool nonzeroViewOffset)
5603 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5604 , m_descriptorType (descriptorType)
5605 , m_stageFlags (stageFlags)
5606 , m_shaderInterface (shaderInterface)
5607 , m_nonzeroViewOffset (nonzeroViewOffset)
5608 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
5609 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5610 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5611 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5612 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_texelBuffers.getBufferViewA(), m_texelBuffers.getBufferViewB()))
5616 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5617 vk::VkDevice device,
5618 vk::VkDescriptorType descriptorType,
5619 ShaderInputInterface shaderInterface,
5620 vk::VkShaderStageFlags stageFlags)
5622 vk::DescriptorSetLayoutBuilder builder;
5624 switch (shaderInterface)
5626 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5627 builder.addSingleBinding(descriptorType, stageFlags);
5630 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5631 builder.addSingleBinding(descriptorType, stageFlags);
5632 builder.addSingleBinding(descriptorType, stageFlags);
5635 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5636 builder.addArrayBinding(descriptorType, 2u, stageFlags);
5640 DE_FATAL("Impossible");
5643 return builder.build(vki, device);
5646 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5647 vk::VkDevice device,
5648 vk::VkDescriptorSetLayout descriptorSetLayout)
5650 const vk::VkPipelineLayoutCreateInfo createInfo =
5652 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5654 (vk::VkPipelineLayoutCreateFlags)0,
5655 1, // descriptorSetCount
5656 &descriptorSetLayout, // pSetLayouts
5657 0u, // pushConstantRangeCount
5658 DE_NULL, // pPushConstantRanges
5660 return vk::createPipelineLayout(vki, device, &createInfo);
5663 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5664 vk::VkDevice device,
5665 vk::VkDescriptorType descriptorType,
5666 ShaderInputInterface shaderInterface)
5668 return vk::DescriptorPoolBuilder()
5669 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
5670 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5673 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5674 vk::VkDevice device,
5675 vk::VkDescriptorType descriptorType,
5676 ShaderInputInterface shaderInterface,
5677 vk::VkDescriptorSetLayout layout,
5678 vk::VkDescriptorPool pool,
5679 vk::VkBufferView viewA,
5680 vk::VkBufferView viewB)
5682 const vk::VkBufferView texelBufferInfos[2] =
5687 const vk::VkDescriptorSetAllocateInfo allocInfo =
5689 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5696 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5697 vk::DescriptorSetUpdateBuilder builder;
5699 switch (shaderInterface)
5701 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5702 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5705 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5706 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5707 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
5710 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5711 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
5715 DE_FATAL("Impossible");
5718 builder.update(vki, device);
5719 return descriptorSet;
5722 void TexelBufferRenderInstance::logTestPlan (void) const
5724 std::ostringstream msg;
5726 msg << "Rendering 2x2 grid.\n"
5727 << "Single descriptor set. Descriptor set contains "
5728 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5729 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5730 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5731 (const char*)DE_NULL)
5732 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5733 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5734 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5736 if (m_stageFlags == 0u)
5738 msg << "Descriptors are not accessed in any shader stage.\n";
5742 msg << "Color in each cell is fetched using the descriptor(s):\n";
5744 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5746 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5748 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5750 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5751 msg << " from texelBuffer " << srcResourceNdx;
5757 msg << "Descriptors are accessed in {"
5758 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5759 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5760 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5761 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5762 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5766 m_context.getTestContext().getLog()
5767 << tcu::TestLog::Message
5769 << tcu::TestLog::EndMessage;
5772 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
5774 return *m_pipelineLayout;
5777 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
5779 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
5780 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
5783 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5785 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5786 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5787 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5788 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
5789 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
5790 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
5791 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
5792 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5794 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5796 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
5797 return tcu::TestStatus::fail("Image verification failed");
5799 return tcu::TestStatus::pass("Pass");
5802 class TexelBufferComputeInstance : public vkt::TestInstance
5805 TexelBufferComputeInstance (vkt::Context& context,
5806 vk::VkDescriptorType descriptorType,
5807 ShaderInputInterface shaderInterface,
5808 bool nonzeroViewOffset);
5811 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5812 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5813 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
5815 tcu::TestStatus iterate (void);
5816 void logTestPlan (void) const;
5817 tcu::TestStatus testResourceAccess (void);
5819 const vk::VkDescriptorType m_descriptorType;
5820 const ShaderInputInterface m_shaderInterface;
5821 const bool m_nonzeroViewOffset;
5823 const vk::DeviceInterface& m_vki;
5824 const vk::VkDevice m_device;
5825 const vk::VkQueue m_queue;
5826 const deUint32 m_queueFamilyIndex;
5827 vk::Allocator& m_allocator;
5829 const ComputeInstanceResultBuffer m_result;
5830 const TexelBufferInstanceBuffers m_texelBuffers;
5833 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
5834 vk::VkDescriptorType descriptorType,
5835 ShaderInputInterface shaderInterface,
5836 bool nonzeroViewOffset)
5837 : vkt::TestInstance (context)
5838 , m_descriptorType (descriptorType)
5839 , m_shaderInterface (shaderInterface)
5840 , m_nonzeroViewOffset (nonzeroViewOffset)
5841 , m_vki (context.getDeviceInterface())
5842 , m_device (context.getDevice())
5843 , m_queue (context.getUniversalQueue())
5844 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5845 , m_allocator (context.getDefaultAllocator())
5846 , m_result (m_vki, m_device, m_allocator)
5847 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5851 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
5853 vk::DescriptorSetLayoutBuilder builder;
5855 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5857 switch (m_shaderInterface)
5859 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5860 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5863 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5864 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5865 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5868 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5869 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5873 DE_FATAL("Impossible");
5876 return builder.build(m_vki, m_device);
5879 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
5881 return vk::DescriptorPoolBuilder()
5882 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
5883 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
5884 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5887 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
5889 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5890 const vk::VkBufferView texelBufferInfos[2] =
5892 m_texelBuffers.getBufferViewA(),
5893 m_texelBuffers.getBufferViewB(),
5895 const vk::VkDescriptorSetAllocateInfo allocInfo =
5897 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5904 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
5905 vk::DescriptorSetUpdateBuilder builder;
5908 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5911 switch (m_shaderInterface)
5913 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5914 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5917 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5918 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5919 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
5922 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5923 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
5927 DE_FATAL("Impossible");
5930 builder.update(m_vki, m_device);
5931 return descriptorSet;
5934 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
5937 return testResourceAccess();
5940 void TexelBufferComputeInstance::logTestPlan (void) const
5942 std::ostringstream msg;
5944 msg << "Fetching 4 values from image in compute shader.\n"
5945 << "Single descriptor set. Descriptor set contains "
5946 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5947 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5948 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5949 (const char*)DE_NULL)
5950 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5951 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5952 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5954 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5956 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5958 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5960 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5961 msg << " from texelBuffer " << srcResourceNdx;
5967 m_context.getTestContext().getLog()
5968 << tcu::TestLog::Message
5970 << tcu::TestLog::EndMessage;
5973 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
5975 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
5976 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5977 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
5978 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
5980 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
5981 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
5982 const deUint32* const dynamicOffsets = DE_NULL;
5983 const int numDynamicOffsets = 0;
5984 const vk::VkBufferMemoryBarrier* const preBarriers = m_texelBuffers.getBufferInitBarriers();
5985 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
5986 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
5987 const int numPostBarriers = 1;
5989 const ComputeCommand compute (m_vki,
5991 pipeline.getPipeline(),
5992 pipeline.getPipelineLayout(),
5993 tcu::UVec3(4, 1, 1),
5994 numDescriptorSets, descriptorSets,
5995 numDynamicOffsets, dynamicOffsets,
5996 numPreBarriers, preBarriers,
5997 numPostBarriers, postBarriers);
5999 tcu::Vec4 results[4];
6000 bool anyResultSet = false;
6001 bool allResultsOk = true;
6003 compute.submitAndWait(m_queueFamilyIndex, m_queue);
6004 m_result.readResultContentsTo(&results);
6007 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6009 const tcu::Vec4 result = results[resultNdx];
6010 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
6011 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
6013 if (result != tcu::Vec4(-1.0f))
6014 anyResultSet = true;
6016 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
6018 allResultsOk = false;
6020 m_context.getTestContext().getLog()
6021 << tcu::TestLog::Message
6022 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
6023 << tcu::TestLog::EndMessage;
6027 // read back and verify
6029 return tcu::TestStatus::pass("Pass");
6030 else if (anyResultSet)
6031 return tcu::TestStatus::fail("Invalid result values");
6034 m_context.getTestContext().getLog()
6035 << tcu::TestLog::Message
6036 << "Result buffer was not written to."
6037 << tcu::TestLog::EndMessage;
6038 return tcu::TestStatus::fail("Result buffer was not written to");
6042 class TexelBufferDescriptorCase : public QuadrantRendederCase
6047 FLAG_VIEW_OFFSET = (1u << 1u),
6049 // enum continues where resource flags ends
6050 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
6052 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6054 const char* description,
6055 bool isPrimaryCmdBuf,
6056 vk::VkDescriptorType descriptorType,
6057 vk::VkShaderStageFlags exitingStages,
6058 vk::VkShaderStageFlags activeStages,
6059 ShaderInputInterface shaderInterface,
6063 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
6064 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
6065 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
6066 std::string genNoAccessSource (void) const;
6068 vkt::TestInstance* createInstance (vkt::Context& context) const;
6070 const bool m_isPrimaryCmdBuf;
6071 const vk::VkDescriptorType m_descriptorType;
6072 const ShaderInputInterface m_shaderInterface;
6073 const bool m_nonzeroViewOffset;
6076 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6078 const char* description,
6079 bool isPrimaryCmdBuf,
6080 vk::VkDescriptorType descriptorType,
6081 vk::VkShaderStageFlags exitingStages,
6082 vk::VkShaderStageFlags activeStages,
6083 ShaderInputInterface shaderInterface,
6085 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
6086 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6087 , m_descriptorType (descriptorType)
6088 , m_shaderInterface (shaderInterface)
6089 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
6093 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
6096 return "#extension GL_EXT_texture_buffer : require\n";
6099 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
6103 const bool isUniform = isUniformDescriptorType(m_descriptorType);
6104 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
6105 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
6107 switch (m_shaderInterface)
6109 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6110 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
6112 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6113 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
6114 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
6116 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6117 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
6120 DE_FATAL("Impossible");
6125 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
6129 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6130 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
6131 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6133 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6134 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
6135 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6137 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
6138 std::ostringstream buf;
6140 buf << " if (quadrant_id == 0)\n"
6141 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
6142 << " else if (quadrant_id == 1)\n"
6143 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
6144 << " else if (quadrant_id == 2)\n"
6145 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
6147 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
6152 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
6154 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6155 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6157 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6160 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
6162 verifyDriverSupport(context.getDeviceFeatures(), m_descriptorType, m_activeStages);
6164 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6166 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
6167 return new TexelBufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
6170 return new TexelBufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
6173 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
6174 bool isPrimaryCmdBuf,
6175 vk::VkDescriptorType descriptorType,
6176 vk::VkShaderStageFlags exitingStages,
6177 vk::VkShaderStageFlags activeStages,
6178 ShaderInputInterface dimension,
6179 deUint32 resourceFlags)
6183 vk::VkImageViewType viewType;
6185 const char* description;
6189 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
6190 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6191 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6193 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
6194 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6195 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6197 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
6198 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6199 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6201 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
6202 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6203 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6205 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
6206 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6207 // no 3d array textures
6209 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
6210 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6211 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6213 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
6214 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6215 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6218 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
6221 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
6223 // SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS only supported in VK_DESCRIPTOR_TYPE_SAMPLER on graphics shaders for now
6224 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS &&
6225 (descriptorType != vk::VK_DESCRIPTOR_TYPE_SAMPLER || activeStages == vk::VK_SHADER_STAGE_COMPUTE_BIT))
6228 group->addChild(new ImageDescriptorCase(group->getTestContext(),
6229 s_imageTypes[ndx].name,
6230 s_imageTypes[ndx].description,
6236 s_imageTypes[ndx].viewType,
6237 s_imageTypes[ndx].flags | resourceFlags));
6241 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
6242 bool isPrimaryCmdBuf,
6243 vk::VkDescriptorType descriptorType,
6244 vk::VkShaderStageFlags exitingStages,
6245 vk::VkShaderStageFlags activeStages,
6246 ShaderInputInterface dimension,
6247 deUint32 resourceFlags)
6249 DE_ASSERT(resourceFlags == 0);
6250 DE_UNREF(resourceFlags);
6255 const char* description;
6257 } s_texelBufferTypes[] =
6259 { "offset_zero", "View offset is zero", 0u },
6260 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
6263 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
6265 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
6268 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
6269 s_texelBufferTypes[ndx].name,
6270 s_texelBufferTypes[ndx].description,
6276 s_texelBufferTypes[ndx].flags));
6280 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
6281 bool isPrimaryCmdBuf,
6282 vk::VkDescriptorType descriptorType,
6283 vk::VkShaderStageFlags exitingStages,
6284 vk::VkShaderStageFlags activeStages,
6285 ShaderInputInterface dimension,
6286 deUint32 resourceFlags)
6288 DE_ASSERT(resourceFlags == 0u);
6289 DE_UNREF(resourceFlags);
6294 const char* description;
6295 bool isForDynamicCases;
6299 { "offset_view_zero", "View offset is zero", false, 0u },
6300 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6302 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6303 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
6304 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6305 { "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 },
6308 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
6310 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
6312 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
6315 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
6316 group->addChild(new BufferDescriptorCase(group->getTestContext(),
6317 s_bufferTypes[ndx].name,
6318 s_bufferTypes[ndx].description,
6324 s_bufferTypes[ndx].flags));
6330 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
6334 const bool isPrimary;
6336 const char* description;
6339 { true, "primary_cmd_buf", "Bind in primary command buffer" },
6340 { false, "secondary_cmd_buf", "Bind in secondary command buffer" },
6344 const vk::VkDescriptorType descriptorType;
6346 const char* description;
6348 } s_descriptorTypes[] =
6350 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
6351 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6352 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
6353 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6354 // \note No way to access SAMPLED_IMAGE without a sampler
6355 //{ vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
6356 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
6357 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
6358 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
6359 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
6360 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
6361 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
6362 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
6367 const char* description;
6368 vk::VkShaderStageFlags existingStages; //!< stages that exists
6369 vk::VkShaderStageFlags activeStages; //!< stages that access resource
6370 bool supportsSecondaryCmdBufs;
6371 } s_shaderStages[] =
6375 "No accessing stages",
6376 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6383 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6384 vk::VK_SHADER_STAGE_VERTEX_BIT,
6389 "Tessellation control stage",
6390 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,
6391 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
6396 "Tessellation evaluation stage",
6397 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,
6398 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
6404 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6405 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
6411 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6412 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6418 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6419 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6424 "Vertex and fragment stages",
6425 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6426 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6432 ShaderInputInterface dimension;
6434 const char* description;
6435 } s_variableDimensions[] =
6437 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
6438 { SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, "multiple_contiguous_descriptors", "Multiple descriptors" },
6439 { SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, "multiple_discontiguous_descriptors", "Multiple descriptors" },
6440 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
6443 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
6445 // .primary_cmd_buf...
6446 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
6448 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
6450 // .sampler, .combined_image_sampler, other resource types ...
6451 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
6453 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
6455 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
6457 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
6459 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
6461 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
6463 de::MovePtr<tcu::TestCaseGroup> dimensionGroup(new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
6464 void (*createTestsFunc)(tcu::TestCaseGroup* group,
6465 bool isPrimaryCmdBuf,
6466 vk::VkDescriptorType descriptorType,
6467 vk::VkShaderStageFlags existingStages,
6468 vk::VkShaderStageFlags activeStages,
6469 ShaderInputInterface dimension,
6470 deUint32 resourceFlags);
6472 switch (s_descriptorTypes[descriptorNdx].descriptorType)
6474 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6475 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6476 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6477 createTestsFunc = createShaderAccessImageTests;
6480 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
6481 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
6482 createTestsFunc = createShaderAccessTexelBufferTests;
6485 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
6486 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
6487 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
6488 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
6489 createTestsFunc = createShaderAccessBufferTests;
6493 createTestsFunc = DE_NULL;
6494 DE_FATAL("Impossible");
6497 if (createTestsFunc)
6499 createTestsFunc(dimensionGroup.get(),
6500 s_bindTypes[bindTypeNdx].isPrimary,
6501 s_descriptorTypes[descriptorNdx].descriptorType,
6502 s_shaderStages[stageNdx].existingStages,
6503 s_shaderStages[stageNdx].activeStages,
6504 s_variableDimensions[dimensionNdx].dimension,
6505 s_descriptorTypes[descriptorNdx].flags);
6508 DE_FATAL("Impossible");
6510 stageGroup->addChild(dimensionGroup.release());
6513 typeGroup->addChild(stageGroup.release());
6517 bindGroup->addChild(typeGroup.release());
6520 group->addChild(bindGroup.release());
6523 return group.release();