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 std::string genPerVertexBlock (const vk::VkShaderStageFlagBits stage, const glu::GLSLVersion version)
80 static const char* const block = "gl_PerVertex {\n"
81 " vec4 gl_Position;\n"
82 " float gl_PointSize;\n" // not used, but for compatibility with how implicit block is declared in ES
84 std::ostringstream str;
86 if (!glu::glslVersionIsES(version))
89 case vk::VK_SHADER_STAGE_VERTEX_BIT:
90 str << "out " << block << ";\n";
93 case vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT:
94 str << "in " << block << " gl_in[gl_MaxPatchVertices];\n"
95 << "out " << block << " gl_out[];\n";
98 case vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT:
99 str << "in " << block << " gl_in[gl_MaxPatchVertices];\n"
100 << "out " << block << ";\n";
103 case vk::VK_SHADER_STAGE_GEOMETRY_BIT:
104 str << "in " << block << " gl_in[];\n"
105 << "out " << block << ";\n";
115 bool isUniformDescriptorType (vk::VkDescriptorType type)
117 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER ||
118 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC ||
119 type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER;
122 bool isDynamicDescriptorType (vk::VkDescriptorType type)
124 return type == vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC || type == vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC;
127 void verifyDriverSupport(const vk::VkPhysicalDeviceFeatures& deviceFeatures,
128 vk::VkDescriptorType descType,
129 vk::VkShaderStageFlags activeStages)
133 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
134 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
135 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
136 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
137 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
138 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
139 // These are supported in all stages
142 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
143 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
144 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
145 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
146 if (activeStages & (vk::VK_SHADER_STAGE_VERTEX_BIT |
147 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT |
148 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT |
149 vk::VK_SHADER_STAGE_GEOMETRY_BIT))
151 if (!deviceFeatures.vertexPipelineStoresAndAtomics)
152 TCU_THROW(NotSupportedError, (de::toString(descType) + " is not supported in the vertex pipeline").c_str());
155 if (activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT)
157 if (!deviceFeatures.fragmentStoresAndAtomics)
158 TCU_THROW(NotSupportedError, (de::toString(descType) + " is not supported in fragment shaders").c_str());
163 DE_FATAL("Impossible");
167 vk::VkImageType viewTypeToImageType (vk::VkImageViewType type)
171 case vk::VK_IMAGE_VIEW_TYPE_1D:
172 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return vk::VK_IMAGE_TYPE_1D;
173 case vk::VK_IMAGE_VIEW_TYPE_2D:
174 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return vk::VK_IMAGE_TYPE_2D;
175 case vk::VK_IMAGE_VIEW_TYPE_3D: return vk::VK_IMAGE_TYPE_3D;
176 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
177 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return vk::VK_IMAGE_TYPE_2D;
180 DE_FATAL("Impossible");
181 return (vk::VkImageType)0;
185 vk::VkImageLayout getImageLayoutForDescriptorType (vk::VkDescriptorType descType)
187 if (descType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
188 return vk::VK_IMAGE_LAYOUT_GENERAL;
190 return vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
193 deUint32 getTextureLevelPyramidDataSize (const tcu::TextureLevelPyramid& srcImage)
195 deUint32 dataSize = 0;
196 for (int level = 0; level < srcImage.getNumLevels(); ++level)
198 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
201 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
203 dataSize += srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
208 void writeTextureLevelPyramidData (void* dst, deUint32 dstLen, const tcu::TextureLevelPyramid& srcImage, vk::VkImageViewType viewType, std::vector<vk::VkBufferImageCopy>* copySlices)
210 // \note cube is copied face-by-face
211 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (srcImage.getLevel(0).getHeight()) :
212 (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
213 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
214 (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (srcImage.getLevel(0).getDepth()) :
216 deUint32 levelOffset = 0;
218 DE_ASSERT(arraySize != 0);
220 for (int level = 0; level < srcImage.getNumLevels(); ++level)
222 const tcu::ConstPixelBufferAccess srcAccess = srcImage.getLevel(level);
223 const tcu::PixelBufferAccess dstAccess (srcAccess.getFormat(), srcAccess.getSize(), srcAccess.getPitch(), (deUint8*)dst + levelOffset);
224 const deUint32 dataSize = srcAccess.getWidth() * srcAccess.getHeight() * srcAccess.getDepth() * srcAccess.getFormat().getPixelSize();
225 const deUint32 sliceDataSize = dataSize / arraySize;
226 const deInt32 sliceHeight = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1) : (srcAccess.getHeight());
227 const deInt32 sliceDepth = (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (srcAccess.getDepth()) : (1);
228 const tcu::IVec3 sliceSize (srcAccess.getWidth(), sliceHeight, sliceDepth);
231 DE_ASSERT(srcAccess.getFormat().getPixelSize() == srcAccess.getPixelPitch());
233 for (int sliceNdx = 0; sliceNdx < (int)arraySize; ++sliceNdx)
235 const vk::VkBufferImageCopy copySlice =
237 (vk::VkDeviceSize)levelOffset + sliceNdx * sliceDataSize, // bufferOffset
238 (deUint32)sliceSize.x(), // bufferRowLength
239 (deUint32)sliceSize.y(), // bufferImageHeight
241 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
242 (deUint32)level, // mipLevel
243 (deUint32)sliceNdx, // arrayLayer
245 }, // imageSubresource
252 (deUint32)sliceSize.x(),
253 (deUint32)sliceSize.y(),
254 (deUint32)sliceSize.z(),
257 copySlices->push_back(copySlice);
260 DE_ASSERT(arraySize * sliceDataSize == dataSize);
262 tcu::copy(dstAccess, srcAccess);
263 levelOffset += dataSize;
266 DE_ASSERT(dstLen == levelOffset);
270 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkBuffer buffer, vk::MemoryRequirement requirement)
272 const vk::VkMemoryRequirements requirements = vk::getBufferMemoryRequirements(vki, device, buffer);
273 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
275 VK_CHECK(vki.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
279 de::MovePtr<vk::Allocation> allocateAndBindObjectMemory (const vk::DeviceInterface& vki, vk::VkDevice device, vk::Allocator& allocator, vk::VkImage image, vk::MemoryRequirement requirement)
281 const vk::VkMemoryRequirements requirements = vk::getImageMemoryRequirements(vki, device, image);
282 de::MovePtr<vk::Allocation> allocation = allocator.allocate(requirements, requirement);
284 VK_CHECK(vki.bindImageMemory(device, image, allocation->getMemory(), allocation->getOffset()));
288 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkSampler sampler)
290 return vk::makeDescriptorImageInfo(sampler, (vk::VkImageView)0, (vk::VkImageLayout)0);
293 vk::VkDescriptorImageInfo makeDescriptorImageInfo (vk::VkImageView imageView, vk::VkImageLayout layout)
295 return vk::makeDescriptorImageInfo((vk::VkSampler)0, imageView, layout);
298 void drawQuadrantReferenceResult (const tcu::PixelBufferAccess& dst, const tcu::Vec4& c1, const tcu::Vec4& c2, const tcu::Vec4& c3, const tcu::Vec4& c4)
300 tcu::clear(tcu::getSubregion(dst, 0, 0, dst.getWidth() / 2, dst.getHeight() / 2), c1);
301 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, 0, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() / 2), c2);
302 tcu::clear(tcu::getSubregion(dst, 0, dst.getHeight() / 2, dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c3);
303 tcu::clear(tcu::getSubregion(dst, dst.getWidth() / 2, dst.getHeight() / 2, dst.getWidth() - dst.getWidth() / 2, dst.getHeight() - dst.getHeight() / 2), c4);
306 class SingleTargetRenderInstance : public vkt::TestInstance
309 SingleTargetRenderInstance (Context& context,
310 const tcu::UVec2& size);
313 static vk::Move<vk::VkImage> createColorAttachment (const vk::DeviceInterface& vki,
315 vk::Allocator& allocator,
316 const tcu::TextureFormat& format,
317 const tcu::UVec2& size,
318 de::MovePtr<vk::Allocation>* outAllocation);
320 static vk::Move<vk::VkImageView> createColorAttachmentView (const vk::DeviceInterface& vki,
322 const tcu::TextureFormat& format,
325 static vk::Move<vk::VkRenderPass> createRenderPass (const vk::DeviceInterface& vki,
327 const tcu::TextureFormat& format);
329 static vk::Move<vk::VkFramebuffer> createFramebuffer (const vk::DeviceInterface& vki,
331 vk::VkRenderPass renderpass,
332 vk::VkImageView colorAttachmentView,
333 const tcu::UVec2& size);
335 static vk::Move<vk::VkCommandPool> createCommandPool (const vk::DeviceInterface& vki,
337 deUint32 queueFamilyIndex);
339 virtual void logTestPlan (void) const = 0;
340 virtual void renderToTarget (void) = 0;
341 virtual tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const = 0;
343 void readRenderTarget (tcu::TextureLevel& dst);
344 tcu::TestStatus iterate (void);
347 const tcu::TextureFormat m_targetFormat;
348 const tcu::UVec2 m_targetSize;
350 const vk::DeviceInterface& m_vki;
351 const vk::VkDevice m_device;
352 const vk::VkQueue m_queue;
353 const deUint32 m_queueFamilyIndex;
354 vk::Allocator& m_allocator;
355 de::MovePtr<vk::Allocation> m_colorAttachmentMemory;
356 const vk::Unique<vk::VkImage> m_colorAttachmentImage;
357 const vk::Unique<vk::VkImageView> m_colorAttachmentView;
358 const vk::Unique<vk::VkRenderPass> m_renderPass;
359 const vk::Unique<vk::VkFramebuffer> m_framebuffer;
360 const vk::Unique<vk::VkCommandPool> m_cmdPool;
362 bool m_firstIteration;
365 SingleTargetRenderInstance::SingleTargetRenderInstance (Context& context,
366 const tcu::UVec2& size)
367 : vkt::TestInstance (context)
368 , m_targetFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
369 , m_targetSize (size)
370 , m_vki (context.getDeviceInterface())
371 , m_device (context.getDevice())
372 , m_queue (context.getUniversalQueue())
373 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
374 , m_allocator (context.getDefaultAllocator())
375 , m_colorAttachmentMemory (DE_NULL)
376 , m_colorAttachmentImage (createColorAttachment(m_vki, m_device, m_allocator, m_targetFormat, m_targetSize, &m_colorAttachmentMemory))
377 , m_colorAttachmentView (createColorAttachmentView(m_vki, m_device, m_targetFormat, *m_colorAttachmentImage))
378 , m_renderPass (createRenderPass(m_vki, m_device, m_targetFormat))
379 , m_framebuffer (createFramebuffer(m_vki, m_device, *m_renderPass, *m_colorAttachmentView, m_targetSize))
380 , m_cmdPool (createCommandPool(m_vki, m_device, context.getUniversalQueueFamilyIndex()))
381 , m_firstIteration (true)
385 vk::Move<vk::VkImage> SingleTargetRenderInstance::createColorAttachment (const vk::DeviceInterface& vki,
387 vk::Allocator& allocator,
388 const tcu::TextureFormat& format,
389 const tcu::UVec2& size,
390 de::MovePtr<vk::Allocation>* outAllocation)
392 const vk::VkImageCreateInfo imageInfo =
394 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
396 (vk::VkImageCreateFlags)0,
397 vk::VK_IMAGE_TYPE_2D, // imageType
398 vk::mapTextureFormat(format), // format
399 { size.x(), size.y(), 1u }, // extent
402 vk::VK_SAMPLE_COUNT_1_BIT, // samples
403 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
404 vk::VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | vk::VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // usage
405 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
406 0u, // queueFamilyCount
407 DE_NULL, // pQueueFamilyIndices
408 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
411 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &imageInfo));
412 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any));
414 *outAllocation = allocation;
418 vk::Move<vk::VkImageView> SingleTargetRenderInstance::createColorAttachmentView (const vk::DeviceInterface& vki,
420 const tcu::TextureFormat& format,
423 const vk::VkImageViewCreateInfo createInfo =
425 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
427 (vk::VkImageViewCreateFlags)0,
429 vk::VK_IMAGE_VIEW_TYPE_2D, // viewType
430 vk::mapTextureFormat(format), // format
431 vk::makeComponentMappingRGBA(),
433 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
436 0u, // baseArrayLayer
441 return vk::createImageView(vki, device, &createInfo);
444 vk::Move<vk::VkRenderPass> SingleTargetRenderInstance::createRenderPass (const vk::DeviceInterface& vki,
446 const tcu::TextureFormat& format)
448 const vk::VkAttachmentDescription attachmentDescription =
450 (vk::VkAttachmentDescriptionFlags)0,
451 vk::mapTextureFormat(format), // format
452 vk::VK_SAMPLE_COUNT_1_BIT, // samples
453 vk::VK_ATTACHMENT_LOAD_OP_CLEAR, // loadOp
454 vk::VK_ATTACHMENT_STORE_OP_STORE, // storeOp
455 vk::VK_ATTACHMENT_LOAD_OP_DONT_CARE, // stencilLoadOp
456 vk::VK_ATTACHMENT_STORE_OP_DONT_CARE, // stencilStoreOp
457 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // initialLayout
458 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // finalLayout
460 const vk::VkAttachmentReference colorAttachment =
463 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // layout
465 const vk::VkAttachmentReference depthStencilAttachment =
467 VK_ATTACHMENT_UNUSED, // attachment
468 vk::VK_IMAGE_LAYOUT_UNDEFINED // layout
470 const vk::VkSubpassDescription subpass =
472 (vk::VkSubpassDescriptionFlags)0,
473 vk::VK_PIPELINE_BIND_POINT_GRAPHICS, // pipelineBindPoint
474 0u, // inputAttachmentCount
475 DE_NULL, // pInputAttachments
476 1u, // colorAttachmentCount
477 &colorAttachment, // pColorAttachments
478 DE_NULL, // pResolveAttachments
479 &depthStencilAttachment, // pDepthStencilAttachment
480 0u, // preserveAttachmentCount
481 DE_NULL // pPreserveAttachments
483 const vk::VkRenderPassCreateInfo renderPassCreateInfo =
485 vk::VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO,
487 (vk::VkRenderPassCreateFlags)0,
488 1u, // attachmentCount
489 &attachmentDescription, // pAttachments
491 &subpass, // pSubpasses
492 0u, // dependencyCount
493 DE_NULL, // pDependencies
496 return vk::createRenderPass(vki, device, &renderPassCreateInfo);
499 vk::Move<vk::VkFramebuffer> SingleTargetRenderInstance::createFramebuffer (const vk::DeviceInterface& vki,
501 vk::VkRenderPass renderpass,
502 vk::VkImageView colorAttachmentView,
503 const tcu::UVec2& size)
505 const vk::VkFramebufferCreateInfo framebufferCreateInfo =
507 vk::VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
509 (vk::VkFramebufferCreateFlags)0,
510 renderpass, // renderPass
511 1u, // attachmentCount
512 &colorAttachmentView, // pAttachments
518 return vk::createFramebuffer(vki, device, &framebufferCreateInfo);
521 vk::Move<vk::VkCommandPool> SingleTargetRenderInstance::createCommandPool (const vk::DeviceInterface& vki,
523 deUint32 queueFamilyIndex)
525 const vk::VkCommandPoolCreateInfo createInfo =
527 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
529 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
530 queueFamilyIndex, // queueFamilyIndex
532 return vk::createCommandPool(vki, device, &createInfo);
535 void SingleTargetRenderInstance::readRenderTarget (tcu::TextureLevel& dst)
537 const deUint64 pixelDataSize = (deUint64)(m_targetSize.x() * m_targetSize.y() * m_targetFormat.getPixelSize());
538 const vk::VkBufferCreateInfo bufferCreateInfo =
540 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
543 pixelDataSize, // size
544 vk::VK_BUFFER_USAGE_TRANSFER_DST_BIT, // usage
545 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
546 0u, // queueFamilyCount
547 DE_NULL, // pQueueFamilyIndices
549 const vk::Unique<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &bufferCreateInfo));
550 const vk::VkImageSubresourceRange fullSubrange =
552 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
555 0u, // baseArraySlice
558 const vk::VkImageMemoryBarrier imageBarrier =
560 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
562 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // srcAccessMask
563 vk::VK_ACCESS_TRANSFER_READ_BIT, // dstAccessMask
564 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // oldLayout
565 vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, // newLayout
566 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
567 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
568 *m_colorAttachmentImage, // image
569 fullSubrange, // subresourceRange
571 const vk::VkBufferMemoryBarrier memoryBarrier =
573 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
575 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // srcAccessMask
576 vk::VK_ACCESS_HOST_READ_BIT, // dstAccessMask
577 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
578 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
581 (vk::VkDeviceSize)pixelDataSize // size
583 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
585 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
587 *m_cmdPool, // cmdPool
588 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
591 const vk::VkFenceCreateInfo fenceCreateInfo =
593 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
597 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
599 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
601 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
602 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
604 const vk::VkImageSubresourceLayers firstSlice =
606 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspect
611 const vk::VkBufferImageCopy copyRegion =
614 m_targetSize.x(), // bufferRowLength
615 m_targetSize.y(), // bufferImageHeight
616 firstSlice, // imageSubresource
617 { 0, 0, 0 }, // imageOffset
618 { m_targetSize.x(), m_targetSize.y(), 1u } // imageExtent
621 const de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible);
623 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
624 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
625 const deUint64 infiniteTimeout = ~(deUint64)0u;
627 // copy content to buffer
628 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
629 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
630 0, (const vk::VkMemoryBarrier*)DE_NULL,
631 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
633 m_vki.cmdCopyImageToBuffer(*cmd, *m_colorAttachmentImage, vk::VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, *buffer, 1, ©Region);
634 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
635 0, (const vk::VkMemoryBarrier*)DE_NULL,
637 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
638 VK_CHECK(m_vki.endCommandBuffer(*cmd));
640 // wait for transfer to complete
642 const vk::VkSubmitInfo submitInfo =
644 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
647 (const vk::VkSemaphore*)0,
648 (const vk::VkPipelineStageFlags*)DE_NULL,
652 (const vk::VkSemaphore*)0,
655 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *cmdCompleteFence));
657 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
659 dst.setStorage(m_targetFormat, m_targetSize.x(), m_targetSize.y());
662 invalidateMappedMemoryRange(m_vki, m_device, bufferMemory->getMemory(), bufferMemory->getOffset(), pixelDataSize);
663 tcu::copy(dst, tcu::ConstPixelBufferAccess(dst.getFormat(), dst.getSize(), bufferMemory->getHostPtr()));
666 tcu::TestStatus SingleTargetRenderInstance::iterate (void)
668 tcu::TextureLevel resultImage;
671 if (m_firstIteration)
674 m_firstIteration = false;
679 // transition to VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
680 const vk::VkImageSubresourceRange fullSubrange =
682 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
685 0u, // baseArraySlice
688 const vk::VkImageMemoryBarrier imageBarrier =
690 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
693 vk::VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT, // dstAccessMask
694 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
695 vk::VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // newLayout
696 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
697 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
698 *m_colorAttachmentImage, // image
699 fullSubrange, // subresourceRange
701 const vk::VkCommandBufferAllocateInfo cmdBufAllocInfo =
703 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
705 *m_cmdPool, // cmdPool
706 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
709 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
711 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
713 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
714 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
716 const vk::VkFenceCreateInfo fenceCreateInfo =
718 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
720 (vk::VkFenceCreateFlags)0,
723 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufAllocInfo));
724 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
725 const deUint64 infiniteTimeout = ~(deUint64)0u;
727 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
728 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
729 0, (const vk::VkMemoryBarrier*)DE_NULL,
730 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
732 VK_CHECK(m_vki.endCommandBuffer(*cmd));
735 const vk::VkSubmitInfo submitInfo =
737 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
740 (const vk::VkSemaphore*)0,
741 (const vk::VkPipelineStageFlags*)DE_NULL,
745 (const vk::VkSemaphore*)0,
748 VK_CHECK(m_vki.queueSubmit(m_queue, 1u, &submitInfo, *fence));
750 VK_CHECK(m_vki.waitForFences(m_device, 1u, &fence.get(), VK_TRUE, infiniteTimeout));
752 // and then render to
757 readRenderTarget(resultImage);
758 return verifyResultImage(resultImage.getAccess());
761 class RenderInstanceShaders
764 RenderInstanceShaders (const vk::DeviceInterface& vki,
766 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
767 const vk::BinaryCollection& programCollection);
769 inline bool hasTessellationStage (void) const { return *m_tessCtrlShaderModule != 0 || *m_tessEvalShaderModule != 0; }
770 inline deUint32 getNumStages (void) const { return (deUint32)m_stageInfos.size(); }
771 inline const vk::VkPipelineShaderStageCreateInfo* getStages (void) const { return &m_stageInfos[0]; }
774 void addStage (const vk::DeviceInterface& vki,
776 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
777 const vk::BinaryCollection& programCollection,
779 vk::VkShaderStageFlagBits stage,
780 vk::Move<vk::VkShaderModule>* outModule);
782 vk::VkPipelineShaderStageCreateInfo getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const;
784 vk::Move<vk::VkShaderModule> m_vertexShaderModule;
785 vk::Move<vk::VkShaderModule> m_tessCtrlShaderModule;
786 vk::Move<vk::VkShaderModule> m_tessEvalShaderModule;
787 vk::Move<vk::VkShaderModule> m_geometryShaderModule;
788 vk::Move<vk::VkShaderModule> m_fragmentShaderModule;
789 std::vector<vk::VkPipelineShaderStageCreateInfo> m_stageInfos;
792 RenderInstanceShaders::RenderInstanceShaders (const vk::DeviceInterface& vki,
794 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
795 const vk::BinaryCollection& programCollection)
797 addStage(vki, device, deviceFeatures, programCollection, "vertex", vk::VK_SHADER_STAGE_VERTEX_BIT, &m_vertexShaderModule);
798 addStage(vki, device, deviceFeatures, programCollection, "tess_ctrl", vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, &m_tessCtrlShaderModule);
799 addStage(vki, device, deviceFeatures, programCollection, "tess_eval", vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, &m_tessEvalShaderModule);
800 addStage(vki, device, deviceFeatures, programCollection, "geometry", vk::VK_SHADER_STAGE_GEOMETRY_BIT, &m_geometryShaderModule);
801 addStage(vki, device, deviceFeatures, programCollection, "fragment", vk::VK_SHADER_STAGE_FRAGMENT_BIT, &m_fragmentShaderModule);
803 DE_ASSERT(!m_stageInfos.empty());
806 void RenderInstanceShaders::addStage (const vk::DeviceInterface& vki,
808 const vk::VkPhysicalDeviceFeatures& deviceFeatures,
809 const vk::BinaryCollection& programCollection,
811 vk::VkShaderStageFlagBits stage,
812 vk::Move<vk::VkShaderModule>* outModule)
814 if (programCollection.contains(name))
816 if (vk::isShaderStageSupported(deviceFeatures, stage))
818 vk::Move<vk::VkShaderModule> module = createShaderModule(vki, device, programCollection.get(name), (vk::VkShaderModuleCreateFlags)0);
820 m_stageInfos.push_back(getShaderStageCreateInfo(stage, *module));
825 // Wait for the GPU to idle so that throwing the exception
826 // below doesn't free in-use GPU resource.
827 vki.deviceWaitIdle(device);
828 TCU_THROW(NotSupportedError, (de::toString(stage) + " is not supported").c_str());
833 vk::VkPipelineShaderStageCreateInfo RenderInstanceShaders::getShaderStageCreateInfo (vk::VkShaderStageFlagBits stage, vk::VkShaderModule shader) const
835 const vk::VkPipelineShaderStageCreateInfo stageCreateInfo =
837 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
839 (vk::VkPipelineShaderStageCreateFlags)0,
843 DE_NULL, // pSpecializationInfo
845 return stageCreateInfo;
848 class SingleCmdRenderInstance : public SingleTargetRenderInstance
851 SingleCmdRenderInstance (Context& context,
852 bool isPrimaryCmdBuf,
853 const tcu::UVec2& renderSize);
856 vk::Move<vk::VkPipeline> createPipeline (vk::VkPipelineLayout pipelineLayout);
858 virtual vk::VkPipelineLayout getPipelineLayout (void) const = 0;
859 virtual void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const = 0;
861 void renderToTarget (void);
863 const bool m_isPrimaryCmdBuf;
866 SingleCmdRenderInstance::SingleCmdRenderInstance (Context& context,
867 bool isPrimaryCmdBuf,
868 const tcu::UVec2& renderSize)
869 : SingleTargetRenderInstance (context, renderSize)
870 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
874 vk::Move<vk::VkPipeline> SingleCmdRenderInstance::createPipeline (vk::VkPipelineLayout pipelineLayout)
876 const RenderInstanceShaders shaderStages (m_vki, m_device, m_context.getDeviceFeatures(), m_context.getBinaryCollection());
877 const vk::VkPrimitiveTopology topology = shaderStages.hasTessellationStage() ? vk::VK_PRIMITIVE_TOPOLOGY_PATCH_LIST : vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
878 const vk::VkPipelineVertexInputStateCreateInfo vertexInputState =
880 vk::VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
882 (vk::VkPipelineVertexInputStateCreateFlags)0,
884 DE_NULL, // pVertexBindingDescriptions
885 0u, // attributeCount
886 DE_NULL, // pVertexAttributeDescriptions
888 const vk::VkPipelineInputAssemblyStateCreateInfo iaState =
890 vk::VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
892 (vk::VkPipelineInputAssemblyStateCreateFlags)0,
893 topology, // topology
894 VK_FALSE, // primitiveRestartEnable
896 const vk::VkPipelineTessellationStateCreateInfo tessState =
898 vk::VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO,
900 (vk::VkPipelineTessellationStateCreateFlags)0,
901 3u, // patchControlPoints
903 const vk::VkViewport viewport =
907 float(m_targetSize.x()), // width
908 float(m_targetSize.y()), // height
912 const vk::VkRect2D renderArea =
915 { m_targetSize.x(), m_targetSize.y() }, // extent
917 const vk::VkPipelineViewportStateCreateInfo vpState =
919 vk::VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
921 (vk::VkPipelineViewportStateCreateFlags)0,
927 const vk::VkPipelineRasterizationStateCreateInfo rsState =
929 vk::VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
931 (vk::VkPipelineRasterizationStateCreateFlags)0,
932 VK_TRUE, // depthClipEnable
933 VK_FALSE, // rasterizerDiscardEnable
934 vk::VK_POLYGON_MODE_FILL, // fillMode
935 vk::VK_CULL_MODE_NONE, // cullMode
936 vk::VK_FRONT_FACE_COUNTER_CLOCKWISE, // frontFace
937 VK_FALSE, // depthBiasEnable
939 0.0f, // depthBiasClamp
940 0.0f, // slopeScaledDepthBias
943 const vk::VkSampleMask sampleMask = 0x01u;
944 const vk::VkPipelineMultisampleStateCreateInfo msState =
946 vk::VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
948 (vk::VkPipelineMultisampleStateCreateFlags)0,
949 vk::VK_SAMPLE_COUNT_1_BIT, // rasterSamples
950 VK_FALSE, // sampleShadingEnable
951 0.0f, // minSampleShading
952 &sampleMask, // sampleMask
953 VK_FALSE, // alphaToCoverageEnable
954 VK_FALSE, // alphaToOneEnable
956 const vk::VkPipelineDepthStencilStateCreateInfo dsState =
958 vk::VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
960 (vk::VkPipelineDepthStencilStateCreateFlags)0,
961 VK_FALSE, // depthTestEnable
962 VK_FALSE, // depthWriteEnable
963 vk::VK_COMPARE_OP_ALWAYS, // depthCompareOp
964 VK_FALSE, // depthBoundsTestEnable
965 VK_FALSE, // stencilTestEnable
966 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // front
967 { vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_STENCIL_OP_KEEP, vk::VK_COMPARE_OP_ALWAYS, 0u, 0u, 0u }, // back
968 -1.0f, // minDepthBounds
969 +1.0f, // maxDepthBounds
971 const vk::VkPipelineColorBlendAttachmentState cbAttachment =
973 VK_FALSE, // blendEnable
974 vk::VK_BLEND_FACTOR_ZERO, // srcBlendColor
975 vk::VK_BLEND_FACTOR_ZERO, // destBlendColor
976 vk::VK_BLEND_OP_ADD, // blendOpColor
977 vk::VK_BLEND_FACTOR_ZERO, // srcBlendAlpha
978 vk::VK_BLEND_FACTOR_ZERO, // destBlendAlpha
979 vk::VK_BLEND_OP_ADD, // blendOpAlpha
980 (vk::VK_COLOR_COMPONENT_R_BIT |
981 vk::VK_COLOR_COMPONENT_G_BIT |
982 vk::VK_COLOR_COMPONENT_B_BIT |
983 vk::VK_COLOR_COMPONENT_A_BIT), // channelWriteMask
985 const vk::VkPipelineColorBlendStateCreateInfo cbState =
987 vk::VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
989 (vk::VkPipelineColorBlendStateCreateFlags)0,
990 VK_FALSE, // logicOpEnable
991 vk::VK_LOGIC_OP_CLEAR, // logicOp
992 1u, // attachmentCount
993 &cbAttachment, // pAttachments
994 { 0.0f, 0.0f, 0.0f, 0.0f }, // blendConst
996 const vk::VkGraphicsPipelineCreateInfo createInfo =
998 vk::VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
1000 (vk::VkPipelineCreateFlags)0,
1001 shaderStages.getNumStages(), // stageCount
1002 shaderStages.getStages(), // pStages
1003 &vertexInputState, // pVertexInputState
1004 &iaState, // pInputAssemblyState
1005 (shaderStages.hasTessellationStage() ? &tessState : DE_NULL), // pTessellationState
1006 &vpState, // pViewportState
1007 &rsState, // pRasterState
1008 &msState, // pMultisampleState
1009 &dsState, // pDepthStencilState
1010 &cbState, // pColorBlendState
1011 (const vk::VkPipelineDynamicStateCreateInfo*)DE_NULL, // pDynamicState
1012 pipelineLayout, // layout
1013 *m_renderPass, // renderPass
1015 (vk::VkPipeline)0, // basePipelineHandle
1016 0u, // basePipelineIndex
1018 return createGraphicsPipeline(m_vki, m_device, (vk::VkPipelineCache)0u, &createInfo);
1021 void SingleCmdRenderInstance::renderToTarget (void)
1023 const vk::VkRect2D renderArea =
1026 { m_targetSize.x(), m_targetSize.y() }, // extent
1028 const vk::VkCommandBufferAllocateInfo mainCmdBufCreateInfo =
1030 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1032 *m_cmdPool, // cmdPool
1033 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1036 const vk::VkCommandBufferBeginInfo mainCmdBufBeginInfo =
1038 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1040 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1041 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
1043 const vk::VkCommandBufferAllocateInfo passCmdBufCreateInfo =
1045 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1047 *m_cmdPool, // cmdPool
1048 vk::VK_COMMAND_BUFFER_LEVEL_SECONDARY, // level
1051 const vk::VkCommandBufferInheritanceInfo passCmdBufInheritInfo =
1053 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_INFO,
1055 (vk::VkRenderPass)*m_renderPass, // renderPass
1057 (vk::VkFramebuffer)*m_framebuffer, // framebuffer
1058 VK_FALSE, // occlusionQueryEnable
1059 (vk::VkQueryControlFlags)0,
1060 (vk::VkQueryPipelineStatisticFlags)0,
1062 const vk::VkCommandBufferBeginInfo passCmdBufBeginInfo =
1064 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1066 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT |
1067 vk::VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT, // flags
1068 &passCmdBufInheritInfo,
1070 const vk::VkFenceCreateInfo fenceCreateInfo =
1072 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1076 const vk::VkClearValue clearValue = vk::makeClearValueColorF32(0.0f, 0.0f, 0.0f, 0.0f);
1077 const vk::VkRenderPassBeginInfo renderPassBeginInfo =
1079 vk::VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
1081 *m_renderPass, // renderPass
1082 *m_framebuffer, // framebuffer
1083 renderArea, // renderArea
1084 1u, // clearValueCount
1085 &clearValue, // pClearValues
1088 const vk::VkPipelineLayout pipelineLayout (getPipelineLayout());
1089 const vk::Unique<vk::VkPipeline> pipeline (createPipeline(pipelineLayout));
1090 const vk::Unique<vk::VkCommandBuffer> mainCmd (vk::allocateCommandBuffer(m_vki, m_device, &mainCmdBufCreateInfo));
1091 const vk::Unique<vk::VkCommandBuffer> passCmd ((m_isPrimaryCmdBuf) ? (vk::Move<vk::VkCommandBuffer>()) : (vk::allocateCommandBuffer(m_vki, m_device, &passCmdBufCreateInfo)));
1092 const vk::Unique<vk::VkFence> fence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1093 const deUint64 infiniteTimeout = ~(deUint64)0u;
1094 const vk::VkSubpassContents passContents = (m_isPrimaryCmdBuf) ? (vk::VK_SUBPASS_CONTENTS_INLINE) : (vk::VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS);
1096 VK_CHECK(m_vki.beginCommandBuffer(*mainCmd, &mainCmdBufBeginInfo));
1097 m_vki.cmdBeginRenderPass(*mainCmd, &renderPassBeginInfo, passContents);
1099 if (m_isPrimaryCmdBuf)
1101 m_vki.cmdBindPipeline(*mainCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1102 writeDrawCmdBuffer(*mainCmd);
1106 VK_CHECK(m_vki.beginCommandBuffer(*passCmd, &passCmdBufBeginInfo));
1107 m_vki.cmdBindPipeline(*passCmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, *pipeline);
1108 writeDrawCmdBuffer(*passCmd);
1109 VK_CHECK(m_vki.endCommandBuffer(*passCmd));
1111 m_vki.cmdExecuteCommands(*mainCmd, 1, &passCmd.get());
1114 m_vki.cmdEndRenderPass(*mainCmd);
1115 VK_CHECK(m_vki.endCommandBuffer(*mainCmd));
1117 // submit and wait for them to finish before exiting scope. (Killing in-flight objects is a no-no).
1119 const vk::VkSubmitInfo submitInfo =
1121 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1124 (const vk::VkSemaphore*)0,
1125 (const vk::VkPipelineStageFlags*)DE_NULL,
1129 (const vk::VkSemaphore*)0,
1131 VK_CHECK(m_vki.queueSubmit(m_queue, 1, &submitInfo, *fence));
1133 VK_CHECK(m_vki.waitForFences(m_device, 1, &fence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1136 enum ShaderInputInterface
1138 SHADER_INPUT_SINGLE_DESCRIPTOR = 0, //!< one descriptor
1139 SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with contiguous binding id's
1140 SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, //!< multiple descriptors with discontiguous binding id's
1141 SHADER_INPUT_DESCRIPTOR_ARRAY, //!< descriptor array
1146 deUint32 getInterfaceNumResources (ShaderInputInterface shaderInterface)
1148 switch (shaderInterface)
1150 case SHADER_INPUT_SINGLE_DESCRIPTOR: return 1u;
1151 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS: return 2u;
1152 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS: return 2u;
1153 case SHADER_INPUT_DESCRIPTOR_ARRAY: return 2u;
1156 DE_FATAL("Impossible");
1161 class BufferRenderInstance : public SingleCmdRenderInstance
1164 BufferRenderInstance (Context& context,
1165 bool isPrimaryCmdBuf,
1166 vk::VkDescriptorType descriptorType,
1167 vk::VkShaderStageFlags stageFlags,
1168 ShaderInputInterface shaderInterface,
1171 bool dynamicOffsetNonZero);
1173 static vk::Move<vk::VkBuffer> createSourceBuffer (const vk::DeviceInterface& vki,
1174 vk::VkDevice device,
1175 vk::Allocator& allocator,
1176 vk::VkDescriptorType descriptorType,
1178 deUint32 bufferSize,
1179 de::MovePtr<vk::Allocation>* outMemory);
1181 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
1182 vk::VkDevice device,
1183 vk::VkDescriptorType descriptorType,
1184 ShaderInputInterface shaderInterface);
1186 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
1187 vk::VkDevice device,
1188 vk::VkDescriptorType descriptorType,
1189 ShaderInputInterface shaderInterface,
1190 vk::VkShaderStageFlags stageFlags);
1192 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
1193 vk::VkDevice device,
1194 vk::VkDescriptorSetLayout descriptorSetLayout,
1195 vk::VkDescriptorPool descriptorPool,
1196 vk::VkDescriptorType descriptorType,
1197 ShaderInputInterface shaderInterface,
1198 vk::VkBuffer sourceBufferA,
1199 const deUint32 viewOffsetA,
1200 vk::VkBuffer sourceBufferB,
1201 const deUint32 viewOffsetB);
1203 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1204 vk::VkDevice device,
1205 vk::VkDescriptorSetLayout descriptorSetLayout);
1207 void logTestPlan (void) const;
1208 vk::VkPipelineLayout getPipelineLayout (void) const;
1209 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
1210 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
1215 BUFFER_DATA_SIZE = 8 * sizeof(float),
1216 BUFFER_SIZE_A = 2048, //!< a lot more than required
1217 BUFFER_SIZE_B = 2560, //!< a lot more than required
1219 STATIC_OFFSET_VALUE_A = 256,
1220 DYNAMIC_OFFSET_VALUE_A = 512,
1221 STATIC_OFFSET_VALUE_B = 1024,
1222 DYNAMIC_OFFSET_VALUE_B = 768,
1225 const vk::VkDescriptorType m_descriptorType;
1226 const ShaderInputInterface m_shaderInterface;
1227 const bool m_setViewOffset;
1228 const bool m_setDynamicOffset;
1229 const bool m_dynamicOffsetNonZero;
1230 const vk::VkShaderStageFlags m_stageFlags;
1232 const deUint32 m_viewOffsetA;
1233 const deUint32 m_viewOffsetB;
1234 const deUint32 m_dynamicOffsetA;
1235 const deUint32 m_dynamicOffsetB;
1236 const deUint32 m_effectiveOffsetA;
1237 const deUint32 m_effectiveOffsetB;
1238 const deUint32 m_bufferSizeA;
1239 const deUint32 m_bufferSizeB;
1241 de::MovePtr<vk::Allocation> m_bufferMemoryA;
1242 de::MovePtr<vk::Allocation> m_bufferMemoryB;
1243 const vk::Unique<vk::VkBuffer> m_sourceBufferA;
1244 const vk::Unique<vk::VkBuffer> m_sourceBufferB;
1245 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
1246 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
1247 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
1248 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1251 BufferRenderInstance::BufferRenderInstance (Context& context,
1252 bool isPrimaryCmdBuf,
1253 vk::VkDescriptorType descriptorType,
1254 vk::VkShaderStageFlags stageFlags,
1255 ShaderInputInterface shaderInterface,
1258 bool dynamicOffsetNonZero)
1259 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
1260 , m_descriptorType (descriptorType)
1261 , m_shaderInterface (shaderInterface)
1262 , m_setViewOffset (viewOffset)
1263 , m_setDynamicOffset (dynamicOffset)
1264 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1265 , m_stageFlags (stageFlags)
1266 , m_viewOffsetA ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u))
1267 , m_viewOffsetB ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u))
1268 , m_dynamicOffsetA ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u))
1269 , m_dynamicOffsetB ((dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u))
1270 , m_effectiveOffsetA ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetA + m_dynamicOffsetA) : (m_viewOffsetA))
1271 , m_effectiveOffsetB ((isDynamicDescriptorType(m_descriptorType)) ? (m_viewOffsetB + m_dynamicOffsetB) : (m_viewOffsetB))
1272 , m_bufferSizeA (BUFFER_SIZE_A)
1273 , m_bufferSizeB (BUFFER_SIZE_B)
1274 , m_bufferMemoryA (DE_NULL)
1275 , m_bufferMemoryB (DE_NULL)
1276 , m_sourceBufferA (createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetA, m_bufferSizeA, &m_bufferMemoryA))
1277 , m_sourceBufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
1278 ? vk::Move<vk::VkBuffer>()
1279 : createSourceBuffer(m_vki, m_device, m_allocator, m_descriptorType, m_effectiveOffsetB, m_bufferSizeB, &m_bufferMemoryB))
1280 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
1281 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
1282 , m_descriptorSet (createDescriptorSet(m_vki, m_device, *m_descriptorSetLayout, *m_descriptorPool, m_descriptorType, m_shaderInterface, *m_sourceBufferA, m_viewOffsetA, *m_sourceBufferB, m_viewOffsetB))
1283 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
1285 if (m_setDynamicOffset)
1286 DE_ASSERT(isDynamicDescriptorType(m_descriptorType));
1287 if (m_dynamicOffsetNonZero)
1288 DE_ASSERT(m_setDynamicOffset);
1291 vk::Move<vk::VkBuffer> BufferRenderInstance::createSourceBuffer (const vk::DeviceInterface& vki,
1292 vk::VkDevice device,
1293 vk::Allocator& allocator,
1294 vk::VkDescriptorType descriptorType,
1296 deUint32 bufferSize,
1297 de::MovePtr<vk::Allocation>* outMemory)
1299 static const float s_colors[] =
1301 0.0f, 1.0f, 0.0f, 1.0f, // green
1302 1.0f, 1.0f, 0.0f, 1.0f, // yellow
1304 DE_STATIC_ASSERT(sizeof(s_colors) == BUFFER_DATA_SIZE);
1305 DE_ASSERT(offset + BUFFER_DATA_SIZE <= bufferSize);
1306 DE_ASSERT(offset % sizeof(float) == 0);
1307 DE_ASSERT(bufferSize % sizeof(float) == 0);
1309 const bool isUniformBuffer = isUniformDescriptorType(descriptorType);
1310 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1311 const float preGuardValue = 0.5f;
1312 const float postGuardValue = 0.75f;
1313 const vk::VkBufferCreateInfo bufferCreateInfo =
1315 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1319 usageFlags, // usage
1320 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1321 0u, // queueFamilyCount
1322 DE_NULL, // pQueueFamilyIndices
1324 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &bufferCreateInfo));
1325 de::MovePtr<vk::Allocation> bufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible);
1326 void* const mapPtr = bufferMemory->getHostPtr();
1328 // guard with interesting values
1329 for (size_t preGuardOffset = 0; preGuardOffset + sizeof(float) <= (size_t)offset; preGuardOffset += sizeof(float))
1330 deMemcpy((deUint8*)mapPtr + preGuardOffset, &preGuardValue, sizeof(float));
1332 deMemcpy((deUint8*)mapPtr + offset, s_colors, sizeof(s_colors));
1333 for (size_t postGuardOffset = (size_t)offset + sizeof(s_colors); postGuardOffset + sizeof(float) <= (size_t)bufferSize; postGuardOffset += sizeof(float))
1334 deMemcpy((deUint8*)mapPtr + postGuardOffset, &postGuardValue, sizeof(float));
1335 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
1337 flushMappedMemoryRange(vki, device, bufferMemory->getMemory(), bufferMemory->getOffset(), bufferSize);
1339 // Flushed host-visible memory is automatically made available to the GPU, no barrier is needed.
1341 *outMemory = bufferMemory;
1345 vk::Move<vk::VkDescriptorPool> BufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
1346 vk::VkDevice device,
1347 vk::VkDescriptorType descriptorType,
1348 ShaderInputInterface shaderInterface)
1350 return vk::DescriptorPoolBuilder()
1351 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
1352 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1355 vk::Move<vk::VkDescriptorSetLayout> BufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
1356 vk::VkDevice device,
1357 vk::VkDescriptorType descriptorType,
1358 ShaderInputInterface shaderInterface,
1359 vk::VkShaderStageFlags stageFlags)
1361 vk::DescriptorSetLayoutBuilder builder;
1363 switch (shaderInterface)
1365 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1366 builder.addSingleBinding(descriptorType, stageFlags);
1369 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1370 builder.addSingleBinding(descriptorType, stageFlags);
1371 builder.addSingleBinding(descriptorType, stageFlags);
1374 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1375 builder.addArrayBinding(descriptorType, 2u, stageFlags);
1379 DE_FATAL("Impossible");
1382 return builder.build(vki, device);
1385 vk::Move<vk::VkDescriptorSet> BufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
1386 vk::VkDevice device,
1387 vk::VkDescriptorSetLayout descriptorSetLayout,
1388 vk::VkDescriptorPool descriptorPool,
1389 vk::VkDescriptorType descriptorType,
1390 ShaderInputInterface shaderInterface,
1391 vk::VkBuffer bufferA,
1393 vk::VkBuffer bufferB,
1396 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1398 vk::makeDescriptorBufferInfo(bufferA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1399 vk::makeDescriptorBufferInfo(bufferB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)BUFFER_DATA_SIZE),
1401 const vk::VkDescriptorSetAllocateInfo allocInfo =
1403 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
1407 &descriptorSetLayout
1410 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
1411 vk::DescriptorSetUpdateBuilder builder;
1413 switch (shaderInterface)
1415 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1416 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1419 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1420 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &bufferInfos[0]);
1421 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &bufferInfos[1]);
1424 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1425 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, bufferInfos);
1429 DE_FATAL("Impossible");
1432 builder.update(vki, device);
1433 return descriptorSet;
1436 vk::Move<vk::VkPipelineLayout> BufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
1437 vk::VkDevice device,
1438 vk::VkDescriptorSetLayout descriptorSetLayout)
1440 const vk::VkPipelineLayoutCreateInfo createInfo =
1442 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1444 (vk::VkPipelineLayoutCreateFlags)0,
1445 1, // descriptorSetCount
1446 &descriptorSetLayout, // pSetLayouts
1447 0u, // pushConstantRangeCount
1448 DE_NULL, // pPushConstantRanges
1451 return vk::createPipelineLayout(vki, device, &createInfo);
1454 void BufferRenderInstance::logTestPlan (void) const
1456 std::ostringstream msg;
1458 msg << "Rendering 2x2 yellow-green grid.\n"
1459 << "Single descriptor set. Descriptor set contains "
1460 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
1461 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
1462 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
1463 (const char*)DE_NULL)
1464 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
1465 << "Buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
1467 if (isDynamicDescriptorType(m_descriptorType))
1469 if (m_setDynamicOffset)
1471 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
1472 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
1476 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
1480 if (m_stageFlags == 0u)
1482 msg << "Descriptors are not accessed in any shader stage.\n";
1486 msg << "Descriptors are accessed in {"
1487 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
1488 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
1489 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
1490 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
1491 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
1495 m_context.getTestContext().getLog()
1496 << tcu::TestLog::Message
1498 << tcu::TestLog::EndMessage;
1501 vk::VkPipelineLayout BufferRenderInstance::getPipelineLayout (void) const
1503 return *m_pipelineLayout;
1506 void BufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
1508 // \note dynamic offset replaces the view offset, i.e. it is not offset relative to the view offset
1509 const deUint32 dynamicOffsets[] =
1514 const deUint32 numOffsets = (!m_setDynamicOffset) ? (0u) : (getInterfaceNumResources(m_shaderInterface));
1515 const deUint32* const dynamicOffsetPtr = (!m_setDynamicOffset) ? (DE_NULL) : (dynamicOffsets);
1517 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), numOffsets, dynamicOffsetPtr);
1518 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
1521 tcu::TestStatus BufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
1523 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
1524 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
1525 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
1527 drawQuadrantReferenceResult(reference.getAccess(), yellow, green, green, yellow);
1529 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
1530 return tcu::TestStatus::fail("Image verification failed");
1532 return tcu::TestStatus::pass("Pass");
1535 class ComputeInstanceResultBuffer
1540 DATA_SIZE = sizeof(tcu::Vec4[4])
1543 ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1544 vk::VkDevice device,
1545 vk::Allocator& allocator);
1547 void readResultContentsTo (tcu::Vec4 (*results)[4]) const;
1549 inline vk::VkBuffer getBuffer (void) const { return *m_buffer; }
1550 inline const vk::VkBufferMemoryBarrier* getResultReadBarrier (void) const { return &m_bufferBarrier; }
1553 static vk::Move<vk::VkBuffer> createResultBuffer (const vk::DeviceInterface& vki,
1554 vk::VkDevice device,
1555 vk::Allocator& allocator,
1556 de::MovePtr<vk::Allocation>* outAllocation);
1558 static vk::VkBufferMemoryBarrier createResultBufferBarrier (vk::VkBuffer buffer);
1560 const vk::DeviceInterface& m_vki;
1561 const vk::VkDevice m_device;
1563 de::MovePtr<vk::Allocation> m_bufferMem;
1564 const vk::Unique<vk::VkBuffer> m_buffer;
1565 const vk::VkBufferMemoryBarrier m_bufferBarrier;
1568 ComputeInstanceResultBuffer::ComputeInstanceResultBuffer (const vk::DeviceInterface& vki,
1569 vk::VkDevice device,
1570 vk::Allocator& allocator)
1573 , m_bufferMem (DE_NULL)
1574 , m_buffer (createResultBuffer(m_vki, m_device, allocator, &m_bufferMem))
1575 , m_bufferBarrier (createResultBufferBarrier(*m_buffer))
1579 void ComputeInstanceResultBuffer::readResultContentsTo (tcu::Vec4 (*results)[4]) const
1581 invalidateMappedMemoryRange(m_vki, m_device, m_bufferMem->getMemory(), m_bufferMem->getOffset(), sizeof(*results));
1582 deMemcpy(*results, m_bufferMem->getHostPtr(), sizeof(*results));
1585 vk::Move<vk::VkBuffer> ComputeInstanceResultBuffer::createResultBuffer (const vk::DeviceInterface& vki,
1586 vk::VkDevice device,
1587 vk::Allocator& allocator,
1588 de::MovePtr<vk::Allocation>* outAllocation)
1590 const vk::VkBufferCreateInfo createInfo =
1592 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1595 (vk::VkDeviceSize)DATA_SIZE, // size
1596 vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, // usage
1597 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1598 0u, // queueFamilyCount
1599 DE_NULL, // pQueueFamilyIndices
1601 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
1602 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
1603 const float clearValue = -1.0f;
1604 void* mapPtr = allocation->getHostPtr();
1606 for (size_t offset = 0; offset < DATA_SIZE; offset += sizeof(float))
1607 deMemcpy(((deUint8*)mapPtr) + offset, &clearValue, sizeof(float));
1609 flushMappedMemoryRange(vki, device, allocation->getMemory(), allocation->getOffset(), (vk::VkDeviceSize)DATA_SIZE);
1611 *outAllocation = allocation;
1615 vk::VkBufferMemoryBarrier ComputeInstanceResultBuffer::createResultBufferBarrier (vk::VkBuffer buffer)
1617 const vk::VkBufferMemoryBarrier bufferBarrier =
1619 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
1621 vk::VK_ACCESS_SHADER_WRITE_BIT, // outputMask
1622 vk::VK_ACCESS_HOST_READ_BIT, // inputMask
1623 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
1624 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
1626 (vk::VkDeviceSize)0u, // offset
1629 return bufferBarrier;
1632 class ComputePipeline
1635 ComputePipeline (const vk::DeviceInterface& vki,
1636 vk::VkDevice device,
1637 const vk::BinaryCollection& programCollection,
1638 deUint32 numDescriptorSets,
1639 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1641 inline vk::VkPipeline getPipeline (void) const { return *m_pipeline; };
1642 inline vk::VkPipelineLayout getPipelineLayout (void) const { return *m_pipelineLayout; };
1645 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
1646 vk::VkDevice device,
1647 deUint32 numDescriptorSets,
1648 const vk::VkDescriptorSetLayout* descriptorSetLayouts);
1650 static vk::Move<vk::VkPipeline> createPipeline (const vk::DeviceInterface& vki,
1651 vk::VkDevice device,
1652 const vk::BinaryCollection& programCollection,
1653 vk::VkPipelineLayout layout);
1655 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
1656 const vk::Unique<vk::VkPipeline> m_pipeline;
1659 ComputePipeline::ComputePipeline (const vk::DeviceInterface& vki,
1660 vk::VkDevice device,
1661 const vk::BinaryCollection& programCollection,
1662 deUint32 numDescriptorSets,
1663 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1664 : m_pipelineLayout (createPipelineLayout(vki, device, numDescriptorSets, descriptorSetLayouts))
1665 , m_pipeline (createPipeline(vki, device, programCollection, *m_pipelineLayout))
1669 vk::Move<vk::VkPipelineLayout> ComputePipeline::createPipelineLayout (const vk::DeviceInterface& vki,
1670 vk::VkDevice device,
1671 deUint32 numDescriptorSets,
1672 const vk::VkDescriptorSetLayout* descriptorSetLayouts)
1674 const vk::VkPipelineLayoutCreateInfo createInfo =
1676 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
1678 (vk::VkPipelineLayoutCreateFlags)0,
1679 numDescriptorSets, // descriptorSetCount
1680 descriptorSetLayouts, // pSetLayouts
1681 0u, // pushConstantRangeCount
1682 DE_NULL, // pPushConstantRanges
1684 return vk::createPipelineLayout(vki, device, &createInfo);
1687 vk::Move<vk::VkPipeline> ComputePipeline::createPipeline (const vk::DeviceInterface& vki,
1688 vk::VkDevice device,
1689 const vk::BinaryCollection& programCollection,
1690 vk::VkPipelineLayout layout)
1692 const vk::Unique<vk::VkShaderModule> computeModule (vk::createShaderModule(vki, device, programCollection.get("compute"), (vk::VkShaderModuleCreateFlags)0u));
1693 const vk::VkPipelineShaderStageCreateInfo cs =
1695 vk::VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
1697 (vk::VkPipelineShaderStageCreateFlags)0,
1698 vk::VK_SHADER_STAGE_COMPUTE_BIT, // stage
1699 *computeModule, // shader
1701 DE_NULL, // pSpecializationInfo
1703 const vk::VkComputePipelineCreateInfo createInfo =
1705 vk::VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO,
1710 (vk::VkPipeline)0, // basePipelineHandle
1711 0u, // basePipelineIndex
1713 return createComputePipeline(vki, device, (vk::VkPipelineCache)0u, &createInfo);
1716 class ComputeCommand
1719 ComputeCommand (const vk::DeviceInterface& vki,
1720 vk::VkDevice device,
1721 vk::VkPipeline pipeline,
1722 vk::VkPipelineLayout pipelineLayout,
1723 const tcu::UVec3& numWorkGroups,
1724 int numDescriptorSets,
1725 const vk::VkDescriptorSet* descriptorSets,
1726 int numDynamicOffsets,
1727 const deUint32* dynamicOffsets,
1729 const vk::VkBufferMemoryBarrier* preBarriers,
1730 int numPostBarriers,
1731 const vk::VkBufferMemoryBarrier* postBarriers);
1733 void submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const;
1736 const vk::DeviceInterface& m_vki;
1737 const vk::VkDevice m_device;
1738 const vk::VkPipeline m_pipeline;
1739 const vk::VkPipelineLayout m_pipelineLayout;
1740 const tcu::UVec3 m_numWorkGroups;
1741 const int m_numDescriptorSets;
1742 const vk::VkDescriptorSet* const m_descriptorSets;
1743 const int m_numDynamicOffsets;
1744 const deUint32* const m_dynamicOffsets;
1745 const int m_numPreBarriers;
1746 const vk::VkBufferMemoryBarrier* const m_preBarriers;
1747 const int m_numPostBarriers;
1748 const vk::VkBufferMemoryBarrier* const m_postBarriers;
1751 ComputeCommand::ComputeCommand (const vk::DeviceInterface& vki,
1752 vk::VkDevice device,
1753 vk::VkPipeline pipeline,
1754 vk::VkPipelineLayout pipelineLayout,
1755 const tcu::UVec3& numWorkGroups,
1756 int numDescriptorSets,
1757 const vk::VkDescriptorSet* descriptorSets,
1758 int numDynamicOffsets,
1759 const deUint32* dynamicOffsets,
1761 const vk::VkBufferMemoryBarrier* preBarriers,
1762 int numPostBarriers,
1763 const vk::VkBufferMemoryBarrier* postBarriers)
1766 , m_pipeline (pipeline)
1767 , m_pipelineLayout (pipelineLayout)
1768 , m_numWorkGroups (numWorkGroups)
1769 , m_numDescriptorSets (numDescriptorSets)
1770 , m_descriptorSets (descriptorSets)
1771 , m_numDynamicOffsets (numDynamicOffsets)
1772 , m_dynamicOffsets (dynamicOffsets)
1773 , m_numPreBarriers (numPreBarriers)
1774 , m_preBarriers (preBarriers)
1775 , m_numPostBarriers (numPostBarriers)
1776 , m_postBarriers (postBarriers)
1780 void ComputeCommand::submitAndWait (deUint32 queueFamilyIndex, vk::VkQueue queue) const
1782 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
1784 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
1786 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
1787 queueFamilyIndex, // queueFamilyIndex
1789 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(m_vki, m_device, &cmdPoolCreateInfo));
1791 const vk::VkFenceCreateInfo fenceCreateInfo =
1793 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
1798 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
1800 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
1802 *cmdPool, // cmdPool
1803 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
1806 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
1808 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
1810 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
1811 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
1814 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(m_vki, m_device, &fenceCreateInfo));
1815 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(m_vki, m_device, &cmdBufCreateInfo));
1816 const deUint64 infiniteTimeout = ~(deUint64)0u;
1818 VK_CHECK(m_vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
1820 m_vki.cmdBindPipeline(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipeline);
1821 m_vki.cmdBindDescriptorSets(*cmd, vk::VK_PIPELINE_BIND_POINT_COMPUTE, m_pipelineLayout, 0, m_numDescriptorSets, m_descriptorSets, m_numDynamicOffsets, m_dynamicOffsets);
1823 if (m_numPreBarriers)
1824 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, (vk::VkDependencyFlags)0,
1825 0, (const vk::VkMemoryBarrier*)DE_NULL,
1826 m_numPreBarriers, m_preBarriers,
1827 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
1829 m_vki.cmdDispatch(*cmd, m_numWorkGroups.x(), m_numWorkGroups.y(), m_numWorkGroups.z());
1830 m_vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
1831 0, (const vk::VkMemoryBarrier*)DE_NULL,
1832 m_numPostBarriers, m_postBarriers,
1833 0, (const vk::VkImageMemoryBarrier*)DE_NULL);
1834 VK_CHECK(m_vki.endCommandBuffer(*cmd));
1838 const vk::VkSubmitInfo submitInfo =
1840 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
1843 (const vk::VkSemaphore*)0,
1844 (const vk::VkPipelineStageFlags*)DE_NULL,
1848 (const vk::VkSemaphore*)0,
1850 VK_CHECK(m_vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
1852 VK_CHECK(m_vki.waitForFences(m_device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
1855 class BufferComputeInstance : public vkt::TestInstance
1858 BufferComputeInstance (Context& context,
1859 vk::VkDescriptorType descriptorType,
1860 ShaderInputInterface shaderInterface,
1863 bool dynamicOffsetNonZero);
1866 vk::Move<vk::VkBuffer> createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation);
1867 vk::Move<vk::VkBufferView> createBufferView (vk::VkBuffer buffer, deUint32 offset) const;
1868 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
1869 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
1870 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;
1872 tcu::TestStatus iterate (void);
1873 void logTestPlan (void) const;
1874 tcu::TestStatus testResourceAccess (void);
1878 STATIC_OFFSET_VALUE_A = 256,
1879 DYNAMIC_OFFSET_VALUE_A = 512,
1880 STATIC_OFFSET_VALUE_B = 1024,
1881 DYNAMIC_OFFSET_VALUE_B = 768,
1884 const vk::VkDescriptorType m_descriptorType;
1885 const ShaderInputInterface m_shaderInterface;
1886 const bool m_setViewOffset;
1887 const bool m_setDynamicOffset;
1888 const bool m_dynamicOffsetNonZero;
1890 const vk::DeviceInterface& m_vki;
1891 const vk::VkDevice m_device;
1892 const vk::VkQueue m_queue;
1893 const deUint32 m_queueFamilyIndex;
1894 vk::Allocator& m_allocator;
1896 const ComputeInstanceResultBuffer m_result;
1899 BufferComputeInstance::BufferComputeInstance (Context& context,
1900 vk::VkDescriptorType descriptorType,
1901 ShaderInputInterface shaderInterface,
1904 bool dynamicOffsetNonZero)
1905 : vkt::TestInstance (context)
1906 , m_descriptorType (descriptorType)
1907 , m_shaderInterface (shaderInterface)
1908 , m_setViewOffset (viewOffset)
1909 , m_setDynamicOffset (dynamicOffset)
1910 , m_dynamicOffsetNonZero (dynamicOffsetNonZero)
1911 , m_vki (context.getDeviceInterface())
1912 , m_device (context.getDevice())
1913 , m_queue (context.getUniversalQueue())
1914 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
1915 , m_allocator (context.getDefaultAllocator())
1916 , m_result (m_vki, m_device, m_allocator)
1918 if (m_dynamicOffsetNonZero)
1919 DE_ASSERT(m_setDynamicOffset);
1922 vk::Move<vk::VkBuffer> BufferComputeInstance::createColorDataBuffer (deUint32 offset, deUint32 bufferSize, const tcu::Vec4& value1, const tcu::Vec4& value2, de::MovePtr<vk::Allocation>* outAllocation)
1924 DE_ASSERT(offset + sizeof(tcu::Vec4[2]) <= bufferSize);
1926 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
1927 const vk::VkBufferUsageFlags usageFlags = (isUniformBuffer) ? (vk::VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_BUFFER_BIT);
1928 const vk::VkBufferCreateInfo createInfo =
1930 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
1933 (vk::VkDeviceSize)bufferSize, // size
1934 usageFlags, // usage
1935 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
1936 0u, // queueFamilyCount
1937 DE_NULL, // pQueueFamilyIndices
1939 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(m_vki, m_device, &createInfo));
1940 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(m_vki, m_device, m_allocator, *buffer, vk::MemoryRequirement::HostVisible));
1941 void* mapPtr = allocation->getHostPtr();
1944 deMemset(mapPtr, 0x5A, (size_t)offset);
1945 deMemcpy((deUint8*)mapPtr + offset, value1.getPtr(), sizeof(tcu::Vec4));
1946 deMemcpy((deUint8*)mapPtr + offset + sizeof(tcu::Vec4), value2.getPtr(), sizeof(tcu::Vec4));
1947 deMemset((deUint8*)mapPtr + offset + 2 * sizeof(tcu::Vec4), 0x5A, (size_t)bufferSize - (size_t)offset - 2 * sizeof(tcu::Vec4));
1949 flushMappedMemoryRange(m_vki, m_device, allocation->getMemory(), allocation->getOffset(), bufferSize);
1951 *outAllocation = allocation;
1955 vk::Move<vk::VkDescriptorSetLayout> BufferComputeInstance::createDescriptorSetLayout (void) const
1957 vk::DescriptorSetLayoutBuilder builder;
1959 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1961 switch (m_shaderInterface)
1963 case SHADER_INPUT_SINGLE_DESCRIPTOR:
1964 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1967 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
1968 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1969 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1972 case SHADER_INPUT_DESCRIPTOR_ARRAY:
1973 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
1977 DE_FATAL("Impossible");
1980 return builder.build(m_vki, m_device);
1983 vk::Move<vk::VkDescriptorPool> BufferComputeInstance::createDescriptorPool (void) const
1985 return vk::DescriptorPoolBuilder()
1986 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
1987 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
1988 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
1991 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
1993 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(resBuf, 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
1994 const vk::VkDescriptorBufferInfo bufferInfos[2] =
1996 vk::makeDescriptorBufferInfo(viewA, (vk::VkDeviceSize)offsetA, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1997 vk::makeDescriptorBufferInfo(viewB, (vk::VkDeviceSize)offsetB, (vk::VkDeviceSize)sizeof(tcu::Vec4[2])),
1999 const vk::VkDescriptorSetAllocateInfo allocInfo =
2001 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
2008 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
2009 vk::DescriptorSetUpdateBuilder builder;
2012 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
2015 switch (m_shaderInterface)
2017 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2018 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2021 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2022 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &bufferInfos[0]);
2023 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &bufferInfos[1]);
2026 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2027 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, bufferInfos);
2031 DE_FATAL("Impossible");
2034 builder.update(m_vki, m_device);
2035 return descriptorSet;
2038 tcu::TestStatus BufferComputeInstance::iterate (void)
2041 return testResourceAccess();
2044 void BufferComputeInstance::logTestPlan (void) const
2046 std::ostringstream msg;
2048 msg << "Accessing resource in a compute program.\n"
2049 << "Single descriptor set. Descriptor set contains "
2050 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
2051 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
2052 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
2053 (const char*)DE_NULL)
2054 << " source descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType)
2055 << " and one destination VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to store results to.\n"
2056 << "Source descriptor buffer view(s) have " << ((m_setViewOffset) ? ("non-") : ("")) << "zero offset.\n";
2058 if (isDynamicDescriptorType(m_descriptorType))
2060 if (m_setDynamicOffset)
2062 msg << "Source buffer(s) are given a dynamic offset at bind time.\n"
2063 << "The supplied dynamic offset is " << ((m_dynamicOffsetNonZero) ? ("non-") : ("")) << "zero.\n";
2067 msg << "Dynamic offset is not supplied at bind time. Expecting bind to offset 0.\n";
2071 msg << "Destination buffer is pre-initialized to -1.\n";
2073 m_context.getTestContext().getLog()
2074 << tcu::TestLog::Message
2076 << tcu::TestLog::EndMessage;
2079 tcu::TestStatus BufferComputeInstance::testResourceAccess (void)
2083 ADDRESSABLE_SIZE = 256, // allocate a lot more than required
2086 const bool isDynamicCase = isDynamicDescriptorType(m_descriptorType);
2087 const bool isUniformBuffer = isUniformDescriptorType(m_descriptorType);
2088 const deUint32 bindTimeOffsets[] =
2090 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_A) : (0u),
2091 (m_dynamicOffsetNonZero) ? ((deUint32)DYNAMIC_OFFSET_VALUE_B) : (0u),
2094 const tcu::Vec4 colorA1 = tcu::Vec4(0.0f, 1.0f, 0.0f, 1.0f);
2095 const tcu::Vec4 colorA2 = tcu::Vec4(1.0f, 1.0f, 0.0f, 1.0f);
2096 const tcu::Vec4 colorB1 = tcu::Vec4(1.0f, 0.0f, 0.0f, 1.0f);
2097 const tcu::Vec4 colorB2 = tcu::Vec4(0.0f, 0.0f, 1.0f, 1.0f);
2099 const deUint32 dataOffsetA = ((isDynamicCase) ? (bindTimeOffsets[0]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u));
2100 const deUint32 dataOffsetB = ((isDynamicCase) ? (bindTimeOffsets[1]) : 0) + ((m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u));
2101 const deUint32 viewOffsetA = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_A) : (0u);
2102 const deUint32 viewOffsetB = (m_setViewOffset) ? ((deUint32)STATIC_OFFSET_VALUE_B) : (0u);
2103 const deUint32 bufferSizeA = dataOffsetA + ADDRESSABLE_SIZE;
2104 const deUint32 bufferSizeB = dataOffsetB + ADDRESSABLE_SIZE;
2106 de::MovePtr<vk::Allocation> bufferMemA;
2107 const vk::Unique<vk::VkBuffer> bufferA (createColorDataBuffer(dataOffsetA, bufferSizeA, colorA1, colorA2, &bufferMemA));
2109 de::MovePtr<vk::Allocation> bufferMemB;
2110 const vk::Unique<vk::VkBuffer> bufferB ((getInterfaceNumResources(m_shaderInterface) == 1u)
2111 ? (vk::Move<vk::VkBuffer>())
2112 : (createColorDataBuffer(dataOffsetB, bufferSizeB, colorB1, colorB2, &bufferMemB)));
2114 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
2115 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
2116 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout, *bufferA, viewOffsetA, *bufferB, viewOffsetB, m_result.getBuffer()));
2117 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
2119 const vk::VkAccessFlags inputBit = (isUniformBuffer) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
2120 const vk::VkBufferMemoryBarrier bufferBarriers[] =
2123 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2125 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2126 inputBit, // inputMask
2127 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2128 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2130 (vk::VkDeviceSize)0u, // offset
2131 (vk::VkDeviceSize)bufferSizeA, // size
2134 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
2136 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
2137 inputBit, // inputMask
2138 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
2139 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
2141 (vk::VkDeviceSize)0u, // offset
2142 (vk::VkDeviceSize)bufferSizeB, // size
2146 const deUint32 numSrcBuffers = getInterfaceNumResources(m_shaderInterface);
2148 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
2149 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
2150 const deUint32* const dynamicOffsets = (m_setDynamicOffset) ? (bindTimeOffsets) : (DE_NULL);
2151 const deUint32 numDynamicOffsets = (m_setDynamicOffset) ? (numSrcBuffers) : (0);
2152 const vk::VkBufferMemoryBarrier* const preBarriers = bufferBarriers;
2153 const int numPreBarriers = numSrcBuffers;
2154 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
2155 const int numPostBarriers = 1;
2157 const ComputeCommand compute (m_vki,
2159 pipeline.getPipeline(),
2160 pipeline.getPipelineLayout(),
2161 tcu::UVec3(4, 1, 1),
2162 numDescriptorSets, descriptorSets,
2163 numDynamicOffsets, dynamicOffsets,
2164 numPreBarriers, preBarriers,
2165 numPostBarriers, postBarriers);
2167 const tcu::Vec4 refQuadrantValue14 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA2) :
2168 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? (colorB2) :
2169 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorB2) :
2171 const tcu::Vec4 refQuadrantValue23 = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (colorA1) :
2172 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? (colorA1) :
2173 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? (colorA1) :
2175 const tcu::Vec4 references[4] =
2182 tcu::Vec4 results[4];
2184 compute.submitAndWait(m_queueFamilyIndex, m_queue);
2185 m_result.readResultContentsTo(&results);
2188 if (results[0] == references[0] &&
2189 results[1] == references[1] &&
2190 results[2] == references[2] &&
2191 results[3] == references[3])
2193 return tcu::TestStatus::pass("Pass");
2195 else if (results[0] == tcu::Vec4(-1.0f) &&
2196 results[1] == tcu::Vec4(-1.0f) &&
2197 results[2] == tcu::Vec4(-1.0f) &&
2198 results[3] == tcu::Vec4(-1.0f))
2200 m_context.getTestContext().getLog()
2201 << tcu::TestLog::Message
2202 << "Result buffer was not written to."
2203 << tcu::TestLog::EndMessage;
2204 return tcu::TestStatus::fail("Result buffer was not written to");
2208 m_context.getTestContext().getLog()
2209 << tcu::TestLog::Message
2210 << "Error expected ["
2211 << references[0] << ", "
2212 << references[1] << ", "
2213 << references[2] << ", "
2214 << references[3] << "], got ["
2215 << results[0] << ", "
2216 << results[1] << ", "
2217 << results[2] << ", "
2218 << results[3] << "]"
2219 << tcu::TestLog::EndMessage;
2220 return tcu::TestStatus::fail("Invalid result values");
2224 class QuadrantRendederCase : public vkt::TestCase
2227 QuadrantRendederCase (tcu::TestContext& testCtx,
2229 const char* description,
2230 glu::GLSLVersion glslVersion,
2231 vk::VkShaderStageFlags exitingStages,
2232 vk::VkShaderStageFlags activeStages);
2234 virtual std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const = 0;
2235 virtual std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const = 0;
2236 virtual std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const = 0;
2237 virtual std::string genNoAccessSource (void) const = 0;
2239 std::string genVertexSource (void) const;
2240 std::string genTessCtrlSource (void) const;
2241 std::string genTessEvalSource (void) const;
2242 std::string genGeometrySource (void) const;
2243 std::string genFragmentSource (void) const;
2244 std::string genComputeSource (void) const;
2246 void initPrograms (vk::SourceCollections& programCollection) const;
2249 const glu::GLSLVersion m_glslVersion;
2250 const vk::VkShaderStageFlags m_exitingStages;
2251 const vk::VkShaderStageFlags m_activeStages;
2254 QuadrantRendederCase::QuadrantRendederCase (tcu::TestContext& testCtx,
2256 const char* description,
2257 glu::GLSLVersion glslVersion,
2258 vk::VkShaderStageFlags exitingStages,
2259 vk::VkShaderStageFlags activeStages)
2260 : vkt::TestCase (testCtx, name, description)
2261 , m_glslVersion (glslVersion)
2262 , m_exitingStages (exitingStages)
2263 , m_activeStages (activeStages)
2265 DE_ASSERT((m_exitingStages & m_activeStages) == m_activeStages);
2268 std::string QuadrantRendederCase::genVertexSource (void) const
2270 const char* const nextStageName = ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u) ? ("tsc")
2271 : ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u) ? ("geo")
2272 : ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u) ? ("frag")
2274 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2275 std::ostringstream buf;
2277 if ((m_activeStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2279 const bool onlyVS = (m_activeStages == vk::VK_SHADER_STAGE_VERTEX_BIT);
2281 // active vertex shader
2282 buf << versionDecl << "\n"
2283 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2284 << genResourceDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT, 0)
2285 << "layout(location = 0) out highp vec4 " << nextStageName << "_color;\n"
2286 << (onlyVS ? "" : "layout(location = 1) flat out highp int " + de::toString(nextStageName) + "_quadrant_id;\n")
2287 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
2288 << "void main (void)\n"
2290 << " highp vec4 result_position;\n"
2291 << " highp int quadrant_id;\n"
2292 << s_quadrantGenVertexPosSource
2293 << " gl_Position = result_position;\n"
2294 << (onlyVS ? "" : "\t" + de::toString(nextStageName) + "_quadrant_id = quadrant_id;\n")
2296 << " highp vec4 result_color;\n"
2297 << genResourceAccessSource(vk::VK_SHADER_STAGE_VERTEX_BIT)
2298 << " " << nextStageName << "_color = result_color;\n"
2304 buf << versionDecl << "\n"
2305 << genExtensionDeclarations(vk::VK_SHADER_STAGE_VERTEX_BIT)
2306 << "layout(location = 1) flat out highp int " << nextStageName << "_quadrant_id;\n"
2307 << genPerVertexBlock(vk::VK_SHADER_STAGE_VERTEX_BIT, m_glslVersion)
2308 << "void main (void)\n"
2310 << " highp vec4 result_position;\n"
2311 << " highp int quadrant_id;\n"
2312 << s_quadrantGenVertexPosSource
2313 << " gl_Position = result_position;\n"
2314 << " " << nextStageName << "_quadrant_id = quadrant_id;\n"
2321 std::string QuadrantRendederCase::genTessCtrlSource (void) const
2323 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2324 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2325 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2326 std::ostringstream buf;
2328 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2330 // contributing not implemented
2331 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2334 buf << versionDecl << "\n"
2336 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2337 << "layout(vertices=3) out;\n"
2338 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, 0)
2339 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2340 << "layout(location = 0) out highp vec4 tes_color[];\n"
2341 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
2342 << "void main (void)\n"
2344 << " highp vec4 result_color;\n"
2345 << " highp int quadrant_id = tsc_quadrant_id[gl_InvocationID];\n"
2346 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT)
2348 << " tes_color[gl_InvocationID] = result_color;\n"
2350 << " // no dynamic input block indexing\n"
2351 << " highp vec4 position;\n"
2352 << " if (gl_InvocationID == 0)\n"
2353 << " position = gl_in[0].gl_Position;\n"
2354 << " else if (gl_InvocationID == 1)\n"
2355 << " position = gl_in[1].gl_Position;\n"
2357 << " position = gl_in[2].gl_Position;\n"
2358 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2359 << " gl_TessLevelInner[0] = 2.8;\n"
2360 << " gl_TessLevelInner[1] = 2.8;\n"
2361 << " gl_TessLevelOuter[0] = 2.8;\n"
2362 << " gl_TessLevelOuter[1] = 2.8;\n"
2363 << " gl_TessLevelOuter[2] = 2.8;\n"
2364 << " gl_TessLevelOuter[3] = 2.8;\n"
2367 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2369 // active te shader, tc passthru
2370 buf << versionDecl << "\n"
2372 << "layout(vertices=3) out;\n"
2373 << "layout(location = 1) flat in highp int tsc_quadrant_id[];\n"
2374 << "layout(location = 1) flat out highp int tes_quadrant_id[];\n"
2375 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT, m_glslVersion)
2376 << "void main (void)\n"
2378 << " tes_quadrant_id[gl_InvocationID] = tsc_quadrant_id[0];\n"
2380 << " // no dynamic input block indexing\n"
2381 << " highp vec4 position;\n"
2382 << " if (gl_InvocationID == 0)\n"
2383 << " position = gl_in[0].gl_Position;\n"
2384 << " else if (gl_InvocationID == 1)\n"
2385 << " position = gl_in[1].gl_Position;\n"
2387 << " position = gl_in[2].gl_Position;\n"
2388 << " gl_out[gl_InvocationID].gl_Position = position;\n"
2389 << " gl_TessLevelInner[0] = 2.8;\n"
2390 << " gl_TessLevelInner[1] = 2.8;\n"
2391 << " gl_TessLevelOuter[0] = 2.8;\n"
2392 << " gl_TessLevelOuter[1] = 2.8;\n"
2393 << " gl_TessLevelOuter[2] = 2.8;\n"
2394 << " gl_TessLevelOuter[3] = 2.8;\n"
2399 // passthrough not implemented
2400 DE_FATAL("not implemented");
2406 std::string QuadrantRendederCase::genTessEvalSource (void) const
2408 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2409 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2410 const char* const tessExtDecl = extRequired ? "#extension GL_EXT_tessellation_shader : require\n" : "";
2411 std::ostringstream buf;
2413 if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2415 // contributing not implemented
2416 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT);
2419 buf << versionDecl << "\n"
2421 << genExtensionDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2422 << "layout(triangles) in;\n"
2423 << genResourceDeclarations(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, 0)
2424 << "layout(location = 1) flat in highp int tes_quadrant_id[];\n"
2425 << "layout(location = 0) out mediump vec4 frag_color;\n"
2426 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
2427 << "void main (void)\n"
2429 << " highp vec4 result_color;\n"
2430 << " highp int quadrant_id = tes_quadrant_id[0];\n"
2431 << genResourceAccessSource(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT)
2433 << " frag_color = result_color;\n"
2434 << " 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"
2437 else if ((m_activeStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2439 // contributing not implemented
2440 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT);
2442 // active tc shader, te is passthru
2443 buf << versionDecl << "\n"
2445 << "layout(triangles) in;\n"
2446 << "layout(location = 0) in highp vec4 tes_color[];\n"
2447 << "layout(location = 0) out mediump vec4 frag_color;\n"
2448 << genPerVertexBlock(vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT, m_glslVersion)
2449 << "void main (void)\n"
2451 << " frag_color = tes_color[0];\n"
2452 << " 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"
2457 // passthrough not implemented
2458 DE_FATAL("not implemented");
2464 std::string QuadrantRendederCase::genGeometrySource (void) const
2466 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2467 const bool extRequired = glu::glslVersionIsES(m_glslVersion) && m_glslVersion <= glu::GLSL_VERSION_310_ES;
2468 const char* const geomExtDecl = extRequired ? "#extension GL_EXT_geometry_shader : require\n" : "";
2469 std::ostringstream buf;
2471 if ((m_activeStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2473 // contributing not implemented
2474 DE_ASSERT(m_activeStages == vk::VK_SHADER_STAGE_GEOMETRY_BIT);
2476 // active geometry shader
2477 buf << versionDecl << "\n"
2479 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2480 << "layout(triangles) in;\n"
2481 << "layout(triangle_strip, max_vertices=4) out;\n"
2482 << genResourceDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT, 0)
2483 << "layout(location = 1) flat in highp int geo_quadrant_id[];\n"
2484 << "layout(location = 0) out mediump vec4 frag_color;\n"
2485 << genPerVertexBlock(vk::VK_SHADER_STAGE_GEOMETRY_BIT, m_glslVersion)
2486 << "void main (void)\n"
2488 << " highp int quadrant_id;\n"
2489 << " highp vec4 result_color;\n"
2491 << " quadrant_id = geo_quadrant_id[0];\n"
2492 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2493 << " frag_color = result_color;\n"
2494 << " gl_Position = gl_in[0].gl_Position;\n"
2495 << " EmitVertex();\n"
2497 << " quadrant_id = geo_quadrant_id[1];\n"
2498 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2499 << " frag_color = result_color;\n"
2500 << " gl_Position = gl_in[1].gl_Position;\n"
2501 << " EmitVertex();\n"
2503 << " quadrant_id = geo_quadrant_id[2];\n"
2504 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2505 << " frag_color = result_color;\n"
2506 << " gl_Position = gl_in[0].gl_Position * 0.5 + gl_in[2].gl_Position * 0.5;\n"
2507 << " EmitVertex();\n"
2509 << " quadrant_id = geo_quadrant_id[0];\n"
2510 << genResourceAccessSource(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2511 << " frag_color = result_color;\n"
2512 << " gl_Position = gl_in[2].gl_Position;\n"
2513 << " EmitVertex();\n"
2518 // passthrough not implemented
2519 DE_FATAL("not implemented");
2525 std::string QuadrantRendederCase::genFragmentSource (void) const
2527 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2528 std::ostringstream buf;
2530 if ((m_activeStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2532 buf << versionDecl << "\n"
2533 << genExtensionDeclarations(vk::VK_SHADER_STAGE_GEOMETRY_BIT)
2534 << genResourceDeclarations(vk::VK_SHADER_STAGE_FRAGMENT_BIT, 0);
2536 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2538 // there are other stages, this is just a contributor
2539 buf << "layout(location = 0) in mediump vec4 frag_color;\n";
2542 buf << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2543 << "layout(location = 0) out mediump vec4 o_color;\n"
2544 << "void main (void)\n"
2546 << " highp int quadrant_id = frag_quadrant_id;\n"
2547 << " highp vec4 result_color;\n"
2548 << genResourceAccessSource(vk::VK_SHADER_STAGE_FRAGMENT_BIT);
2550 if (m_activeStages != vk::VK_SHADER_STAGE_FRAGMENT_BIT)
2553 buf << " if (frag_quadrant_id < 2)\n"
2554 << " o_color = result_color;\n"
2556 << " o_color = frag_color;\n";
2559 buf << " o_color = result_color;\n";
2563 else if (m_activeStages == 0u)
2565 // special case, no active stages
2566 buf << versionDecl << "\n"
2567 << "layout(location = 1) flat in highp int frag_quadrant_id;\n"
2568 << "layout(location = 0) out mediump vec4 o_color;\n"
2569 << "void main (void)\n"
2571 << " highp int quadrant_id = frag_quadrant_id;\n"
2572 << " highp vec4 result_color;\n"
2573 << genNoAccessSource()
2574 << " o_color = result_color;\n"
2580 buf << versionDecl << "\n"
2581 << "layout(location = 0) in mediump vec4 frag_color;\n"
2582 "layout(location = 0) out mediump vec4 o_color;\n"
2583 "void main (void)\n"
2585 " o_color = frag_color;\n"
2592 std::string QuadrantRendederCase::genComputeSource (void) const
2594 const char* const versionDecl = glu::getGLSLVersionDeclaration(m_glslVersion);
2595 std::ostringstream buf;
2597 buf << versionDecl << "\n"
2598 << genExtensionDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2599 << "layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;\n"
2600 << genResourceDeclarations(vk::VK_SHADER_STAGE_COMPUTE_BIT, 1)
2601 << "layout(set = 0, binding = 0, std140) writeonly buffer OutBuf\n"
2603 << " highp vec4 read_colors[4];\n"
2605 << "void main (void)\n"
2607 << " highp int quadrant_id = int(gl_WorkGroupID.x);\n"
2608 << " highp vec4 result_color;\n"
2609 << genResourceAccessSource(vk::VK_SHADER_STAGE_COMPUTE_BIT)
2610 << " b_out.read_colors[gl_WorkGroupID.x] = result_color;\n"
2616 void QuadrantRendederCase::initPrograms (vk::SourceCollections& programCollection) const
2618 if ((m_exitingStages & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0u)
2619 programCollection.glslSources.add("vertex") << glu::VertexSource(genVertexSource());
2621 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0u)
2622 programCollection.glslSources.add("tess_ctrl") << glu::TessellationControlSource(genTessCtrlSource());
2624 if ((m_exitingStages & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0u)
2625 programCollection.glslSources.add("tess_eval") << glu::TessellationEvaluationSource(genTessEvalSource());
2627 if ((m_exitingStages & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0u)
2628 programCollection.glslSources.add("geometry") << glu::GeometrySource(genGeometrySource());
2630 if ((m_exitingStages & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0u)
2631 programCollection.glslSources.add("fragment") << glu::FragmentSource(genFragmentSource());
2633 if ((m_exitingStages & vk::VK_SHADER_STAGE_COMPUTE_BIT) != 0u)
2634 programCollection.glslSources.add("compute") << glu::ComputeSource(genComputeSource());
2637 class BufferDescriptorCase : public QuadrantRendederCase
2642 FLAG_VIEW_OFFSET = (1u << 1u),
2643 FLAG_DYNAMIC_OFFSET_ZERO = (1u << 2u),
2644 FLAG_DYNAMIC_OFFSET_NONZERO = (1u << 3u),
2646 // enum continues where resource flags ends
2647 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
2649 BufferDescriptorCase (tcu::TestContext& testCtx,
2651 const char* description,
2652 bool isPrimaryCmdBuf,
2653 vk::VkDescriptorType descriptorType,
2654 vk::VkShaderStageFlags exitingStages,
2655 vk::VkShaderStageFlags activeStages,
2656 ShaderInputInterface shaderInterface,
2660 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
2661 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
2662 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
2663 std::string genNoAccessSource (void) const;
2665 vkt::TestInstance* createInstance (vkt::Context& context) const;
2667 const bool m_viewOffset;
2668 const bool m_dynamicOffsetSet;
2669 const bool m_dynamicOffsetNonZero;
2670 const bool m_isPrimaryCmdBuf;
2671 const vk::VkDescriptorType m_descriptorType;
2672 const ShaderInputInterface m_shaderInterface;
2675 BufferDescriptorCase::BufferDescriptorCase (tcu::TestContext& testCtx,
2677 const char* description,
2678 bool isPrimaryCmdBuf,
2679 vk::VkDescriptorType descriptorType,
2680 vk::VkShaderStageFlags exitingStages,
2681 vk::VkShaderStageFlags activeStages,
2682 ShaderInputInterface shaderInterface,
2684 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
2685 , m_viewOffset ((flags & FLAG_VIEW_OFFSET) != 0u)
2686 , m_dynamicOffsetSet ((flags & (FLAG_DYNAMIC_OFFSET_ZERO | FLAG_DYNAMIC_OFFSET_NONZERO)) != 0u)
2687 , m_dynamicOffsetNonZero ((flags & FLAG_DYNAMIC_OFFSET_NONZERO) != 0u)
2688 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
2689 , m_descriptorType (descriptorType)
2690 , m_shaderInterface (shaderInterface)
2694 std::string BufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
2700 std::string BufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
2704 const bool isUniform = isUniformDescriptorType(m_descriptorType);
2705 const char* const storageType = (isUniform) ? ("uniform") : ("buffer");
2706 std::ostringstream buf;
2708 switch (m_shaderInterface)
2710 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2711 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2713 << " highp vec4 colorA;\n"
2714 << " highp vec4 colorB;\n"
2715 << "} b_instance;\n";
2718 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2719 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferNameA\n"
2721 << " highp vec4 colorA;\n"
2722 << " highp vec4 colorB;\n"
2723 << "} b_instanceA;\n"
2724 << "layout(set = 0, binding = " << (numUsedBindings+1) << ", std140) " << storageType << " BufferNameB\n"
2726 << " highp vec4 colorA;\n"
2727 << " highp vec4 colorB;\n"
2728 << "} b_instanceB;\n";
2731 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2732 buf << "layout(set = 0, binding = " << (numUsedBindings) << ", std140) " << storageType << " BufferName\n"
2734 << " highp vec4 colorA;\n"
2735 << " highp vec4 colorB;\n"
2736 << "} b_instances[2];\n";
2740 DE_FATAL("Impossible");
2746 std::string BufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
2750 std::ostringstream buf;
2752 switch (m_shaderInterface)
2754 case SHADER_INPUT_SINGLE_DESCRIPTOR:
2755 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2756 << " result_color = b_instance.colorA;\n"
2758 << " result_color = b_instance.colorB;\n";
2761 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
2762 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2763 << " result_color = b_instanceA.colorA;\n"
2765 << " result_color = b_instanceB.colorB;\n";
2768 case SHADER_INPUT_DESCRIPTOR_ARRAY:
2769 buf << " if (quadrant_id == 1 || quadrant_id == 2)\n"
2770 << " result_color = b_instances[0].colorA;\n"
2772 << " result_color = b_instances[1].colorB;\n";
2776 DE_FATAL("Impossible");
2782 std::string BufferDescriptorCase::genNoAccessSource (void) const
2784 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
2785 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
2787 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
2790 vkt::TestInstance* BufferDescriptorCase::createInstance (vkt::Context& context) const
2792 verifyDriverSupport(context.getDeviceFeatures(), m_descriptorType, m_activeStages);
2794 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
2796 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
2797 return new BufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2800 return new BufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewOffset, m_dynamicOffsetSet, m_dynamicOffsetNonZero);
2803 class ImageInstanceImages
2806 ImageInstanceImages (const vk::DeviceInterface& vki,
2807 vk::VkDevice device,
2808 deUint32 queueFamilyIndex,
2810 vk::Allocator& allocator,
2811 vk::VkDescriptorType descriptorType,
2812 vk::VkImageViewType viewType,
2814 deUint32 baseMipLevel,
2815 deUint32 baseArraySlice);
2818 static vk::Move<vk::VkImage> createImage (const vk::DeviceInterface& vki,
2819 vk::VkDevice device,
2820 vk::Allocator& allocator,
2821 vk::VkDescriptorType descriptorType,
2822 vk::VkImageViewType viewType,
2823 const tcu::TextureLevelPyramid& sourceImage,
2824 de::MovePtr<vk::Allocation>* outAllocation);
2826 static vk::Move<vk::VkImageView> createImageView (const vk::DeviceInterface& vki,
2827 vk::VkDevice device,
2828 vk::VkImageViewType viewType,
2829 const tcu::TextureLevelPyramid& sourceImage,
2831 deUint32 baseMipLevel,
2832 deUint32 baseArraySlice);
2834 void populateSourceImage (tcu::TextureLevelPyramid* dst,
2835 bool isFirst) const;
2837 void uploadImage (const vk::DeviceInterface& vki,
2838 vk::VkDevice device,
2839 deUint32 queueFamilyIndex,
2841 vk::Allocator& allocator,
2843 vk::VkImageLayout layout,
2844 const tcu::TextureLevelPyramid& data);
2854 const vk::VkImageViewType m_viewType;
2855 const deUint32 m_baseMipLevel;
2856 const deUint32 m_baseArraySlice;
2858 const tcu::TextureFormat m_imageFormat;
2859 tcu::TextureLevelPyramid m_sourceImageA;
2860 tcu::TextureLevelPyramid m_sourceImageB;
2862 de::MovePtr<vk::Allocation> m_imageMemoryA;
2863 de::MovePtr<vk::Allocation> m_imageMemoryB;
2864 vk::Move<vk::VkImage> m_imageA;
2865 vk::Move<vk::VkImage> m_imageB;
2866 vk::Move<vk::VkImageView> m_imageViewA;
2867 vk::Move<vk::VkImageView> m_imageViewB;
2870 ImageInstanceImages::ImageInstanceImages (const vk::DeviceInterface& vki,
2871 vk::VkDevice device,
2872 deUint32 queueFamilyIndex,
2874 vk::Allocator& allocator,
2875 vk::VkDescriptorType descriptorType,
2876 vk::VkImageViewType viewType,
2878 deUint32 baseMipLevel,
2879 deUint32 baseArraySlice)
2880 : m_viewType (viewType)
2881 , m_baseMipLevel (baseMipLevel)
2882 , m_baseArraySlice (baseArraySlice)
2883 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
2884 , m_sourceImageA (m_imageFormat, NUM_MIP_LEVELS)
2885 , m_sourceImageB (m_imageFormat, NUM_MIP_LEVELS)
2886 , m_imageMemoryA (DE_NULL)
2887 , m_imageMemoryB (DE_NULL)
2888 , m_imageA (vk::Move<vk::VkImage>())
2889 , m_imageB (vk::Move<vk::VkImage>())
2890 , m_imageViewA (vk::Move<vk::VkImageView>())
2891 , m_imageViewB (vk::Move<vk::VkImageView>())
2893 const vk::VkImageLayout layout = getImageLayoutForDescriptorType(descriptorType);
2895 DE_ASSERT(numImages == 1 || numImages == 2);
2897 populateSourceImage(&m_sourceImageA, true);
2898 m_imageA = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageA, &m_imageMemoryA);
2899 m_imageViewA = createImageView(vki, device, viewType, m_sourceImageA, *m_imageA, m_baseMipLevel, m_baseArraySlice);
2900 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageA, layout, m_sourceImageA);
2904 populateSourceImage(&m_sourceImageB, false);
2905 m_imageB = createImage(vki, device, allocator, descriptorType, viewType, m_sourceImageB, &m_imageMemoryB);
2906 m_imageViewB = createImageView(vki, device, viewType, m_sourceImageB, *m_imageB, m_baseMipLevel, m_baseArraySlice);
2907 uploadImage(vki, device, queueFamilyIndex, queue, allocator, *m_imageB, layout, m_sourceImageB);
2911 vk::Move<vk::VkImage> ImageInstanceImages::createImage (const vk::DeviceInterface& vki,
2912 vk::VkDevice device,
2913 vk::Allocator& allocator,
2914 vk::VkDescriptorType descriptorType,
2915 vk::VkImageViewType viewType,
2916 const tcu::TextureLevelPyramid& sourceImage,
2917 de::MovePtr<vk::Allocation>* outAllocation)
2919 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2920 const bool isCube = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY);
2921 const bool isStorage = (descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
2922 const deUint32 readUsage = (isStorage) ? (vk::VK_IMAGE_USAGE_STORAGE_BIT) : (vk::VK_IMAGE_USAGE_SAMPLED_BIT);
2923 const deUint32 arraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight())
2924 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth())
2925 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2926 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth()) // cube: numFaces * numLayers
2928 const vk::VkExtent3D extent =
2931 (deUint32)baseLevel.getWidth(),
2934 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1u) : (deUint32)baseLevel.getHeight(),
2937 (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ((deUint32)baseLevel.getDepth()) : (1u),
2939 const vk::VkImageCreateInfo createInfo =
2941 vk::VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
2943 isCube ? (vk::VkImageCreateFlags)vk::VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT : (vk::VkImageCreateFlags)0,
2944 viewTypeToImageType(viewType), // imageType
2945 vk::mapTextureFormat(baseLevel.getFormat()), // format
2947 (deUint32)sourceImage.getNumLevels(), // mipLevels
2948 arraySize, // arraySize
2949 vk::VK_SAMPLE_COUNT_1_BIT, // samples
2950 vk::VK_IMAGE_TILING_OPTIMAL, // tiling
2951 readUsage | vk::VK_IMAGE_USAGE_TRANSFER_DST_BIT, // usage
2952 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
2953 0u, // queueFamilyCount
2954 DE_NULL, // pQueueFamilyIndices
2955 vk::VK_IMAGE_LAYOUT_UNDEFINED, // initialLayout
2957 vk::Move<vk::VkImage> image (vk::createImage(vki, device, &createInfo));
2959 *outAllocation = allocateAndBindObjectMemory(vki, device, allocator, *image, vk::MemoryRequirement::Any);
2963 vk::Move<vk::VkImageView> ImageInstanceImages::createImageView (const vk::DeviceInterface& vki,
2964 vk::VkDevice device,
2965 vk::VkImageViewType viewType,
2966 const tcu::TextureLevelPyramid& sourceImage,
2968 deUint32 baseMipLevel,
2969 deUint32 baseArraySlice)
2971 const tcu::ConstPixelBufferAccess baseLevel = sourceImage.getLevel(0);
2972 const deUint32 viewTypeBaseSlice = (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * baseArraySlice) : (baseArraySlice);
2973 const deUint32 viewArraySize = (viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? (1)
2974 : (viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (baseLevel.getHeight() - viewTypeBaseSlice)
2975 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? (1)
2976 : (viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice)
2977 : (viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1)
2978 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? (6)
2979 : (viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (baseLevel.getDepth() - viewTypeBaseSlice) // cube: numFaces * numLayers
2982 DE_ASSERT(viewArraySize > 0);
2984 const vk::VkImageSubresourceRange resourceRange =
2986 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
2987 baseMipLevel, // baseMipLevel
2988 sourceImage.getNumLevels() - baseMipLevel, // mipLevels
2989 viewTypeBaseSlice, // baseArraySlice
2990 viewArraySize, // arraySize
2992 const vk::VkImageViewCreateInfo createInfo =
2994 vk::VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
2996 (vk::VkImageViewCreateFlags)0,
2998 viewType, // viewType
2999 vk::mapTextureFormat(baseLevel.getFormat()), // format
3001 vk::VK_COMPONENT_SWIZZLE_R,
3002 vk::VK_COMPONENT_SWIZZLE_G,
3003 vk::VK_COMPONENT_SWIZZLE_B,
3004 vk::VK_COMPONENT_SWIZZLE_A
3006 resourceRange, // subresourceRange
3008 return vk::createImageView(vki, device, &createInfo);
3011 void ImageInstanceImages::populateSourceImage (tcu::TextureLevelPyramid* dst, bool isFirst) const
3013 const int numLevels = dst->getNumLevels();
3015 for (int level = 0; level < numLevels; ++level)
3017 const int width = IMAGE_SIZE >> level;
3018 const int height = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (ARRAY_SIZE)
3019 : (IMAGE_SIZE >> level);
3020 const int depth = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? (1)
3021 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? (ARRAY_SIZE)
3022 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * ARRAY_SIZE)
3023 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (IMAGE_SIZE >> level)
3026 dst->allocLevel(level, width, height, depth);
3029 const tcu::PixelBufferAccess levelAccess = dst->getLevel(level);
3031 for (int z = 0; z < depth; ++z)
3032 for (int y = 0; y < height; ++y)
3033 for (int x = 0; x < width; ++x)
3035 const int gradPos = x + y + z;
3036 const int gradMax = width + height + depth - 3;
3038 const int red = 255 * gradPos / gradMax; //!< gradient from 0 -> max (detects large offset errors)
3039 const int green = ((gradPos % 2 == 0) ? (127) : (0)) + ((gradPos % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
3040 const int blue = (128 * level / numLevels) + (isFirst ? 127 : 0); //!< level and image index (detects incorrect lod / image)
3042 DE_ASSERT(de::inRange(red, 0, 255));
3043 DE_ASSERT(de::inRange(green, 0, 255));
3044 DE_ASSERT(de::inRange(blue, 0, 255));
3046 levelAccess.setPixel(tcu::IVec4(red, green, blue, 255), x, y, z);
3052 void ImageInstanceImages::uploadImage (const vk::DeviceInterface& vki,
3053 vk::VkDevice device,
3054 deUint32 queueFamilyIndex,
3056 vk::Allocator& allocator,
3058 vk::VkImageLayout layout,
3059 const tcu::TextureLevelPyramid& data)
3061 const deUint32 arraySize = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? (1) :
3062 (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? (6 * (deUint32)ARRAY_SIZE) :
3063 ((deUint32)ARRAY_SIZE);
3064 const deUint32 dataBufferSize = getTextureLevelPyramidDataSize(data);
3065 const vk::VkBufferCreateInfo bufferCreateInfo =
3067 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
3070 dataBufferSize, // size
3071 vk::VK_BUFFER_USAGE_TRANSFER_SRC_BIT, // usage
3072 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
3073 0u, // queueFamilyCount
3074 DE_NULL, // pQueueFamilyIndices
3076 const vk::Unique<vk::VkBuffer> dataBuffer (vk::createBuffer(vki, device, &bufferCreateInfo));
3077 const de::MovePtr<vk::Allocation> dataBufferMemory = allocateAndBindObjectMemory(vki, device, allocator, *dataBuffer, vk::MemoryRequirement::HostVisible);
3078 const vk::VkFenceCreateInfo fenceCreateInfo =
3080 vk::VK_STRUCTURE_TYPE_FENCE_CREATE_INFO,
3084 const vk::VkBufferMemoryBarrier preMemoryBarrier =
3086 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
3088 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
3089 vk::VK_ACCESS_TRANSFER_READ_BIT, // inputMask
3090 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3091 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3092 *dataBuffer, // buffer
3094 dataBufferSize, // size
3096 const vk::VkImageSubresourceRange fullSubrange =
3098 vk::VK_IMAGE_ASPECT_COLOR_BIT, // aspectMask
3100 (deUint32)data.getNumLevels(), // mipLevels
3101 0u, // baseArraySlice
3102 arraySize, // arraySize
3104 const vk::VkImageMemoryBarrier preImageBarrier =
3106 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3109 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // inputMask
3110 vk::VK_IMAGE_LAYOUT_UNDEFINED, // oldLayout
3111 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // newLayout
3112 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3113 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3115 fullSubrange // subresourceRange
3117 const vk::VkImageMemoryBarrier postImageBarrier =
3119 vk::VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
3121 vk::VK_ACCESS_TRANSFER_WRITE_BIT, // outputMask
3122 vk::VK_ACCESS_SHADER_READ_BIT, // inputMask
3123 vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, // oldLayout
3124 layout, // newLayout
3125 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
3126 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
3128 fullSubrange // subresourceRange
3130 const vk::VkCommandPoolCreateInfo cmdPoolCreateInfo =
3132 vk::VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
3134 vk::VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // flags
3135 queueFamilyIndex, // queueFamilyIndex
3137 const vk::Unique<vk::VkCommandPool> cmdPool (vk::createCommandPool(vki, device, &cmdPoolCreateInfo));
3138 const vk::VkCommandBufferAllocateInfo cmdBufCreateInfo =
3140 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
3142 *cmdPool, // cmdPool
3143 vk::VK_COMMAND_BUFFER_LEVEL_PRIMARY, // level
3146 const vk::VkCommandBufferBeginInfo cmdBufBeginInfo =
3148 vk::VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
3150 vk::VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // flags
3151 (const vk::VkCommandBufferInheritanceInfo*)DE_NULL,
3154 const vk::Unique<vk::VkCommandBuffer> cmd (vk::allocateCommandBuffer(vki, device, &cmdBufCreateInfo));
3155 const vk::Unique<vk::VkFence> cmdCompleteFence (vk::createFence(vki, device, &fenceCreateInfo));
3156 const deUint64 infiniteTimeout = ~(deUint64)0u;
3157 std::vector<vk::VkBufferImageCopy> copySlices;
3159 // copy data to buffer
3160 writeTextureLevelPyramidData(dataBufferMemory->getHostPtr(), dataBufferSize, data, m_viewType , ©Slices);
3161 flushMappedMemoryRange(vki, device, dataBufferMemory->getMemory(), dataBufferMemory->getOffset(), dataBufferSize);
3163 // record command buffer
3164 VK_CHECK(vki.beginCommandBuffer(*cmd, &cmdBufBeginInfo));
3165 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, (vk::VkDependencyFlags)0,
3166 0, (const vk::VkMemoryBarrier*)DE_NULL,
3167 1, &preMemoryBarrier,
3168 1, &preImageBarrier);
3169 vki.cmdCopyBufferToImage(*cmd, *dataBuffer, image, vk::VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, (deUint32)copySlices.size(), ©Slices[0]);
3170 vki.cmdPipelineBarrier(*cmd, vk::VK_PIPELINE_STAGE_TRANSFER_BIT, vk::VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, (vk::VkDependencyFlags)0,
3171 0, (const vk::VkMemoryBarrier*)DE_NULL,
3172 0, (const vk::VkBufferMemoryBarrier*)DE_NULL,
3173 1, &postImageBarrier);
3174 VK_CHECK(vki.endCommandBuffer(*cmd));
3176 // submit and wait for command buffer to complete before killing it
3178 const vk::VkSubmitInfo submitInfo =
3180 vk::VK_STRUCTURE_TYPE_SUBMIT_INFO,
3183 (const vk::VkSemaphore*)0,
3184 (const vk::VkPipelineStageFlags*)DE_NULL,
3188 (const vk::VkSemaphore*)0,
3190 VK_CHECK(vki.queueSubmit(queue, 1, &submitInfo, *cmdCompleteFence));
3192 VK_CHECK(vki.waitForFences(device, 1, &cmdCompleteFence.get(), 0u, infiniteTimeout)); // \note: timeout is failure
3195 class ImageFetchInstanceImages : private ImageInstanceImages
3198 ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3199 vk::VkDevice device,
3200 deUint32 queueFamilyIndex,
3202 vk::Allocator& allocator,
3203 vk::VkDescriptorType descriptorType,
3204 ShaderInputInterface shaderInterface,
3205 vk::VkImageViewType viewType,
3206 deUint32 baseMipLevel,
3207 deUint32 baseArraySlice);
3209 static tcu::IVec3 getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx);
3210 tcu::Vec4 fetchImageValue (int fetchPosNdx) const;
3212 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3213 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3218 // some arbitrary sample points for all four quadrants
3219 SAMPLE_POINT_0_X = 6,
3220 SAMPLE_POINT_0_Y = 13,
3221 SAMPLE_POINT_0_Z = 49,
3223 SAMPLE_POINT_1_X = 51,
3224 SAMPLE_POINT_1_Y = 40,
3225 SAMPLE_POINT_1_Z = 44,
3227 SAMPLE_POINT_2_X = 42,
3228 SAMPLE_POINT_2_Y = 26,
3229 SAMPLE_POINT_2_Z = 19,
3231 SAMPLE_POINT_3_X = 25,
3232 SAMPLE_POINT_3_Y = 25,
3233 SAMPLE_POINT_3_Z = 18,
3236 const ShaderInputInterface m_shaderInterface;
3239 ImageFetchInstanceImages::ImageFetchInstanceImages (const vk::DeviceInterface& vki,
3240 vk::VkDevice device,
3241 deUint32 queueFamilyIndex,
3243 vk::Allocator& allocator,
3244 vk::VkDescriptorType descriptorType,
3245 ShaderInputInterface shaderInterface,
3246 vk::VkImageViewType viewType,
3247 deUint32 baseMipLevel,
3248 deUint32 baseArraySlice)
3249 : ImageInstanceImages (vki,
3256 getInterfaceNumResources(shaderInterface), // numImages
3259 , m_shaderInterface (shaderInterface)
3263 bool isImageViewTypeArray (vk::VkImageViewType type)
3265 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;
3268 tcu::IVec3 ImageFetchInstanceImages::getFetchPos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int fetchPosNdx)
3270 const tcu::IVec3 fetchPositions[4] =
3272 tcu::IVec3(SAMPLE_POINT_0_X, SAMPLE_POINT_0_Y, SAMPLE_POINT_0_Z),
3273 tcu::IVec3(SAMPLE_POINT_1_X, SAMPLE_POINT_1_Y, SAMPLE_POINT_1_Z),
3274 tcu::IVec3(SAMPLE_POINT_2_X, SAMPLE_POINT_2_Y, SAMPLE_POINT_2_Z),
3275 tcu::IVec3(SAMPLE_POINT_3_X, SAMPLE_POINT_3_Y, SAMPLE_POINT_3_Z),
3277 const tcu::IVec3 coord = de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
3278 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3279 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3283 case vk::VK_IMAGE_VIEW_TYPE_1D:
3284 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % arraySize, 0);
3285 case vk::VK_IMAGE_VIEW_TYPE_2D:
3286 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % arraySize);
3287 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3288 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % (arraySize * 6));
3289 case vk::VK_IMAGE_VIEW_TYPE_3D: return tcu::IVec3(coord.x() % imageSize, coord.y() % imageSize, coord.z() % imageSize);
3291 DE_FATAL("Impossible");
3292 return tcu::IVec3();
3296 tcu::Vec4 ImageFetchInstanceImages::fetchImageValue (int fetchPosNdx) const
3298 DE_ASSERT(de::inBounds(fetchPosNdx, 0, 4));
3300 const tcu::TextureLevelPyramid& fetchSrcA = m_sourceImageA;
3301 const tcu::TextureLevelPyramid& fetchSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
3302 const tcu::TextureLevelPyramid& fetchSrc = ((fetchPosNdx % 2) == 0) ? (fetchSrcA) : (fetchSrcB); // sampling order is ABAB
3303 tcu::IVec3 fetchPos = getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
3305 // add base array layer into the appropriate coordinate, based on the view type
3306 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
3307 fetchPos.z() += 6 * m_baseArraySlice;
3308 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3309 fetchPos.y() += m_baseArraySlice;
3311 fetchPos.z() += m_baseArraySlice;
3313 return fetchSrc.getLevel(m_baseMipLevel).getPixel(fetchPos.x(), fetchPos.y(), fetchPos.z());
3316 class ImageFetchRenderInstance : public SingleCmdRenderInstance
3319 ImageFetchRenderInstance (vkt::Context& context,
3320 bool isPrimaryCmdBuf,
3321 vk::VkDescriptorType descriptorType,
3322 vk::VkShaderStageFlags stageFlags,
3323 ShaderInputInterface shaderInterface,
3324 vk::VkImageViewType viewType,
3325 deUint32 baseMipLevel,
3326 deUint32 baseArraySlice);
3329 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
3330 vk::VkDevice device,
3331 vk::VkDescriptorType descriptorType,
3332 ShaderInputInterface shaderInterface,
3333 vk::VkShaderStageFlags stageFlags);
3335 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
3336 vk::VkDevice device,
3337 vk::VkDescriptorSetLayout descriptorSetLayout);
3339 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
3340 vk::VkDevice device,
3341 vk::VkDescriptorType descriptorType,
3342 ShaderInputInterface shaderInterface);
3344 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
3345 vk::VkDevice device,
3346 vk::VkDescriptorType descriptorType,
3347 ShaderInputInterface shaderInterface,
3348 vk::VkDescriptorSetLayout layout,
3349 vk::VkDescriptorPool pool,
3350 vk::VkImageView viewA,
3351 vk::VkImageView viewB);
3353 void logTestPlan (void) const;
3354 vk::VkPipelineLayout getPipelineLayout (void) const;
3355 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
3356 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
3363 const vk::VkDescriptorType m_descriptorType;
3364 const vk::VkShaderStageFlags m_stageFlags;
3365 const ShaderInputInterface m_shaderInterface;
3366 const vk::VkImageViewType m_viewType;
3367 const deUint32 m_baseMipLevel;
3368 const deUint32 m_baseArraySlice;
3370 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
3371 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
3372 const ImageFetchInstanceImages m_images;
3373 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
3374 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
3377 ImageFetchRenderInstance::ImageFetchRenderInstance (vkt::Context& context,
3378 bool isPrimaryCmdBuf,
3379 vk::VkDescriptorType descriptorType,
3380 vk::VkShaderStageFlags stageFlags,
3381 ShaderInputInterface shaderInterface,
3382 vk::VkImageViewType viewType,
3383 deUint32 baseMipLevel,
3384 deUint32 baseArraySlice)
3385 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
3386 , m_descriptorType (descriptorType)
3387 , m_stageFlags (stageFlags)
3388 , m_shaderInterface (shaderInterface)
3389 , m_viewType (viewType)
3390 , m_baseMipLevel (baseMipLevel)
3391 , m_baseArraySlice (baseArraySlice)
3392 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
3393 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
3394 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3395 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
3396 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_images.getImageViewA(), m_images.getImageViewB()))
3400 vk::Move<vk::VkDescriptorSetLayout> ImageFetchRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
3401 vk::VkDevice device,
3402 vk::VkDescriptorType descriptorType,
3403 ShaderInputInterface shaderInterface,
3404 vk::VkShaderStageFlags stageFlags)
3406 vk::DescriptorSetLayoutBuilder builder;
3408 switch (shaderInterface)
3410 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3411 builder.addSingleBinding(descriptorType, stageFlags);
3414 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3415 builder.addSingleBinding(descriptorType, stageFlags);
3416 builder.addSingleBinding(descriptorType, stageFlags);
3419 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3420 builder.addArrayBinding(descriptorType, 2u, stageFlags);
3424 DE_FATAL("Impossible");
3427 return builder.build(vki, device);
3430 vk::Move<vk::VkPipelineLayout> ImageFetchRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
3431 vk::VkDevice device,
3432 vk::VkDescriptorSetLayout descriptorSetLayout)
3434 const vk::VkPipelineLayoutCreateInfo createInfo =
3436 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
3438 (vk::VkPipelineLayoutCreateFlags)0,
3439 1, // descriptorSetCount
3440 &descriptorSetLayout, // pSetLayouts
3441 0u, // pushConstantRangeCount
3442 DE_NULL, // pPushConstantRanges
3444 return vk::createPipelineLayout(vki, device, &createInfo);
3447 vk::Move<vk::VkDescriptorPool> ImageFetchRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
3448 vk::VkDevice device,
3449 vk::VkDescriptorType descriptorType,
3450 ShaderInputInterface shaderInterface)
3452 return vk::DescriptorPoolBuilder()
3453 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
3454 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3457 vk::Move<vk::VkDescriptorSet> ImageFetchRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
3458 vk::VkDevice device,
3459 vk::VkDescriptorType descriptorType,
3460 ShaderInputInterface shaderInterface,
3461 vk::VkDescriptorSetLayout layout,
3462 vk::VkDescriptorPool pool,
3463 vk::VkImageView viewA,
3464 vk::VkImageView viewB)
3466 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(descriptorType);
3467 const vk::VkDescriptorImageInfo imageInfos[2] =
3469 makeDescriptorImageInfo(viewA, imageLayout),
3470 makeDescriptorImageInfo(viewB, imageLayout),
3472 const vk::VkDescriptorSetAllocateInfo allocInfo =
3474 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3481 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
3482 vk::DescriptorSetUpdateBuilder builder;
3484 switch (shaderInterface)
3486 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3487 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3490 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3491 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &imageInfos[0]);
3492 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &imageInfos[1]);
3495 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3496 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, imageInfos);
3500 DE_FATAL("Impossible");
3503 builder.update(vki, device);
3504 return descriptorSet;
3507 void ImageFetchRenderInstance::logTestPlan (void) const
3509 std::ostringstream msg;
3511 msg << "Rendering 2x2 grid.\n"
3512 << "Single descriptor set. Descriptor set contains "
3513 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3514 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
3515 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3516 (const char*)DE_NULL)
3517 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3518 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3521 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3522 if (m_baseArraySlice)
3523 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3525 if (m_stageFlags == 0u)
3527 msg << "Descriptors are not accessed in any shader stage.\n";
3531 msg << "Color in each cell is fetched using the descriptor(s):\n";
3533 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3535 msg << "Test sample " << resultNdx << ": fetching at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3537 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3539 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3540 msg << " from descriptor " << srcResourceNdx;
3546 msg << "Descriptors are accessed in {"
3547 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
3548 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
3549 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
3550 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
3551 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
3555 m_context.getTestContext().getLog()
3556 << tcu::TestLog::Message
3558 << tcu::TestLog::EndMessage;
3561 vk::VkPipelineLayout ImageFetchRenderInstance::getPipelineLayout (void) const
3563 return *m_pipelineLayout;
3566 void ImageFetchRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
3568 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
3569 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
3572 tcu::TestStatus ImageFetchRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
3574 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
3575 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
3576 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
3577 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(0));
3578 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchImageValue(1));
3579 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchImageValue(2));
3580 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchImageValue(3));
3581 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
3583 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
3585 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
3586 return tcu::TestStatus::fail("Image verification failed");
3588 return tcu::TestStatus::pass("Pass");
3591 class ImageFetchComputeInstance : public vkt::TestInstance
3594 ImageFetchComputeInstance (vkt::Context& context,
3595 vk::VkDescriptorType descriptorType,
3596 ShaderInputInterface shaderInterface,
3597 vk::VkImageViewType viewType,
3598 deUint32 baseMipLevel,
3599 deUint32 baseArraySlice);
3602 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
3603 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
3604 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
3606 tcu::TestStatus iterate (void);
3607 void logTestPlan (void) const;
3608 tcu::TestStatus testResourceAccess (void);
3610 const vk::VkDescriptorType m_descriptorType;
3611 const ShaderInputInterface m_shaderInterface;
3612 const vk::VkImageViewType m_viewType;
3613 const deUint32 m_baseMipLevel;
3614 const deUint32 m_baseArraySlice;
3616 const vk::DeviceInterface& m_vki;
3617 const vk::VkDevice m_device;
3618 const vk::VkQueue m_queue;
3619 const deUint32 m_queueFamilyIndex;
3620 vk::Allocator& m_allocator;
3622 const ComputeInstanceResultBuffer m_result;
3623 const ImageFetchInstanceImages m_images;
3626 ImageFetchComputeInstance::ImageFetchComputeInstance (Context& context,
3627 vk::VkDescriptorType descriptorType,
3628 ShaderInputInterface shaderInterface,
3629 vk::VkImageViewType viewType,
3630 deUint32 baseMipLevel,
3631 deUint32 baseArraySlice)
3632 : vkt::TestInstance (context)
3633 , m_descriptorType (descriptorType)
3634 , m_shaderInterface (shaderInterface)
3635 , m_viewType (viewType)
3636 , m_baseMipLevel (baseMipLevel)
3637 , m_baseArraySlice (baseArraySlice)
3638 , m_vki (context.getDeviceInterface())
3639 , m_device (context.getDevice())
3640 , m_queue (context.getUniversalQueue())
3641 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
3642 , m_allocator (context.getDefaultAllocator())
3643 , m_result (m_vki, m_device, m_allocator)
3644 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice)
3648 vk::Move<vk::VkDescriptorSetLayout> ImageFetchComputeInstance::createDescriptorSetLayout (void) const
3650 vk::DescriptorSetLayoutBuilder builder;
3652 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3654 switch (m_shaderInterface)
3656 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3657 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3660 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3661 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3662 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3665 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3666 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
3670 DE_FATAL("Impossible");
3673 return builder.build(m_vki, m_device);
3676 vk::Move<vk::VkDescriptorPool> ImageFetchComputeInstance::createDescriptorPool (void) const
3678 return vk::DescriptorPoolBuilder()
3679 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
3680 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
3681 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
3684 vk::Move<vk::VkDescriptorSet> ImageFetchComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
3686 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
3687 const vk::VkImageLayout imageLayout = getImageLayoutForDescriptorType(m_descriptorType);
3688 const vk::VkDescriptorImageInfo imageInfos[2] =
3690 makeDescriptorImageInfo(m_images.getImageViewA(), imageLayout),
3691 makeDescriptorImageInfo(m_images.getImageViewB(), imageLayout),
3693 const vk::VkDescriptorSetAllocateInfo allocInfo =
3695 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
3702 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
3703 vk::DescriptorSetUpdateBuilder builder;
3706 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
3709 switch (m_shaderInterface)
3711 case SHADER_INPUT_SINGLE_DESCRIPTOR:
3712 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3715 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
3716 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &imageInfos[0]);
3717 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &imageInfos[1]);
3720 case SHADER_INPUT_DESCRIPTOR_ARRAY:
3721 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, imageInfos);
3725 DE_FATAL("Impossible");
3728 builder.update(m_vki, m_device);
3729 return descriptorSet;
3732 tcu::TestStatus ImageFetchComputeInstance::iterate (void)
3735 return testResourceAccess();
3738 void ImageFetchComputeInstance::logTestPlan (void) const
3740 std::ostringstream msg;
3742 msg << "Fetching 4 values from image in compute shader.\n"
3743 << "Single descriptor set. Descriptor set contains "
3744 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
3745 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
3746 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
3747 (const char*)DE_NULL)
3748 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
3749 << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
3752 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
3753 if (m_baseArraySlice)
3754 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
3756 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3758 msg << "Test sample " << resultNdx << ": fetch at position " << m_images.getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
3760 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
3762 const int srcResourceNdx = (resultNdx % 2); // ABAB source
3763 msg << " from descriptor " << srcResourceNdx;
3769 m_context.getTestContext().getLog()
3770 << tcu::TestLog::Message
3772 << tcu::TestLog::EndMessage;
3775 tcu::TestStatus ImageFetchComputeInstance::testResourceAccess (void)
3777 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
3778 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
3779 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
3780 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
3782 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
3783 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
3784 const deUint32* const dynamicOffsets = DE_NULL;
3785 const int numDynamicOffsets = 0;
3786 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
3787 const int numPreBarriers = 0;
3788 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
3789 const int numPostBarriers = 1;
3791 const ComputeCommand compute (m_vki,
3793 pipeline.getPipeline(),
3794 pipeline.getPipelineLayout(),
3795 tcu::UVec3(4, 1, 1),
3796 numDescriptorSets, descriptorSets,
3797 numDynamicOffsets, dynamicOffsets,
3798 numPreBarriers, preBarriers,
3799 numPostBarriers, postBarriers);
3801 tcu::Vec4 results[4];
3802 bool anyResultSet = false;
3803 bool allResultsOk = true;
3805 compute.submitAndWait(m_queueFamilyIndex, m_queue);
3806 m_result.readResultContentsTo(&results);
3809 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
3811 const tcu::Vec4 result = results[resultNdx];
3812 const tcu::Vec4 reference = m_images.fetchImageValue(resultNdx);
3813 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
3815 if (result != tcu::Vec4(-1.0f))
3816 anyResultSet = true;
3818 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
3820 allResultsOk = false;
3822 m_context.getTestContext().getLog()
3823 << tcu::TestLog::Message
3824 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
3825 << tcu::TestLog::EndMessage;
3829 // read back and verify
3831 return tcu::TestStatus::pass("Pass");
3832 else if (anyResultSet)
3833 return tcu::TestStatus::fail("Invalid result values");
3836 m_context.getTestContext().getLog()
3837 << tcu::TestLog::Message
3838 << "Result buffer was not written to."
3839 << tcu::TestLog::EndMessage;
3840 return tcu::TestStatus::fail("Result buffer was not written to");
3844 class ImageSampleInstanceImages : private ImageInstanceImages
3847 ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3848 vk::VkDevice device,
3849 deUint32 queueFamilyIndex,
3851 vk::Allocator& allocator,
3852 vk::VkDescriptorType descriptorType,
3853 ShaderInputInterface shaderInterface,
3854 vk::VkImageViewType viewType,
3855 deUint32 baseMipLevel,
3856 deUint32 baseArraySlice,
3859 static tcu::Vec4 getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx);
3860 tcu::Vec4 fetchSampleValue (int samplePosNdx) const;
3862 inline vk::VkImageView getImageViewA (void) const { return *m_imageViewA; }
3863 inline vk::VkImageView getImageViewB (void) const { return *m_imageViewB; }
3864 inline vk::VkSampler getSamplerA (void) const { return *m_samplerA; }
3865 inline vk::VkSampler getSamplerB (void) const { return *m_samplerB; }
3866 inline bool isImmutable (void) const { return m_isImmutable; }
3869 static int getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface);
3870 static tcu::Sampler createRefSampler (bool isFirst);
3871 static vk::Move<vk::VkSampler> createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format);
3873 static tcu::Texture1DArrayView getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3874 static tcu::Texture2DArrayView getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3875 static tcu::Texture3DView getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3876 static tcu::TextureCubeArrayView getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage);
3878 const vk::VkDescriptorType m_descriptorType;
3879 const ShaderInputInterface m_shaderInterface;
3880 const bool m_isImmutable;
3882 const tcu::Sampler m_refSamplerA;
3883 const tcu::Sampler m_refSamplerB;
3884 const vk::Unique<vk::VkSampler> m_samplerA;
3885 const vk::Unique<vk::VkSampler> m_samplerB;
3888 ImageSampleInstanceImages::ImageSampleInstanceImages (const vk::DeviceInterface& vki,
3889 vk::VkDevice device,
3890 deUint32 queueFamilyIndex,
3892 vk::Allocator& allocator,
3893 vk::VkDescriptorType descriptorType,
3894 ShaderInputInterface shaderInterface,
3895 vk::VkImageViewType viewType,
3896 deUint32 baseMipLevel,
3897 deUint32 baseArraySlice,
3899 : ImageInstanceImages (vki,
3906 getNumImages(descriptorType, shaderInterface),
3909 , m_descriptorType (descriptorType)
3910 , m_shaderInterface (shaderInterface)
3911 , m_isImmutable (immutable)
3912 , m_refSamplerA (createRefSampler(true))
3913 , m_refSamplerB (createRefSampler(false))
3914 , m_samplerA (createSampler(vki, device, m_refSamplerA, m_imageFormat))
3915 , m_samplerB ((getInterfaceNumResources(m_shaderInterface) == 1u)
3916 ? vk::Move<vk::VkSampler>()
3917 : createSampler(vki, device, m_refSamplerB, m_imageFormat))
3921 tcu::Vec4 ImageSampleInstanceImages::getSamplePos (vk::VkImageViewType viewType, deUint32 baseMipLevel, deUint32 baseArraySlice, int samplePosNdx)
3923 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
3925 const deUint32 imageSize = (deUint32)IMAGE_SIZE >> baseMipLevel;
3926 const deUint32 arraySize = isImageViewTypeArray(viewType) ? ARRAY_SIZE - baseArraySlice : 1;
3928 // choose arbitrary values that are not ambiguous with NEAREST filtering
3932 case vk::VK_IMAGE_VIEW_TYPE_1D:
3933 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY:
3934 case vk::VK_IMAGE_VIEW_TYPE_2D:
3935 case vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY:
3936 case vk::VK_IMAGE_VIEW_TYPE_3D:
3938 const tcu::Vec3 coords[4] =
3942 (float)(12u % imageSize) + 0.25f),
3944 tcu::Vec3((float)(23u % imageSize) + 0.25f,
3945 (float)(73u % imageSize) + 0.5f,
3946 (float)(16u % imageSize) + 0.5f + (float)imageSize),
3948 tcu::Vec3(-(float)(43u % imageSize) + 0.25f,
3949 (float)(84u % imageSize) + 0.5f + (float)imageSize,
3950 (float)(117u % imageSize) + 0.75f),
3952 tcu::Vec3((float)imageSize + 0.5f,
3953 (float)(75u % imageSize) + 0.25f,
3954 (float)(83u % imageSize) + 0.25f + (float)imageSize),
3956 const deUint32 slices[4] =
3964 if (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY)
3965 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3966 (float)slices[samplePosNdx],
3969 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_2D || viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY)
3970 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3971 coords[samplePosNdx].y() / (float)imageSize,
3972 (float)slices[samplePosNdx],
3974 else if (viewType == vk::VK_IMAGE_VIEW_TYPE_3D)
3975 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize,
3976 coords[samplePosNdx].y() / (float)imageSize,
3977 coords[samplePosNdx].z() / (float)imageSize,
3981 DE_FATAL("Impossible");
3986 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
3987 case vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
3989 // \note these values are in [0, texSize]*3 space for convenience
3990 const tcu::Vec3 coords[4] =
3996 tcu::Vec3((float)(13u % imageSize) + 0.25f,
3998 (float)(16u % imageSize) + 0.5f),
4001 (float)(84u % imageSize) + 0.5f,
4002 (float)(10u % imageSize) + 0.75f),
4004 tcu::Vec3((float)imageSize,
4005 (float)(75u % imageSize) + 0.25f,
4006 (float)(83u % imageSize) + 0.75f),
4008 const deUint32 slices[4] =
4016 DE_ASSERT(de::inRange(coords[samplePosNdx].x(), 0.0f, (float)imageSize));
4017 DE_ASSERT(de::inRange(coords[samplePosNdx].y(), 0.0f, (float)imageSize));
4018 DE_ASSERT(de::inRange(coords[samplePosNdx].z(), 0.0f, (float)imageSize));
4020 // map to [-1, 1]*3 space
4021 return tcu::Vec4(coords[samplePosNdx].x() / (float)imageSize * 2.0f - 1.0f,
4022 coords[samplePosNdx].y() / (float)imageSize * 2.0f - 1.0f,
4023 coords[samplePosNdx].z() / (float)imageSize * 2.0f - 1.0f,
4024 (float)slices[samplePosNdx]);
4028 DE_FATAL("Impossible");
4033 tcu::Vec4 ImageSampleInstanceImages::fetchSampleValue (int samplePosNdx) const
4035 DE_ASSERT(de::inBounds(samplePosNdx, 0, 4));
4037 // texture order is ABAB
4038 const bool isSamplerCase = (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
4039 const tcu::TextureLevelPyramid& sampleSrcA = m_sourceImageA;
4040 const tcu::TextureLevelPyramid& sampleSrcB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_sourceImageA) : (m_sourceImageB);
4041 const tcu::TextureLevelPyramid& sampleSrc = (isSamplerCase) ? (sampleSrcA) : ((samplePosNdx % 2) == 0) ? (sampleSrcA) : (sampleSrcB);
4043 // sampler order is ABAB
4044 const tcu::Sampler& samplerA = m_refSamplerA;
4045 const tcu::Sampler& samplerB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? (m_refSamplerA) : (m_refSamplerB);
4046 const tcu::Sampler& sampler = ((samplePosNdx % 2) == 0) ? (samplerA) : (samplerB);
4048 const tcu::Vec4 samplePos = getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
4049 const float lod = 0.0f;
4050 std::vector<tcu::ConstPixelBufferAccess> levelStorage;
4054 case vk::VK_IMAGE_VIEW_TYPE_1D:
4055 case vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY: return getRef1DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), lod);
4056 case vk::VK_IMAGE_VIEW_TYPE_2D:
4057 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);
4058 case vk::VK_IMAGE_VIEW_TYPE_3D: return getRef3DView(sampleSrc, m_baseMipLevel, m_baseArraySlice, &levelStorage).sample(sampler, samplePos.x(), samplePos.y(), samplePos.z(), lod);
4059 case vk::VK_IMAGE_VIEW_TYPE_CUBE:
4060 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);
4064 DE_FATAL("Impossible");
4070 int ImageSampleInstanceImages::getNumImages (vk::VkDescriptorType descriptorType, ShaderInputInterface shaderInterface)
4072 // If we are testing separate samplers, just one image is enough
4073 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4075 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4077 // combined: numImages == numSamplers
4078 return getInterfaceNumResources(shaderInterface);
4082 DE_FATAL("Impossible");
4087 tcu::Sampler ImageSampleInstanceImages::createRefSampler (bool isFirst)
4092 return tcu::Sampler(tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::REPEAT_GL, tcu::Sampler::LINEAR, tcu::Sampler::LINEAR);
4096 // nearest, clamping
4097 return tcu::Sampler(tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::CLAMP_TO_EDGE, tcu::Sampler::NEAREST, tcu::Sampler::NEAREST);
4101 vk::Move<vk::VkSampler> ImageSampleInstanceImages::createSampler (const vk::DeviceInterface& vki, vk::VkDevice device, const tcu::Sampler& sampler, const tcu::TextureFormat& format)
4103 const vk::VkSamplerCreateInfo createInfo = vk::mapSampler(sampler, format);
4105 return vk::createSampler(vki, device, &createInfo);
4108 tcu::Texture1DArrayView ImageSampleInstanceImages::getRef1DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4110 DE_ASSERT(levelStorage->empty());
4112 const deUint32 numSlices = (deUint32)source.getLevel(0).getHeight();
4113 const deUint32 numLevels = (deUint32)source.getNumLevels();
4115 // cut pyramid from baseMipLevel
4116 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4118 // cut levels from baseArraySlice
4119 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4120 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, baseArraySlice, wholeLevel.getWidth(), numSlices - baseArraySlice);
4121 levelStorage->push_back(cutLevel);
4124 return tcu::Texture1DArrayView((int)levelStorage->size(), &levelStorage->front());
4127 tcu::Texture2DArrayView ImageSampleInstanceImages::getRef2DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4129 DE_ASSERT(levelStorage->empty());
4131 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth();
4132 const deUint32 numLevels = (deUint32)source.getNumLevels();
4134 // cut pyramid from baseMipLevel
4135 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4137 // cut levels from baseArraySlice
4138 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4139 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice, wholeLevel.getWidth(), wholeLevel.getHeight(), numSlices - baseArraySlice);
4140 levelStorage->push_back(cutLevel);
4143 return tcu::Texture2DArrayView((int)levelStorage->size(), &levelStorage->front());
4146 tcu::Texture3DView ImageSampleInstanceImages::getRef3DView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4148 DE_ASSERT(levelStorage->empty());
4149 DE_ASSERT(baseArraySlice == 0);
4150 DE_UNREF(baseArraySlice);
4152 const deUint32 numLevels = (deUint32)source.getNumLevels();
4154 // cut pyramid from baseMipLevel
4155 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4156 levelStorage->push_back(source.getLevel(level));
4158 return tcu::Texture3DView((int)levelStorage->size(), &levelStorage->front());
4161 tcu::TextureCubeArrayView ImageSampleInstanceImages::getRefCubeView (const tcu::TextureLevelPyramid& source, deUint32 baseMipLevel, deUint32 baseArraySlice, std::vector<tcu::ConstPixelBufferAccess>* levelStorage)
4163 DE_ASSERT(levelStorage->empty());
4165 const deUint32 numSlices = (deUint32)source.getLevel(0).getDepth() / 6;
4166 const deUint32 numLevels = (deUint32)source.getNumLevels();
4168 // cut pyramid from baseMipLevel
4169 for (deUint32 level = baseMipLevel; level < numLevels; ++level)
4171 // cut levels from baseArraySlice
4172 const tcu::ConstPixelBufferAccess wholeLevel = source.getLevel(level);
4173 const tcu::ConstPixelBufferAccess cutLevel = tcu::getSubregion(wholeLevel, 0, 0, baseArraySlice * 6, wholeLevel.getWidth(), wholeLevel.getHeight(), (numSlices - baseArraySlice) * 6);
4174 levelStorage->push_back(cutLevel);
4177 return tcu::TextureCubeArrayView((int)levelStorage->size(), &levelStorage->front());
4180 class ImageSampleRenderInstance : public SingleCmdRenderInstance
4183 ImageSampleRenderInstance (vkt::Context& context,
4184 bool isPrimaryCmdBuf,
4185 vk::VkDescriptorType descriptorType,
4186 vk::VkShaderStageFlags stageFlags,
4187 ShaderInputInterface shaderInterface,
4188 vk::VkImageViewType viewType,
4189 deUint32 baseMipLevel,
4190 deUint32 baseArraySlice,
4194 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
4195 vk::VkDevice device,
4196 vk::VkDescriptorType descriptorType,
4197 ShaderInputInterface shaderInterface,
4198 vk::VkShaderStageFlags stageFlags,
4199 const ImageSampleInstanceImages& images);
4201 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
4202 vk::VkDevice device,
4203 vk::VkDescriptorSetLayout descriptorSetLayout);
4205 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
4206 vk::VkDevice device,
4207 vk::VkDescriptorType descriptorType,
4208 ShaderInputInterface shaderInterface);
4210 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
4211 vk::VkDevice device,
4212 vk::VkDescriptorType descriptorType,
4213 ShaderInputInterface shaderInterface,
4214 vk::VkDescriptorSetLayout layout,
4215 vk::VkDescriptorPool pool,
4217 const ImageSampleInstanceImages& images);
4219 static void writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4220 vk::VkDevice device,
4221 ShaderInputInterface shaderInterface,
4223 const ImageSampleInstanceImages& images,
4224 vk::VkDescriptorSet descriptorSet);
4226 static void writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4227 vk::VkDevice device,
4228 ShaderInputInterface shaderInterface,
4230 const ImageSampleInstanceImages& images,
4231 vk::VkDescriptorSet descriptorSet);
4233 void logTestPlan (void) const;
4234 vk::VkPipelineLayout getPipelineLayout (void) const;
4235 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
4236 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
4243 const vk::VkDescriptorType m_descriptorType;
4244 const vk::VkShaderStageFlags m_stageFlags;
4245 const ShaderInputInterface m_shaderInterface;
4246 const vk::VkImageViewType m_viewType;
4247 const deUint32 m_baseMipLevel;
4248 const deUint32 m_baseArraySlice;
4250 const ImageSampleInstanceImages m_images;
4251 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
4252 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
4253 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
4254 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
4257 ImageSampleRenderInstance::ImageSampleRenderInstance (vkt::Context& context,
4258 bool isPrimaryCmdBuf,
4259 vk::VkDescriptorType descriptorType,
4260 vk::VkShaderStageFlags stageFlags,
4261 ShaderInputInterface shaderInterface,
4262 vk::VkImageViewType viewType,
4263 deUint32 baseMipLevel,
4264 deUint32 baseArraySlice,
4266 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
4267 , m_descriptorType (descriptorType)
4268 , m_stageFlags (stageFlags)
4269 , m_shaderInterface (shaderInterface)
4270 , m_viewType (viewType)
4271 , m_baseMipLevel (baseMipLevel)
4272 , m_baseArraySlice (baseArraySlice)
4273 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutable)
4274 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags, m_images))
4275 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
4276 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
4277 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, isImmutable, m_images))
4281 vk::Move<vk::VkDescriptorSetLayout> ImageSampleRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
4282 vk::VkDevice device,
4283 vk::VkDescriptorType descriptorType,
4284 ShaderInputInterface shaderInterface,
4285 vk::VkShaderStageFlags stageFlags,
4286 const ImageSampleInstanceImages& images)
4288 const vk::VkSampler samplers[2] =
4290 images.getSamplerA(),
4291 images.getSamplerB(),
4294 vk::DescriptorSetLayoutBuilder builder;
4295 const bool addSeparateImage = descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER;
4297 // (combined)samplers follow
4298 switch (shaderInterface)
4300 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4301 if (addSeparateImage)
4302 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4303 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4306 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4307 if (addSeparateImage)
4308 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4309 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4310 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4313 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4314 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4315 if (addSeparateImage)
4316 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4317 builder.addSingleSamplerBinding(descriptorType, stageFlags, (images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4320 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4321 if (addSeparateImage)
4322 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, stageFlags);
4323 builder.addArraySamplerBinding(descriptorType, 2u, stageFlags, (images.isImmutable()) ? (samplers) : (DE_NULL));
4327 DE_FATAL("Impossible");
4330 return builder.build(vki, device);
4333 vk::Move<vk::VkPipelineLayout> ImageSampleRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
4334 vk::VkDevice device,
4335 vk::VkDescriptorSetLayout descriptorSetLayout)
4337 const vk::VkPipelineLayoutCreateInfo createInfo =
4339 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
4341 (vk::VkPipelineLayoutCreateFlags)0,
4342 1, // descriptorSetCount
4343 &descriptorSetLayout, // pSetLayouts
4344 0u, // pushConstantRangeCount
4345 DE_NULL, // pPushConstantRanges
4347 return vk::createPipelineLayout(vki, device, &createInfo);
4350 vk::Move<vk::VkDescriptorPool> ImageSampleRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
4351 vk::VkDevice device,
4352 vk::VkDescriptorType descriptorType,
4353 ShaderInputInterface shaderInterface)
4355 vk::DescriptorPoolBuilder builder;
4357 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4359 // separate samplers need image to sample
4360 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4362 // also need sample to use, indifferent of whether immutable or not
4363 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLER, getInterfaceNumResources(shaderInterface));
4365 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4367 // combined image samplers
4368 builder.addType(vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, getInterfaceNumResources(shaderInterface));
4371 DE_FATAL("Impossible");
4373 return builder.build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4376 vk::Move<vk::VkDescriptorSet> ImageSampleRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
4377 vk::VkDevice device,
4378 vk::VkDescriptorType descriptorType,
4379 ShaderInputInterface shaderInterface,
4380 vk::VkDescriptorSetLayout layout,
4381 vk::VkDescriptorPool pool,
4383 const ImageSampleInstanceImages& images)
4385 const vk::VkDescriptorSetAllocateInfo allocInfo =
4387 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4394 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
4396 if (descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4397 writeSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4398 else if (descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4399 writeImageSamplerDescriptorSet(vki, device, shaderInterface, isImmutable, images, *descriptorSet);
4401 DE_FATAL("Impossible");
4403 return descriptorSet;
4406 void ImageSampleRenderInstance::writeSamplerDescriptorSet (const vk::DeviceInterface& vki,
4407 vk::VkDevice device,
4408 ShaderInputInterface shaderInterface,
4410 const ImageSampleInstanceImages& images,
4411 vk::VkDescriptorSet descriptorSet)
4413 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4414 const vk::VkDescriptorImageInfo samplersInfos[2] =
4416 makeDescriptorImageInfo(images.getSamplerA()),
4417 makeDescriptorImageInfo(images.getSamplerB()),
4420 vk::DescriptorSetUpdateBuilder builder;
4421 const deUint32 samplerLocation = shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS ? 1u : 0u;
4423 // stand alone texture
4424 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(samplerLocation), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4429 switch (shaderInterface)
4431 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4432 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4435 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4436 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4437 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4440 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
4441 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4442 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4445 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4446 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4450 DE_FATAL("Impossible");
4454 builder.update(vki, device);
4457 void ImageSampleRenderInstance::writeImageSamplerDescriptorSet (const vk::DeviceInterface& vki,
4458 vk::VkDevice device,
4459 ShaderInputInterface shaderInterface,
4461 const ImageSampleInstanceImages& images,
4462 vk::VkDescriptorSet descriptorSet)
4464 const vk::VkSampler samplers[2] =
4466 (isImmutable) ? (0) : (images.getSamplerA()),
4467 (isImmutable) ? (0) : (images.getSamplerB()),
4469 const vk::VkDescriptorImageInfo imageSamplers[2] =
4471 vk::makeDescriptorImageInfo(samplers[0], images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4472 vk::makeDescriptorImageInfo(samplers[1], images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4475 vk::DescriptorSetUpdateBuilder builder;
4477 // combined image samplers
4478 switch (shaderInterface)
4480 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4481 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4484 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4485 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4486 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4489 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4490 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4494 DE_FATAL("Impossible");
4497 builder.update(vki, device);
4500 void ImageSampleRenderInstance::logTestPlan (void) const
4502 std::ostringstream msg;
4504 msg << "Rendering 2x2 grid.\n";
4506 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4508 msg << "Single descriptor set. Descriptor set contains "
4509 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4510 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4511 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
4512 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4513 (const char*)DE_NULL)
4514 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4516 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4518 msg << "Single descriptor set. Descriptor set contains "
4519 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4520 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4521 (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? "two" :
4522 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4523 (const char*)DE_NULL)
4524 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4527 DE_FATAL("Impossible");
4529 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4532 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4533 if (m_baseArraySlice)
4534 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4536 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4537 msg << "Sampler mode is LINEAR, with WRAP\n";
4539 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4541 if (m_stageFlags == 0u)
4543 msg << "Descriptors are not accessed in any shader stage.\n";
4547 msg << "Color in each cell is fetched using the descriptor(s):\n";
4549 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4551 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4553 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4555 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4557 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4558 msg << " using sampler " << srcResourceNdx;
4559 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4560 msg << " from combined image sampler " << srcResourceNdx;
4562 DE_FATAL("Impossible");
4567 msg << "Descriptors are accessed in {"
4568 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
4569 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
4570 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
4571 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
4572 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
4576 m_context.getTestContext().getLog()
4577 << tcu::TestLog::Message
4579 << tcu::TestLog::EndMessage;
4582 vk::VkPipelineLayout ImageSampleRenderInstance::getPipelineLayout (void) const
4584 return *m_pipelineLayout;
4587 void ImageSampleRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
4589 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0u, 1u, &m_descriptorSet.get(), 0u, DE_NULL);
4590 m_vki.cmdDraw(cmd, 6u * 4u, 1u, 0u, 0u); // render four quads (two separate triangles)
4593 tcu::TestStatus ImageSampleRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
4595 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
4596 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
4597 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
4598 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(0));
4599 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_images.fetchSampleValue(1));
4600 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_images.fetchSampleValue(2));
4601 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_images.fetchSampleValue(3));
4602 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
4603 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
4605 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
4607 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, threshold, tcu::COMPARE_LOG_RESULT))
4608 return tcu::TestStatus::fail("Image verification failed");
4610 return tcu::TestStatus::pass("Pass");
4613 class ImageSampleComputeInstance : public vkt::TestInstance
4616 ImageSampleComputeInstance (vkt::Context& context,
4617 vk::VkDescriptorType descriptorType,
4618 ShaderInputInterface shaderInterface,
4619 vk::VkImageViewType viewType,
4620 deUint32 baseMipLevel,
4621 deUint32 baseArraySlice,
4622 bool isImmutableSampler);
4625 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
4626 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
4627 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
4628 void writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4629 void writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const;
4631 tcu::TestStatus iterate (void);
4632 void logTestPlan (void) const;
4633 tcu::TestStatus testResourceAccess (void);
4635 const vk::VkDescriptorType m_descriptorType;
4636 const ShaderInputInterface m_shaderInterface;
4637 const vk::VkImageViewType m_viewType;
4638 const deUint32 m_baseMipLevel;
4639 const deUint32 m_baseArraySlice;
4640 const bool m_isImmutableSampler;
4642 const vk::DeviceInterface& m_vki;
4643 const vk::VkDevice m_device;
4644 const vk::VkQueue m_queue;
4645 const deUint32 m_queueFamilyIndex;
4646 vk::Allocator& m_allocator;
4648 const ComputeInstanceResultBuffer m_result;
4649 const ImageSampleInstanceImages m_images;
4652 ImageSampleComputeInstance::ImageSampleComputeInstance (Context& context,
4653 vk::VkDescriptorType descriptorType,
4654 ShaderInputInterface shaderInterface,
4655 vk::VkImageViewType viewType,
4656 deUint32 baseMipLevel,
4657 deUint32 baseArraySlice,
4658 bool isImmutableSampler)
4659 : vkt::TestInstance (context)
4660 , m_descriptorType (descriptorType)
4661 , m_shaderInterface (shaderInterface)
4662 , m_viewType (viewType)
4663 , m_baseMipLevel (baseMipLevel)
4664 , m_baseArraySlice (baseArraySlice)
4665 , m_isImmutableSampler (isImmutableSampler)
4666 , m_vki (context.getDeviceInterface())
4667 , m_device (context.getDevice())
4668 , m_queue (context.getUniversalQueue())
4669 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
4670 , m_allocator (context.getDefaultAllocator())
4671 , m_result (m_vki, m_device, m_allocator)
4672 , m_images (m_vki, m_device, m_queueFamilyIndex, m_queue, m_allocator, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, isImmutableSampler)
4676 vk::Move<vk::VkDescriptorSetLayout> ImageSampleComputeInstance::createDescriptorSetLayout (void) const
4678 const vk::VkSampler samplers[2] =
4680 m_images.getSamplerA(),
4681 m_images.getSamplerB(),
4684 vk::DescriptorSetLayoutBuilder builder;
4687 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4689 // with samplers, separate texture at binding 0
4690 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4691 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, vk::VK_SHADER_STAGE_COMPUTE_BIT);
4693 // (combined)samplers follow
4694 switch (m_shaderInterface)
4696 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4697 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4700 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4701 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[0]) : (DE_NULL));
4702 builder.addSingleSamplerBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (&samplers[1]) : (DE_NULL));
4705 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4706 builder.addArraySamplerBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT, (m_images.isImmutable()) ? (samplers) : (DE_NULL));
4710 DE_FATAL("Impossible");
4713 return builder.build(m_vki, m_device);
4716 vk::Move<vk::VkDescriptorPool> ImageSampleComputeInstance::createDescriptorPool (void) const
4718 vk::DescriptorPoolBuilder builder;
4720 builder.addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER);
4721 builder.addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface));
4723 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4724 builder.addType(vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
4726 return builder.build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
4729 vk::Move<vk::VkDescriptorSet> ImageSampleComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
4731 const vk::VkDescriptorSetAllocateInfo allocInfo =
4733 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
4740 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
4742 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4743 writeSamplerDescriptorSet(*descriptorSet);
4744 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4745 writeImageSamplerDescriptorSet(*descriptorSet);
4747 DE_FATAL("Impossible");
4749 return descriptorSet;
4752 void ImageSampleComputeInstance::writeSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4754 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4755 const vk::VkDescriptorImageInfo imageInfo = makeDescriptorImageInfo(m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
4756 const vk::VkDescriptorImageInfo samplersInfos[2] =
4758 makeDescriptorImageInfo(m_images.getSamplerA()),
4759 makeDescriptorImageInfo(m_images.getSamplerB()),
4762 vk::DescriptorSetUpdateBuilder builder;
4765 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4767 // stand alone texture
4768 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, &imageInfo);
4771 if (!m_isImmutableSampler)
4773 switch (m_shaderInterface)
4775 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4776 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4779 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4780 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[0]);
4781 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(3u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, &samplersInfos[1]);
4784 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4785 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_SAMPLER, 2u, samplersInfos);
4789 DE_FATAL("Impossible");
4793 builder.update(m_vki, m_device);
4796 void ImageSampleComputeInstance::writeImageSamplerDescriptorSet (vk::VkDescriptorSet descriptorSet) const
4798 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
4799 const vk::VkSampler samplers[2] =
4801 (m_isImmutableSampler) ? (0) : (m_images.getSamplerA()),
4802 (m_isImmutableSampler) ? (0) : (m_images.getSamplerB()),
4804 const vk::VkDescriptorImageInfo imageSamplers[2] =
4806 makeDescriptorImageInfo(samplers[0], m_images.getImageViewA(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4807 makeDescriptorImageInfo(samplers[1], m_images.getImageViewB(), vk::VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL),
4810 vk::DescriptorSetUpdateBuilder builder;
4813 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
4815 // combined image samplers
4816 switch (m_shaderInterface)
4818 case SHADER_INPUT_SINGLE_DESCRIPTOR:
4819 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4822 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
4823 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[0]);
4824 builder.writeSingle(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &imageSamplers[1]);
4827 case SHADER_INPUT_DESCRIPTOR_ARRAY:
4828 builder.writeArray(descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u, imageSamplers);
4832 DE_FATAL("Impossible");
4835 builder.update(m_vki, m_device);
4838 tcu::TestStatus ImageSampleComputeInstance::iterate (void)
4841 return testResourceAccess();
4844 void ImageSampleComputeInstance::logTestPlan (void) const
4846 std::ostringstream msg;
4848 msg << "Accessing resource in a compute program.\n";
4850 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4852 msg << "Single descriptor set. Descriptor set contains "
4853 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4854 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4855 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4856 (const char*)DE_NULL)
4857 << " VK_DESCRIPTOR_TYPE_SAMPLER descriptor(s) and a single texture.\n";
4859 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4861 msg << "Single descriptor set. Descriptor set contains "
4862 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
4863 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
4864 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
4865 (const char*)DE_NULL)
4866 << " VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER descriptor(s).\n";
4869 DE_FATAL("Impossible");
4871 msg << "Image view type is " << vk::getImageViewTypeName(m_viewType) << "\n";
4874 msg << "Image view base mip level = " << m_baseMipLevel << "\n";
4875 if (m_baseArraySlice)
4876 msg << "Image view base array slice = " << m_baseArraySlice << "\n";
4878 if (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR)
4879 msg << "Sampler mode is LINEAR, with WRAP\n";
4881 msg << "Sampler 0 mode is LINEAR, with WRAP\nSampler 1 mode is NEAREST with CLAMP\n";
4883 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4885 msg << "Test sample " << resultNdx << ": sample at position " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx);
4887 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
4889 const int srcResourceNdx = (resultNdx % 2); // ABAB source
4891 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
4892 msg << " using sampler " << srcResourceNdx;
4893 else if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER)
4894 msg << " from combined image sampler " << srcResourceNdx;
4896 DE_FATAL("Impossible");
4901 m_context.getTestContext().getLog()
4902 << tcu::TestLog::Message
4904 << tcu::TestLog::EndMessage;
4907 tcu::TestStatus ImageSampleComputeInstance::testResourceAccess (void)
4909 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
4910 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
4911 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
4912 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
4914 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
4915 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
4916 const deUint32* const dynamicOffsets = DE_NULL;
4917 const int numDynamicOffsets = 0;
4918 const vk::VkBufferMemoryBarrier* const preBarriers = DE_NULL;
4919 const int numPreBarriers = 0;
4920 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
4921 const int numPostBarriers = 1;
4923 const ComputeCommand compute (m_vki,
4925 pipeline.getPipeline(),
4926 pipeline.getPipelineLayout(),
4927 tcu::UVec3(4, 1, 1),
4928 numDescriptorSets, descriptorSets,
4929 numDynamicOffsets, dynamicOffsets,
4930 numPreBarriers, preBarriers,
4931 numPostBarriers, postBarriers);
4933 tcu::Vec4 results[4];
4934 bool anyResultSet = false;
4935 bool allResultsOk = true;
4937 compute.submitAndWait(m_queueFamilyIndex, m_queue);
4938 m_result.readResultContentsTo(&results);
4941 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
4943 const tcu::Vec4 result = results[resultNdx];
4944 const tcu::Vec4 reference = m_images.fetchSampleValue(resultNdx);
4946 // source image is high-frequency so the threshold is quite large to tolerate sampling errors
4947 const tcu::Vec4 samplingThreshold = tcu::Vec4(8.0f / 255.0f);
4949 if (result != tcu::Vec4(-1.0f))
4950 anyResultSet = true;
4952 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), samplingThreshold)))
4954 allResultsOk = false;
4956 m_context.getTestContext().getLog()
4957 << tcu::TestLog::Message
4958 << "Test sample " << resultNdx << ":\n"
4959 << "\tSampling at " << m_images.getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, resultNdx) << "\n"
4960 << "\tError expected " << reference << ", got " << result
4961 << tcu::TestLog::EndMessage;
4965 // read back and verify
4967 return tcu::TestStatus::pass("Pass");
4968 else if (anyResultSet)
4969 return tcu::TestStatus::fail("Invalid result values");
4972 m_context.getTestContext().getLog()
4973 << tcu::TestLog::Message
4974 << "Result buffer was not written to."
4975 << tcu::TestLog::EndMessage;
4976 return tcu::TestStatus::fail("Result buffer was not written to");
4980 class ImageDescriptorCase : public QuadrantRendederCase
4985 FLAG_BASE_MIP = (1u << 1u),
4986 FLAG_BASE_SLICE = (1u << 2u),
4988 // enum continues where resource flags ends
4989 DE_STATIC_ASSERT((deUint32)FLAG_BASE_MIP == (deUint32)RESOURCE_FLAG_LAST);
4991 ImageDescriptorCase (tcu::TestContext& testCtx,
4993 const char* description,
4994 bool isPrimaryCmdBuf,
4995 vk::VkDescriptorType descriptorType,
4996 vk::VkShaderStageFlags exitingStages,
4997 vk::VkShaderStageFlags activeStages,
4998 ShaderInputInterface shaderInterface,
4999 vk::VkImageViewType viewType,
5003 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
5004 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
5005 std::string genFetchCoordStr (int fetchPosNdx) const;
5006 std::string genSampleCoordStr (int samplePosNdx) const;
5007 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
5008 std::string genNoAccessSource (void) const;
5010 vkt::TestInstance* createInstance (vkt::Context& context) const;
5013 const bool m_isPrimaryCmdBuf;
5014 const vk::VkDescriptorType m_descriptorType;
5015 const ShaderInputInterface m_shaderInterface;
5016 const vk::VkImageViewType m_viewType;
5017 const deUint32 m_baseMipLevel;
5018 const deUint32 m_baseArraySlice;
5019 const bool m_isImmutableSampler;
5022 ImageDescriptorCase::ImageDescriptorCase (tcu::TestContext& testCtx,
5024 const char* description,
5025 bool isPrimaryCmdBuf,
5026 vk::VkDescriptorType descriptorType,
5027 vk::VkShaderStageFlags exitingStages,
5028 vk::VkShaderStageFlags activeStages,
5029 ShaderInputInterface shaderInterface,
5030 vk::VkImageViewType viewType,
5032 : QuadrantRendederCase (testCtx, name, description,
5033 // \note 1D textures are not supported in ES
5034 (viewType == vk::VK_IMAGE_VIEW_TYPE_1D || viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? glu::GLSL_VERSION_440 : glu::GLSL_VERSION_310_ES,
5035 exitingStages, activeStages)
5036 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
5037 , m_descriptorType (descriptorType)
5038 , m_shaderInterface (shaderInterface)
5039 , m_viewType (viewType)
5040 , m_baseMipLevel (((flags & FLAG_BASE_MIP) != 0) ? (1u) : (0u))
5041 , m_baseArraySlice (((flags & FLAG_BASE_SLICE) != 0) ? (1u) : (0u))
5042 , m_isImmutableSampler ((flags & RESOURCE_FLAG_IMMUTABLE_SAMPLER) != 0)
5046 std::string ImageDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
5050 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5051 return "#extension GL_OES_texture_cube_map_array : require\n";
5056 std::string ImageDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
5060 // Vulkan-style resources are arrays implicitly, OpenGL-style are not
5061 const std::string dimensionBase = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1D")
5062 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2D")
5063 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5064 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("Cube")
5066 const std::string dimensionArray = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5067 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5068 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5069 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE || m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5071 const std::string dimension = isImageViewTypeArray(m_viewType) ? dimensionArray : dimensionBase;
5073 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
5074 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER);
5076 switch (m_shaderInterface)
5078 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5080 switch (m_descriptorType)
5082 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5083 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5084 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler;\n";
5085 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5086 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler;\n";
5087 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5088 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture;\n";
5089 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5090 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image;\n";
5092 DE_FATAL("invalid descriptor");
5097 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5098 case SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS:
5099 switch (m_descriptorType)
5101 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5102 if (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS)
5103 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5104 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSamplerA;\n"
5105 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5107 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler u_separateSamplerA;\n"
5108 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5109 "layout(set = 0, binding = " + de::toString(numUsedBindings+2) + ") uniform highp sampler u_separateSamplerB;\n";
5110 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5111 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerA;\n"
5112 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler" + dimension + " u_combinedTextureSamplerB;\n";
5113 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5114 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTextureA;\n"
5115 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp texture" + dimensionBase + " u_separateTextureB;\n";
5116 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5117 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_imageA;\n"
5118 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ", rgba8) readonly uniform highp image" + dimension + " u_imageB;\n";
5120 DE_FATAL("invalid descriptor");
5124 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5125 switch (m_descriptorType)
5127 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5128 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimension + " u_separateTexture;\n"
5129 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + ") uniform highp sampler u_separateSampler[2];\n";
5130 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5131 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp sampler" + dimension + " u_combinedTextureSampler[2];\n";
5132 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5133 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ") uniform highp texture" + dimensionBase + " u_separateTexture[2];\n";
5134 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5135 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + ", rgba8) readonly uniform highp image" + dimension + " u_image[2];\n";
5137 DE_FATAL("invalid descriptor");
5142 DE_FATAL("Impossible");
5147 std::string ImageDescriptorCase::genFetchCoordStr (int fetchPosNdx) const
5149 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE);
5150 const tcu::IVec3 fetchPos = ImageFetchInstanceImages::getFetchPos(m_viewType, m_baseMipLevel, m_baseArraySlice, fetchPosNdx);
5152 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5154 return de::toString(fetchPos.x());
5156 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5158 std::ostringstream buf;
5159 buf << "ivec2(" << fetchPos.x() << ", " << fetchPos.y() << ")";
5164 std::ostringstream buf;
5165 buf << "ivec3(" << fetchPos.x() << ", " << fetchPos.y() << ", " << fetchPos.z() << ")";
5170 std::string ImageDescriptorCase::genSampleCoordStr (int samplePosNdx) const
5172 DE_ASSERT(m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER || m_descriptorType == vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER);
5173 const tcu::Vec4 fetchPos = ImageSampleInstanceImages::getSamplePos(m_viewType, m_baseMipLevel, m_baseArraySlice, samplePosNdx);
5175 if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D)
5177 std::ostringstream buf;
5178 buf << "float(" << fetchPos.x() << ")";
5181 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY || m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D)
5183 std::ostringstream buf;
5184 buf << "vec2(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "))";
5187 else if (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
5189 std::ostringstream buf;
5190 buf << "vec4(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "), float(" << fetchPos.w() << "))";
5195 std::ostringstream buf;
5196 buf << "vec3(float(" << fetchPos.x() << "), float(" << fetchPos.y() << "), float(" << fetchPos.z() << "))";
5201 std::string ImageDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
5205 const char* const dimension = (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D) ? ("1D")
5206 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY) ? ("1DArray")
5207 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D) ? ("2D")
5208 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY) ? ("2DArray")
5209 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_3D) ? ("3D")
5210 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE) ? ("Cube")
5211 : (m_viewType == vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) ? ("CubeArray")
5213 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5214 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
5215 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("A")
5216 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
5218 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
5219 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
5220 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS) ? ("B")
5221 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
5224 switch (m_descriptorType)
5226 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5227 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5229 const std::string coodStr[4] =
5231 genSampleCoordStr(0),
5232 genSampleCoordStr(1),
5233 genSampleCoordStr(2),
5234 genSampleCoordStr(3),
5236 std::ostringstream buf;
5238 if (m_descriptorType == vk::VK_DESCRIPTOR_TYPE_SAMPLER)
5240 buf << " if (quadrant_id == 0)\n"
5241 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[0] << ", 0.0);\n"
5242 << " else if (quadrant_id == 1)\n"
5243 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[1] << ", 0.0);\n"
5244 << " else if (quadrant_id == 2)\n"
5245 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixA << "), " << coodStr[2] << ", 0.0);\n"
5247 << " result_color = textureLod(sampler" << dimension << "(u_separateTexture, u_separateSampler" << accessPostfixB << "), " << coodStr[3] << ", 0.0);\n";
5251 buf << " if (quadrant_id == 0)\n"
5252 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[0] << ", 0.0);\n"
5253 << " else if (quadrant_id == 1)\n"
5254 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[1] << ", 0.0);\n"
5255 << " else if (quadrant_id == 2)\n"
5256 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixA << ", " << coodStr[2] << ", 0.0);\n"
5258 << " result_color = textureLod(u_combinedTextureSampler" << accessPostfixB << ", " << coodStr[3] << ", 0.0);\n";
5264 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5266 const std::string coodStr[4] =
5268 genFetchCoordStr(0),
5269 genFetchCoordStr(1),
5270 genFetchCoordStr(2),
5271 genFetchCoordStr(3),
5273 std::ostringstream buf;
5275 buf << " if (quadrant_id == 0)\n"
5276 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[0] << ");\n"
5277 << " else if (quadrant_id == 1)\n"
5278 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[1] << ");\n"
5279 << " else if (quadrant_id == 2)\n"
5280 << " result_color = imageLoad(u_image" << accessPostfixA << ", " << coodStr[2] << ");\n"
5282 << " result_color = imageLoad(u_image" << accessPostfixB << ", " << coodStr[3] << ");\n";
5288 DE_FATAL("invalid descriptor");
5293 std::string ImageDescriptorCase::genNoAccessSource (void) const
5295 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
5296 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
5298 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
5301 vkt::TestInstance* ImageDescriptorCase::createInstance (vkt::Context& context) const
5303 verifyDriverSupport(context.getDeviceFeatures(), m_descriptorType, m_activeStages);
5305 switch (m_descriptorType)
5307 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
5308 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
5309 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5311 DE_ASSERT(m_isPrimaryCmdBuf);
5312 return new ImageSampleComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5315 return new ImageSampleRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice, m_isImmutableSampler);
5317 case vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
5318 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
5319 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
5321 DE_ASSERT(m_isPrimaryCmdBuf);
5322 return new ImageFetchComputeInstance(context, m_descriptorType, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5325 return new ImageFetchRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_viewType, m_baseMipLevel, m_baseArraySlice);
5328 DE_FATAL("Impossible");
5333 class TexelBufferInstanceBuffers
5336 TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5337 vk::VkDevice device,
5338 vk::Allocator& allocator,
5339 vk::VkDescriptorType descriptorType,
5340 int numTexelBuffers,
5341 bool hasViewOffset);
5344 static vk::Move<vk::VkBuffer> createBuffer (const vk::DeviceInterface& vki,
5345 vk::VkDevice device,
5346 vk::Allocator& allocator,
5347 vk::VkDescriptorType descriptorType,
5348 de::MovePtr<vk::Allocation> *outAllocation);
5350 static vk::Move<vk::VkBufferView> createBufferView (const vk::DeviceInterface& vki,
5351 vk::VkDevice device,
5352 const tcu::TextureFormat& textureFormat,
5354 vk::VkBuffer buffer);
5356 static vk::VkBufferMemoryBarrier createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer);
5358 void populateSourceBuffer (const tcu::PixelBufferAccess& access);
5359 void uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data);
5362 static int getFetchPos (int fetchPosNdx);
5363 tcu::Vec4 fetchTexelValue (int fetchPosNdx) const;
5365 inline int getNumTexelBuffers (void) const { return m_numTexelBuffers; }
5366 const tcu::TextureFormat& getTextureFormat (void) const { return m_imageFormat; }
5367 inline vk::VkBufferView getBufferViewA (void) const { return *m_bufferViewA; }
5368 inline vk::VkBufferView getBufferViewB (void) const { return *m_bufferViewB; }
5369 inline const vk::VkBufferMemoryBarrier* getBufferInitBarriers (void) const { return m_bufferBarriers; }
5375 VIEW_OFFSET_VALUE = 256,
5376 VIEW_DATA_SIZE = 256, //!< size in bytes
5377 VIEW_WIDTH = 64, //!< size in pixels
5381 // some arbitrary points
5383 SAMPLE_POINT_1 = 51,
5384 SAMPLE_POINT_2 = 42,
5385 SAMPLE_POINT_3 = 25,
5388 const deUint32 m_numTexelBuffers;
5389 const tcu::TextureFormat m_imageFormat;
5390 const deUint32 m_viewOffset;
5392 de::ArrayBuffer<deUint8> m_sourceBufferA;
5393 de::ArrayBuffer<deUint8> m_sourceBufferB;
5394 const tcu::ConstPixelBufferAccess m_sourceViewA;
5395 const tcu::ConstPixelBufferAccess m_sourceViewB;
5397 de::MovePtr<vk::Allocation> m_bufferMemoryA;
5398 de::MovePtr<vk::Allocation> m_bufferMemoryB;
5399 const vk::Unique<vk::VkBuffer> m_bufferA;
5400 const vk::Unique<vk::VkBuffer> m_bufferB;
5401 const vk::Unique<vk::VkBufferView> m_bufferViewA;
5402 const vk::Unique<vk::VkBufferView> m_bufferViewB;
5403 vk::VkBufferMemoryBarrier m_bufferBarriers[2];
5406 TexelBufferInstanceBuffers::TexelBufferInstanceBuffers (const vk::DeviceInterface& vki,
5407 vk::VkDevice device,
5408 vk::Allocator& allocator,
5409 vk::VkDescriptorType descriptorType,
5410 int numTexelBuffers,
5412 : m_numTexelBuffers (numTexelBuffers)
5413 , m_imageFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8)
5414 , m_viewOffset ((hasViewOffset) ? ((deUint32)VIEW_OFFSET_VALUE) : (0u))
5415 , m_sourceBufferA (BUFFER_SIZE)
5416 , m_sourceBufferB ((numTexelBuffers == 1)
5418 : ((size_t)BUFFER_SIZE))
5419 , m_sourceViewA (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferA.getElementPtr(m_viewOffset))
5420 , m_sourceViewB (m_imageFormat, tcu::IVec3(VIEW_WIDTH, 1, 1), m_sourceBufferB.getElementPtr(m_viewOffset))
5421 , m_bufferMemoryA (DE_NULL)
5422 , m_bufferMemoryB (DE_NULL)
5423 , m_bufferA (createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryA))
5424 , m_bufferB ((numTexelBuffers == 1)
5425 ? vk::Move<vk::VkBuffer>()
5426 : createBuffer(vki, device, allocator, descriptorType, &m_bufferMemoryB))
5427 , m_bufferViewA (createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferA))
5428 , m_bufferViewB ((numTexelBuffers == 1)
5429 ? vk::Move<vk::VkBufferView>()
5430 : createBufferView(vki, device, m_imageFormat, m_viewOffset, *m_bufferB))
5432 DE_ASSERT(numTexelBuffers == 1 || numTexelBuffers == 2);
5433 DE_ASSERT(VIEW_WIDTH * m_imageFormat.getPixelSize() == VIEW_DATA_SIZE);
5434 DE_ASSERT(BUFFER_SIZE % m_imageFormat.getPixelSize() == 0);
5436 // specify and upload
5438 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferA.getPtr()));
5439 uploadData(vki, device, *m_bufferMemoryA, m_sourceBufferA);
5441 if (numTexelBuffers == 2)
5443 populateSourceBuffer(tcu::PixelBufferAccess(m_imageFormat, tcu::IVec3(BUFFER_SIZE / m_imageFormat.getPixelSize(), 1, 1), m_sourceBufferB.getPtr()));
5444 uploadData(vki, device, *m_bufferMemoryB, m_sourceBufferB);
5447 m_bufferBarriers[0] = createBarrier(descriptorType, *m_bufferA);
5448 m_bufferBarriers[1] = createBarrier(descriptorType, *m_bufferB);
5451 vk::Move<vk::VkBuffer> TexelBufferInstanceBuffers::createBuffer (const vk::DeviceInterface& vki,
5452 vk::VkDevice device,
5453 vk::Allocator& allocator,
5454 vk::VkDescriptorType descriptorType,
5455 de::MovePtr<vk::Allocation> *outAllocation)
5457 const vk::VkBufferUsageFlags usage = (isUniformDescriptorType(descriptorType)) ? (vk::VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) : (vk::VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT);
5458 const vk::VkBufferCreateInfo createInfo =
5460 vk::VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
5463 (vk::VkDeviceSize)BUFFER_SIZE, // size
5465 vk::VK_SHARING_MODE_EXCLUSIVE, // sharingMode
5466 0u, // queueFamilyCount
5467 DE_NULL, // pQueueFamilyIndices
5469 vk::Move<vk::VkBuffer> buffer (vk::createBuffer(vki, device, &createInfo));
5470 de::MovePtr<vk::Allocation> allocation (allocateAndBindObjectMemory(vki, device, allocator, *buffer, vk::MemoryRequirement::HostVisible));
5472 *outAllocation = allocation;
5476 vk::Move<vk::VkBufferView> TexelBufferInstanceBuffers::createBufferView (const vk::DeviceInterface& vki,
5477 vk::VkDevice device,
5478 const tcu::TextureFormat& textureFormat,
5480 vk::VkBuffer buffer)
5482 const vk::VkBufferViewCreateInfo createInfo =
5484 vk::VK_STRUCTURE_TYPE_BUFFER_VIEW_CREATE_INFO,
5486 (vk::VkBufferViewCreateFlags)0,
5488 vk::mapTextureFormat(textureFormat), // format
5489 (vk::VkDeviceSize)offset, // offset
5490 (vk::VkDeviceSize)VIEW_DATA_SIZE // range
5492 return vk::createBufferView(vki, device, &createInfo);
5495 vk::VkBufferMemoryBarrier TexelBufferInstanceBuffers::createBarrier (vk::VkDescriptorType descriptorType, vk::VkBuffer buffer)
5497 const vk::VkAccessFlags inputBit = (isUniformDescriptorType(descriptorType)) ? (vk::VK_ACCESS_UNIFORM_READ_BIT) : (vk::VK_ACCESS_SHADER_READ_BIT);
5498 const vk::VkBufferMemoryBarrier barrier =
5500 vk::VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER,
5502 vk::VK_ACCESS_HOST_WRITE_BIT, // outputMask
5503 inputBit, // inputMask
5504 VK_QUEUE_FAMILY_IGNORED, // srcQueueFamilyIndex
5505 VK_QUEUE_FAMILY_IGNORED, // destQueueFamilyIndex
5508 (vk::VkDeviceSize)BUFFER_SIZE // size
5513 void TexelBufferInstanceBuffers::populateSourceBuffer (const tcu::PixelBufferAccess& access)
5515 DE_ASSERT(access.getHeight() == 1);
5516 DE_ASSERT(access.getDepth() == 1);
5518 const deInt32 width = access.getWidth();
5520 for (int x = 0; x < width; ++x)
5522 const int red = 255 * x / width; //!< gradient from 0 -> max (detects large offset errors)
5523 const int green = ((x % 2 == 0) ? (127) : (0)) + ((x % 4 < 3) ? (128) : (0)); //!< 3-level M pattern (detects small offset errors)
5524 const int blue = 16 * (x % 16); //!< 16-long triangle wave
5526 DE_ASSERT(de::inRange(red, 0, 255));
5527 DE_ASSERT(de::inRange(green, 0, 255));
5528 DE_ASSERT(de::inRange(blue, 0, 255));
5530 access.setPixel(tcu::IVec4(red, green, blue, 255), x, 0, 0);
5534 void TexelBufferInstanceBuffers::uploadData (const vk::DeviceInterface& vki, vk::VkDevice device, const vk::Allocation& memory, const de::ArrayBuffer<deUint8>& data)
5536 deMemcpy(memory.getHostPtr(), data.getPtr(), data.size());
5537 flushMappedMemoryRange(vki, device, memory.getMemory(), memory.getOffset(), data.size());
5540 int TexelBufferInstanceBuffers::getFetchPos (int fetchPosNdx)
5542 static const int fetchPositions[4] =
5549 return de::getSizedArrayElement<4>(fetchPositions, fetchPosNdx);
5552 tcu::Vec4 TexelBufferInstanceBuffers::fetchTexelValue (int fetchPosNdx) const
5554 // source order is ABAB
5555 const tcu::ConstPixelBufferAccess& texelSrcA = m_sourceViewA;
5556 const tcu::ConstPixelBufferAccess& texelSrcB = (m_numTexelBuffers == 1) ? (m_sourceViewA) : (m_sourceViewB);
5557 const tcu::ConstPixelBufferAccess& texelSrc = ((fetchPosNdx % 2) == 0) ? (texelSrcA) : (texelSrcB);
5559 return texelSrc.getPixel(getFetchPos(fetchPosNdx), 0, 0);
5562 class TexelBufferRenderInstance : public SingleCmdRenderInstance
5565 TexelBufferRenderInstance (vkt::Context& context,
5566 bool isPrimaryCmdBuf,
5567 vk::VkDescriptorType descriptorType,
5568 vk::VkShaderStageFlags stageFlags,
5569 ShaderInputInterface shaderInterface,
5570 bool nonzeroViewOffset);
5573 static vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (const vk::DeviceInterface& vki,
5574 vk::VkDevice device,
5575 vk::VkDescriptorType descriptorType,
5576 ShaderInputInterface shaderInterface,
5577 vk::VkShaderStageFlags stageFlags);
5579 static vk::Move<vk::VkPipelineLayout> createPipelineLayout (const vk::DeviceInterface& vki,
5580 vk::VkDevice device,
5581 vk::VkDescriptorSetLayout descriptorSetLayout);
5583 static vk::Move<vk::VkDescriptorPool> createDescriptorPool (const vk::DeviceInterface& vki,
5584 vk::VkDevice device,
5585 vk::VkDescriptorType descriptorType,
5586 ShaderInputInterface shaderInterface);
5588 static vk::Move<vk::VkDescriptorSet> createDescriptorSet (const vk::DeviceInterface& vki,
5589 vk::VkDevice device,
5590 vk::VkDescriptorType descriptorType,
5591 ShaderInputInterface shaderInterface,
5592 vk::VkDescriptorSetLayout layout,
5593 vk::VkDescriptorPool pool,
5594 vk::VkBufferView viewA,
5595 vk::VkBufferView viewB);
5597 void logTestPlan (void) const;
5598 vk::VkPipelineLayout getPipelineLayout (void) const;
5599 void writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const;
5600 tcu::TestStatus verifyResultImage (const tcu::ConstPixelBufferAccess& result) const;
5607 const vk::VkDescriptorType m_descriptorType;
5608 const vk::VkShaderStageFlags m_stageFlags;
5609 const ShaderInputInterface m_shaderInterface;
5610 const bool m_nonzeroViewOffset;
5612 const vk::Unique<vk::VkDescriptorSetLayout> m_descriptorSetLayout;
5613 const vk::Unique<vk::VkPipelineLayout> m_pipelineLayout;
5614 const TexelBufferInstanceBuffers m_texelBuffers;
5615 const vk::Unique<vk::VkDescriptorPool> m_descriptorPool;
5616 const vk::Unique<vk::VkDescriptorSet> m_descriptorSet;
5619 TexelBufferRenderInstance::TexelBufferRenderInstance (vkt::Context& context,
5620 bool isPrimaryCmdBuf,
5621 vk::VkDescriptorType descriptorType,
5622 vk::VkShaderStageFlags stageFlags,
5623 ShaderInputInterface shaderInterface,
5624 bool nonzeroViewOffset)
5625 : SingleCmdRenderInstance (context, isPrimaryCmdBuf, tcu::UVec2(RENDER_SIZE, RENDER_SIZE))
5626 , m_descriptorType (descriptorType)
5627 , m_stageFlags (stageFlags)
5628 , m_shaderInterface (shaderInterface)
5629 , m_nonzeroViewOffset (nonzeroViewOffset)
5630 , m_descriptorSetLayout (createDescriptorSetLayout(m_vki, m_device, m_descriptorType, m_shaderInterface, m_stageFlags))
5631 , m_pipelineLayout (createPipelineLayout(m_vki, m_device, *m_descriptorSetLayout))
5632 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5633 , m_descriptorPool (createDescriptorPool(m_vki, m_device, m_descriptorType, m_shaderInterface))
5634 , m_descriptorSet (createDescriptorSet(m_vki, m_device, m_descriptorType, m_shaderInterface, *m_descriptorSetLayout, *m_descriptorPool, m_texelBuffers.getBufferViewA(), m_texelBuffers.getBufferViewB()))
5638 vk::Move<vk::VkDescriptorSetLayout> TexelBufferRenderInstance::createDescriptorSetLayout (const vk::DeviceInterface& vki,
5639 vk::VkDevice device,
5640 vk::VkDescriptorType descriptorType,
5641 ShaderInputInterface shaderInterface,
5642 vk::VkShaderStageFlags stageFlags)
5644 vk::DescriptorSetLayoutBuilder builder;
5646 switch (shaderInterface)
5648 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5649 builder.addSingleBinding(descriptorType, stageFlags);
5652 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5653 builder.addSingleBinding(descriptorType, stageFlags);
5654 builder.addSingleBinding(descriptorType, stageFlags);
5657 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5658 builder.addArrayBinding(descriptorType, 2u, stageFlags);
5662 DE_FATAL("Impossible");
5665 return builder.build(vki, device);
5668 vk::Move<vk::VkPipelineLayout> TexelBufferRenderInstance::createPipelineLayout (const vk::DeviceInterface& vki,
5669 vk::VkDevice device,
5670 vk::VkDescriptorSetLayout descriptorSetLayout)
5672 const vk::VkPipelineLayoutCreateInfo createInfo =
5674 vk::VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
5676 (vk::VkPipelineLayoutCreateFlags)0,
5677 1, // descriptorSetCount
5678 &descriptorSetLayout, // pSetLayouts
5679 0u, // pushConstantRangeCount
5680 DE_NULL, // pPushConstantRanges
5682 return vk::createPipelineLayout(vki, device, &createInfo);
5685 vk::Move<vk::VkDescriptorPool> TexelBufferRenderInstance::createDescriptorPool (const vk::DeviceInterface& vki,
5686 vk::VkDevice device,
5687 vk::VkDescriptorType descriptorType,
5688 ShaderInputInterface shaderInterface)
5690 return vk::DescriptorPoolBuilder()
5691 .addType(descriptorType, getInterfaceNumResources(shaderInterface))
5692 .build(vki, device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5695 vk::Move<vk::VkDescriptorSet> TexelBufferRenderInstance::createDescriptorSet (const vk::DeviceInterface& vki,
5696 vk::VkDevice device,
5697 vk::VkDescriptorType descriptorType,
5698 ShaderInputInterface shaderInterface,
5699 vk::VkDescriptorSetLayout layout,
5700 vk::VkDescriptorPool pool,
5701 vk::VkBufferView viewA,
5702 vk::VkBufferView viewB)
5704 const vk::VkBufferView texelBufferInfos[2] =
5709 const vk::VkDescriptorSetAllocateInfo allocInfo =
5711 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5718 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(vki, device, &allocInfo);
5719 vk::DescriptorSetUpdateBuilder builder;
5721 switch (shaderInterface)
5723 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5724 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5727 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5728 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, &texelBufferInfos[0]);
5729 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), descriptorType, &texelBufferInfos[1]);
5732 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5733 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), descriptorType, 2u, texelBufferInfos);
5737 DE_FATAL("Impossible");
5740 builder.update(vki, device);
5741 return descriptorSet;
5744 void TexelBufferRenderInstance::logTestPlan (void) const
5746 std::ostringstream msg;
5748 msg << "Rendering 2x2 grid.\n"
5749 << "Single descriptor set. Descriptor set contains "
5750 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5751 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5752 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5753 (const char*)DE_NULL)
5754 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5755 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5756 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5758 if (m_stageFlags == 0u)
5760 msg << "Descriptors are not accessed in any shader stage.\n";
5764 msg << "Color in each cell is fetched using the descriptor(s):\n";
5766 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5768 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5770 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5772 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5773 msg << " from texelBuffer " << srcResourceNdx;
5779 msg << "Descriptors are accessed in {"
5780 << (((m_stageFlags & vk::VK_SHADER_STAGE_VERTEX_BIT) != 0) ? (" vertex") : (""))
5781 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) != 0) ? (" tess_control") : (""))
5782 << (((m_stageFlags & vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT) != 0) ? (" tess_evaluation") : (""))
5783 << (((m_stageFlags & vk::VK_SHADER_STAGE_GEOMETRY_BIT) != 0) ? (" geometry") : (""))
5784 << (((m_stageFlags & vk::VK_SHADER_STAGE_FRAGMENT_BIT) != 0) ? (" fragment") : (""))
5788 m_context.getTestContext().getLog()
5789 << tcu::TestLog::Message
5791 << tcu::TestLog::EndMessage;
5794 vk::VkPipelineLayout TexelBufferRenderInstance::getPipelineLayout (void) const
5796 return *m_pipelineLayout;
5799 void TexelBufferRenderInstance::writeDrawCmdBuffer (vk::VkCommandBuffer cmd) const
5801 m_vki.cmdBindDescriptorSets(cmd, vk::VK_PIPELINE_BIND_POINT_GRAPHICS, getPipelineLayout(), 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
5802 m_vki.cmdDraw(cmd, 6 * 4, 1, 0, 0); // render four quads (two separate triangles)
5805 tcu::TestStatus TexelBufferRenderInstance::verifyResultImage (const tcu::ConstPixelBufferAccess& result) const
5807 const tcu::Vec4 green (0.0f, 1.0f, 0.0f, 1.0f);
5808 const tcu::Vec4 yellow (1.0f, 1.0f, 0.0f, 1.0f);
5809 const bool doFetch = (m_stageFlags != 0u); // no active stages? Then don't fetch
5810 const tcu::Vec4 sample0 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(0));
5811 const tcu::Vec4 sample1 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(1));
5812 const tcu::Vec4 sample2 = (!doFetch) ? (green) : (m_texelBuffers.fetchTexelValue(2));
5813 const tcu::Vec4 sample3 = (!doFetch) ? (yellow) : (m_texelBuffers.fetchTexelValue(3));
5814 tcu::Surface reference (m_targetSize.x(), m_targetSize.y());
5816 drawQuadrantReferenceResult(reference.getAccess(), sample0, sample1, sample2, sample3);
5818 if (!bilinearCompare(m_context.getTestContext().getLog(), "Compare", "Result comparison", reference.getAccess(), result, tcu::RGBA(1, 1, 1, 1), tcu::COMPARE_LOG_RESULT))
5819 return tcu::TestStatus::fail("Image verification failed");
5821 return tcu::TestStatus::pass("Pass");
5824 class TexelBufferComputeInstance : public vkt::TestInstance
5827 TexelBufferComputeInstance (vkt::Context& context,
5828 vk::VkDescriptorType descriptorType,
5829 ShaderInputInterface shaderInterface,
5830 bool nonzeroViewOffset);
5833 vk::Move<vk::VkDescriptorSetLayout> createDescriptorSetLayout (void) const;
5834 vk::Move<vk::VkDescriptorPool> createDescriptorPool (void) const;
5835 vk::Move<vk::VkDescriptorSet> createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const;
5837 tcu::TestStatus iterate (void);
5838 void logTestPlan (void) const;
5839 tcu::TestStatus testResourceAccess (void);
5841 const vk::VkDescriptorType m_descriptorType;
5842 const ShaderInputInterface m_shaderInterface;
5843 const bool m_nonzeroViewOffset;
5845 const vk::DeviceInterface& m_vki;
5846 const vk::VkDevice m_device;
5847 const vk::VkQueue m_queue;
5848 const deUint32 m_queueFamilyIndex;
5849 vk::Allocator& m_allocator;
5851 const ComputeInstanceResultBuffer m_result;
5852 const TexelBufferInstanceBuffers m_texelBuffers;
5855 TexelBufferComputeInstance::TexelBufferComputeInstance (Context& context,
5856 vk::VkDescriptorType descriptorType,
5857 ShaderInputInterface shaderInterface,
5858 bool nonzeroViewOffset)
5859 : vkt::TestInstance (context)
5860 , m_descriptorType (descriptorType)
5861 , m_shaderInterface (shaderInterface)
5862 , m_nonzeroViewOffset (nonzeroViewOffset)
5863 , m_vki (context.getDeviceInterface())
5864 , m_device (context.getDevice())
5865 , m_queue (context.getUniversalQueue())
5866 , m_queueFamilyIndex (context.getUniversalQueueFamilyIndex())
5867 , m_allocator (context.getDefaultAllocator())
5868 , m_result (m_vki, m_device, m_allocator)
5869 , m_texelBuffers (m_vki, m_device, m_allocator, m_descriptorType, getInterfaceNumResources(m_shaderInterface), m_nonzeroViewOffset)
5873 vk::Move<vk::VkDescriptorSetLayout> TexelBufferComputeInstance::createDescriptorSetLayout (void) const
5875 vk::DescriptorSetLayoutBuilder builder;
5877 builder.addSingleBinding(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5879 switch (m_shaderInterface)
5881 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5882 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5885 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5886 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5887 builder.addSingleBinding(m_descriptorType, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5890 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5891 builder.addArrayBinding(m_descriptorType, 2u, vk::VK_SHADER_STAGE_COMPUTE_BIT);
5895 DE_FATAL("Impossible");
5898 return builder.build(m_vki, m_device);
5901 vk::Move<vk::VkDescriptorPool> TexelBufferComputeInstance::createDescriptorPool (void) const
5903 return vk::DescriptorPoolBuilder()
5904 .addType(vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER)
5905 .addType(m_descriptorType, getInterfaceNumResources(m_shaderInterface))
5906 .build(m_vki, m_device, vk::VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1);
5909 vk::Move<vk::VkDescriptorSet> TexelBufferComputeInstance::createDescriptorSet (vk::VkDescriptorPool pool, vk::VkDescriptorSetLayout layout) const
5911 const vk::VkDescriptorBufferInfo resultInfo = vk::makeDescriptorBufferInfo(m_result.getBuffer(), 0u, (vk::VkDeviceSize)ComputeInstanceResultBuffer::DATA_SIZE);
5912 const vk::VkBufferView texelBufferInfos[2] =
5914 m_texelBuffers.getBufferViewA(),
5915 m_texelBuffers.getBufferViewB(),
5917 const vk::VkDescriptorSetAllocateInfo allocInfo =
5919 vk::VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
5926 vk::Move<vk::VkDescriptorSet> descriptorSet = allocateDescriptorSet(m_vki, m_device, &allocInfo);
5927 vk::DescriptorSetUpdateBuilder builder;
5930 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(0u), vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, &resultInfo);
5933 switch (m_shaderInterface)
5935 case SHADER_INPUT_SINGLE_DESCRIPTOR:
5936 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5939 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
5940 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, &texelBufferInfos[0]);
5941 builder.writeSingle(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(2u), m_descriptorType, &texelBufferInfos[1]);
5944 case SHADER_INPUT_DESCRIPTOR_ARRAY:
5945 builder.writeArray(*descriptorSet, vk::DescriptorSetUpdateBuilder::Location::binding(1u), m_descriptorType, 2u, texelBufferInfos);
5949 DE_FATAL("Impossible");
5952 builder.update(m_vki, m_device);
5953 return descriptorSet;
5956 tcu::TestStatus TexelBufferComputeInstance::iterate (void)
5959 return testResourceAccess();
5962 void TexelBufferComputeInstance::logTestPlan (void) const
5964 std::ostringstream msg;
5966 msg << "Fetching 4 values from image in compute shader.\n"
5967 << "Single descriptor set. Descriptor set contains "
5968 << ((m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? "single" :
5969 (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? "two" :
5970 (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? "an array (size 2) of" :
5971 (const char*)DE_NULL)
5972 << " descriptor(s) of type " << vk::getDescriptorTypeName(m_descriptorType) << "\n"
5973 << "Buffer view is created with a " << ((m_nonzeroViewOffset) ? ("non-zero") : ("zero")) << " offset.\n"
5974 << "Buffer format is " << vk::getFormatName(vk::mapTextureFormat(m_texelBuffers.getTextureFormat())) << ".\n";
5976 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
5978 msg << "Test sample " << resultNdx << ": fetch at position " << m_texelBuffers.getFetchPos(resultNdx);
5980 if (m_shaderInterface != SHADER_INPUT_SINGLE_DESCRIPTOR)
5982 const int srcResourceNdx = (resultNdx % 2); // ABAB source
5983 msg << " from texelBuffer " << srcResourceNdx;
5989 m_context.getTestContext().getLog()
5990 << tcu::TestLog::Message
5992 << tcu::TestLog::EndMessage;
5995 tcu::TestStatus TexelBufferComputeInstance::testResourceAccess (void)
5997 const vk::Unique<vk::VkDescriptorSetLayout> descriptorSetLayout (createDescriptorSetLayout());
5998 const vk::Unique<vk::VkDescriptorPool> descriptorPool (createDescriptorPool());
5999 const vk::Unique<vk::VkDescriptorSet> descriptorSet (createDescriptorSet(*descriptorPool, *descriptorSetLayout));
6000 const ComputePipeline pipeline (m_vki, m_device, m_context.getBinaryCollection(), 1, &descriptorSetLayout.get());
6002 const vk::VkDescriptorSet descriptorSets[] = { *descriptorSet };
6003 const int numDescriptorSets = DE_LENGTH_OF_ARRAY(descriptorSets);
6004 const deUint32* const dynamicOffsets = DE_NULL;
6005 const int numDynamicOffsets = 0;
6006 const vk::VkBufferMemoryBarrier* const preBarriers = m_texelBuffers.getBufferInitBarriers();
6007 const int numPreBarriers = m_texelBuffers.getNumTexelBuffers();
6008 const vk::VkBufferMemoryBarrier* const postBarriers = m_result.getResultReadBarrier();
6009 const int numPostBarriers = 1;
6011 const ComputeCommand compute (m_vki,
6013 pipeline.getPipeline(),
6014 pipeline.getPipelineLayout(),
6015 tcu::UVec3(4, 1, 1),
6016 numDescriptorSets, descriptorSets,
6017 numDynamicOffsets, dynamicOffsets,
6018 numPreBarriers, preBarriers,
6019 numPostBarriers, postBarriers);
6021 tcu::Vec4 results[4];
6022 bool anyResultSet = false;
6023 bool allResultsOk = true;
6025 compute.submitAndWait(m_queueFamilyIndex, m_queue);
6026 m_result.readResultContentsTo(&results);
6029 for (int resultNdx = 0; resultNdx < 4; ++resultNdx)
6031 const tcu::Vec4 result = results[resultNdx];
6032 const tcu::Vec4 reference = m_texelBuffers.fetchTexelValue(resultNdx);
6033 const tcu::Vec4 conversionThreshold = tcu::Vec4(1.0f / 255.0f);
6035 if (result != tcu::Vec4(-1.0f))
6036 anyResultSet = true;
6038 if (tcu::boolAny(tcu::greaterThan(tcu::abs(result - reference), conversionThreshold)))
6040 allResultsOk = false;
6042 m_context.getTestContext().getLog()
6043 << tcu::TestLog::Message
6044 << "Test sample " << resultNdx << ": Expected " << reference << ", got " << result
6045 << tcu::TestLog::EndMessage;
6049 // read back and verify
6051 return tcu::TestStatus::pass("Pass");
6052 else if (anyResultSet)
6053 return tcu::TestStatus::fail("Invalid result values");
6056 m_context.getTestContext().getLog()
6057 << tcu::TestLog::Message
6058 << "Result buffer was not written to."
6059 << tcu::TestLog::EndMessage;
6060 return tcu::TestStatus::fail("Result buffer was not written to");
6064 class TexelBufferDescriptorCase : public QuadrantRendederCase
6069 FLAG_VIEW_OFFSET = (1u << 1u),
6071 // enum continues where resource flags ends
6072 DE_STATIC_ASSERT((deUint32)FLAG_VIEW_OFFSET == (deUint32)RESOURCE_FLAG_LAST);
6074 TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6076 const char* description,
6077 bool isPrimaryCmdBuf,
6078 vk::VkDescriptorType descriptorType,
6079 vk::VkShaderStageFlags exitingStages,
6080 vk::VkShaderStageFlags activeStages,
6081 ShaderInputInterface shaderInterface,
6085 std::string genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const;
6086 std::string genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const;
6087 std::string genResourceAccessSource (vk::VkShaderStageFlagBits stage) const;
6088 std::string genNoAccessSource (void) const;
6090 vkt::TestInstance* createInstance (vkt::Context& context) const;
6092 const bool m_isPrimaryCmdBuf;
6093 const vk::VkDescriptorType m_descriptorType;
6094 const ShaderInputInterface m_shaderInterface;
6095 const bool m_nonzeroViewOffset;
6098 TexelBufferDescriptorCase::TexelBufferDescriptorCase (tcu::TestContext& testCtx,
6100 const char* description,
6101 bool isPrimaryCmdBuf,
6102 vk::VkDescriptorType descriptorType,
6103 vk::VkShaderStageFlags exitingStages,
6104 vk::VkShaderStageFlags activeStages,
6105 ShaderInputInterface shaderInterface,
6107 : QuadrantRendederCase (testCtx, name, description, glu::GLSL_VERSION_310_ES, exitingStages, activeStages)
6108 , m_isPrimaryCmdBuf (isPrimaryCmdBuf)
6109 , m_descriptorType (descriptorType)
6110 , m_shaderInterface (shaderInterface)
6111 , m_nonzeroViewOffset (((flags & FLAG_VIEW_OFFSET) != 0) ? (1u) : (0u))
6115 std::string TexelBufferDescriptorCase::genExtensionDeclarations (vk::VkShaderStageFlagBits stage) const
6118 return "#extension GL_EXT_texture_buffer : require\n";
6121 std::string TexelBufferDescriptorCase::genResourceDeclarations (vk::VkShaderStageFlagBits stage, int numUsedBindings) const
6125 const bool isUniform = isUniformDescriptorType(m_descriptorType);
6126 const char* const storageType = (isUniform) ? ("samplerBuffer ") : ("readonly imageBuffer ");
6127 const char* const formatQualifier = (isUniform) ? ("") : (", rgba8");
6129 switch (m_shaderInterface)
6131 case SHADER_INPUT_SINGLE_DESCRIPTOR:
6132 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer;\n";
6134 case SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS:
6135 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferA;\n"
6136 "layout(set = 0, binding = " + de::toString(numUsedBindings+1) + formatQualifier + ") uniform highp " + storageType + " u_texelBufferB;\n";
6138 case SHADER_INPUT_DESCRIPTOR_ARRAY:
6139 return "layout(set = 0, binding = " + de::toString(numUsedBindings) + formatQualifier + ") uniform highp " + storageType + " u_texelBuffer[2];\n";
6142 DE_FATAL("Impossible");
6147 std::string TexelBufferDescriptorCase::genResourceAccessSource (vk::VkShaderStageFlagBits stage) const
6151 const char* const accessPostfixA = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6152 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("A")
6153 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[0]")
6155 const char* const accessPostfixB = (m_shaderInterface == SHADER_INPUT_SINGLE_DESCRIPTOR) ? ("")
6156 : (m_shaderInterface == SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS) ? ("B")
6157 : (m_shaderInterface == SHADER_INPUT_DESCRIPTOR_ARRAY) ? ("[1]")
6159 const char* const fetchFunc = (isUniformDescriptorType(m_descriptorType)) ? ("texelFetch") : ("imageLoad");
6160 std::ostringstream buf;
6162 buf << " if (quadrant_id == 0)\n"
6163 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(0) << ");\n"
6164 << " else if (quadrant_id == 1)\n"
6165 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(1) << ");\n"
6166 << " else if (quadrant_id == 2)\n"
6167 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixA << ", " << TexelBufferInstanceBuffers::getFetchPos(2) << ");\n"
6169 << " result_color = " << fetchFunc << "(u_texelBuffer" << accessPostfixB << ", " << TexelBufferInstanceBuffers::getFetchPos(3) << ");\n";
6174 std::string TexelBufferDescriptorCase::genNoAccessSource (void) const
6176 return " if (quadrant_id == 1 || quadrant_id == 2)\n"
6177 " result_color = vec4(0.0, 1.0, 0.0, 1.0);\n"
6179 " result_color = vec4(1.0, 1.0, 0.0, 1.0);\n";
6182 vkt::TestInstance* TexelBufferDescriptorCase::createInstance (vkt::Context& context) const
6184 verifyDriverSupport(context.getDeviceFeatures(), m_descriptorType, m_activeStages);
6186 if (m_exitingStages == vk::VK_SHADER_STAGE_COMPUTE_BIT)
6188 DE_ASSERT(m_isPrimaryCmdBuf); // secondaries are only valid within renderpass
6189 return new TexelBufferComputeInstance(context, m_descriptorType, m_shaderInterface, m_nonzeroViewOffset);
6192 return new TexelBufferRenderInstance(context, m_isPrimaryCmdBuf, m_descriptorType, m_activeStages, m_shaderInterface, m_nonzeroViewOffset);
6195 void createShaderAccessImageTests (tcu::TestCaseGroup* group,
6196 bool isPrimaryCmdBuf,
6197 vk::VkDescriptorType descriptorType,
6198 vk::VkShaderStageFlags exitingStages,
6199 vk::VkShaderStageFlags activeStages,
6200 ShaderInputInterface dimension,
6201 deUint32 resourceFlags)
6205 vk::VkImageViewType viewType;
6207 const char* description;
6211 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d", "1D image view", 0u },
6212 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_mip", "1D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6213 { vk::VK_IMAGE_VIEW_TYPE_1D, "1d_base_slice", "1D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6215 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array", "1D array image view", 0u },
6216 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_mip", "1D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6217 { vk::VK_IMAGE_VIEW_TYPE_1D_ARRAY, "1d_array_base_slice", "1D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6219 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d", "2D image view", 0u },
6220 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_mip", "2D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6221 { vk::VK_IMAGE_VIEW_TYPE_2D, "2d_base_slice", "2D image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6223 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array", "2D array image view", 0u },
6224 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_mip", "2D array image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6225 { vk::VK_IMAGE_VIEW_TYPE_2D_ARRAY, "2d_array_base_slice", "2D array image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6227 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d", "3D image view", 0u },
6228 { vk::VK_IMAGE_VIEW_TYPE_3D, "3d_base_mip", "3D image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6229 // no 3d array textures
6231 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube", "Cube image view", 0u },
6232 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6233 { vk::VK_IMAGE_VIEW_TYPE_CUBE, "cube_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6235 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array", "Cube image view", 0u },
6236 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_mip", "Cube image subview with base mip level", ImageDescriptorCase::FLAG_BASE_MIP },
6237 { vk::VK_IMAGE_VIEW_TYPE_CUBE_ARRAY, "cube_array_base_slice", "Cube image subview with base array slice", ImageDescriptorCase::FLAG_BASE_SLICE },
6240 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_imageTypes); ++ndx)
6243 DE_ASSERT((s_imageTypes[ndx].flags & resourceFlags) == 0u);
6245 // SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS only supported in VK_DESCRIPTOR_TYPE_SAMPLER on graphics shaders for now
6246 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS &&
6247 (descriptorType != vk::VK_DESCRIPTOR_TYPE_SAMPLER || activeStages == vk::VK_SHADER_STAGE_COMPUTE_BIT))
6250 group->addChild(new ImageDescriptorCase(group->getTestContext(),
6251 s_imageTypes[ndx].name,
6252 s_imageTypes[ndx].description,
6258 s_imageTypes[ndx].viewType,
6259 s_imageTypes[ndx].flags | resourceFlags));
6263 void createShaderAccessTexelBufferTests (tcu::TestCaseGroup* group,
6264 bool isPrimaryCmdBuf,
6265 vk::VkDescriptorType descriptorType,
6266 vk::VkShaderStageFlags exitingStages,
6267 vk::VkShaderStageFlags activeStages,
6268 ShaderInputInterface dimension,
6269 deUint32 resourceFlags)
6271 DE_ASSERT(resourceFlags == 0);
6272 DE_UNREF(resourceFlags);
6277 const char* description;
6279 } s_texelBufferTypes[] =
6281 { "offset_zero", "View offset is zero", 0u },
6282 { "offset_nonzero", "View offset is non-zero", TexelBufferDescriptorCase::FLAG_VIEW_OFFSET },
6285 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_texelBufferTypes); ++ndx)
6287 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
6290 group->addChild(new TexelBufferDescriptorCase(group->getTestContext(),
6291 s_texelBufferTypes[ndx].name,
6292 s_texelBufferTypes[ndx].description,
6298 s_texelBufferTypes[ndx].flags));
6302 void createShaderAccessBufferTests (tcu::TestCaseGroup* group,
6303 bool isPrimaryCmdBuf,
6304 vk::VkDescriptorType descriptorType,
6305 vk::VkShaderStageFlags exitingStages,
6306 vk::VkShaderStageFlags activeStages,
6307 ShaderInputInterface dimension,
6308 deUint32 resourceFlags)
6310 DE_ASSERT(resourceFlags == 0u);
6311 DE_UNREF(resourceFlags);
6316 const char* description;
6317 bool isForDynamicCases;
6321 { "offset_view_zero", "View offset is zero", false, 0u },
6322 { "offset_view_nonzero", "View offset is non-zero", false, BufferDescriptorCase::FLAG_VIEW_OFFSET },
6324 { "offset_view_zero_dynamic_zero", "View offset is zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6325 { "offset_view_zero_dynamic_nonzero", "View offset is zero, dynamic offset is non-zero", true, BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_NONZERO },
6326 { "offset_view_nonzero_dynamic_zero", "View offset is non-zero, dynamic offset is zero", true, BufferDescriptorCase::FLAG_VIEW_OFFSET | BufferDescriptorCase::FLAG_DYNAMIC_OFFSET_ZERO },
6327 { "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 },
6330 const bool isDynamicCase = isDynamicDescriptorType(descriptorType);
6332 for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_bufferTypes); ++ndx)
6334 if (dimension == SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS)
6337 if (isDynamicCase == s_bufferTypes[ndx].isForDynamicCases)
6338 group->addChild(new BufferDescriptorCase(group->getTestContext(),
6339 s_bufferTypes[ndx].name,
6340 s_bufferTypes[ndx].description,
6346 s_bufferTypes[ndx].flags));
6352 tcu::TestCaseGroup* createShaderAccessTests (tcu::TestContext& testCtx)
6356 const bool isPrimary;
6358 const char* description;
6361 { true, "primary_cmd_buf", "Bind in primary command buffer" },
6362 { false, "secondary_cmd_buf", "Bind in secondary command buffer" },
6366 const vk::VkDescriptorType descriptorType;
6368 const char* description;
6370 } s_descriptorTypes[] =
6372 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_mutable", "VK_DESCRIPTOR_TYPE_SAMPLER with mutable sampler", 0u },
6373 { vk::VK_DESCRIPTOR_TYPE_SAMPLER, "sampler_immutable", "VK_DESCRIPTOR_TYPE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6374 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_mutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with mutable sampler", 0u },
6375 { vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, "combined_image_sampler_immutable", "VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER with immutable sampler", RESOURCE_FLAG_IMMUTABLE_SAMPLER },
6376 // \note No way to access SAMPLED_IMAGE without a sampler
6377 //{ vk::VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, "sampled_image", "VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE", 0u },
6378 { vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, "storage_image", "VK_DESCRIPTOR_TYPE_STORAGE_IMAGE", 0u },
6379 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, "uniform_texel_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER", 0u },
6380 { vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER, "storage_texel_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER", 0u },
6381 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, "uniform_buffer", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER", 0u },
6382 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, "storage_buffer", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER", 0u },
6383 { vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, "uniform_buffer_dynamic", "VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC", 0u },
6384 { vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, "storage_buffer_dynamic", "VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC", 0u },
6389 const char* description;
6390 vk::VkShaderStageFlags existingStages; //!< stages that exists
6391 vk::VkShaderStageFlags activeStages; //!< stages that access resource
6392 bool supportsSecondaryCmdBufs;
6393 } s_shaderStages[] =
6397 "No accessing stages",
6398 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6405 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6406 vk::VK_SHADER_STAGE_VERTEX_BIT,
6411 "Tessellation control stage",
6412 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,
6413 vk::VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT,
6418 "Tessellation evaluation stage",
6419 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,
6420 vk::VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT,
6426 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_GEOMETRY_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6427 vk::VK_SHADER_STAGE_GEOMETRY_BIT,
6433 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6434 vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6440 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6441 vk::VK_SHADER_STAGE_COMPUTE_BIT,
6446 "Vertex and fragment stages",
6447 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6448 vk::VK_SHADER_STAGE_VERTEX_BIT | vk::VK_SHADER_STAGE_FRAGMENT_BIT,
6454 ShaderInputInterface dimension;
6456 const char* description;
6457 } s_variableDimensions[] =
6459 { SHADER_INPUT_SINGLE_DESCRIPTOR, "single_descriptor", "Single descriptor" },
6460 { SHADER_INPUT_MULTIPLE_CONTIGUOUS_DESCRIPTORS, "multiple_contiguous_descriptors", "Multiple descriptors" },
6461 { SHADER_INPUT_MULTIPLE_DISCONTIGUOUS_DESCRIPTORS, "multiple_discontiguous_descriptors", "Multiple descriptors" },
6462 { SHADER_INPUT_DESCRIPTOR_ARRAY, "descriptor_array", "Descriptor array" },
6465 de::MovePtr<tcu::TestCaseGroup> group(new tcu::TestCaseGroup(testCtx, "shader_access", "Access resource via descriptor in a single descriptor set"));
6467 // .primary_cmd_buf...
6468 for (int bindTypeNdx = 0; bindTypeNdx < DE_LENGTH_OF_ARRAY(s_bindTypes); ++bindTypeNdx)
6470 de::MovePtr<tcu::TestCaseGroup> bindGroup(new tcu::TestCaseGroup(testCtx, s_bindTypes[bindTypeNdx].name, s_bindTypes[bindTypeNdx].description));
6472 // .sampler, .combined_image_sampler, other resource types ...
6473 for (int descriptorNdx = 0; descriptorNdx < DE_LENGTH_OF_ARRAY(s_descriptorTypes); ++descriptorNdx)
6475 de::MovePtr<tcu::TestCaseGroup> typeGroup(new tcu::TestCaseGroup(testCtx, s_descriptorTypes[descriptorNdx].name, s_descriptorTypes[descriptorNdx].description));
6477 for (int stageNdx = 0; stageNdx < DE_LENGTH_OF_ARRAY(s_shaderStages); ++stageNdx)
6479 if (s_bindTypes[bindTypeNdx].isPrimary || s_shaderStages[stageNdx].supportsSecondaryCmdBufs)
6481 de::MovePtr<tcu::TestCaseGroup> stageGroup(new tcu::TestCaseGroup(testCtx, s_shaderStages[stageNdx].name, s_shaderStages[stageNdx].description));
6483 for (int dimensionNdx = 0; dimensionNdx < DE_LENGTH_OF_ARRAY(s_variableDimensions); ++dimensionNdx)
6485 de::MovePtr<tcu::TestCaseGroup> dimensionGroup(new tcu::TestCaseGroup(testCtx, s_variableDimensions[dimensionNdx].name, s_variableDimensions[dimensionNdx].description));
6486 void (*createTestsFunc)(tcu::TestCaseGroup* group,
6487 bool isPrimaryCmdBuf,
6488 vk::VkDescriptorType descriptorType,
6489 vk::VkShaderStageFlags existingStages,
6490 vk::VkShaderStageFlags activeStages,
6491 ShaderInputInterface dimension,
6492 deUint32 resourceFlags);
6494 switch (s_descriptorTypes[descriptorNdx].descriptorType)
6496 case vk::VK_DESCRIPTOR_TYPE_SAMPLER:
6497 case vk::VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER:
6498 case vk::VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
6499 createTestsFunc = createShaderAccessImageTests;
6502 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER:
6503 case vk::VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER:
6504 createTestsFunc = createShaderAccessTexelBufferTests;
6507 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
6508 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER:
6509 case vk::VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC:
6510 case vk::VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC:
6511 createTestsFunc = createShaderAccessBufferTests;
6515 createTestsFunc = DE_NULL;
6516 DE_FATAL("Impossible");
6519 if (createTestsFunc)
6521 createTestsFunc(dimensionGroup.get(),
6522 s_bindTypes[bindTypeNdx].isPrimary,
6523 s_descriptorTypes[descriptorNdx].descriptorType,
6524 s_shaderStages[stageNdx].existingStages,
6525 s_shaderStages[stageNdx].activeStages,
6526 s_variableDimensions[dimensionNdx].dimension,
6527 s_descriptorTypes[descriptorNdx].flags);
6530 DE_FATAL("Impossible");
6532 stageGroup->addChild(dimensionGroup.release());
6535 typeGroup->addChild(stageGroup.release());
6539 bindGroup->addChild(typeGroup.release());
6542 group->addChild(bindGroup.release());
6545 return group.release();