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 Move<VkImage> createTestImage (const DeviceInterface& vkd,
71 VkImageCreateFlags createFlags)
73 const VkImageCreateInfo createInfo =
75 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
80 makeExtent3D(size.x(), size.y(), 1u),
83 VK_SAMPLE_COUNT_1_BIT,
84 VK_IMAGE_TILING_OPTIMAL,
85 VK_IMAGE_USAGE_SAMPLED_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT,
86 VK_SHARING_MODE_EXCLUSIVE,
88 (const deUint32*)DE_NULL,
89 VK_IMAGE_LAYOUT_UNDEFINED,
92 return createImage(vkd, device, &createInfo);
95 Move<VkImageView> createImageView (const DeviceInterface& vkd,
99 VkImageAspectFlagBits imageAspect,
100 const VkSamplerYcbcrConversionInfo* samplerConversionInfo)
102 const VkImageViewCreateInfo viewInfo =
104 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
105 samplerConversionInfo,
106 (VkImageViewCreateFlags)0,
108 VK_IMAGE_VIEW_TYPE_2D,
111 VK_COMPONENT_SWIZZLE_IDENTITY,
112 VK_COMPONENT_SWIZZLE_IDENTITY,
113 VK_COMPONENT_SWIZZLE_IDENTITY,
114 VK_COMPONENT_SWIZZLE_IDENTITY,
116 { (VkImageAspectFlags)imageAspect, 0u, 1u, 0u, 1u },
119 return createImageView(vkd, device, &viewInfo);
122 // Descriptor layout for set 1:
123 // 0: Plane view bound as COMBINED_IMAGE_SAMPLER
124 // 1: "Whole" image bound as COMBINED_IMAGE_SAMPLER
125 // + immutable sampler (required for color conversion)
127 Move<VkDescriptorSetLayout> createDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device, VkSampler conversionSampler)
129 const VkDescriptorSetLayoutBinding bindings[] =
133 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
134 1u, // descriptorCount
136 (const VkSampler*)DE_NULL
140 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
141 1u, // descriptorCount
146 const VkDescriptorSetLayoutCreateInfo layoutInfo =
148 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
150 (VkDescriptorSetLayoutCreateFlags)0u,
151 DE_LENGTH_OF_ARRAY(bindings),
155 return createDescriptorSetLayout(vkd, device, &layoutInfo);
158 Move<VkDescriptorPool> createDescriptorPool (const DeviceInterface& vkd, VkDevice device)
160 const VkDescriptorPoolSize poolSizes[] =
162 { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 2u },
164 const VkDescriptorPoolCreateInfo poolInfo =
166 VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO,
168 (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
170 DE_LENGTH_OF_ARRAY(poolSizes),
174 return createDescriptorPool(vkd, device, & poolInfo);
177 Move<VkDescriptorSet> createDescriptorSet (const DeviceInterface& vkd,
179 VkDescriptorPool descPool,
180 VkDescriptorSetLayout descLayout,
181 VkImageView planeView,
182 VkSampler planeViewSampler,
183 VkImageView wholeView,
184 VkSampler wholeViewSampler)
186 Move<VkDescriptorSet> descSet;
189 const VkDescriptorSetAllocateInfo allocInfo =
191 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
198 descSet = allocateDescriptorSet(vkd, device, &allocInfo);
202 const VkDescriptorImageInfo imageInfo0 =
206 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
208 const VkDescriptorImageInfo imageInfo1 =
212 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL
214 const VkWriteDescriptorSet descriptorWrites[] =
217 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
221 0u, // dstArrayElement
222 1u, // descriptorCount
223 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
225 (const VkDescriptorBufferInfo*)DE_NULL,
226 (const VkBufferView*)DE_NULL,
229 VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
233 0u, // dstArrayElement
234 1u, // descriptorCount
235 VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
237 (const VkDescriptorBufferInfo*)DE_NULL,
238 (const VkBufferView*)DE_NULL,
242 vkd.updateDescriptorSets(device, DE_LENGTH_OF_ARRAY(descriptorWrites), descriptorWrites, 0u, DE_NULL);
248 void executeImageBarrier (const DeviceInterface& vkd,
250 deUint32 queueFamilyNdx,
251 VkPipelineStageFlags srcStage,
252 VkPipelineStageFlags dstStage,
253 const VkImageMemoryBarrier& barrier)
255 const VkQueue queue = getDeviceQueue(vkd, device, queueFamilyNdx, 0u);
256 const Unique<VkCommandPool> cmdPool (createCommandPool(vkd, device, (VkCommandPoolCreateFlags)0, queueFamilyNdx));
257 const Unique<VkCommandBuffer> cmdBuffer (allocateCommandBuffer(vkd, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
259 beginCommandBuffer(vkd, *cmdBuffer);
261 vkd.cmdPipelineBarrier(*cmdBuffer,
264 (VkDependencyFlags)0u,
266 (const VkMemoryBarrier*)DE_NULL,
268 (const VkBufferMemoryBarrier*)DE_NULL,
272 endCommandBuffer(vkd, *cmdBuffer);
274 submitCommandsAndWait(vkd, device, queue, *cmdBuffer);
277 struct TestParameters
281 VIEWTYPE_IMAGE_VIEW = 0,
282 VIEWTYPE_MEMORY_ALIAS,
290 VkImageCreateFlags createFlags;
292 glu::ShaderType shaderType;
294 TestParameters (ViewType viewType_, VkFormat format_, const UVec2& size_, VkImageCreateFlags createFlags_, deUint32 planeNdx_, glu::ShaderType shaderType_)
295 : viewType (viewType_)
298 , createFlags (createFlags_)
299 , planeNdx (planeNdx_)
300 , shaderType (shaderType_)
304 TestParameters (void)
305 : viewType (VIEWTYPE_LAST)
306 , format (VK_FORMAT_UNDEFINED)
309 , shaderType (glu::SHADERTYPE_LAST)
314 ShaderSpec getShaderSpec (const TestParameters&)
318 spec.inputs.push_back(Symbol("texCoord", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP)));
319 spec.outputs.push_back(Symbol("result0", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
320 spec.outputs.push_back(Symbol("result1", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP)));
322 spec.globalDeclarations =
323 "layout(binding = 1, set = 1) uniform highp sampler2D u_image;\n"
324 "layout(binding = 0, set = 1) uniform highp sampler2D u_planeView;\n";
327 "result0 = texture(u_image, texCoord);\n"
328 "result1 = texture(u_planeView, texCoord);\n";
334 void generateLookupCoordinates (const UVec2& imageSize, size_t numCoords, de::Random* rnd, vector<Vec2>* dst)
336 dst->resize(numCoords);
338 for (size_t coordNdx = 0; coordNdx < numCoords; ++coordNdx)
340 const deUint32 texelX = rnd->getUint32() % imageSize.x();
341 const deUint32 texelY = rnd->getUint32() % imageSize.y();
342 const float x = ((float)texelX + 0.5f) / (float)imageSize.x();
343 const float y = ((float)texelY + 0.5f) / (float)imageSize.y();
345 (*dst)[coordNdx] = Vec2(x, y);
349 void checkImageUsageSupport (Context& context,
351 VkImageUsageFlags usage)
354 const VkFormatProperties formatProperties = getPhysicalDeviceFormatProperties(context.getInstanceInterface(),
355 context.getPhysicalDevice(),
357 const VkFormatFeatureFlags featureFlags = formatProperties.optimalTilingFeatures;
359 if ((usage & VK_IMAGE_USAGE_SAMPLED_BIT) != 0
360 && (featureFlags & VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT) == 0)
362 TCU_THROW(NotSupportedError, "Format doesn't support sampling");
365 // Other image usages are not handled currently
366 DE_ASSERT((usage & ~(VK_IMAGE_USAGE_TRANSFER_SRC_BIT|VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT)) == 0);
370 void checkSupport(Context& context, TestParameters params)
372 const VkFormat planeViewFormat = getPlaneCompatibleFormat(params.format, params.planeNdx);
373 const VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
375 checkImageSupport(context, params.format, params.createFlags);
376 checkImageUsageSupport(context, params.format, usage);
377 checkImageUsageSupport(context, planeViewFormat, usage);
380 tcu::TestStatus testPlaneView (Context& context, TestParameters params)
382 de::Random randomGen (deInt32Hash((deUint32)params.format) ^
383 deInt32Hash((deUint32)params.planeNdx) ^
384 deInt32Hash((deUint32)params.shaderType));
386 const DeviceInterface& vkd = context.getDeviceInterface();
387 const VkDevice device = context.getDevice();
389 const VkFormat format = params.format;
390 const VkImageCreateFlags createFlags = params.createFlags;
391 const VkFormat planeViewFormat = getPlaneCompatibleFormat(format, params.planeNdx);
392 const PlanarFormatDescription formatInfo = getPlanarFormatDescription(format);
393 const UVec2 size = params.size;
394 const UVec2 planeExtent = getPlaneExtent(formatInfo, size, params.planeNdx, 0);
395 const Unique<VkImage> image (createTestImage(vkd, device, format, size, createFlags));
396 const Unique<VkImage> imageAlias ((params.viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS)
397 ? createTestImage(vkd, device, planeViewFormat, planeExtent, createFlags)
399 const vector<AllocationSp> allocations (allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags));
402 VK_CHECK(vkd.bindImageMemory(device, *imageAlias, allocations[params.planeNdx]->getMemory(), allocations[params.planeNdx]->getOffset()));
404 const VkSamplerYcbcrConversionCreateInfo conversionInfo =
406 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO,
409 VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY,
410 VK_SAMPLER_YCBCR_RANGE_ITU_FULL,
412 VK_COMPONENT_SWIZZLE_IDENTITY,
413 VK_COMPONENT_SWIZZLE_IDENTITY,
414 VK_COMPONENT_SWIZZLE_IDENTITY,
415 VK_COMPONENT_SWIZZLE_IDENTITY,
417 VK_CHROMA_LOCATION_MIDPOINT,
418 VK_CHROMA_LOCATION_MIDPOINT,
420 VK_FALSE, // forceExplicitReconstruction
422 const Unique<VkSamplerYcbcrConversion> conversion (createSamplerYcbcrConversion(vkd, device, &conversionInfo));
423 const VkSamplerYcbcrConversionInfo samplerConversionInfo =
425 VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO,
429 const Unique<VkImageView> wholeView (createImageView(vkd, device, *image, format, VK_IMAGE_ASPECT_COLOR_BIT, &samplerConversionInfo));
430 const Unique<VkImageView> planeView (createImageView(vkd,
432 !imageAlias ? *image : *imageAlias,
434 !imageAlias ? getPlaneAspect(params.planeNdx) : VK_IMAGE_ASPECT_COLOR_BIT,
437 const VkSamplerCreateInfo wholeSamplerInfo =
439 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
440 &samplerConversionInfo,
442 VK_FILTER_NEAREST, // magFilter
443 VK_FILTER_NEAREST, // minFilter
444 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
445 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
446 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
447 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
449 VK_FALSE, // anisotropyEnable
450 1.0f, // maxAnisotropy
451 VK_FALSE, // compareEnable
452 VK_COMPARE_OP_ALWAYS, // compareOp
455 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor
456 VK_FALSE, // unnormalizedCoords
458 const VkSamplerCreateInfo planeSamplerInfo =
460 VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO,
463 VK_FILTER_NEAREST, // magFilter
464 VK_FILTER_NEAREST, // minFilter
465 VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode
466 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU
467 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV
468 VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW
470 VK_FALSE, // anisotropyEnable
471 1.0f, // maxAnisotropy
472 VK_FALSE, // compareEnable
473 VK_COMPARE_OP_ALWAYS, // compareOp
476 VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor
477 VK_FALSE, // unnormalizedCoords
480 const Unique<VkSampler> wholeSampler(createSampler(vkd, device, &wholeSamplerInfo));
481 const Unique<VkSampler> planeSampler(createSampler(vkd, device, &planeSamplerInfo));
483 const Unique<VkDescriptorSetLayout> descLayout (createDescriptorSetLayout(vkd, device, *wholeSampler));
484 const Unique<VkDescriptorPool> descPool (createDescriptorPool(vkd, device));
485 const Unique<VkDescriptorSet> descSet (createDescriptorSet(vkd, device, *descPool, *descLayout, *planeView, *planeSampler, *wholeView, *wholeSampler));
487 MultiPlaneImageData imageData (format, size);
489 // Prepare texture data
490 fillRandom(&randomGen, &imageData);
494 // Transition alias to right layout first
495 const VkImageMemoryBarrier initAliasBarrier =
497 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
500 VK_ACCESS_SHADER_READ_BIT,
501 VK_IMAGE_LAYOUT_UNDEFINED,
502 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
503 VK_QUEUE_FAMILY_IGNORED,
504 VK_QUEUE_FAMILY_IGNORED,
506 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u }
509 executeImageBarrier(vkd,
511 context.getUniversalQueueFamilyIndex(),
512 (VkPipelineStageFlags)VK_PIPELINE_STAGE_HOST_BIT,
513 (VkPipelineStageFlags)VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
517 // Upload and prepare image
520 context.getUniversalQueueFamilyIndex(),
521 context.getDefaultAllocator(),
524 (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT,
525 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
528 const size_t numValues = 500;
529 vector<Vec2> texCoord (numValues);
530 vector<Vec4> resultWhole (numValues);
531 vector<Vec4> resultPlane (numValues);
532 vector<Vec4> referenceWhole (numValues);
533 vector<Vec4> referencePlane (numValues);
535 Vec4 threshold (0.02f);
537 generateLookupCoordinates(size, numValues, &randomGen, &texCoord);
540 UniquePtr<ShaderExecutor> executor (createExecutor(context, params.shaderType, getShaderSpec(params), *descLayout));
541 const void* inputs[] = { texCoord[0].getPtr() };
542 void* outputs[] = { resultWhole[0].getPtr(), resultPlane[0].getPtr() };
544 executor->execute((int)numValues, inputs, outputs, *descSet);
547 // Whole image sampling reference
548 for (deUint32 channelNdx = 0; channelNdx < 4; channelNdx++)
550 if (formatInfo.hasChannelNdx(channelNdx))
552 const tcu::ConstPixelBufferAccess channelAccess = imageData.getChannelAccess(channelNdx);
553 const tcu::Sampler refSampler = mapVkSampler(wholeSamplerInfo);
554 const tcu::Texture2DView refTexView (1u, &channelAccess);
556 for (size_t ndx = 0; ndx < numValues; ++ndx)
558 const Vec2& coord = texCoord[ndx];
559 referenceWhole[ndx][channelNdx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f)[0];
564 for (size_t ndx = 0; ndx < numValues; ++ndx)
565 referenceWhole[ndx][channelNdx] = channelNdx == 3 ? 1.0f : 0.0f;
569 // Plane view sampling reference
571 const tcu::ConstPixelBufferAccess planeAccess (mapVkFormat(planeViewFormat),
572 tcu::IVec3((int)planeExtent.x(), (int)planeExtent.y(), 1),
573 imageData.getPlanePtr(params.planeNdx));
574 const tcu::Sampler refSampler = mapVkSampler(planeSamplerInfo);
575 const tcu::Texture2DView refTexView (1u, &planeAccess);
577 for (size_t ndx = 0; ndx < numValues; ++ndx)
579 const Vec2& coord = texCoord[ndx];
580 referencePlane[ndx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f);
584 for (int viewNdx = 0; viewNdx < 2; ++viewNdx)
586 const char* const viewName = (viewNdx == 0) ? "complete image" : "plane view";
587 const vector<Vec4>& reference = (viewNdx == 0) ? referenceWhole : referencePlane;
588 const vector<Vec4>& result = (viewNdx == 0) ? resultWhole : resultPlane;
590 for (size_t ndx = 0; ndx < numValues; ++ndx)
592 if (boolAny(greaterThanEqual(abs(result[ndx] - reference[ndx]), threshold)))
594 context.getTestContext().getLog()
595 << TestLog::Message << "ERROR: When sampling " << viewName << " at " << texCoord[ndx]
596 << ": got " << result[ndx]
597 << ", expected " << reference[ndx]
598 << TestLog::EndMessage;
605 return tcu::TestStatus::pass("All samples passed");
607 return tcu::TestStatus::fail("Got invalid results");
611 void initPrograms (SourceCollections& dst, TestParameters params)
613 const ShaderSpec spec = getShaderSpec(params);
615 generateSources(params.shaderType, spec, dst);
618 void addPlaneViewCase (tcu::TestCaseGroup* group, const TestParameters& params)
620 std::ostringstream name;
622 name << de::toLower(de::toString(params.format).substr(10));
624 if ((params.viewType != TestParameters::VIEWTYPE_MEMORY_ALIAS) &&
625 ((params.createFlags & VK_IMAGE_CREATE_DISJOINT_BIT) != 0))
628 name << "_plane_" << params.planeNdx;
630 addFunctionCaseWithPrograms(group, name.str(), "", checkSupport, initPrograms, testPlaneView, params);
633 void populateViewTypeGroup (tcu::TestCaseGroup* group, TestParameters::ViewType viewType)
635 const glu::ShaderType shaderType = glu::SHADERTYPE_FRAGMENT;
636 const UVec2 size (32, 58);
637 const VkImageCreateFlags baseFlags = (VkImageCreateFlags)VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
638 | (viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS ? (VkImageCreateFlags)VK_IMAGE_CREATE_ALIAS_BIT : 0u);
640 for (int formatNdx = VK_YCBCR_FORMAT_FIRST; formatNdx < VK_YCBCR_FORMAT_LAST; formatNdx++)
642 const VkFormat format = (VkFormat)formatNdx;
643 const deUint32 numPlanes = getPlaneCount(format);
646 continue; // Plane views not possible
648 for (int isDisjoint = 0; isDisjoint < 2; ++isDisjoint)
650 const VkImageCreateFlags flags = baseFlags | (isDisjoint == 1 ? (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT : 0u);
652 if ((viewType == TestParameters::VIEWTYPE_MEMORY_ALIAS) &&
653 ((flags & VK_IMAGE_CREATE_DISJOINT_BIT) == 0))
654 continue; // Memory alias cases require disjoint planes
656 for (deUint32 planeNdx = 0; planeNdx < numPlanes; ++planeNdx)
657 addPlaneViewCase(group, TestParameters(viewType, format, size, flags, planeNdx, shaderType));
662 void populateViewGroup (tcu::TestCaseGroup* group)
664 addTestGroup(group, "image_view", "Plane View via VkImageView", populateViewTypeGroup, TestParameters::VIEWTYPE_IMAGE_VIEW);
665 addTestGroup(group, "memory_alias", "Plane View via Memory Aliasing", populateViewTypeGroup, TestParameters::VIEWTYPE_MEMORY_ALIAS);
670 tcu::TestCaseGroup* createViewTests (tcu::TestContext& testCtx)
672 // \todo [2017-05-24 pyry] Extend with memory alias views
673 return createTestGroup(testCtx, "plane_view", "YCbCr Plane View Tests", populateViewGroup);