1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Imagination Technologies Ltd.
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 * \brief Image sampling case
23 *//*--------------------------------------------------------------------*/
25 #include "vktPipelineImageSamplingInstance.hpp"
26 #include "vktPipelineClearUtil.hpp"
27 #include "vktPipelineReferenceRenderer.hpp"
28 #include "vkBuilderUtil.hpp"
29 #include "vkImageUtil.hpp"
30 #include "vkPrograms.hpp"
31 #include "vkQueryUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "tcuImageCompare.hpp"
46 static VkImageType getCompatibleImageType (VkImageViewType viewType)
50 case VK_IMAGE_VIEW_TYPE_1D: return VK_IMAGE_TYPE_1D;
51 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return VK_IMAGE_TYPE_1D;
52 case VK_IMAGE_VIEW_TYPE_2D: return VK_IMAGE_TYPE_2D;
53 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return VK_IMAGE_TYPE_2D;
54 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D;
55 case VK_IMAGE_VIEW_TYPE_CUBE: return VK_IMAGE_TYPE_2D;
56 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D;
62 return VK_IMAGE_TYPE_1D;
65 template<typename TcuFormatType>
66 static MovePtr<TestTexture> createTestTexture (const TcuFormatType format, VkImageViewType viewType, const tcu::IVec3& size, int layerCount)
68 MovePtr<TestTexture> texture;
69 const VkImageType imageType = getCompatibleImageType(viewType);
73 case VK_IMAGE_TYPE_1D:
75 texture = MovePtr<TestTexture>(new TestTexture1D(format, size.x()));
77 texture = MovePtr<TestTexture>(new TestTexture1DArray(format, size.x(), layerCount));
81 case VK_IMAGE_TYPE_2D:
84 texture = MovePtr<TestTexture>(new TestTexture2D(format, size.x(), size.y()));
88 if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
90 if (layerCount == tcu::CUBEFACE_LAST)
92 texture = MovePtr<TestTexture>(new TestTextureCube(format, size.x()));
96 DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
98 texture = MovePtr<TestTexture>(new TestTextureCubeArray(format, size.x(), layerCount));
103 texture = MovePtr<TestTexture>(new TestTexture2DArray(format, size.x(), size.y(), layerCount));
109 case VK_IMAGE_TYPE_3D:
110 texture = MovePtr<TestTexture>(new TestTexture3D(format, size.x(), size.y(), size.z()));
120 template<typename TcuTextureType>
121 static void copySubresourceRange (TcuTextureType& dest, const TcuTextureType& src, const VkImageSubresourceRange& subresourceRange)
123 DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
124 DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
126 for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
128 const tcu::ConstPixelBufferAccess srcLevel (src.getLevel(subresourceRange.baseMipLevel + levelNdx));
129 const deUint32 srcLayerOffset = subresourceRange.baseArrayLayer * srcLevel.getWidth() * srcLevel.getHeight() * srcLevel.getFormat().getPixelSize();
130 const tcu::ConstPixelBufferAccess srcLevelLayers (srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), subresourceRange.layerCount, (deUint8*)srcLevel.getDataPtr() + srcLayerOffset);
132 if (dest.isLevelEmpty(levelNdx))
133 dest.allocLevel(levelNdx);
135 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
140 void copySubresourceRange<tcu::Texture1DArray> (tcu::Texture1DArray& dest, const tcu::Texture1DArray& src, const VkImageSubresourceRange& subresourceRange)
142 DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
143 DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
145 DE_ASSERT(subresourceRange.layerCount == (deUint32)dest.getNumLayers());
146 DE_ASSERT(subresourceRange.baseArrayLayer + subresourceRange.layerCount <= (deUint32)src.getNumLayers());
148 for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
150 const tcu::ConstPixelBufferAccess srcLevel (src.getLevel(subresourceRange.baseMipLevel + levelNdx));
151 const deUint32 srcLayerOffset = subresourceRange.baseArrayLayer * srcLevel.getWidth() * srcLevel.getFormat().getPixelSize();
152 const tcu::ConstPixelBufferAccess srcLevelLayers (srcLevel.getFormat(), srcLevel.getWidth(), subresourceRange.layerCount, 1, (deUint8*)srcLevel.getDataPtr() + srcLayerOffset);
154 if (dest.isLevelEmpty(levelNdx))
155 dest.allocLevel(levelNdx);
157 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
162 void copySubresourceRange<tcu::Texture3D>(tcu::Texture3D& dest, const tcu::Texture3D& src, const VkImageSubresourceRange& subresourceRange)
164 DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
165 DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
167 for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
169 const tcu::ConstPixelBufferAccess srcLevel(src.getLevel(subresourceRange.baseMipLevel + levelNdx));
170 const tcu::ConstPixelBufferAccess srcLevelLayers(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), (deUint8*)srcLevel.getDataPtr());
172 if (dest.isLevelEmpty(levelNdx))
173 dest.allocLevel(levelNdx);
175 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
179 static MovePtr<Program> createRefProgram(const tcu::TextureFormat& renderTargetFormat,
180 const tcu::Sampler& sampler,
182 const tcu::UVec4& componentMapping,
183 const TestTexture& testTexture,
184 VkImageViewType viewType,
186 const VkImageSubresourceRange& subresource)
188 MovePtr<Program> program;
189 const VkImageType imageType = getCompatibleImageType(viewType);
190 tcu::Vec4 lookupScale (1.0f);
191 tcu::Vec4 lookupBias (0.0f);
193 if (!testTexture.isCompressed())
195 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(testTexture.getLevel(0, 0).getFormat());
197 // Needed to normalize various formats to 0..1 range for writing into RT
198 lookupScale = fmtInfo.lookupScale;
199 lookupBias = fmtInfo.lookupBias;
201 // else: All supported compressed formats are fine with no normalization.
202 // ASTC LDR blocks decompress to f16 so querying normalization parameters
203 // based on uncompressed formats would actually lead to massive precision loss
204 // and complete lack of coverage in case of R8G8B8A8_UNORM RT.
208 case VK_IMAGE_TYPE_1D:
211 const tcu::Texture1D& texture = dynamic_cast<const TestTexture1D&>(testTexture).getTexture();
212 program = MovePtr<Program>(new SamplerProgram<tcu::Texture1D>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
216 const tcu::Texture1DArray& texture = dynamic_cast<const TestTexture1DArray&>(testTexture).getTexture();
218 if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getNumLayers())
220 // Not all texture levels and layers are needed. Create new sub-texture.
221 const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel);
222 tcu::Texture1DArray textureView (texture.getFormat(), baseLevel.getWidth(), subresource.layerCount);
224 copySubresourceRange(textureView, texture, subresource);
226 program = MovePtr<Program>(new SamplerProgram<tcu::Texture1DArray>(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
230 program = MovePtr<Program>(new SamplerProgram<tcu::Texture1DArray>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
235 case VK_IMAGE_TYPE_2D:
238 const tcu::Texture2D& texture = dynamic_cast<const TestTexture2D&>(testTexture).getTexture();
239 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2D>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
243 if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
245 if (layerCount == tcu::CUBEFACE_LAST)
247 const tcu::TextureCube& texture = dynamic_cast<const TestTextureCube&>(testTexture).getTexture();
248 program = MovePtr<Program>(new SamplerProgram<tcu::TextureCube>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
252 DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
254 const tcu::TextureCubeArray& texture = dynamic_cast<const TestTextureCubeArray&>(testTexture).getTexture();
256 if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getDepth())
258 DE_ASSERT(subresource.baseArrayLayer + subresource.layerCount <= (deUint32)texture.getDepth());
260 // Not all texture levels and layers are needed. Create new sub-texture.
261 const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel);
262 tcu::TextureCubeArray textureView (texture.getFormat(), baseLevel.getWidth(), subresource.layerCount);
264 copySubresourceRange(textureView, texture, subresource);
266 program = MovePtr<Program>(new SamplerProgram<tcu::TextureCubeArray>(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
270 // Use all array layers
271 program = MovePtr<Program>(new SamplerProgram<tcu::TextureCubeArray>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
277 const tcu::Texture2DArray& texture = dynamic_cast<const TestTexture2DArray&>(testTexture).getTexture();
279 if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getNumLayers())
281 DE_ASSERT(subresource.baseArrayLayer + subresource.layerCount <= (deUint32)texture.getNumLayers());
283 // Not all texture levels and layers are needed. Create new sub-texture.
284 const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel);
285 tcu::Texture2DArray textureView (texture.getFormat(), baseLevel.getWidth(), baseLevel.getHeight(), subresource.layerCount);
287 copySubresourceRange(textureView, texture, subresource);
289 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2DArray>(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
293 // Use all array layers
294 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2DArray>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
300 case VK_IMAGE_TYPE_3D:
302 const tcu::Texture3D& texture = dynamic_cast<const TestTexture3D&>(testTexture).getTexture();
304 if (subresource.baseMipLevel > 0)
306 // Not all texture levels are needed. Create new sub-texture.
307 const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel);
308 tcu::Texture3D textureView(texture.getFormat(), baseLevel.getWidth(), baseLevel.getHeight(), baseLevel.getDepth());
310 copySubresourceRange(textureView, texture, subresource);
312 program = MovePtr<Program>(new SamplerProgram<tcu::Texture3D>(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
316 program = MovePtr<Program>(new SamplerProgram<tcu::Texture3D>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
330 ImageSamplingInstance::ImageSamplingInstance (Context& context,
331 const tcu::UVec2& renderSize,
332 VkImageViewType imageViewType,
333 VkFormat imageFormat,
334 const tcu::IVec3& imageSize,
336 const VkComponentMapping& componentMapping,
337 const VkImageSubresourceRange& subresourceRange,
338 const VkSamplerCreateInfo& samplerParams,
340 const std::vector<Vertex4Tex4>& vertices)
341 : vkt::TestInstance (context)
342 , m_imageViewType (imageViewType)
343 , m_imageFormat (imageFormat)
344 , m_imageSize (imageSize)
345 , m_layerCount (layerCount)
346 , m_componentMapping (componentMapping)
347 , m_subresourceRange (subresourceRange)
348 , m_samplerParams (samplerParams)
349 , m_samplerLod (samplerLod)
350 , m_renderSize (renderSize)
351 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
352 , m_vertices (vertices)
354 const DeviceInterface& vk = context.getDeviceInterface();
355 const VkDevice vkDevice = context.getDevice();
356 const VkQueue queue = context.getUniversalQueue();
357 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
358 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
359 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
361 if (!isSupportedSamplableFormat(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat))
362 throw tcu::NotSupportedError(std::string("Unsupported format for sampling: ") + getFormatName(imageFormat));
364 if ((samplerParams.minFilter == VK_FILTER_LINEAR ||
365 samplerParams.magFilter == VK_FILTER_LINEAR ||
366 samplerParams.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR) &&
367 !isLinearFilteringSupported(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat, VK_IMAGE_TILING_OPTIMAL))
368 throw tcu::NotSupportedError(std::string("Unsupported format for linear filtering: ") + getFormatName(imageFormat));
370 if (isCompressedFormat(imageFormat) && imageViewType == VK_IMAGE_VIEW_TYPE_3D)
372 // \todo [2016-01-22 pyry] Mandate VK_ERROR_FORMAT_NOT_SUPPORTED
375 const VkImageFormatProperties formatProperties = getPhysicalDeviceImageFormatProperties(context.getInstanceInterface(),
376 context.getPhysicalDevice(),
379 VK_IMAGE_TILING_OPTIMAL,
380 VK_IMAGE_USAGE_SAMPLED_BIT,
381 (VkImageCreateFlags)0);
383 if (formatProperties.maxExtent.width == 0 &&
384 formatProperties.maxExtent.height == 0 &&
385 formatProperties.maxExtent.depth == 0)
386 TCU_THROW(NotSupportedError, "3D compressed format not supported");
390 TCU_THROW(NotSupportedError, "3D compressed format not supported");
394 // Create texture image, view and sampler
396 VkImageCreateFlags imageFlags = 0u;
398 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
399 imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
401 // Initialize texture data
402 if (isCompressedFormat(imageFormat))
403 m_texture = createTestTexture(mapVkCompressedFormat(imageFormat), imageViewType, imageSize, layerCount);
405 m_texture = createTestTexture(mapVkFormat(imageFormat), imageViewType, imageSize, layerCount);
407 const VkImageCreateInfo imageParams =
409 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
410 DE_NULL, // const void* pNext;
411 imageFlags, // VkImageCreateFlags flags;
412 getCompatibleImageType(m_imageViewType), // VkImageType imageType;
413 imageFormat, // VkFormat format;
414 { // VkExtent3D extent;
415 (deUint32)m_imageSize.x(),
416 (deUint32)m_imageSize.y(),
417 (deUint32)m_imageSize.z()
419 (deUint32)m_texture->getNumLevels(), // deUint32 mipLevels;
420 (deUint32)m_layerCount, // deUint32 arrayLayers;
421 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
422 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
423 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
424 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
425 1u, // deUint32 queueFamilyIndexCount;
426 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
427 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
430 m_image = createImage(vk, vkDevice, &imageParams);
431 m_imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_image), MemoryRequirement::Any);
432 VK_CHECK(vk.bindImageMemory(vkDevice, *m_image, m_imageAlloc->getMemory(), m_imageAlloc->getOffset()));
434 // Upload texture data
435 uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, *m_image);
437 // Create image view and sampler
438 const VkImageViewCreateInfo imageViewParams =
440 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
441 DE_NULL, // const void* pNext;
442 0u, // VkImageViewCreateFlags flags;
443 *m_image, // VkImage image;
444 m_imageViewType, // VkImageViewType viewType;
445 imageFormat, // VkFormat format;
446 m_componentMapping, // VkComponentMapping components;
447 m_subresourceRange, // VkImageSubresourceRange subresourceRange;
450 m_imageView = createImageView(vk, vkDevice, &imageViewParams);
451 m_sampler = createSampler(vk, vkDevice, &m_samplerParams);
454 // Create descriptor set for combined image and sampler
456 DescriptorPoolBuilder descriptorPoolBuilder;
457 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u);
458 m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
460 DescriptorSetLayoutBuilder setLayoutBuilder;
461 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
462 m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
464 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
466 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
467 DE_NULL, // const void* pNext;
468 *m_descriptorPool, // VkDescriptorPool descriptorPool;
469 1u, // deUint32 setLayoutCount;
470 &m_descriptorSetLayout.get() // const VkDescriptorSetLayout* pSetLayouts;
473 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
475 const VkDescriptorImageInfo descriptorImageInfo =
477 *m_sampler, // VkSampler sampler;
478 *m_imageView, // VkImageView imageView;
479 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
482 DescriptorSetUpdateBuilder setUpdateBuilder;
483 setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo);
484 setUpdateBuilder.update(vk, vkDevice);
487 // Create color image and view
489 const VkImageCreateInfo colorImageParams =
491 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
492 DE_NULL, // const void* pNext;
493 0u, // VkImageCreateFlags flags;
494 VK_IMAGE_TYPE_2D, // VkImageType imageType;
495 m_colorFormat, // VkFormat format;
496 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
497 1u, // deUint32 mipLevels;
498 1u, // deUint32 arrayLayers;
499 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
500 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
501 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
502 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
503 1u, // deUint32 queueFamilyIndexCount;
504 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
505 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
508 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
509 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
510 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
512 const VkImageViewCreateInfo colorAttachmentViewParams =
514 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
515 DE_NULL, // const void* pNext;
516 0u, // VkImageViewCreateFlags flags;
517 *m_colorImage, // VkImage image;
518 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
519 m_colorFormat, // VkFormat format;
520 componentMappingRGBA, // VkComponentMapping components;
521 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
524 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
527 // Create render pass
529 const VkAttachmentDescription colorAttachmentDescription =
531 0u, // VkAttachmentDescriptionFlags flags;
532 m_colorFormat, // VkFormat format;
533 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
534 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
535 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
536 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
537 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
538 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
539 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
542 const VkAttachmentReference colorAttachmentReference =
544 0u, // deUint32 attachment;
545 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
548 const VkSubpassDescription subpassDescription =
550 0u, // VkSubpassDescriptionFlags flags;
551 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
552 0u, // deUint32 inputAttachmentCount;
553 DE_NULL, // const VkAttachmentReference* pInputAttachments;
554 1u, // deUint32 colorAttachmentCount;
555 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
556 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
557 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
558 0u, // deUint32 preserveAttachmentCount;
559 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
562 const VkRenderPassCreateInfo renderPassParams =
564 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
565 DE_NULL, // const void* pNext;
566 0u, // VkRenderPassCreateFlags flags;
567 1u, // deUint32 attachmentCount;
568 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
569 1u, // deUint32 subpassCount;
570 &subpassDescription, // const VkSubpassDescription* pSubpasses;
571 0u, // deUint32 dependencyCount;
572 DE_NULL // const VkSubpassDependency* pDependencies;
575 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
578 // Create framebuffer
580 const VkFramebufferCreateInfo framebufferParams =
582 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
583 DE_NULL, // const void* pNext;
584 0u, // VkFramebufferCreateFlags flags;
585 *m_renderPass, // VkRenderPass renderPass;
586 1u, // deUint32 attachmentCount;
587 &m_colorAttachmentView.get(), // const VkImageView* pAttachments;
588 (deUint32)m_renderSize.x(), // deUint32 width;
589 (deUint32)m_renderSize.y(), // deUint32 height;
590 1u // deUint32 layers;
593 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
596 // Create pipeline layout
598 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
600 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
601 DE_NULL, // const void* pNext;
602 0u, // VkPipelineLayoutCreateFlags flags;
603 1u, // deUint32 setLayoutCount;
604 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
605 0u, // deUint32 pushConstantRangeCount;
606 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
609 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
612 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
613 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
617 const VkPipelineShaderStageCreateInfo shaderStages[2] =
620 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
621 DE_NULL, // const void* pNext;
622 0u, // VkPipelineShaderStageCreateFlags flags;
623 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
624 *m_vertexShaderModule, // VkShaderModule module;
625 "main", // const char* pName;
626 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
629 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
630 DE_NULL, // const void* pNext;
631 0u, // VkPipelineShaderStageCreateFlags flags;
632 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
633 *m_fragmentShaderModule, // VkShaderModule module;
634 "main", // const char* pName;
635 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
639 const VkVertexInputBindingDescription vertexInputBindingDescription =
641 0u, // deUint32 binding;
642 sizeof(Vertex4Tex4), // deUint32 strideInBytes;
643 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
646 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
649 0u, // deUint32 location;
650 0u, // deUint32 binding;
651 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
652 0u // deUint32 offset;
655 1u, // deUint32 location;
656 0u, // deUint32 binding;
657 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
658 DE_OFFSET_OF(Vertex4Tex4, texCoord), // deUint32 offset;
662 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
664 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
665 DE_NULL, // const void* pNext;
666 0u, // VkPipelineVertexInputStateCreateFlags flags;
667 1u, // deUint32 vertexBindingDescriptionCount;
668 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
669 2u, // deUint32 vertexAttributeDescriptionCount;
670 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
673 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
675 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
676 DE_NULL, // const void* pNext;
677 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
678 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
679 false // VkBool32 primitiveRestartEnable;
682 const VkViewport viewport =
686 (float)m_renderSize.x(), // float width;
687 (float)m_renderSize.y(), // float height;
688 0.0f, // float minDepth;
689 1.0f // float maxDepth;
692 const VkRect2D scissor = { { 0, 0 }, { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } };
694 const VkPipelineViewportStateCreateInfo viewportStateParams =
696 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
697 DE_NULL, // const void* pNext;
698 0u, // VkPipelineViewportStateCreateFlags flags;
699 1u, // deUint32 viewportCount;
700 &viewport, // const VkViewport* pViewports;
701 1u, // deUint32 scissorCount;
702 &scissor // const VkRect2D* pScissors;
705 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
707 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
708 DE_NULL, // const void* pNext;
709 0u, // VkPipelineRasterizationStateCreateFlags flags;
710 false, // VkBool32 depthClampEnable;
711 false, // VkBool32 rasterizerDiscardEnable;
712 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
713 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
714 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
715 false, // VkBool32 depthBiasEnable;
716 0.0f, // float depthBiasConstantFactor;
717 0.0f, // float depthBiasClamp;
718 0.0f, // float depthBiasSlopeFactor;
719 1.0f // float lineWidth;
722 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
724 false, // VkBool32 blendEnable;
725 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
726 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
727 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
728 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
729 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
730 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
731 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
732 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
735 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
737 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
738 DE_NULL, // const void* pNext;
739 0u, // VkPipelineColorBlendStateCreateFlags flags;
740 false, // VkBool32 logicOpEnable;
741 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
742 1u, // deUint32 attachmentCount;
743 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
744 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
747 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
749 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
750 DE_NULL, // const void* pNext;
751 0u, // VkPipelineMultisampleStateCreateFlags flags;
752 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
753 false, // VkBool32 sampleShadingEnable;
754 0.0f, // float minSampleShading;
755 DE_NULL, // const VkSampleMask* pSampleMask;
756 false, // VkBool32 alphaToCoverageEnable;
757 false // VkBool32 alphaToOneEnable;
760 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
762 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
763 DE_NULL, // const void* pNext;
764 0u, // VkPipelineDepthStencilStateCreateFlags flags;
765 false, // VkBool32 depthTestEnable;
766 false, // VkBool32 depthWriteEnable;
767 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
768 false, // VkBool32 depthBoundsTestEnable;
769 false, // VkBool32 stencilTestEnable;
770 { // VkStencilOpState front;
771 VK_STENCIL_OP_ZERO, // VkStencilOp failOp;
772 VK_STENCIL_OP_ZERO, // VkStencilOp passOp;
773 VK_STENCIL_OP_ZERO, // VkStencilOp depthFailOp;
774 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
775 0u, // deUint32 compareMask;
776 0u, // deUint32 writeMask;
777 0u // deUint32 reference;
779 { // VkStencilOpState back;
780 VK_STENCIL_OP_ZERO, // VkStencilOp failOp;
781 VK_STENCIL_OP_ZERO, // VkStencilOp passOp;
782 VK_STENCIL_OP_ZERO, // VkStencilOp depthFailOp;
783 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
784 0u, // deUint32 compareMask;
785 0u, // deUint32 writeMask;
786 0u // deUint32 reference;
788 -1.0f, // float minDepthBounds;
789 +1.0f // float maxDepthBounds;
792 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
794 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
795 DE_NULL, // const void* pNext;
796 0u, // VkPipelineCreateFlags flags;
797 2u, // deUint32 stageCount;
798 shaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
799 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
800 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
801 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
802 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
803 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
804 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
805 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
806 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
807 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
808 *m_pipelineLayout, // VkPipelineLayout layout;
809 *m_renderPass, // VkRenderPass renderPass;
810 0u, // deUint32 subpass;
811 0u, // VkPipeline basePipelineHandle;
812 0u // deInt32 basePipelineIndex;
815 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
818 // Create vertex buffer
820 const VkDeviceSize vertexBufferSize = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
821 const VkBufferCreateInfo vertexBufferParams =
823 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
824 DE_NULL, // const void* pNext;
825 0u, // VkBufferCreateFlags flags;
826 vertexBufferSize, // VkDeviceSize size;
827 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
828 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
829 1u, // deUint32 queueFamilyIndexCount;
830 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
833 DE_ASSERT(vertexBufferSize > 0);
835 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
836 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
838 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
840 // Load vertices into vertex buffer
841 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
842 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
845 // Create command pool
847 const VkCommandPoolCreateInfo cmdPoolParams =
849 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
850 DE_NULL, // const void* pNext;
851 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
852 queueFamilyIndex // deUint32 queueFamilyIndex;
855 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
858 // Create command buffer
860 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
862 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
863 DE_NULL, // const void* pNext;
864 *m_cmdPool, // VkCommandPool commandPool;
865 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
866 1u, // deUint32 bufferCount;
869 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
871 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
872 DE_NULL, // const void* pNext;
873 0u, // VkCommandBufferUsageFlags flags;
874 (const VkCommandBufferInheritanceInfo*)DE_NULL,
877 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
879 const VkRenderPassBeginInfo renderPassBeginInfo =
881 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
882 DE_NULL, // const void* pNext;
883 *m_renderPass, // VkRenderPass renderPass;
884 *m_framebuffer, // VkFramebuffer framebuffer;
887 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
888 }, // VkRect2D renderArea;
889 1, // deUint32 clearValueCount;
890 &attachmentClearValue // const VkClearValue* pClearValues;
893 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
895 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
896 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
898 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
900 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
902 const VkDeviceSize vertexBufferOffset = 0;
903 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
904 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
906 vk.cmdEndRenderPass(*m_cmdBuffer);
907 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
912 const VkFenceCreateInfo fenceParams =
914 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
915 DE_NULL, // const void* pNext;
916 0u // VkFenceCreateFlags flags;
919 m_fence = createFence(vk, vkDevice, &fenceParams);
923 ImageSamplingInstance::~ImageSamplingInstance (void)
927 tcu::TestStatus ImageSamplingInstance::iterate (void)
929 const DeviceInterface& vk = m_context.getDeviceInterface();
930 const VkDevice vkDevice = m_context.getDevice();
931 const VkQueue queue = m_context.getUniversalQueue();
932 const VkSubmitInfo submitInfo =
934 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
935 DE_NULL, // const void* pNext;
936 0u, // deUint32 waitSemaphoreCount;
937 DE_NULL, // const VkSemaphore* pWaitSemaphores;
939 1u, // deUint32 commandBufferCount;
940 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
941 0u, // deUint32 signalSemaphoreCount;
942 DE_NULL // const VkSemaphore* pSignalSemaphores;
945 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
946 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
947 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
949 return verifyImage();
952 tcu::TestStatus ImageSamplingInstance::verifyImage (void)
954 const tcu::TextureFormat colorFormat = mapVkFormat(m_colorFormat);
955 const tcu::TextureFormat depthStencilFormat = tcu::TextureFormat(); // Undefined depth/stencil format.
956 const tcu::Sampler sampler = mapVkSampler(m_samplerParams);
957 const tcu::UVec4 componentMapping = mapVkComponentMapping(m_componentMapping);
960 MovePtr<Program> program;
961 MovePtr<ReferenceRenderer> refRenderer;
963 // Set up LOD of reference sampler
964 samplerLod = de::max(m_samplerParams.minLod, de::min(m_samplerParams.maxLod, m_samplerParams.mipLodBias + m_samplerLod));
966 // Create reference program that uses image subresource range
967 program = createRefProgram(colorFormat, sampler, samplerLod, componentMapping, *m_texture, m_imageViewType, m_layerCount, m_subresourceRange);
968 const rr::Program referenceProgram = program->getReferenceProgram();
970 // Render reference image
971 refRenderer = MovePtr<ReferenceRenderer>(new ReferenceRenderer(m_renderSize.x(), m_renderSize.y(), 1, colorFormat, depthStencilFormat, &referenceProgram));
972 const rr::RenderState renderState(refRenderer->getViewportState());
973 refRenderer->draw(renderState, rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
975 // Compare result with reference image
977 const DeviceInterface& vk = m_context.getDeviceInterface();
978 const VkDevice vkDevice = m_context.getDevice();
979 const VkQueue queue = m_context.getUniversalQueue();
980 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
981 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
982 MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_colorImage, m_colorFormat, m_renderSize);
983 tcu::UVec4 threshold = tcu::UVec4(4, 4, 4, 4);
985 if ((m_imageFormat == vk::VK_FORMAT_EAC_R11G11_SNORM_BLOCK) || (m_imageFormat == vk::VK_FORMAT_EAC_R11_SNORM_BLOCK))
986 threshold = tcu::UVec4(8, 8, 8, 8);
988 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
991 refRenderer->getAccess(),
996 tcu::COMPARE_LOG_RESULT);
1000 return tcu::TestStatus::pass("Result image matches reference");
1002 return tcu::TestStatus::fail("Image mismatch");