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,
75 // 16-bit compatibility class
76 // Compatible formats with VK_FORMAT_R8G8_UNORM, VK_FORMAT_R10X6_UNORM_PACK16, VK_FORMAT_R12X4_UNORM_PACK16 and VK_FORMAT_R16_UNORM
79 VK_FORMAT_R10X6_UNORM_PACK16,
80 VK_FORMAT_R12X4_UNORM_PACK16,
84 VK_FORMAT_R4G4B4A4_UNORM_PACK16,
85 // 32-bit compatibility class
86 // Compatible formats for VK_FORMAT_R10X6G10X6_UNORM_2PACK16, VK_FORMAT_R12X4G12X4_UNORM_2PACK16 and VK_FORMAT_R16G16_UNORM
87 VK_FORMAT_R10X6G10X6_UNORM_2PACK16,
88 VK_FORMAT_R12X4G12X4_UNORM_2PACK16,
89 VK_FORMAT_R16G16_UNORM,
90 VK_FORMAT_R8G8B8A8_UNORM,
91 VK_FORMAT_R8G8B8A8_UINT,
95 inline bool formatsAreCompatible (const VkFormat format0, const VkFormat format1)
97 return format0 == format1 || mapVkFormat(format0).getPixelSize() == mapVkFormat(format1).getPixelSize();
100 Move<VkImage> createTestImage (const DeviceInterface& vkd,
104 VkImageCreateFlags createFlags)
106 const VkImageCreateInfo createInfo =
108 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
113 makeExtent3D(size.x(), size.y(), 1u),
116 VK_SAMPLE_COUNT_1_BIT,
117 VK_IMAGE_TILING_OPTIMAL,
118 VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT,
119 VK_SHARING_MODE_EXCLUSIVE,
121 (const deUint32*)DE_NULL,
122 VK_IMAGE_LAYOUT_UNDEFINED,
125 return createImage(vkd, device, &createInfo);
128 Move<VkImageView> createImageView (const DeviceInterface& vkd,
132 VkImageAspectFlagBits imageAspect,
133 const VkSamplerYcbcrConversionInfo* samplerConversionInfo)
135 const VkImageViewCreateInfo viewInfo =
137 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
138 samplerConversionInfo,
139 (VkImageViewCreateFlags)0,
141 VK_IMAGE_VIEW_TYPE_2D,
144 VK_COMPONENT_SWIZZLE_IDENTITY,
145 VK_COMPONENT_SWIZZLE_IDENTITY,
146 VK_COMPONENT_SWIZZLE_IDENTITY,
147 VK_COMPONENT_SWIZZLE_IDENTITY,
149 { (VkImageAspectFlags)imageAspect, 0u, 1u, 0u, 1u },
152 return createImageView(vkd, device, &viewInfo);
155 // Descriptor layout for set 1:
156 // 0: Plane view bound as COMBINED_IMAGE_SAMPLER
157 // 1: "Whole" image bound as COMBINED_IMAGE_SAMPLER
158 // + immutable sampler (required for color conversion)
160 Move<VkDescriptorSetLayout> createDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device, VkSampler conversionSampler)
162 const VkDescriptorSetLayoutBinding bindings[] =
166 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
167 1u, // descriptorCount
169 (const VkSampler*)DE_NULL
173 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
174 1u, // descriptorCount
179 const VkDescriptorSetLayoutCreateInfo layoutInfo =
181 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
183 (VkDescriptorSetLayoutCreateFlags)0u,
184 DE_LENGTH_OF_ARRAY(bindings),
188 return createDescriptorSetLayout(vkd, device, &layoutInfo);
191 Move<VkDescriptorPool> createDescriptorPool (const DeviceInterface& vkd, VkDevice device, const deUint32 combinedSamplerDescriptorCount)
193 const VkDescriptorPoolSize poolSizes[] =
195 { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u * combinedSamplerDescriptorCount },
197 const VkDescriptorPoolCreateInfo poolInfo =
199 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
201 (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
203 DE_LENGTH_OF_ARRAY(poolSizes),
207 return createDescriptorPool(vkd, device, & poolInfo);
210 Move<VkDescriptorSet> createDescriptorSet (const DeviceInterface& vkd,
212 VkDescriptorPool descPool,
213 VkDescriptorSetLayout descLayout,
214 VkImageView planeView,
215 VkSampler planeViewSampler,
216 VkImageView wholeView,
217 VkSampler wholeViewSampler)
219 Move<VkDescriptorSet> descSet;
222 const VkDescriptorSetAllocateInfo allocInfo =
224 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
231 descSet = allocateDescriptorSet(vkd, device, &allocInfo);
235 const VkDescriptorImageInfo imageInfo0 =
239 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
241 const VkDescriptorImageInfo imageInfo1 =
245 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
247 const VkWriteDescriptorSet descriptorWrites[] =
250 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
254 0u, // dstArrayElement
255 1u, // descriptorCount
256 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
258 (const VkDescriptorBufferInfo*)DE_NULL,
259 (const VkBufferView*)DE_NULL,
262 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
266 0u, // dstArrayElement
267 1u, // descriptorCount
268 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
270 (const VkDescriptorBufferInfo*)DE_NULL,
271 (const VkBufferView*)DE_NULL,
275 vkd.updateDescriptorSets(device, DE_LENGTH_OF_ARRAY(descriptorWrites), descriptorWrites, 0u, DE_NULL);
281 void executeImageBarrier (const DeviceInterface& vkd,
283 deUint32 queueFamilyNdx,
284 VkPipelineStageFlags srcStage,
285 VkPipelineStageFlags dstStage,
286 const VkImageMemoryBarrier& barrier)
288 const VkQueue queue = getDeviceQueue(vkd, device, queueFamilyNdx, 0u);
289 const Unique<VkCommandPool> cmdPool (createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx));
290 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
292 beginCommandBuffer(vkd, *cmdBuffer);
294 vkd.cmdPipelineBarrier(*cmdBuffer,
297 (VkDependencyFlags)0u,
299 (const VkMemoryBarrier*)DE_NULL,
301 (const VkBufferMemoryBarrier*)DE_NULL,
305 endCommandBuffer(vkd, *cmdBuffer);
307 submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
310 struct TestParameters
314 VIEWTYPE_IMAGE_VIEW = 0,
315 VIEWTYPE_MEMORY_ALIAS,
323 VkImageCreateFlags createFlags;
325 VkFormat planeCompatibleFormat;
326 glu::ShaderType shaderType;
327 deBool isCompatibilityFormat;
329 TestParameters (ViewType viewType_, VkFormat format_, const UVec2& size_, VkImageCreateFlags createFlags_, deUint32 planeNdx_, VkFormat planeCompatibleFormat_, glu::ShaderType shaderType_, deBool isCompatibilityFormat_)
330 : viewType (viewType_)
333 , createFlags (createFlags_)
334 , planeNdx (planeNdx_)
335 , planeCompatibleFormat (planeCompatibleFormat_)
336 , shaderType (shaderType_)
337 , isCompatibilityFormat (isCompatibilityFormat_)
341 TestParameters (void)
342 : viewType (VIEWTYPE_LAST)
343 , format (VK_FORMAT_UNDEFINED)
346 , planeCompatibleFormat (VK_FORMAT_UNDEFINED)
347 , shaderType (glu::SHADERTYPE_LAST)
348 , isCompatibilityFormat (false)
353 static std::string getSamplerDecl(VkFormat f) {
354 if (isIntFormat(f)) return "isampler2D";
355 else if (isUintFormat(f)) return "usampler2D";
356 else return "sampler2D";
359 ShaderSpec getShaderSpec (const TestParameters& params)
363 spec.inputs.push_back(Symbol("texCoord", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
364 spec.outputs.push_back(Symbol("result0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
365 spec.outputs.push_back(Symbol("result1", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
367 const std::string sampler = getSamplerDecl(params.planeCompatibleFormat);
368 spec.globalDeclarations =
369 "layout(binding = 1, set = 1) uniform highp sampler2D u_image;\n"
370 "layout(binding = 0, set = 1) uniform highp " + sampler + " u_planeView;\n";
373 "result0 = texture(u_image, texCoord);\n"
374 "result1 = vec4(texture(u_planeView, texCoord));\n";
380 void generateLookupCoordinates (const UVec2& imageSize, size_t numCoords, de::Random* rnd, vector<Vec2>* dst)
382 dst->resize(numCoords);
384 for (size_t coordNdx = 0; coordNdx < numCoords; ++coordNdx)
386 const deUint32 texelX = rnd->getUint32() % imageSize.x();
387 const deUint32 texelY = rnd->getUint32() % imageSize.y();
388 const float x = ((float)texelX + 0.5f) / (float)imageSize.x();
389 const float y = ((float)texelY + 0.5f) / (float)imageSize.y();
391 (*dst)[coordNdx] = Vec2(x, y);
395 void checkImageUsageSupport (Context& context,
397 VkImageUsageFlags usage)
399 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(),
400 context.getPhysicalDevice(),
402 const VkFormatFeatureFlags featureFlags = formatProperties.optimalTilingFeatures;
404 if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0
405 && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0)
407 TCU_THROW(NotSupportedError, "Format doesn't support sampling");
410 // Other image usages are not handled currently
411 DE_ASSERT((usage & ~(VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT)) == 0);
414 void checkSupport(Context& context, TestParameters params)
416 const VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
418 checkImageSupport(context, params.format, params.createFlags);
419 checkImageUsageSupport(context, params.format, usage);
420 checkImageUsageSupport(context, params.planeCompatibleFormat, usage);
423 tcu::TestStatus testPlaneView (Context& context, TestParameters params)
425 de::Random randomGen (deInt32Hash((deUint32)params.format) ^
426 deInt32Hash((deUint32)params.planeNdx) ^
427 deInt32Hash((deUint32)params.shaderType));
429 const InstanceInterface& vk = context.getInstanceInterface();
430 const DeviceInterface& vkd = context.getDeviceInterface();
431 const VkDevice device = context.getDevice();
433 const VkFormat format = params.format;
434 const VkImageCreateFlags createFlags = params.createFlags;
435 const PlanarFormatDescription formatInfo = getPlanarFormatDescription(format);
436 const UVec2 size = params.size;
437 const UVec2 planeExtent = getPlaneExtent(formatInfo, size, params.planeNdx, 0);
438 const Unique<VkImage> image (createTestImage(vkd, device, format, size, createFlags));
439 const Unique<VkImage> imageAlias ((params.viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS)
440 ? createTestImage(vkd, device, params.planeCompatibleFormat, planeExtent, createFlags)
442 const vector<AllocationSp> allocations (allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags));
446 if ((createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0)
448 VkBindImagePlaneMemoryInfo planeInfo =
450 VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO_KHR,
452 VK_IMAGE_ASPECT_PLANE_0_BIT_KHR
455 VkBindImageMemoryInfo coreInfo =
457 VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_INFO_KHR,
460 allocations[params.planeNdx]->getMemory(),
461 allocations[params.planeNdx]->getOffset(),
464 VK_CHECK(vkd.bindImageMemory2(device, 1, &coreInfo));
468 VK_CHECK(vkd.bindImageMemory(device, *imageAlias, allocations[params.planeNdx]->getMemory(), allocations[params.planeNdx]->getOffset()));
472 const VkSamplerYcbcrConversionCreateInfo conversionInfo =
474 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
477 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
478 VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
480 VK_COMPONENT_SWIZZLE_IDENTITY,
481 VK_COMPONENT_SWIZZLE_IDENTITY,
482 VK_COMPONENT_SWIZZLE_IDENTITY,
483 VK_COMPONENT_SWIZZLE_IDENTITY,
485 VK_CHROMA_LOCATION_MIDPOINT,
486 VK_CHROMA_LOCATION_MIDPOINT,
488 VK_FALSE, // forceExplicitReconstruction
490 const Unique<VkSamplerYcbcrConversion> conversion (createSamplerYcbcrConversion(vkd, device, &conversionInfo));
491 const VkSamplerYcbcrConversionInfo samplerConversionInfo =
493 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
497 const Unique<VkImageView> wholeView (createImageView(vkd, device, *image, format, VK_IMAGE_ASPECT_COLOR_BIT, &samplerConversionInfo));
498 const Unique<VkImageView> planeView (createImageView(vkd,
500 !imageAlias ? *image : *imageAlias,
501 params.planeCompatibleFormat,
502 !imageAlias ? getPlaneAspect(params.planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT,
505 const VkSamplerCreateInfo wholeSamplerInfo =
507 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
508 &samplerConversionInfo,
510 VK_FILTER_NEAREST, // magFilter
511 VK_FILTER_NEAREST, // minFilter
512 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
513 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
514 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
515 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
517 VK_FALSE, // anisotropyEnable
518 1.0f, // maxAnisotropy
519 VK_FALSE, // compareEnable
520 VK_COMPARE_OP_ALWAYS, // compareOp
523 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor
524 VK_FALSE, // unnormalizedCoords
526 const VkSamplerCreateInfo planeSamplerInfo =
528 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
531 VK_FILTER_NEAREST, // magFilter
532 VK_FILTER_NEAREST, // minFilter
533 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
534 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
535 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
536 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
538 VK_FALSE, // anisotropyEnable
539 1.0f, // maxAnisotropy
540 VK_FALSE, // compareEnable
541 VK_COMPARE_OP_ALWAYS, // compareOp
544 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor
545 VK_FALSE, // unnormalizedCoords
548 deUint32 combinedSamplerDescriptorCount = 1;
550 const VkPhysicalDeviceImageFormatInfo2 imageFormatInfo =
552 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // sType;
555 VK_IMAGE_TYPE_2D, // type;
556 VK_IMAGE_TILING_OPTIMAL, // tiling;
557 VK_IMAGE_USAGE_TRANSFER_DST_BIT |
558 VK_IMAGE_USAGE_SAMPLED_BIT, // usage;
559 createFlags // flags;
562 VkSamplerYcbcrConversionImageFormatProperties samplerYcbcrConversionImage = {};
563 samplerYcbcrConversionImage.sType = VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES;
564 samplerYcbcrConversionImage.pNext = DE_NULL;
566 VkImageFormatProperties2 imageFormatProperties = {};
567 imageFormatProperties.sType = VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2;
568 imageFormatProperties.pNext = &samplerYcbcrConversionImage;
570 VkResult result = vk.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &imageFormatInfo, &imageFormatProperties);
571 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
572 TCU_THROW(NotSupportedError, "Format not supported.");
574 combinedSamplerDescriptorCount = samplerYcbcrConversionImage.combinedImageSamplerDescriptorCount;
577 const Unique<VkSampler> wholeSampler(createSampler(vkd, device, &wholeSamplerInfo));
578 const Unique<VkSampler> planeSampler(createSampler(vkd, device, &planeSamplerInfo));
580 const Unique<VkDescriptorSetLayout> descLayout (createDescriptorSetLayout(vkd, device, *wholeSampler));
581 const Unique<VkDescriptorPool> descPool (createDescriptorPool(vkd, device, combinedSamplerDescriptorCount));
582 const Unique<VkDescriptorSet> descSet (createDescriptorSet(vkd, device, *descPool, *descLayout, *planeView, *planeSampler, *wholeView, *wholeSampler));
584 MultiPlaneImageData imageData (format, size);
586 // Prepare texture data
587 fillRandom(&randomGen, &imageData);
591 // Transition alias to right layout first
592 const VkImageMemoryBarrier initAliasBarrier =
594 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
597 VK_ACCESS_SHADER_READ_BIT,
598 VK_IMAGE_LAYOUT_UNDEFINED,
599 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
600 VK_QUEUE_FAMILY_IGNORED,
601 VK_QUEUE_FAMILY_IGNORED,
603 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }
606 executeImageBarrier(vkd,
608 context.getUniversalQueueFamilyIndex(),
609 (VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT,
610 (VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
614 // Upload and prepare image
617 context.getUniversalQueueFamilyIndex(),
618 context.getDefaultAllocator(),
621 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,
622 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
625 const size_t numValues = 500;
626 vector<Vec2> texCoord (numValues);
627 vector<Vec4> resultWhole (numValues);
628 vector<Vec4> resultPlane (numValues);
629 vector<Vec4> referenceWhole (numValues);
630 vector<Vec4> referencePlane (numValues);
632 Vec4 threshold (0.02f);
634 generateLookupCoordinates(size, numValues, &randomGen, &texCoord);
637 UniquePtr<ShaderExecutor> executor (createExecutor(context, params.shaderType, getShaderSpec(params), *descLayout));
638 const void* inputs[] = { texCoord[0].getPtr() };
639 void* outputs[] = { resultWhole[0].getPtr(), resultPlane[0].getPtr() };
641 executor->execute((int)numValues, inputs, outputs, *descSet);
644 // Whole image sampling reference
645 for (deUint32 channelNdx = 0; channelNdx < 4; channelNdx++)
647 if (formatInfo.hasChannelNdx(channelNdx))
649 const tcu::ConstPixelBufferAccess channelAccess = imageData.getChannelAccess(channelNdx);
650 const tcu::Sampler refSampler = mapVkSampler(wholeSamplerInfo);
651 const tcu::Texture2DView refTexView (1u, &channelAccess);
653 for (size_t ndx = 0; ndx < numValues; ++ndx)
655 const Vec2& coord = texCoord[ndx];
656 referenceWhole[ndx][channelNdx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f)[0];
661 for (size_t ndx = 0; ndx < numValues; ++ndx)
662 referenceWhole[ndx][channelNdx] = channelNdx == 3 ? 1.0f : 0.0f;
666 // Plane view sampling reference
668 const tcu::ConstPixelBufferAccess planeAccess (mapVkFormat(params.planeCompatibleFormat),
669 tcu::IVec3((int)planeExtent.x(), (int)planeExtent.y(), 1),
670 imageData.getPlanePtr(params.planeNdx));
671 const tcu::Sampler refSampler = mapVkSampler(planeSamplerInfo);
672 const tcu::Texture2DView refTexView (1u, &planeAccess);
674 for (size_t ndx = 0; ndx < numValues; ++ndx)
676 const Vec2& coord = texCoord[ndx];
677 referencePlane[ndx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f);
681 for (int viewNdx = 0; viewNdx < 2; ++viewNdx)
683 const char* const viewName = (viewNdx == 0) ? "complete image" : "plane view";
684 const vector<Vec4>& reference = (viewNdx == 0) ? referenceWhole : referencePlane;
685 const vector<Vec4>& result = (viewNdx == 0) ? resultWhole : resultPlane;
687 for (size_t ndx = 0; ndx < numValues; ++ndx)
689 if (boolAny(greaterThanEqual(abs(result[ndx] - reference[ndx]), threshold)))
691 context.getTestContext().getLog()
692 << TestLog::Message << "ERROR: When sampling " << viewName << " at " << texCoord[ndx]
693 << ": got " << result[ndx]
694 << ", expected " << reference[ndx]
695 << TestLog::EndMessage;
702 return tcu::TestStatus::pass("All samples passed");
704 return tcu::TestStatus::fail("Got invalid results");
708 void initPrograms (SourceCollections& dst, TestParameters params)
710 const ShaderSpec spec = getShaderSpec(params);
712 generateSources(params.shaderType, spec, dst);
715 void addPlaneViewCase (tcu::TestCaseGroup* group, const TestParameters& params)
717 std::ostringstream name;
719 name << de::toLower(de::toString(params.format).substr(10));
721 if ((params.viewType != TestParameters::VIEWTYPE_MEMORY_ALIAS) &&
722 ((params.createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0))
725 name << "_plane_" << params.planeNdx;
727 if (params.isCompatibilityFormat)
729 name << "_compatible_format_" << de::toLower(de::toString(params.planeCompatibleFormat).substr(10));
732 addFunctionCaseWithPrograms(group, name.str(), "", checkSupport, initPrograms, testPlaneView, params);
735 void populateViewTypeGroup (tcu::TestCaseGroup* group, TestParameters::ViewType viewType)
737 const glu::ShaderType shaderType = glu::SHADERTYPE_FRAGMENT;
738 const UVec2 size (32, 58);
739 const VkImageCreateFlags baseFlags = (VkImageCreateFlags)VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
740 | (viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS ? (VkImageCreateFlags)VK_IMAGE_CREATE_ALIAS_BIT : 0u);
742 auto addTests = [&](int formatNdx)
744 const VkFormat format = (VkFormat)formatNdx;
745 const deUint32 numPlanes = getPlaneCount(format);
748 return; // Plane views not possible
750 for (int isDisjoint = 0; isDisjoint < 2; ++isDisjoint)
752 const VkImageCreateFlags flags = baseFlags | (isDisjoint == 1 ? (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT : 0u);
754 if ((viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS) &&
755 ((flags & VK_IMAGE_CREATE_DISJOINT_BIT) == 0))
756 continue; // Memory alias cases require disjoint planes
758 for (deUint32 planeNdx = 0; planeNdx < numPlanes; ++planeNdx)
760 const VkFormat planeFormat = getPlaneCompatibleFormat(format, planeNdx);
761 // Add test case using image view with a format taken from the "Plane Format Compatibility Table"
762 addPlaneViewCase(group, TestParameters(viewType, format, size, flags, planeNdx, planeFormat, shaderType, DE_FALSE));
764 // Add test cases using image view with a format that is compatible with the plane's format.
765 // For example: VK_FORMAT_R4G4_UNORM_PACK8 is compatible with VK_FORMAT_R8_UNORM.
766 for (const auto& compatibleFormat : s_compatible_formats)
768 if (compatibleFormat == planeFormat)
771 if (!formatsAreCompatible(planeFormat, compatibleFormat))
774 addPlaneViewCase(group, TestParameters(viewType, format, size, flags, planeNdx, compatibleFormat, shaderType, DE_TRUE));
780 for (int formatNdx = VK_YCBCR_FORMAT_FIRST; formatNdx < VK_YCBCR_FORMAT_LAST; formatNdx++)
785 for (int formatNdx = VK_FORMAT_G8_B8R8_2PLANE_444_UNORM_EXT; formatNdx < VK_FORMAT_G16_B16R16_2PLANE_444_UNORM_EXT; formatNdx++)
791 void populateViewGroup (tcu::TestCaseGroup* group)
793 addTestGroup(group, "image_view", "Plane View via VkImageView", populateViewTypeGroup, TestParameters::VIEWTYPE_IMAGE_VIEW);
794 addTestGroup(group, "memory_alias", "Plane View via Memory Aliasing", populateViewTypeGroup, TestParameters::VIEWTYPE_MEMORY_ALIAS);
799 tcu::TestCaseGroup* createViewTests (tcu::TestContext& testCtx)
801 return createTestGroup(testCtx, "plane_view", "YCbCr Plane View Tests", populateViewGroup);