| /*------------------------------------------------------------------------- |
| * Vulkan Conformance Tests |
| * ------------------------ |
| * |
| * Copyright (c) 2017 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| *//*! |
| * \file |
| * \brief YCbCr Format Tests |
| *//*--------------------------------------------------------------------*/ |
| |
| #include "vktYCbCrFormatTests.hpp" |
| #include "vktTestCaseUtil.hpp" |
| #include "vktCustomInstancesDevices.hpp" |
| #include "vktTestGroupUtil.hpp" |
| #include "vktShaderExecutor.hpp" |
| #include "vktYCbCrUtil.hpp" |
| |
| #include "vkStrUtil.hpp" |
| #include "vkRef.hpp" |
| #include "vkRefUtil.hpp" |
| #include "vkTypeUtil.hpp" |
| #include "vkQueryUtil.hpp" |
| #include "vkMemUtil.hpp" |
| #include "vkImageUtil.hpp" |
| #include "vkDeviceUtil.hpp" |
| #include "vkPlatform.hpp" |
| |
| #include "tcuTestLog.hpp" |
| #include "tcuVectorUtil.hpp" |
| |
| #include "deStringUtil.hpp" |
| #include "deSharedPtr.hpp" |
| #include "deUniquePtr.hpp" |
| #include "deRandom.hpp" |
| #include "deSTLUtil.hpp" |
| |
| namespace vkt |
| { |
| namespace ycbcr |
| { |
| namespace |
| { |
| |
| using namespace vk; |
| using namespace shaderexecutor; |
| |
| using tcu::UVec2; |
| using tcu::Vec2; |
| using tcu::Vec4; |
| using tcu::TestLog; |
| using de::MovePtr; |
| using de::UniquePtr; |
| using std::vector; |
| using std::string; |
| |
| Move<VkImage> createTestImage (const DeviceInterface& vkd, |
| VkDevice device, |
| VkFormat format, |
| const UVec2& size, |
| VkImageCreateFlags createFlags, |
| VkImageTiling tiling, |
| VkImageLayout layout, |
| deUint32 arrayLayers) |
| { |
| const VkImageCreateInfo createInfo = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, |
| DE_NULL, |
| createFlags, |
| VK_IMAGE_TYPE_2D, |
| format, |
| makeExtent3D(size.x(), size.y(), 1u), |
| 1u, // mipLevels |
| arrayLayers, // arrayLayers |
| VK_SAMPLE_COUNT_1_BIT, |
| tiling, |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, |
| VK_SHARING_MODE_EXCLUSIVE, |
| 0u, |
| (const deUint32*)DE_NULL, |
| layout, |
| }; |
| |
| return createImage(vkd, device, &createInfo); |
| } |
| |
| Move<VkImageView> createImageView (const DeviceInterface& vkd, |
| VkDevice device, |
| VkImage image, |
| VkFormat format, |
| VkSamplerYcbcrConversion conversion, |
| deUint32 layerCount) |
| { |
| const VkSamplerYcbcrConversionInfo conversionInfo = |
| { |
| VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, |
| DE_NULL, |
| conversion |
| }; |
| const VkImageViewCreateInfo viewInfo = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, |
| &conversionInfo, |
| (VkImageViewCreateFlags)0, |
| image, |
| (layerCount > 1) ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, |
| format, |
| { |
| VK_COMPONENT_SWIZZLE_IDENTITY, |
| VK_COMPONENT_SWIZZLE_IDENTITY, |
| VK_COMPONENT_SWIZZLE_IDENTITY, |
| VK_COMPONENT_SWIZZLE_IDENTITY, |
| }, |
| { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, layerCount }, |
| }; |
| |
| return createImageView(vkd, device, &viewInfo); |
| } |
| |
| Move<VkDescriptorSetLayout> createDescriptorSetLayout (const DeviceInterface& vkd, VkDevice device, VkSampler sampler) |
| { |
| const VkDescriptorSetLayoutBinding binding = |
| { |
| 0u, // binding |
| VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, |
| 1u, // descriptorCount |
| VK_SHADER_STAGE_ALL, |
| &sampler |
| }; |
| const VkDescriptorSetLayoutCreateInfo layoutInfo = |
| { |
| VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO, |
| DE_NULL, |
| (VkDescriptorSetLayoutCreateFlags)0u, |
| 1u, |
| &binding, |
| }; |
| |
| return createDescriptorSetLayout(vkd, device, &layoutInfo); |
| } |
| |
| Move<VkDescriptorPool> createDescriptorPool (const DeviceInterface& vkd, VkDevice device) |
| { |
| const VkDescriptorPoolSize poolSizes[] = |
| { |
| { VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u }, |
| }; |
| const VkDescriptorPoolCreateInfo poolInfo = |
| { |
| VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, |
| DE_NULL, |
| (VkDescriptorPoolCreateFlags)VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, |
| 1u, // maxSets |
| DE_LENGTH_OF_ARRAY(poolSizes), |
| poolSizes, |
| }; |
| |
| return createDescriptorPool(vkd, device, & poolInfo); |
| } |
| |
| Move<VkDescriptorSet> createDescriptorSet (const DeviceInterface& vkd, |
| VkDevice device, |
| VkDescriptorPool descPool, |
| VkDescriptorSetLayout descLayout, |
| VkImageView imageView) |
| { |
| Move<VkDescriptorSet> descSet; |
| |
| { |
| const VkDescriptorSetAllocateInfo allocInfo = |
| { |
| VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, |
| DE_NULL, |
| descPool, |
| 1u, |
| &descLayout, |
| }; |
| |
| descSet = allocateDescriptorSet(vkd, device, &allocInfo); |
| } |
| |
| { |
| const VkDescriptorImageInfo imageInfo = |
| { |
| 0xdeadbeef, // Not required to be valid. Use something invalid and not NULL |
| imageView, |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL |
| }; |
| const VkWriteDescriptorSet descriptorWrite = |
| { |
| VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, |
| DE_NULL, |
| *descSet, |
| 0u, // dstBinding |
| 0u, // dstArrayElement |
| 1u, // descriptorCount |
| VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, |
| &imageInfo, |
| (const VkDescriptorBufferInfo*)DE_NULL, |
| (const VkBufferView*)DE_NULL, |
| }; |
| |
| vkd.updateDescriptorSets(device, 1u, &descriptorWrite, 0u, DE_NULL); |
| } |
| |
| return descSet; |
| } |
| |
| struct TestParameters |
| { |
| VkFormat format; |
| UVec2 size; |
| VkImageCreateFlags flags; |
| VkImageTiling tiling; |
| glu::ShaderType shaderType; |
| bool useMappedMemory; |
| bool useArrayLayers; |
| |
| TestParameters (VkFormat format_, |
| const UVec2& size_, |
| VkImageCreateFlags flags_, |
| VkImageTiling tiling_, |
| glu::ShaderType shaderType_, |
| bool useMappedMemory_, |
| bool useArrayLayers_) |
| : format (format_) |
| , size (size_) |
| , flags (flags_) |
| , tiling (tiling_) |
| , shaderType (shaderType_) |
| , useMappedMemory (useMappedMemory_) |
| , useArrayLayers (useArrayLayers_) |
| { |
| } |
| |
| TestParameters (void) |
| : format (VK_FORMAT_UNDEFINED) |
| , flags (0u) |
| , tiling (VK_IMAGE_TILING_OPTIMAL) |
| , shaderType (glu::SHADERTYPE_LAST) |
| , useMappedMemory (false) |
| , useArrayLayers (false) |
| { |
| } |
| }; |
| |
| ShaderSpec getShaderSpec (const TestParameters& params) |
| { |
| ShaderSpec spec; |
| |
| spec.inputs.push_back(Symbol("texCoord", glu::VarType(glu::TYPE_FLOAT_VEC2, glu::PRECISION_HIGHP))); |
| spec.outputs.push_back(Symbol("result", glu::VarType(glu::TYPE_FLOAT_VEC4, glu::PRECISION_HIGHP))); |
| |
| if (params.useArrayLayers) |
| { |
| spec.globalDeclarations = |
| "layout(binding = 0, set = 1) uniform highp sampler2DArray u_image;\n"; |
| spec.source = |
| "result = texture(u_image, vec3(texCoord, 1u));\n"; |
| } |
| else |
| { |
| spec.globalDeclarations = |
| "layout(binding = 0, set = 1) uniform highp sampler2D u_image;\n"; |
| spec.source = |
| "result = texture(u_image, texCoord);\n"; |
| } |
| |
| return spec; |
| } |
| |
| void checkSupport (Context& context, const TestParameters params) |
| { |
| checkImageSupport(context, params.format, params.flags, params.tiling); |
| |
| if (params.useArrayLayers) |
| { |
| if (!context.isDeviceFunctionalitySupported("VK_EXT_ycbcr_image_arrays")) |
| TCU_THROW(NotSupportedError, "VK_EXT_ycbcr_image_arrays is not supported"); |
| |
| VkImageFormatProperties properties = getPhysicalDeviceImageFormatProperties(context.getInstanceInterface(), context.getPhysicalDevice(), |
| params.format, VK_IMAGE_TYPE_2D, params.tiling, VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, params.flags); |
| if (properties.maxArrayLayers < 2) |
| TCU_THROW(NotSupportedError, "Image format does not support more than 1 maxArrayLayers"); |
| } |
| } |
| |
| void generateLookupCoordinates (const UVec2& imageSize, vector<Vec2>* dst) |
| { |
| dst->resize(imageSize.x() * imageSize.y()); |
| |
| for (deUint32 texelY = 0; texelY < imageSize.y(); ++texelY) |
| for (deUint32 texelX = 0; texelX < imageSize.x(); ++texelX) |
| { |
| const float x = ((float)texelX + 0.5f) / (float)imageSize.x(); |
| const float y = ((float)texelY + 0.5f) / (float)imageSize.y(); |
| |
| (*dst)[texelY*imageSize.x() + texelX] = Vec2(x, y); |
| } |
| } |
| |
| tcu::TestStatus testFormat (Context& context, TestParameters params) |
| { |
| const DeviceInterface& vkd = context.getDeviceInterface(); |
| const VkDevice device = context.getDevice(); |
| |
| const VkFormat format = params.format; |
| const PlanarFormatDescription formatInfo = getPlanarFormatDescription(format); |
| const UVec2 size = params.size; |
| const VkImageCreateFlags createFlags = params.flags; |
| const VkImageTiling tiling = params.tiling; |
| const bool mappedMemory = params.useMappedMemory; |
| const deUint32 arrayLayers = (params.useArrayLayers) ? 2u : 1u; |
| const deUint32 arrayLayer = arrayLayers - 1u; |
| |
| const Unique<VkImage> image (createTestImage(vkd, device, format, size, createFlags, tiling, mappedMemory ? VK_IMAGE_LAYOUT_PREINITIALIZED : VK_IMAGE_LAYOUT_UNDEFINED, arrayLayers)); |
| const vector<AllocationSp> allocations (allocateAndBindImageMemory(vkd, device, context.getDefaultAllocator(), *image, format, createFlags, mappedMemory ? MemoryRequirement::HostVisible : MemoryRequirement::Any)); |
| |
| const VkSamplerYcbcrConversionCreateInfo |
| conversionInfo = |
| { |
| VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO, |
| DE_NULL, |
| format, |
| VK_SAMPLER_YCBCR_MODEL_CONVERSION_RGB_IDENTITY, |
| VK_SAMPLER_YCBCR_RANGE_ITU_FULL, |
| { |
| VK_COMPONENT_SWIZZLE_IDENTITY, |
| VK_COMPONENT_SWIZZLE_IDENTITY, |
| VK_COMPONENT_SWIZZLE_IDENTITY, |
| VK_COMPONENT_SWIZZLE_IDENTITY, |
| }, |
| VK_CHROMA_LOCATION_MIDPOINT, |
| VK_CHROMA_LOCATION_MIDPOINT, |
| VK_FILTER_NEAREST, |
| VK_FALSE, // forceExplicitReconstruction |
| }; |
| const Unique<VkSamplerYcbcrConversion> conversion (createSamplerYcbcrConversion(vkd, device, &conversionInfo)); |
| const Unique<VkImageView> imageView (createImageView(vkd, device, *image, format, *conversion, arrayLayers)); |
| |
| const VkSamplerYcbcrConversionInfo samplerConversionInfo = |
| { |
| VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO, |
| DE_NULL, |
| *conversion, |
| }; |
| |
| const VkSamplerCreateInfo samplerInfo = |
| { |
| VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO, |
| &samplerConversionInfo, |
| 0u, |
| VK_FILTER_NEAREST, // magFilter |
| VK_FILTER_NEAREST, // minFilter |
| VK_SAMPLER_MIPMAP_MODE_NEAREST, // mipmapMode |
| VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeU |
| VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeV |
| VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE, // addressModeW |
| 0.0f, // mipLodBias |
| VK_FALSE, // anisotropyEnable |
| 1.0f, // maxAnisotropy |
| VK_FALSE, // compareEnable |
| VK_COMPARE_OP_ALWAYS, // compareOp |
| 0.0f, // minLod |
| 0.0f, // maxLod |
| VK_BORDER_COLOR_FLOAT_TRANSPARENT_BLACK, // borderColor |
| VK_FALSE, // unnormalizedCoords |
| }; |
| |
| const Unique<VkSampler> sampler (createSampler(vkd, device, &samplerInfo)); |
| |
| const Unique<VkDescriptorSetLayout> descLayout (createDescriptorSetLayout(vkd, device, *sampler)); |
| const Unique<VkDescriptorPool> descPool (createDescriptorPool(vkd, device)); |
| const Unique<VkDescriptorSet> descSet (createDescriptorSet(vkd, device, *descPool, *descLayout, *imageView)); |
| |
| MultiPlaneImageData imageData (format, size); |
| |
| const VkPhysicalDeviceImageFormatInfo2 imageFormatInfo = |
| { |
| VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, |
| DE_NULL, |
| params.format, |
| VK_IMAGE_TYPE_2D, |
| params.tiling, |
| VK_IMAGE_USAGE_TRANSFER_DST_BIT|VK_IMAGE_USAGE_SAMPLED_BIT, |
| params.flags, |
| }; |
| VkSamplerYcbcrConversionImageFormatProperties ycbcrProperties = |
| { |
| VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES, |
| DE_NULL, |
| 0, |
| }; |
| VkImageFormatProperties2 extProperties = |
| { |
| VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2, |
| &ycbcrProperties, |
| { |
| { |
| 0, // width |
| 0, // height |
| 0, // depth |
| }, |
| 0u, // maxMipLevels |
| 0u, // maxArrayLayers |
| 0, // sampleCounts |
| 0u, // maxResourceSize |
| }, |
| }; |
| VkResult propsResult; |
| const CustomInstance instance (createCustomInstanceWithExtension(context, "VK_KHR_get_physical_device_properties2")); |
| const InstanceDriver& vki (instance.getDriver()); |
| |
| // Verify that a yuv image consumes at least one descriptor |
| propsResult = vki.getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &imageFormatInfo, &extProperties); |
| |
| TCU_CHECK(propsResult == VK_SUCCESS); |
| TCU_CHECK(ycbcrProperties.combinedImageSamplerDescriptorCount >= 1); |
| |
| // Zero fill unused layer |
| if (params.useArrayLayers) |
| { |
| fillZero(&imageData); |
| |
| if (mappedMemory) |
| { |
| fillImageMemory(vkd, |
| device, |
| context.getUniversalQueueFamilyIndex(), |
| *image, |
| allocations, |
| imageData, |
| (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, |
| 0); |
| } |
| else |
| { |
| uploadImage(vkd, |
| device, |
| context.getUniversalQueueFamilyIndex(), |
| context.getDefaultAllocator(), |
| *image, |
| imageData, |
| (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, |
| 0); |
| } |
| } |
| |
| // Prepare texture data |
| fillGradient(&imageData, Vec4(0.0f), Vec4(1.0f)); |
| |
| if (mappedMemory) |
| { |
| // Fill and prepare image |
| fillImageMemory(vkd, |
| device, |
| context.getUniversalQueueFamilyIndex(), |
| *image, |
| allocations, |
| imageData, |
| (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, |
| arrayLayer); |
| } |
| else |
| { |
| // Upload and prepare image |
| uploadImage(vkd, |
| device, |
| context.getUniversalQueueFamilyIndex(), |
| context.getDefaultAllocator(), |
| *image, |
| imageData, |
| (VkAccessFlags)VK_ACCESS_SHADER_READ_BIT, |
| VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, |
| arrayLayer); |
| } |
| |
| { |
| vector<Vec2> texCoord; |
| vector<Vec4> result; |
| vector<Vec4> reference; |
| bool allOk = true; |
| Vec4 threshold (0.02f); |
| |
| generateLookupCoordinates(size, &texCoord); |
| |
| result.resize(texCoord.size()); |
| reference.resize(texCoord.size()); |
| |
| { |
| UniquePtr<ShaderExecutor> executor (createExecutor(context, params.shaderType, getShaderSpec(params), *descLayout)); |
| const void* inputs[] = { texCoord[0].getPtr() }; |
| void* outputs[] = { result[0].getPtr() }; |
| |
| executor->execute((int)texCoord.size(), inputs, outputs, *descSet); |
| } |
| |
| for (deUint32 channelNdx = 0; channelNdx < 4; channelNdx++) |
| { |
| if (formatInfo.hasChannelNdx(channelNdx)) |
| { |
| const tcu::ConstPixelBufferAccess channelAccess = imageData.getChannelAccess(channelNdx); |
| const tcu::Sampler refSampler = mapVkSampler(samplerInfo); |
| const tcu::Texture2DView refTexView (1u, &channelAccess); |
| |
| for (size_t ndx = 0; ndx < texCoord.size(); ++ndx) |
| { |
| const Vec2& coord = texCoord[ndx]; |
| reference[ndx][channelNdx] = refTexView.sample(refSampler, coord.x(), coord.y(), 0.0f)[0]; |
| } |
| } |
| else |
| { |
| for (size_t ndx = 0; ndx < texCoord.size(); ++ndx) |
| reference[ndx][channelNdx] = channelNdx == 3 ? 1.0f : 0.0f; |
| } |
| } |
| |
| for (size_t ndx = 0; ndx < texCoord.size(); ++ndx) |
| { |
| if (boolAny(greaterThanEqual(abs(result[ndx] - reference[ndx]), threshold))) |
| { |
| context.getTestContext().getLog() |
| << TestLog::Message << "ERROR: At " << texCoord[ndx] |
| << ": got " << result[ndx] |
| << ", expected " << reference[ndx] |
| << TestLog::EndMessage; |
| allOk = false; |
| } |
| } |
| |
| if (allOk) |
| return tcu::TestStatus::pass("All samples passed"); |
| else |
| { |
| const tcu::ConstPixelBufferAccess refAccess (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), |
| tcu::IVec3((int)size.x(), (int)size.y(), 1u), |
| reference[0].getPtr()); |
| const tcu::ConstPixelBufferAccess resAccess (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT), |
| tcu::IVec3((int)size.x(), (int)size.y(), 1u), |
| result[0].getPtr()); |
| |
| context.getTestContext().getLog() |
| << TestLog::Image("Result", "Result Image", resAccess, Vec4(1.0f), Vec4(0.0f)) |
| << TestLog::Image("Reference", "Reference Image", refAccess, Vec4(1.0f), Vec4(0.0f)); |
| |
| return tcu::TestStatus::fail("Got invalid results"); |
| } |
| } |
| } |
| |
| void initPrograms (SourceCollections& dst, TestParameters params) |
| { |
| const ShaderSpec spec = getShaderSpec(params); |
| |
| generateSources(params.shaderType, spec, dst); |
| } |
| |
| void populatePerFormatGroup (tcu::TestCaseGroup* group, VkFormat format) |
| { |
| const UVec2 size (66, 32); |
| const glu::ShaderType shaderTypes[] = |
| { |
| glu::SHADERTYPE_VERTEX, |
| glu::SHADERTYPE_FRAGMENT, |
| glu::SHADERTYPE_GEOMETRY, |
| glu::SHADERTYPE_TESSELLATION_CONTROL, |
| glu::SHADERTYPE_TESSELLATION_EVALUATION, |
| glu::SHADERTYPE_COMPUTE |
| }; |
| const struct |
| { |
| const char* name; |
| VkImageTiling value; |
| } tilings[] = |
| { |
| { "optimal", VK_IMAGE_TILING_OPTIMAL }, |
| { "linear", VK_IMAGE_TILING_LINEAR } |
| }; |
| |
| for (glu::ShaderType shaderType : shaderTypes) |
| for (int tilingNdx = 0; tilingNdx < DE_LENGTH_OF_ARRAY(tilings); tilingNdx++) |
| for (int useArrayLayers = 0; useArrayLayers < 2; useArrayLayers++) |
| { |
| const VkImageTiling tiling = tilings[tilingNdx].value; |
| const char* const tilingName = tilings[tilingNdx].name; |
| const char* const shaderTypeName = glu::getShaderTypeName(shaderType); |
| const string name = string(shaderTypeName) + "_" + tilingName + ((useArrayLayers) ? "_array" : ""); |
| |
| addFunctionCaseWithPrograms(group, name, "", checkSupport, initPrograms, testFormat, TestParameters(format, size, 0u, tiling, shaderType, false, useArrayLayers)); |
| |
| if (getPlaneCount(format) > 1) |
| addFunctionCaseWithPrograms(group, name + "_disjoint", "", checkSupport, initPrograms, testFormat, TestParameters(format, size, (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT, tiling, shaderType, false, useArrayLayers)); |
| |
| if (tiling == VK_IMAGE_TILING_LINEAR) |
| { |
| addFunctionCaseWithPrograms(group, name + "_mapped", "", checkSupport, initPrograms, testFormat, TestParameters(format, size, 0u, tiling, shaderType, true, useArrayLayers)); |
| |
| if (getPlaneCount(format) > 1) |
| addFunctionCaseWithPrograms(group, name + "_disjoint_mapped", "", checkSupport, initPrograms, testFormat, TestParameters(format, size, (VkImageCreateFlags)VK_IMAGE_CREATE_DISJOINT_BIT, tiling, shaderType, true, useArrayLayers)); |
| } |
| } |
| } |
| |
| void populateFormatGroup (tcu::TestCaseGroup* group) |
| { |
| for (int formatNdx = VK_YCBCR_FORMAT_FIRST; formatNdx < VK_YCBCR_FORMAT_LAST; formatNdx++) |
| { |
| const VkFormat format = (VkFormat)formatNdx; |
| const string formatName = de::toLower(de::toString(format).substr(10)); |
| |
| group->addChild(createTestGroup<VkFormat>(group->getTestContext(), formatName, "", populatePerFormatGroup, format)); |
| } |
| } |
| |
| } // namespace |
| |
| tcu::TestCaseGroup* createFormatTests (tcu::TestContext& testCtx) |
| { |
| return createTestGroup(testCtx, "format", "YCbCr Format Tests", populateFormatGroup); |
| } |
| |
| } // ycbcr |
| } // vkt |