1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 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 YCbCr Image View Tests
22 *//*--------------------------------------------------------------------*/
24 #include "vktYCbCrViewTests.hpp"
25 #include "vktYCbCrUtil.hpp"
26 #include "vktTestCaseUtil.hpp"
27 #include "vktTestGroupUtil.hpp"
28 #include "vktShaderExecutor.hpp"
30 #include "vkStrUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkTypeUtil.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkImageUtil.hpp"
37 #include "vkCmdUtil.hpp"
39 #include "tcuTestLog.hpp"
40 #include "tcuVectorUtil.hpp"
42 #include "deStringUtil.hpp"
43 #include "deSharedPtr.hpp"
44 #include "deUniquePtr.hpp"
45 #include "deRandom.hpp"
46 #include "deSTLUtil.hpp"
56 using namespace shaderexecutor;
67 // List of some formats compatible with formats listed in "Plane Format Compatibility Table".
68 const VkFormat s_compatible_formats[] =
70 // 8-bit compatibility class
71 // Compatible format for VK_FORMAT_R8_UNORM
72 VK_FORMAT_R4G4_UNORM_PACK8,
73 // 16-bit compatibility class
74 // Compatible formats with VK_FORMAT_R8G8_UNORM, VK_FORMAT_R10X6_UNORM_PACK16, VK_FORMAT_R12X4_UNORM_PACK16 and VK_FORMAT_R16_UNORM
76 VK_FORMAT_R10X6_UNORM_PACK16,
77 VK_FORMAT_R12X4_UNORM_PACK16,
79 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
80 // 32-bit compatibility class
81 // Compatible formats for VK_FORMAT_R10X6G10X6_UNORM_2PACK16, VK_FORMAT_R12X4G12X4_UNORM_2PACK16 and VK_FORMAT_R16G16_UNORM
82 VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
83 VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
84 VK_FORMAT_R16G16_UNORM,
85 VK_FORMAT_R8G8B8A8_UNORM,
88 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
90 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
93 Move<VkImage> createTestImage (const DeviceInterface& vkd,
97 VkImageCreateFlags createFlags)
99 const VkImageCreateInfo createInfo =
101 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
106 makeExtent3D(size.x(), size.y(), 1u),
109 VK_SAMPLE_COUNT_1_BIT,
110 VK_IMAGE_TILING_OPTIMAL,
111 VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT,
112 VK_SHARING_MODE_EXCLUSIVE,
114 (const deUint32*)DE_NULL,
115 VK_IMAGE_LAYOUT_UNDEFINED,
118 return createImage(vkd, device, &createInfo);
121 Move<VkImageView> createImageView (const DeviceInterface& vkd,
125 VkImageAspectFlagBits imageAspect,
126 const VkSamplerYcbcrConversionInfo* samplerConversionInfo)
128 const VkImageViewCreateInfo viewInfo =
130 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
131 samplerConversionInfo,
132 (VkImageViewCreateFlags)0,
134 VK_IMAGE_VIEW_TYPE_2D,
137 VK_COMPONENT_SWIZZLE_IDENTITY,
138 VK_COMPONENT_SWIZZLE_IDENTITY,
139 VK_COMPONENT_SWIZZLE_IDENTITY,
140 VK_COMPONENT_SWIZZLE_IDENTITY,
142 { (VkImageAspectFlags)imageAspect, 0u, 1u, 0u, 1u },
145 return createImageView(vkd, device, &viewInfo);
148 // Descriptor layout for set 1:
149 // 0: Plane view bound as COMBINED_IMAGE_SAMPLER
150 // 1: "Whole" image bound as COMBINED_IMAGE_SAMPLER
151 // + immutable sampler (required for color conversion)
153 Move<VkDescriptorSetLayout> createDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device, VkSampler conversionSampler)
155 const VkDescriptorSetLayoutBinding bindings[] =
159 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
160 1u, // descriptorCount
162 (const VkSampler*)DE_NULL
166 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
167 1u, // descriptorCount
172 const VkDescriptorSetLayoutCreateInfo layoutInfo =
174 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
176 (VkDescriptorSetLayoutCreateFlags)0u,
177 DE_LENGTH_OF_ARRAY(bindings),
181 return createDescriptorSetLayout(vkd, device, &layoutInfo);
184 Move<VkDescriptorPool> createDescriptorPool (const DeviceInterface& vkd, VkDevice device, const deUint32 combinedSamplerDescriptorCount)
186 const VkDescriptorPoolSize poolSizes[] =
188 { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u * combinedSamplerDescriptorCount },
190 const VkDescriptorPoolCreateInfo poolInfo =
192 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
194 (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
196 DE_LENGTH_OF_ARRAY(poolSizes),
200 return createDescriptorPool(vkd, device, & poolInfo);
203 Move<VkDescriptorSet> createDescriptorSet (const DeviceInterface& vkd,
205 VkDescriptorPool descPool,
206 VkDescriptorSetLayout descLayout,
207 VkImageView planeView,
208 VkSampler planeViewSampler,
209 VkImageView wholeView,
210 VkSampler wholeViewSampler)
212 Move<VkDescriptorSet> descSet;
215 const VkDescriptorSetAllocateInfo allocInfo =
217 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
224 descSet = allocateDescriptorSet(vkd, device, &allocInfo);
228 const VkDescriptorImageInfo imageInfo0 =
232 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
234 const VkDescriptorImageInfo imageInfo1 =
238 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
240 const VkWriteDescriptorSet descriptorWrites[] =
243 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
247 0u, // dstArrayElement
248 1u, // descriptorCount
249 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
251 (const VkDescriptorBufferInfo*)DE_NULL,
252 (const VkBufferView*)DE_NULL,
255 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
259 0u, // dstArrayElement
260 1u, // descriptorCount
261 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
263 (const VkDescriptorBufferInfo*)DE_NULL,
264 (const VkBufferView*)DE_NULL,
268 vkd.updateDescriptorSets(device, DE_LENGTH_OF_ARRAY(descriptorWrites), descriptorWrites, 0u, DE_NULL);
274 void executeImageBarrier (const DeviceInterface& vkd,
276 deUint32 queueFamilyNdx,
277 VkPipelineStageFlags srcStage,
278 VkPipelineStageFlags dstStage,
279 const VkImageMemoryBarrier& barrier)
281 const VkQueue queue = getDeviceQueue(vkd, device, queueFamilyNdx, 0u);
282 const Unique<VkCommandPool> cmdPool (createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx));
283 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
285 beginCommandBuffer(vkd, *cmdBuffer);
287 vkd.cmdPipelineBarrier(*cmdBuffer,
290 (VkDependencyFlags)0u,
292 (const VkMemoryBarrier*)DE_NULL,
294 (const VkBufferMemoryBarrier*)DE_NULL,
298 endCommandBuffer(vkd, *cmdBuffer);
300 submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
303 struct TestParameters
307 VIEWTYPE_IMAGE_VIEW = 0,
308 VIEWTYPE_MEMORY_ALIAS,
316 VkImageCreateFlags createFlags;
318 VkFormat planeCompatibleFormat;
319 glu::ShaderType shaderType;
320 deBool isCompatibilityFormat;
322 TestParameters (ViewType viewType_, VkFormat format_, const UVec2& size_, VkImageCreateFlags createFlags_, deUint32 planeNdx_, VkFormat planeCompatibleFormat_, glu::ShaderType shaderType_, deBool isCompatibilityFormat_)
323 : viewType (viewType_)
326 , createFlags (createFlags_)
327 , planeNdx (planeNdx_)
328 , planeCompatibleFormat (planeCompatibleFormat_)
329 , shaderType (shaderType_)
330 , isCompatibilityFormat (isCompatibilityFormat_)
334 TestParameters (void)
335 : viewType (VIEWTYPE_LAST)
336 , format (VK_FORMAT_UNDEFINED)
339 , planeCompatibleFormat (VK_FORMAT_UNDEFINED)
340 , shaderType (glu::SHADERTYPE_LAST)
341 , isCompatibilityFormat (false)
346 ShaderSpec getShaderSpec (const TestParameters&)
350 spec.inputs.push_back(Symbol("texCoord", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
351 spec.outputs.push_back(Symbol("result0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
352 spec.outputs.push_back(Symbol("result1", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
354 spec.globalDeclarations =
355 "layout(binding = 1, set = 1) uniform highp sampler2D u_image;\n"
356 "layout(binding = 0, set = 1) uniform highp sampler2D u_planeView;\n";
359 "result0 = texture(u_image, texCoord);\n"
360 "result1 = texture(u_planeView, texCoord);\n";
366 void generateLookupCoordinates (const UVec2& imageSize, size_t numCoords, de::Random* rnd, vector<Vec2>* dst)
368 dst->resize(numCoords);
370 for (size_t coordNdx = 0; coordNdx < numCoords; ++coordNdx)
372 const deUint32 texelX = rnd->getUint32() % imageSize.x();
373 const deUint32 texelY = rnd->getUint32() % imageSize.y();
374 const float x = ((float)texelX + 0.5f) / (float)imageSize.x();
375 const float y = ((float)texelY + 0.5f) / (float)imageSize.y();
377 (*dst)[coordNdx] = Vec2(x, y);
381 void checkImageUsageSupport (Context& context,
383 VkImageUsageFlags usage)
385 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(),
386 context.getPhysicalDevice(),
388 const VkFormatFeatureFlags featureFlags = formatProperties.optimalTilingFeatures;
390 if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0
391 && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0)
393 TCU_THROW(NotSupportedError, "Format doesn't support sampling");
396 // Other image usages are not handled currently
397 DE_ASSERT((usage & ~(VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT)) == 0);
400 void checkSupport(Context& context, TestParameters params)
402 const VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
404 checkImageSupport(context, params.format, params.createFlags);
405 checkImageUsageSupport(context, params.format, usage);
406 checkImageUsageSupport(context, params.planeCompatibleFormat, usage);
409 tcu::TestStatus testPlaneView (Context& context, TestParameters params)
411 de::Random randomGen (deInt32Hash((deUint32)params.format) ^
412 deInt32Hash((deUint32)params.planeNdx) ^
413 deInt32Hash((deUint32)params.shaderType));
415 const InstanceInterface& vk = context.getInstanceInterface();
416 const DeviceInterface& vkd = context.getDeviceInterface();
417 const VkDevice device = context.getDevice();
419 const VkFormat format = params.format;
420 const VkImageCreateFlags createFlags = params.createFlags;
421 const PlanarFormatDescription formatInfo = getPlanarFormatDescription(format);
422 const UVec2 size = params.size;
423 const UVec2 planeExtent = getPlaneExtent(formatInfo, size, params.planeNdx, 0);
424 const Unique<VkImage> image (createTestImage(vkd, device, format, size, createFlags));
425 const Unique<VkImage> imageAlias ((params.viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS)
426 ? createTestImage(vkd, device, params.planeCompatibleFormat, planeExtent, createFlags)
428 const vector<AllocationSp> allocations (allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags));
432 if ((createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0)
434 VkBindImagePlaneMemoryInfo planeInfo =
436 VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR,
438 VK_IMAGE_ASPECT_PLANE_0_BIT_KHR
441 VkBindImageMemoryInfo coreInfo =
443 VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,
446 allocations[params.planeNdx]->getMemory(),
447 allocations[params.planeNdx]->getOffset(),
450 VK_CHECK(vkd.bindImageMemory2(device, 1, &coreInfo));
454 VK_CHECK(vkd.bindImageMemory(device, *imageAlias, allocations[params.planeNdx]->getMemory(), allocations[params.planeNdx]->getOffset()));
458 const VkSamplerYcbcrConversionCreateInfo conversionInfo =
460 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
463 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
464 VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
466 VK_COMPONENT_SWIZZLE_IDENTITY,
467 VK_COMPONENT_SWIZZLE_IDENTITY,
468 VK_COMPONENT_SWIZZLE_IDENTITY,
469 VK_COMPONENT_SWIZZLE_IDENTITY,
471 VK_CHROMA_LOCATION_MIDPOINT,
472 VK_CHROMA_LOCATION_MIDPOINT,
474 VK_FALSE, // forceExplicitReconstruction
476 const Unique<VkSamplerYcbcrConversion> conversion (createSamplerYcbcrConversion(vkd, device, &conversionInfo));
477 const VkSamplerYcbcrConversionInfo samplerConversionInfo =
479 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
483 const Unique<VkImageView> wholeView (createImageView(vkd, device, *image, format, VK_IMAGE_ASPECT_COLOR_BIT, &samplerConversionInfo));
484 const Unique<VkImageView> planeView (createImageView(vkd,
486 !imageAlias ? *image : *imageAlias,
487 params.planeCompatibleFormat,
488 !imageAlias ? getPlaneAspect(params.planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT,
491 const VkSamplerCreateInfo wholeSamplerInfo =
493 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
494 &samplerConversionInfo,
496 VK_FILTER_NEAREST, // magFilter
497 VK_FILTER_NEAREST, // minFilter
498 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
499 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
500 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
501 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
503 VK_FALSE, // anisotropyEnable
504 1.0f, // maxAnisotropy
505 VK_FALSE, // compareEnable
506 VK_COMPARE_OP_ALWAYS, // compareOp
509 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor
510 VK_FALSE, // unnormalizedCoords
512 const VkSamplerCreateInfo planeSamplerInfo =
514 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
517 VK_FILTER_NEAREST, // magFilter
518 VK_FILTER_NEAREST, // minFilter
519 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
520 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
521 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
522 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
524 VK_FALSE, // anisotropyEnable
525 1.0f, // maxAnisotropy
526 VK_FALSE, // compareEnable
527 VK_COMPARE_OP_ALWAYS, // compareOp
530 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor
531 VK_FALSE, // unnormalizedCoords
534 deUint32 combinedSamplerDescriptorCount = 1;
536 const VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
538 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType;
541 VK_IMAGE_TYPE_2D, // type;
542 VK_IMAGE_TILING_OPTIMAL, // tiling;
543 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
544 VK_IMAGE_USAGE_SAMPLED_BIT, // usage;
545 createFlags // flags;
548 VkSamplerYcbcrConversionImageFormatProperties samplerYcbcrConversionImage = {};
549 samplerYcbcrConversionImage.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES;
550 samplerYcbcrConversionImage.pNext = DE_NULL;
552 VkImageFormatProperties2 imageFormatProperties = {};
553 imageFormatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
554 imageFormatProperties.pNext = &samplerYcbcrConversionImage;
556 VkResult result = vk.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &imageFormatInfo, &imageFormatProperties);
557 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
558 TCU_THROW(NotSupportedError, "Format not supported.");
560 combinedSamplerDescriptorCount = samplerYcbcrConversionImage.combinedImageSamplerDescriptorCount;
563 const Unique<VkSampler> wholeSampler(createSampler(vkd, device, &wholeSamplerInfo));
564 const Unique<VkSampler> planeSampler(createSampler(vkd, device, &planeSamplerInfo));
566 const Unique<VkDescriptorSetLayout> descLayout (createDescriptorSetLayout(vkd, device, *wholeSampler));
567 const Unique<VkDescriptorPool> descPool (createDescriptorPool(vkd, device, combinedSamplerDescriptorCount));
568 const Unique<VkDescriptorSet> descSet (createDescriptorSet(vkd, device, *descPool, *descLayout, *planeView, *planeSampler, *wholeView, *wholeSampler));
570 MultiPlaneImageData imageData (format, size);
572 // Prepare texture data
573 fillRandom(&randomGen, &imageData);
577 // Transition alias to right layout first
578 const VkImageMemoryBarrier initAliasBarrier =
580 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
583 VK_ACCESS_SHADER_READ_BIT,
584 VK_IMAGE_LAYOUT_UNDEFINED,
585 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
586 VK_QUEUE_FAMILY_IGNORED,
587 VK_QUEUE_FAMILY_IGNORED,
589 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }
592 executeImageBarrier(vkd,
594 context.getUniversalQueueFamilyIndex(),
595 (VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT,
596 (VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
600 // Upload and prepare image
603 context.getUniversalQueueFamilyIndex(),
604 context.getDefaultAllocator(),
607 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,
608 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
611 const size_t numValues = 500;
612 vector<Vec2> texCoord (numValues);
613 vector<Vec4> resultWhole (numValues);
614 vector<Vec4> resultPlane (numValues);
615 vector<Vec4> referenceWhole (numValues);
616 vector<Vec4> referencePlane (numValues);
618 Vec4 threshold (0.02f);
620 generateLookupCoordinates(size, numValues, &randomGen, &texCoord);
623 UniquePtr<ShaderExecutor> executor (createExecutor(context, params.shaderType, getShaderSpec(params), *descLayout));
624 const void* inputs[] = { texCoord[0].getPtr() };
625 void* outputs[] = { resultWhole[0].getPtr(), resultPlane[0].getPtr() };
627 executor->execute((int)numValues, inputs, outputs, *descSet);
630 // Whole image sampling reference
631 for (deUint32 channelNdx = 0; channelNdx < 4; channelNdx++)
633 if (formatInfo.hasChannelNdx(channelNdx))
635 const tcu::ConstPixelBufferAccess channelAccess = imageData.getChannelAccess(channelNdx);
636 const tcu::Sampler refSampler = mapVkSampler(wholeSamplerInfo);
637 const tcu::Texture2DView refTexView (1u, &channelAccess);
639 for (size_t ndx = 0; ndx < numValues; ++ndx)
641 const Vec2& coord = texCoord[ndx];
642 referenceWhole[ndx][channelNdx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f)[0];
647 for (size_t ndx = 0; ndx < numValues; ++ndx)
648 referenceWhole[ndx][channelNdx] = channelNdx == 3 ? 1.0f : 0.0f;
652 // Plane view sampling reference
654 const tcu::ConstPixelBufferAccess planeAccess (mapVkFormat(params.planeCompatibleFormat),
655 tcu::IVec3((int)planeExtent.x(), (int)planeExtent.y(), 1),
656 imageData.getPlanePtr(params.planeNdx));
657 const tcu::Sampler refSampler = mapVkSampler(planeSamplerInfo);
658 const tcu::Texture2DView refTexView (1u, &planeAccess);
660 for (size_t ndx = 0; ndx < numValues; ++ndx)
662 const Vec2& coord = texCoord[ndx];
663 referencePlane[ndx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f);
667 for (int viewNdx = 0; viewNdx < 2; ++viewNdx)
669 const char* const viewName = (viewNdx == 0) ? "complete image" : "plane view";
670 const vector<Vec4>& reference = (viewNdx == 0) ? referenceWhole : referencePlane;
671 const vector<Vec4>& result = (viewNdx == 0) ? resultWhole : resultPlane;
673 for (size_t ndx = 0; ndx < numValues; ++ndx)
675 if (boolAny(greaterThanEqual(abs(result[ndx] - reference[ndx]), threshold)))
677 context.getTestContext().getLog()
678 << TestLog::Message << "ERROR: When sampling " << viewName << " at " << texCoord[ndx]
679 << ": got " << result[ndx]
680 << ", expected " << reference[ndx]
681 << TestLog::EndMessage;
688 return tcu::TestStatus::pass("All samples passed");
690 return tcu::TestStatus::fail("Got invalid results");
694 void initPrograms (SourceCollections& dst, TestParameters params)
696 const ShaderSpec spec = getShaderSpec(params);
698 generateSources(params.shaderType, spec, dst);
701 void addPlaneViewCase (tcu::TestCaseGroup* group, const TestParameters& params)
703 std::ostringstream name;
705 name << de::toLower(de::toString(params.format).substr(10));
707 if ((params.viewType != TestParameters::VIEWTYPE_MEMORY_ALIAS) &&
708 ((params.createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0))
711 name << "_plane_" << params.planeNdx;
713 if (params.isCompatibilityFormat)
715 name << "_compatible_format_" << de::toLower(de::toString(params.planeCompatibleFormat).substr(10));
718 addFunctionCaseWithPrograms(group, name.str(), "", checkSupport, initPrograms, testPlaneView, params);
721 void populateViewTypeGroup (tcu::TestCaseGroup* group, TestParameters::ViewType viewType)
723 const glu::ShaderType shaderType = glu::SHADERTYPE_FRAGMENT;
724 const UVec2 size (32, 58);
725 const VkImageCreateFlags baseFlags = (VkImageCreateFlags)VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
726 | (viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS ? (VkImageCreateFlags)VK_IMAGE_CREATE_ALIAS_BIT : 0u);
728 auto addTests = [&](int formatNdx)
730 const VkFormat format = (VkFormat)formatNdx;
731 const deUint32 numPlanes = getPlaneCount(format);
734 return; // Plane views not possible
736 for (int isDisjoint = 0; isDisjoint < 2; ++isDisjoint)
738 const VkImageCreateFlags flags = baseFlags | (isDisjoint == 1 ? (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT : 0u);
740 if ((viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS) &&
741 ((flags & VK_IMAGE_CREATE_DISJOINT_BIT) == 0))
742 continue; // Memory alias cases require disjoint planes
744 for (deUint32 planeNdx = 0; planeNdx < numPlanes; ++planeNdx)
746 const VkFormat planeFormat = getPlaneCompatibleFormat(format, planeNdx);
747 // Add test case using image view with a format taken from the "Plane Format Compatibility Table"
748 addPlaneViewCase(group, TestParameters(viewType, format, size, flags, planeNdx, planeFormat, shaderType, DE_FALSE));
750 // Add test cases using image view with a format that is compatible with the plane's format.
751 // For example: VK_FORMAT_R4G4_UNORM_PACK8 is compatible with VK_FORMAT_R8_UNORM.
752 for (const auto& compatibleFormat : s_compatible_formats)
754 if (compatibleFormat == planeFormat)
757 if (!formatsAreCompatible(planeFormat, compatibleFormat))
760 addPlaneViewCase(group, TestParameters(viewType, format, size, flags, planeNdx, compatibleFormat, shaderType, DE_TRUE));
766 for (int formatNdx = VK_YCBCR_FORMAT_FIRST; formatNdx < VK_YCBCR_FORMAT_LAST; formatNdx++)
771 for (int formatNdx = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT; formatNdx < VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT; formatNdx++)
777 void populateViewGroup (tcu::TestCaseGroup* group)
779 addTestGroup(group, "image_view", "Plane View via VkImageView", populateViewTypeGroup, TestParameters::VIEWTYPE_IMAGE_VIEW);
780 addTestGroup(group, "memory_alias", "Plane View via Memory Aliasing", populateViewTypeGroup, TestParameters::VIEWTYPE_MEMORY_ALIAS);
785 tcu::TestCaseGroup* createViewTests (tcu::TestContext& testCtx)
787 return createTestGroup(testCtx, "plane_view", "YCbCr Plane View Tests", populateViewGroup);