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 "vkTypeUtil.hpp"
34 #include "vkCmdUtil.hpp"
35 #include "vkTypeUtil.hpp"
36 #include "vkObjUtil.hpp"
37 #include "tcuTexLookupVerifier.hpp"
38 #include "tcuTextureUtil.hpp"
39 #include "tcuTestLog.hpp"
40 #include "deSTLUtil.hpp"
53 de::MovePtr<Allocation> allocateBuffer (const InstanceInterface& vki,
54 const DeviceInterface& vkd,
55 const VkPhysicalDevice& physDevice,
56 const VkDevice device,
57 const VkBuffer& buffer,
58 const MemoryRequirement requirement,
60 AllocationKind allocationKind)
62 switch (allocationKind)
64 case ALLOCATION_KIND_SUBALLOCATED:
66 const VkMemoryRequirements memoryRequirements = getBufferMemoryRequirements(vkd, device, buffer);
68 return allocator.allocate(memoryRequirements, requirement);
71 case ALLOCATION_KIND_DEDICATED:
73 return allocateDedicated(vki, vkd, physDevice, device, buffer, requirement);
78 TCU_THROW(InternalError, "Invalid allocation kind");
83 de::MovePtr<Allocation> allocateImage (const InstanceInterface& vki,
84 const DeviceInterface& vkd,
85 const VkPhysicalDevice& physDevice,
86 const VkDevice device,
88 const MemoryRequirement requirement,
90 AllocationKind allocationKind)
92 switch (allocationKind)
94 case ALLOCATION_KIND_SUBALLOCATED:
96 const VkMemoryRequirements memoryRequirements = getImageMemoryRequirements(vkd, device, image);
98 return allocator.allocate(memoryRequirements, requirement);
101 case ALLOCATION_KIND_DEDICATED:
103 return allocateDedicated(vki, vkd, physDevice, device, image, requirement);
108 TCU_THROW(InternalError, "Invalid allocation kind");
113 static VkImageType getCompatibleImageType (VkImageViewType viewType)
117 case VK_IMAGE_VIEW_TYPE_1D: return VK_IMAGE_TYPE_1D;
118 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return VK_IMAGE_TYPE_1D;
119 case VK_IMAGE_VIEW_TYPE_2D: return VK_IMAGE_TYPE_2D;
120 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return VK_IMAGE_TYPE_2D;
121 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D;
122 case VK_IMAGE_VIEW_TYPE_CUBE: return VK_IMAGE_TYPE_2D;
123 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D;
129 return VK_IMAGE_TYPE_1D;
132 template<typename TcuFormatType>
133 static MovePtr<TestTexture> createTestTexture (const TcuFormatType format, VkImageViewType viewType, const tcu::IVec3& size, int layerCount)
135 MovePtr<TestTexture> texture;
136 const VkImageType imageType = getCompatibleImageType(viewType);
140 case VK_IMAGE_TYPE_1D:
142 texture = MovePtr<TestTexture>(new TestTexture1D(format, size.x()));
144 texture = MovePtr<TestTexture>(new TestTexture1DArray(format, size.x(), layerCount));
148 case VK_IMAGE_TYPE_2D:
151 texture = MovePtr<TestTexture>(new TestTexture2D(format, size.x(), size.y()));
155 if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
157 if (layerCount == tcu::CUBEFACE_LAST && viewType == VK_IMAGE_VIEW_TYPE_CUBE)
159 texture = MovePtr<TestTexture>(new TestTextureCube(format, size.x()));
163 DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
165 texture = MovePtr<TestTexture>(new TestTextureCubeArray(format, size.x(), layerCount));
170 texture = MovePtr<TestTexture>(new TestTexture2DArray(format, size.x(), size.y(), layerCount));
176 case VK_IMAGE_TYPE_3D:
177 texture = MovePtr<TestTexture>(new TestTexture3D(format, size.x(), size.y(), size.z()));
189 void checkSupportImageSamplingInstance (Context& context, ImageSamplingInstanceParams params)
192 if (de::abs(params.samplerParams.mipLodBias) > context.getDeviceProperties().limits.maxSamplerLodBias)
193 TCU_THROW(NotSupportedError, "Unsupported sampler Lod bias value");
195 if (!isSupportedSamplableFormat(context.getInstanceInterface(), context.getPhysicalDevice(), params.imageFormat))
196 throw tcu::NotSupportedError(std::string("Unsupported format for sampling: ") + getFormatName(params.imageFormat));
198 if ((deUint32)params.imageCount > context.getDeviceProperties().limits.maxColorAttachments)
199 throw tcu::NotSupportedError(std::string("Unsupported render target count: ") + de::toString(params.imageCount));
201 if ((params.samplerParams.minFilter == VK_FILTER_LINEAR ||
202 params.samplerParams.magFilter == VK_FILTER_LINEAR ||
203 params.samplerParams.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR) &&
204 !isLinearFilteringSupported(context.getInstanceInterface(), context.getPhysicalDevice(), params.imageFormat, VK_IMAGE_TILING_OPTIMAL))
205 throw tcu::NotSupportedError(std::string("Unsupported format for linear filtering: ") + getFormatName(params.imageFormat));
207 if (params.separateStencilUsage)
209 context.requireDeviceFunctionality("VK_EXT_separate_stencil_usage");
210 context.requireInstanceFunctionality("VK_KHR_get_physical_device_properties2");
212 const VkImageStencilUsageCreateInfo stencilUsage =
214 VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO,
216 VK_IMAGE_USAGE_TRANSFER_DST_BIT
219 const VkPhysicalDeviceImageFormatInfo2 formatInfo2 =
221 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, // VkStructureType sType
222 params.separateStencilUsage ? &stencilUsage
223 : DE_NULL, // const void* pNext
224 params.imageFormat, // VkFormat format
225 getCompatibleImageType(params.imageViewType), // VkImageType type
226 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling
227 VK_IMAGE_USAGE_SAMPLED_BIT
228 | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage
229 (VkImageCreateFlags)0u // VkImageCreateFlags flags
232 VkImageFormatProperties2 extProperties =
234 VK_STRUCTURE_TYPE_IMAGE_FORMAT_PROPERTIES_2,
243 0u, // maxArrayLayers
245 0u, // maxResourceSize
249 if ((context.getInstanceInterface().getPhysicalDeviceImageFormatProperties2(context.getPhysicalDevice(), &formatInfo2, &extProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED)
250 || extProperties.imageFormatProperties.maxExtent.width < (deUint32)params.imageSize.x()
251 || extProperties.imageFormatProperties.maxExtent.height < (deUint32)params.imageSize.y())
253 TCU_THROW(NotSupportedError, "Image format not supported");
257 void const* pNext = params.samplerParams.pNext;
258 while (pNext != DE_NULL)
260 const VkStructureType nextType = *reinterpret_cast<const VkStructureType*>(pNext);
263 case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO:
265 context.requireDeviceFunctionality("VK_EXT_sampler_filter_minmax");
267 if (!isMinMaxFilteringSupported(context.getInstanceInterface(), context.getPhysicalDevice(), params.imageFormat, VK_IMAGE_TILING_OPTIMAL))
268 throw tcu::NotSupportedError(std::string("Unsupported format for min/max filtering: ") + getFormatName(params.imageFormat));
270 pNext = reinterpret_cast<const VkSamplerReductionModeCreateInfo*>(pNext)->pNext;
273 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
274 context.requireDeviceFunctionality("VK_KHR_sampler_ycbcr_conversion");
276 pNext = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(pNext)->pNext;
278 case VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT:
279 pNext = reinterpret_cast<const VkSamplerCustomBorderColorCreateInfoEXT*>(pNext)->pNext;
281 if (!context.getCustomBorderColorFeaturesEXT().customBorderColors)
283 throw tcu::NotSupportedError("customBorderColors feature is not supported");
288 TCU_FAIL("Unrecognized sType in chained sampler create info");
292 if (params.samplerParams.addressModeU == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE ||
293 params.samplerParams.addressModeV == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE ||
294 params.samplerParams.addressModeW == VK_SAMPLER_ADDRESS_MODE_MIRROR_CLAMP_TO_EDGE)
296 context.requireDeviceFunctionality("VK_KHR_sampler_mirror_clamp_to_edge");
299 if ((isCompressedFormat(params.imageFormat) || isDepthStencilFormat(params.imageFormat)) && params.imageViewType == VK_IMAGE_VIEW_TYPE_3D)
301 // \todo [2016-01-22 pyry] Mandate VK_ERROR_FORMAT_NOT_SUPPORTED
304 const VkImageFormatProperties formatProperties = getPhysicalDeviceImageFormatProperties(context.getInstanceInterface(),
305 context.getPhysicalDevice(),
308 VK_IMAGE_TILING_OPTIMAL,
309 VK_IMAGE_USAGE_SAMPLED_BIT,
310 (VkImageCreateFlags)0);
312 if (formatProperties.maxExtent.width == 0 &&
313 formatProperties.maxExtent.height == 0 &&
314 formatProperties.maxExtent.depth == 0)
315 TCU_THROW(NotSupportedError, "3D compressed or depth format not supported");
319 TCU_THROW(NotSupportedError, "3D compressed or depth format not supported");
323 if (params.imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
324 context.requireDeviceCoreFeature(DEVICE_CORE_FEATURE_IMAGE_CUBE_ARRAY);
326 if (params.allocationKind == ALLOCATION_KIND_DEDICATED)
327 context.requireDeviceFunctionality("VK_KHR_dedicated_allocation");
329 #ifndef CTS_USES_VULKANSC
330 if (context.isDeviceFunctionalitySupported("VK_KHR_portability_subset"))
332 const auto portabilitySubsetFeatures = context.getPortabilitySubsetFeatures();
333 const auto componentMapping = params.componentMapping;
334 if (!portabilitySubsetFeatures.imageViewFormatSwizzle &&
335 ((componentMapping.r != VK_COMPONENT_SWIZZLE_IDENTITY) ||
336 (componentMapping.g != VK_COMPONENT_SWIZZLE_IDENTITY) ||
337 (componentMapping.b != VK_COMPONENT_SWIZZLE_IDENTITY) ||
338 (componentMapping.a != VK_COMPONENT_SWIZZLE_IDENTITY)))
340 TCU_THROW(NotSupportedError, "VK_KHR_portability_subset: Implementation does not support remapping format components");
344 bool formatRgba10x6WithoutYCbCrSampler = context.getRGBA10X6FormatsFeaturesEXT().formatRgba10x6WithoutYCbCrSampler;
346 bool formatRgba10x6WithoutYCbCrSampler = VK_FALSE;
347 #endif // CTS_USES_VULKANSC
349 if ((params.imageFormat == VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16) && (params.subresourceRange.levelCount > 1) && (formatRgba10x6WithoutYCbCrSampler == VK_FALSE))
351 TCU_THROW(NotSupportedError, "formatRgba10x6WithoutYCbCrSampler not supported");
355 ImageSamplingInstance::ImageSamplingInstance (Context& context,
356 ImageSamplingInstanceParams params)
357 : vkt::TestInstance (context)
358 , m_allocationKind (params.allocationKind)
359 , m_samplingType (params.samplingType)
360 , m_imageViewType (params.imageViewType)
361 , m_imageFormat (params.imageFormat)
362 , m_imageSize (params.imageSize)
363 , m_layerCount (params.layerCount)
364 , m_imageCount (params.imageCount)
365 , m_componentMapping (params.componentMapping)
366 , m_componentMask (true)
367 , m_subresourceRange (params.subresourceRange)
368 , m_samplerParams (params.samplerParams)
369 , m_samplerLod (params.samplerLod)
370 , m_renderSize (params.renderSize)
371 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
372 , m_vertices (params.vertices)
373 , m_graphicsPipeline (context.getDeviceInterface(), context.getDevice(), params.pipelineConstructionType, params.pipelineCreateFlags)
374 , m_pipelineConstructionType (params.pipelineConstructionType)
375 , m_imageLayout (params.imageLayout)
379 void ImageSamplingInstance::setup ()
381 const InstanceInterface& vki = m_context.getInstanceInterface();
382 const DeviceInterface& vk = m_context.getDeviceInterface();
383 const VkPhysicalDevice physDevice = m_context.getPhysicalDevice();
384 const VkDevice vkDevice = m_context.getDevice();
385 const VkQueue queue = m_context.getUniversalQueue();
386 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
387 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
388 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
390 void const* pNext = m_samplerParams.pNext;
391 while (pNext != DE_NULL)
393 const VkStructureType nextType = *reinterpret_cast<const VkStructureType*>(pNext);
396 case VK_STRUCTURE_TYPE_SAMPLER_REDUCTION_MODE_CREATE_INFO:
398 VkPhysicalDeviceSamplerFilterMinmaxProperties physicalDeviceSamplerMinMaxProperties =
400 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_SAMPLER_FILTER_MINMAX_PROPERTIES,
405 VkPhysicalDeviceProperties2 physicalDeviceProperties;
406 physicalDeviceProperties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2;
407 physicalDeviceProperties.pNext = &physicalDeviceSamplerMinMaxProperties;
409 vki.getPhysicalDeviceProperties2(m_context.getPhysicalDevice(), &physicalDeviceProperties);
411 if (physicalDeviceSamplerMinMaxProperties.filterMinmaxImageComponentMapping != VK_TRUE)
413 // If filterMinmaxImageComponentMapping is VK_FALSE the component mapping of the image
414 // view used with min/max filtering must have been created with the r component set to
415 // VK_COMPONENT_SWIZZLE_IDENTITY. Only the r component of the sampled image value is
416 // defined and the other component values are undefined
418 m_componentMask = tcu::BVec4(true, false, false, false);
420 if (m_componentMapping.r != VK_COMPONENT_SWIZZLE_IDENTITY && m_componentMapping.r != VK_COMPONENT_SWIZZLE_R)
422 TCU_THROW(NotSupportedError, "filterMinmaxImageComponentMapping is not supported (R mapping is not IDENTITY)");
425 pNext = reinterpret_cast<const VkSamplerReductionModeCreateInfo*>(pNext)->pNext;
428 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_INFO:
429 pNext = reinterpret_cast<const VkSamplerYcbcrConversionInfo*>(pNext)->pNext;
431 case VK_STRUCTURE_TYPE_SAMPLER_CUSTOM_BORDER_COLOR_CREATE_INFO_EXT:
433 const VkSamplerCustomBorderColorCreateInfoEXT customBorderColorCreateInfo = *reinterpret_cast<const VkSamplerCustomBorderColorCreateInfoEXT*>(pNext);
435 VkPhysicalDeviceCustomBorderColorFeaturesEXT physicalDeviceCustomBorderColorFeatures =
437 VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_CUSTOM_BORDER_COLOR_FEATURES_EXT,
442 VkPhysicalDeviceFeatures2 physicalDeviceFeatures;
443 physicalDeviceFeatures.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
444 physicalDeviceFeatures.pNext = &physicalDeviceCustomBorderColorFeatures;
446 vki.getPhysicalDeviceFeatures2(m_context.getPhysicalDevice(), &physicalDeviceFeatures);
448 if (physicalDeviceCustomBorderColorFeatures.customBorderColors != VK_TRUE)
450 TCU_THROW(NotSupportedError, "customBorderColors are not supported");
453 if (physicalDeviceCustomBorderColorFeatures.customBorderColorWithoutFormat != VK_TRUE &&
454 customBorderColorCreateInfo.format == VK_FORMAT_UNDEFINED)
456 TCU_THROW(NotSupportedError, "customBorderColorWithoutFormat is not supported");
459 pNext = reinterpret_cast<const VkSamplerCustomBorderColorCreateInfoEXT*>(pNext)->pNext;
463 TCU_FAIL("Unrecognized sType in chained sampler create info");
467 // Create texture images, views and samplers
469 VkImageCreateFlags imageFlags = 0u;
471 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
472 imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
474 // Initialize texture data
475 if (isCompressedFormat(m_imageFormat))
476 m_texture = createTestTexture(mapVkCompressedFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
478 m_texture = createTestTexture(mapVkFormat(m_imageFormat), m_imageViewType, m_imageSize, m_layerCount);
480 const VkImageCreateInfo imageParams =
482 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
483 DE_NULL, // const void* pNext;
484 imageFlags, // VkImageCreateFlags flags;
485 getCompatibleImageType(m_imageViewType), // VkImageType imageType;
486 m_imageFormat, // VkFormat format;
487 { // VkExtent3D extent;
488 (deUint32)m_imageSize.x(),
489 (deUint32)m_imageSize.y(),
490 (deUint32)m_imageSize.z()
492 (deUint32)m_texture->getNumLevels(), // deUint32 mipLevels;
493 (deUint32)m_layerCount, // deUint32 arrayLayers;
494 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
495 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
496 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
497 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
498 1u, // deUint32 queueFamilyIndexCount;
499 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
500 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
503 m_images.resize(m_imageCount);
504 m_imageAllocs.resize(m_imageCount);
505 m_imageViews.resize(m_imageCount);
507 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
509 m_images[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &imageParams)));
510 m_imageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_images[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
511 VK_CHECK(vk.bindImageMemory(vkDevice, **m_images[imgNdx], (*m_imageAllocs[imgNdx])->getMemory(), (*m_imageAllocs[imgNdx])->getOffset()));
513 // Upload texture data
514 uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, **m_images[imgNdx]);
516 // Create image view and sampler
517 const VkImageViewCreateInfo imageViewParams =
519 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
520 DE_NULL, // const void* pNext;
521 0u, // VkImageViewCreateFlags flags;
522 **m_images[imgNdx], // VkImage image;
523 m_imageViewType, // VkImageViewType viewType;
524 m_imageFormat, // VkFormat format;
525 m_componentMapping, // VkComponentMapping components;
526 m_subresourceRange, // VkImageSubresourceRange subresourceRange;
529 m_imageViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &imageViewParams)));
532 m_sampler = createSampler(vk, vkDevice, &m_samplerParams);
535 // Create descriptor set for image and sampler
537 DescriptorPoolBuilder descriptorPoolBuilder;
538 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
539 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_SAMPLER, 1u);
540 descriptorPoolBuilder.addType(m_samplingType, m_imageCount);
541 m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT,
542 m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? m_imageCount + 1u : m_imageCount);
544 DescriptorSetLayoutBuilder setLayoutBuilder;
545 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
546 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
547 setLayoutBuilder.addArrayBinding(m_samplingType, m_imageCount, VK_SHADER_STAGE_FRAGMENT_BIT);
548 m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
550 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
552 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
553 DE_NULL, // const void* pNext;
554 *m_descriptorPool, // VkDescriptorPool descriptorPool;
555 1u, // deUint32 setLayoutCount;
556 &m_descriptorSetLayout.get() // const VkDescriptorSetLayout* pSetLayouts;
559 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
561 const VkSampler sampler = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? DE_NULL : *m_sampler;
562 std::vector<VkDescriptorImageInfo> descriptorImageInfo(m_imageCount);
563 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
565 descriptorImageInfo[imgNdx].sampler = sampler; // VkSampler sampler;
566 descriptorImageInfo[imgNdx].imageView = **m_imageViews[imgNdx]; // VkImageView imageView;
567 descriptorImageInfo[imgNdx].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; // VkImageLayout imageLayout;
570 DescriptorSetUpdateBuilder setUpdateBuilder;
571 if (m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE)
573 const VkDescriptorImageInfo descriptorSamplerInfo =
575 *m_sampler, // VkSampler sampler;
576 DE_NULL, // VkImageView imageView;
577 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
579 setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_SAMPLER, &descriptorSamplerInfo);
582 const deUint32 binding = m_samplingType == VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE ? 1u : 0u;
583 setUpdateBuilder.writeArray(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(binding), m_samplingType, m_imageCount, descriptorImageInfo.data());
584 setUpdateBuilder.update(vk, vkDevice);
587 // Create color images and views
589 const VkImageCreateInfo colorImageParams =
591 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
592 DE_NULL, // const void* pNext;
593 0u, // VkImageCreateFlags flags;
594 VK_IMAGE_TYPE_2D, // VkImageType imageType;
595 m_colorFormat, // VkFormat format;
596 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
597 1u, // deUint32 mipLevels;
598 1u, // deUint32 arrayLayers;
599 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
600 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
601 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
602 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
603 1u, // deUint32 queueFamilyIndexCount;
604 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
605 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
608 m_colorImages.resize(m_imageCount);
609 m_colorImageAllocs.resize(m_imageCount);
610 m_colorAttachmentViews.resize(m_imageCount);
612 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
614 m_colorImages[imgNdx] = SharedImagePtr(new UniqueImage(createImage(vk, vkDevice, &colorImageParams)));
615 m_colorImageAllocs[imgNdx] = SharedAllocPtr(new UniqueAlloc(allocateImage(vki, vk, physDevice, vkDevice, **m_colorImages[imgNdx], MemoryRequirement::Any, memAlloc, m_allocationKind)));
616 VK_CHECK(vk.bindImageMemory(vkDevice, **m_colorImages[imgNdx], (*m_colorImageAllocs[imgNdx])->getMemory(), (*m_colorImageAllocs[imgNdx])->getOffset()));
618 const VkImageViewCreateInfo colorAttachmentViewParams =
620 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
621 DE_NULL, // const void* pNext;
622 0u, // VkImageViewCreateFlags flags;
623 **m_colorImages[imgNdx], // VkImage image;
624 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
625 m_colorFormat, // VkFormat format;
626 componentMappingRGBA, // VkComponentMapping components;
627 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
630 m_colorAttachmentViews[imgNdx] = SharedImageViewPtr(new UniqueImageView(createImageView(vk, vkDevice, &colorAttachmentViewParams)));
634 // Create render pass
636 std::vector<VkAttachmentDescription> colorAttachmentDescriptions(m_imageCount);
637 std::vector<VkAttachmentReference> colorAttachmentReferences(m_imageCount);
639 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
641 colorAttachmentDescriptions[imgNdx].flags = 0u; // VkAttachmentDescriptionFlags flags;
642 colorAttachmentDescriptions[imgNdx].format = m_colorFormat; // VkFormat format;
643 colorAttachmentDescriptions[imgNdx].samples = VK_SAMPLE_COUNT_1_BIT; // VkSampleCountFlagBits samples;
644 colorAttachmentDescriptions[imgNdx].loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR; // VkAttachmentLoadOp loadOp;
645 colorAttachmentDescriptions[imgNdx].storeOp = VK_ATTACHMENT_STORE_OP_STORE; // VkAttachmentStoreOp storeOp;
646 colorAttachmentDescriptions[imgNdx].stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; // VkAttachmentLoadOp stencilLoadOp;
647 colorAttachmentDescriptions[imgNdx].stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; // VkAttachmentStoreOp stencilStoreOp;
648 colorAttachmentDescriptions[imgNdx].initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VkImageLayout initialLayout;
649 colorAttachmentDescriptions[imgNdx].finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VkImageLayout finalLayout;
651 colorAttachmentReferences[imgNdx].attachment = (deUint32)imgNdx; // deUint32 attachment;
652 colorAttachmentReferences[imgNdx].layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VkImageLayout layout;
655 const VkSubpassDescription subpassDescription =
657 0u, // VkSubpassDescriptionFlags flags;
658 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
659 0u, // deUint32 inputAttachmentCount;
660 DE_NULL, // const VkAttachmentReference* pInputAttachments;
661 (deUint32)m_imageCount, // deUint32 colorAttachmentCount;
662 &colorAttachmentReferences[0], // const VkAttachmentReference* pColorAttachments;
663 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
664 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
665 0u, // deUint32 preserveAttachmentCount;
666 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
669 const VkRenderPassCreateInfo renderPassParams =
671 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
672 DE_NULL, // const void* pNext;
673 0u, // VkRenderPassCreateFlags flags;
674 (deUint32)m_imageCount, // deUint32 attachmentCount;
675 &colorAttachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
676 1u, // deUint32 subpassCount;
677 &subpassDescription, // const VkSubpassDescription* pSubpasses;
678 0u, // deUint32 dependencyCount;
679 DE_NULL // const VkSubpassDependency* pDependencies;
682 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
685 // Create framebuffer
687 std::vector<VkImageView> pAttachments(m_imageCount);
688 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
689 pAttachments[imgNdx] = m_colorAttachmentViews[imgNdx]->get();
691 const VkFramebufferCreateInfo framebufferParams =
693 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
694 DE_NULL, // const void* pNext;
695 0u, // VkFramebufferCreateFlags flags;
696 *m_renderPass, // VkRenderPass renderPass;
697 (deUint32)m_imageCount, // deUint32 attachmentCount;
698 &pAttachments[0], // const VkImageView* pAttachments;
699 (deUint32)m_renderSize.x(), // deUint32 width;
700 (deUint32)m_renderSize.y(), // deUint32 height;
701 1u // deUint32 layers;
704 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
707 // Create pipeline layout
709 #ifndef CTS_USES_VULKANSC
710 VkPipelineLayoutCreateFlags pipelineLayoutFlags = (m_pipelineConstructionType == PIPELINE_CONSTRUCTION_TYPE_MONOLITHIC) ? 0u : deUint32(VK_PIPELINE_LAYOUT_CREATE_INDEPENDENT_SETS_BIT_EXT);
712 VkPipelineLayoutCreateFlags pipelineLayoutFlags = 0u;
713 #endif // CTS_USES_VULKANSC
714 VkPipelineLayoutCreateInfo pipelineLayoutParams
716 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
717 DE_NULL, // const void* pNext;
718 pipelineLayoutFlags, // VkPipelineLayoutCreateFlags flags;
719 0u, // deUint32 setLayoutCount;
720 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
721 0u, // deUint32 pushConstantRangeCount;
722 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
725 m_preRasterizationStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
726 pipelineLayoutParams.setLayoutCount = 1u;
727 pipelineLayoutParams.pSetLayouts = &m_descriptorSetLayout.get();
728 m_fragmentStatePipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
731 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
732 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
736 const VkVertexInputBindingDescription vertexInputBindingDescription =
738 0u, // deUint32 binding;
739 sizeof(Vertex4Tex4), // deUint32 strideInBytes;
740 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
743 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
746 0u, // deUint32 location;
747 0u, // deUint32 binding;
748 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
749 0u // deUint32 offset;
752 1u, // deUint32 location;
753 0u, // deUint32 binding;
754 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
755 DE_OFFSET_OF(Vertex4Tex4, texCoord), // deUint32 offset;
759 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
761 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
762 DE_NULL, // const void* pNext;
763 0u, // VkPipelineVertexInputStateCreateFlags flags;
764 1u, // deUint32 vertexBindingDescriptionCount;
765 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
766 2u, // deUint32 vertexAttributeDescriptionCount;
767 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
770 const std::vector<VkViewport> viewports { makeViewport(m_renderSize) };
771 const std::vector<VkRect2D> scissors { makeRect2D(m_renderSize) };
773 std::vector<VkPipelineColorBlendAttachmentState> colorBlendAttachmentStates(m_imageCount);
775 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
777 colorBlendAttachmentStates[imgNdx].blendEnable = false; // VkBool32 blendEnable;
778 colorBlendAttachmentStates[imgNdx].srcColorBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcColorBlendFactor;
779 colorBlendAttachmentStates[imgNdx].dstColorBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstColorBlendFactor;
780 colorBlendAttachmentStates[imgNdx].colorBlendOp = VK_BLEND_OP_ADD; // VkBlendOp colorBlendOp;
781 colorBlendAttachmentStates[imgNdx].srcAlphaBlendFactor = VK_BLEND_FACTOR_ONE; // VkBlendFactor srcAlphaBlendFactor;
782 colorBlendAttachmentStates[imgNdx].dstAlphaBlendFactor = VK_BLEND_FACTOR_ZERO; // VkBlendFactor dstAlphaBlendFactor;
783 colorBlendAttachmentStates[imgNdx].alphaBlendOp = VK_BLEND_OP_ADD; // VkBlendOp alphaBlendOp;
784 colorBlendAttachmentStates[imgNdx].colorWriteMask = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
785 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
788 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
790 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
791 DE_NULL, // const void* pNext;
792 0u, // VkPipelineColorBlendStateCreateFlags flags;
793 false, // VkBool32 logicOpEnable;
794 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
795 (deUint32)m_imageCount, // deUint32 attachmentCount;
796 &colorBlendAttachmentStates[0], // const VkPipelineColorBlendAttachmentState* pAttachments;
797 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
800 m_graphicsPipeline.setMonolithicPipelineLayout(*m_fragmentStatePipelineLayout)
801 .setDefaultDepthStencilState()
802 .setDefaultRasterizationState()
803 .setDefaultMultisampleState()
804 .setupVertexInputState(&vertexInputStateParams)
805 .setupPreRasterizationShaderState(viewports,
807 *m_preRasterizationStatePipelineLayout,
810 *m_vertexShaderModule)
811 .setupFragmentShaderState(*m_fragmentStatePipelineLayout, *m_renderPass, 0u, *m_fragmentShaderModule)
812 .setupFragmentOutputState(*m_renderPass, 0u, &colorBlendStateParams)
816 // Create vertex buffer
818 const VkDeviceSize vertexBufferSize = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
819 const VkBufferCreateInfo vertexBufferParams =
821 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
822 DE_NULL, // const void* pNext;
823 0u, // VkBufferCreateFlags flags;
824 vertexBufferSize, // VkDeviceSize size;
825 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
826 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
827 1u, // deUint32 queueFamilyIndexCount;
828 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
831 DE_ASSERT(vertexBufferSize > 0);
833 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
834 m_vertexBufferAlloc = allocateBuffer(vki, vk, physDevice, vkDevice, *m_vertexBuffer, MemoryRequirement::HostVisible, memAlloc, m_allocationKind);
835 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
837 // Load vertices into vertex buffer
838 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
839 flushAlloc(vk, vkDevice, *m_vertexBufferAlloc);
842 // Create command pool
843 m_cmdPool = createCommandPool(vk, vkDevice, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
845 // Create command buffer
847 const std::vector<VkClearValue> attachmentClearValues (m_imageCount, defaultClearValue(m_colorFormat));
849 std::vector<VkImageMemoryBarrier> preAttachmentBarriers(m_imageCount);
851 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
853 preAttachmentBarriers[imgNdx].sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER; // VkStructureType sType;
854 preAttachmentBarriers[imgNdx].pNext = DE_NULL; // const void* pNext;
855 preAttachmentBarriers[imgNdx].srcAccessMask = 0u; // VkAccessFlags srcAccessMask;
856 preAttachmentBarriers[imgNdx].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; // VkAccessFlags dstAccessMask;
857 preAttachmentBarriers[imgNdx].oldLayout = VK_IMAGE_LAYOUT_UNDEFINED; // VkImageLayout oldLayout;
858 preAttachmentBarriers[imgNdx].newLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; // VkImageLayout newLayout;
859 preAttachmentBarriers[imgNdx].srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 srcQueueFamilyIndex;
860 preAttachmentBarriers[imgNdx].dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED; // deUint32 dstQueueFamilyIndex;
861 preAttachmentBarriers[imgNdx].image = **m_colorImages[imgNdx]; // VkImage image;
862 preAttachmentBarriers[imgNdx].subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; // VkImageSubresourceRange subresourceRange;
863 preAttachmentBarriers[imgNdx].subresourceRange.baseMipLevel = 0u;
864 preAttachmentBarriers[imgNdx].subresourceRange.levelCount = 1u;
865 preAttachmentBarriers[imgNdx].subresourceRange.baseArrayLayer = 0u;
866 preAttachmentBarriers[imgNdx].subresourceRange.layerCount = 1u;
869 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
871 beginCommandBuffer(vk, *m_cmdBuffer, 0u);
873 vk.cmdPipelineBarrier(*m_cmdBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, (VkDependencyFlags)0,
874 0u, DE_NULL, 0u, DE_NULL, (deUint32)m_imageCount, &preAttachmentBarriers[0]);
876 beginRenderPass(vk, *m_cmdBuffer, *m_renderPass, *m_framebuffer, makeRect2D(0, 0, m_renderSize.x(), m_renderSize.y()), (deUint32)attachmentClearValues.size(), &attachmentClearValues[0]);
878 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline.getPipeline());
880 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_fragmentStatePipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
882 const VkDeviceSize vertexBufferOffset = 0;
883 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
884 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
886 endRenderPass(vk, *m_cmdBuffer);
887 endCommandBuffer(vk, *m_cmdBuffer);
891 ImageSamplingInstance::~ImageSamplingInstance (void)
895 tcu::TestStatus ImageSamplingInstance::iterate (void)
897 const DeviceInterface& vk = m_context.getDeviceInterface();
898 const VkDevice vkDevice = m_context.getDevice();
899 const VkQueue queue = m_context.getUniversalQueue();
903 submitCommandsAndWait(vk, vkDevice, queue, m_cmdBuffer.get());
905 return verifyImage();
911 bool isLookupResultValid (const tcu::Texture1DView& texture,
912 const tcu::Sampler& sampler,
913 const tcu::LookupPrecision& precision,
914 const tcu::Vec4& coords,
915 const tcu::Vec2& lodBounds,
916 const tcu::Vec4& result)
918 return tcu::isLookupResultValid(texture, sampler, precision, coords.x(), lodBounds, result);
921 bool isLookupResultValid (const tcu::Texture1DArrayView& texture,
922 const tcu::Sampler& sampler,
923 const tcu::LookupPrecision& precision,
924 const tcu::Vec4& coords,
925 const tcu::Vec2& lodBounds,
926 const tcu::Vec4& result)
928 return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1), lodBounds, result);
931 bool isLookupResultValid (const tcu::Texture2DView& texture,
932 const tcu::Sampler& sampler,
933 const tcu::LookupPrecision& precision,
934 const tcu::Vec4& coords,
935 const tcu::Vec2& lodBounds,
936 const tcu::Vec4& result)
938 return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1), lodBounds, result);
941 bool isLookupResultValid (const tcu::Texture2DArrayView& texture,
942 const tcu::Sampler& sampler,
943 const tcu::LookupPrecision& precision,
944 const tcu::Vec4& coords,
945 const tcu::Vec2& lodBounds,
946 const tcu::Vec4& result)
948 return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1,2), lodBounds, result);
951 bool isLookupResultValid (const tcu::TextureCubeView& texture,
952 const tcu::Sampler& sampler,
953 const tcu::LookupPrecision& precision,
954 const tcu::Vec4& coords,
955 const tcu::Vec2& lodBounds,
956 const tcu::Vec4& result)
958 return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1,2), lodBounds, result);
961 bool isLookupResultValid (const tcu::TextureCubeArrayView& texture,
962 const tcu::Sampler& sampler,
963 const tcu::LookupPrecision& precision,
964 const tcu::Vec4& coords,
965 const tcu::Vec2& lodBounds,
966 const tcu::Vec4& result)
968 return tcu::isLookupResultValid(texture, sampler, precision, tcu::IVec4(precision.coordBits.x()), coords, lodBounds, result);
971 bool isLookupResultValid(const tcu::Texture3DView& texture,
972 const tcu::Sampler& sampler,
973 const tcu::LookupPrecision& precision,
974 const tcu::Vec4& coords,
975 const tcu::Vec2& lodBounds,
976 const tcu::Vec4& result)
978 return tcu::isLookupResultValid(texture, sampler, precision, coords.swizzle(0,1,2), lodBounds, result);
981 template<typename TextureViewType>
982 bool validateResultImage (const TextureViewType& texture,
983 const tcu::Sampler& sampler,
984 const tcu::ConstPixelBufferAccess& texCoords,
985 const tcu::Vec2& lodBounds,
986 const tcu::LookupPrecision& lookupPrecision,
987 const tcu::Vec4& lookupScale,
988 const tcu::Vec4& lookupBias,
989 const tcu::ConstPixelBufferAccess& result,
990 const tcu::PixelBufferAccess& errorMask)
992 const int w = result.getWidth();
993 const int h = result.getHeight();
996 for (int y = 0; y < h; ++y)
998 for (int x = 0; x < w; ++x)
1000 const tcu::Vec4 resultPixel = result.getPixel(x, y);
1001 const tcu::Vec4 resultColor = (resultPixel - lookupBias) / lookupScale;
1002 const tcu::Vec4 texCoord = texCoords.getPixel(x, y);
1003 const bool pixelOk = isLookupResultValid(texture, sampler, lookupPrecision, texCoord, lodBounds, resultColor);
1005 errorMask.setPixel(tcu::Vec4(pixelOk?0.0f:1.0f, pixelOk?1.0f:0.0f, 0.0f, 1.0f), x, y);
1015 template<typename ScalarType>
1016 ScalarType getSwizzledComp (const tcu::Vector<ScalarType, 4>& vec, vk::VkComponentSwizzle comp, int identityNdx)
1018 if (comp == vk::VK_COMPONENT_SWIZZLE_IDENTITY)
1019 return vec[identityNdx];
1020 else if (comp == vk::VK_COMPONENT_SWIZZLE_ZERO)
1021 return ScalarType(0);
1022 else if (comp == vk::VK_COMPONENT_SWIZZLE_ONE)
1023 return ScalarType(1);
1025 return vec[comp - vk::VK_COMPONENT_SWIZZLE_R];
1028 template<typename ScalarType>
1029 tcu::Vector<ScalarType, 4> swizzle (const tcu::Vector<ScalarType, 4>& vec, const vk::VkComponentMapping& swz)
1031 return tcu::Vector<ScalarType, 4>(getSwizzledComp(vec, swz.r, 0),
1032 getSwizzledComp(vec, swz.g, 1),
1033 getSwizzledComp(vec, swz.b, 2),
1034 getSwizzledComp(vec, swz.a, 3));
1037 /*--------------------------------------------------------------------*//*!
1038 * \brief Swizzle scale or bias vector by given mapping
1040 * \param vec scale or bias vector
1041 * \param swz swizzle component mapping, may include ZERO, ONE, or IDENTITY
1042 * \param zeroOrOneValue vector value for component swizzled as ZERO or ONE
1043 * \return swizzled vector
1044 *//*--------------------------------------------------------------------*/
1045 tcu::Vec4 swizzleScaleBias (const tcu::Vec4& vec, const vk::VkComponentMapping& swz, float zeroOrOneValue)
1048 // Remove VK_COMPONENT_SWIZZLE_IDENTITY to avoid addressing channelValues[0]
1049 const vk::VkComponentMapping nonIdentitySwz =
1051 swz.r == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_R : swz.r,
1052 swz.g == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_G : swz.g,
1053 swz.b == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_B : swz.b,
1054 swz.a == VK_COMPONENT_SWIZZLE_IDENTITY ? VK_COMPONENT_SWIZZLE_A : swz.a
1057 const float channelValues[] =
1059 -1.0f, // impossible
1060 zeroOrOneValue, // SWIZZLE_ZERO
1061 zeroOrOneValue, // SWIZZLE_ONE
1068 return tcu::Vec4(channelValues[nonIdentitySwz.r], channelValues[nonIdentitySwz.g], channelValues[nonIdentitySwz.b], channelValues[nonIdentitySwz.a]);
1071 template<typename ScalarType>
1072 void swizzleT (const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& dst, const vk::VkComponentMapping& swz)
1074 for (int z = 0; z < dst.getDepth(); ++z)
1075 for (int y = 0; y < dst.getHeight(); ++y)
1076 for (int x = 0; x < dst.getWidth(); ++x)
1077 dst.setPixel(swizzle(src.getPixelT<ScalarType>(x, y, z), swz), x, y, z);
1080 void swizzleFromSRGB (const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& dst, const vk::VkComponentMapping& swz)
1082 for (int z = 0; z < dst.getDepth(); ++z)
1083 for (int y = 0; y < dst.getHeight(); ++y)
1084 for (int x = 0; x < dst.getWidth(); ++x)
1085 dst.setPixel(swizzle(tcu::sRGBToLinear(src.getPixelT<float>(x, y, z)), swz), x, y, z);
1088 void swizzle (const tcu::ConstPixelBufferAccess& src, const tcu::PixelBufferAccess& dst, const vk::VkComponentMapping& swz)
1090 const tcu::TextureChannelClass chnClass = tcu::getTextureChannelClass(dst.getFormat().type);
1092 DE_ASSERT(src.getWidth() == dst.getWidth() &&
1093 src.getHeight() == dst.getHeight() &&
1094 src.getDepth() == dst.getDepth());
1096 if (chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
1097 swizzleT<deInt32>(src, dst, swz);
1098 else if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
1099 swizzleT<deUint32>(src, dst, swz);
1100 else if (tcu::isSRGB(src.getFormat()) && !tcu::isSRGB(dst.getFormat()))
1101 swizzleFromSRGB(src, dst, swz);
1103 swizzleT<float>(src, dst, swz);
1106 bool isIdentitySwizzle (const vk::VkComponentMapping& swz)
1108 return (swz.r == vk::VK_COMPONENT_SWIZZLE_IDENTITY || swz.r == vk::VK_COMPONENT_SWIZZLE_R) &&
1109 (swz.g == vk::VK_COMPONENT_SWIZZLE_IDENTITY || swz.g == vk::VK_COMPONENT_SWIZZLE_G) &&
1110 (swz.b == vk::VK_COMPONENT_SWIZZLE_IDENTITY || swz.b == vk::VK_COMPONENT_SWIZZLE_B) &&
1111 (swz.a == vk::VK_COMPONENT_SWIZZLE_IDENTITY || swz.a == vk::VK_COMPONENT_SWIZZLE_A);
1114 template<typename TextureViewType> struct TexViewTraits;
1116 template<> struct TexViewTraits<tcu::Texture1DView> { typedef tcu::Texture1D TextureType; };
1117 template<> struct TexViewTraits<tcu::Texture1DArrayView> { typedef tcu::Texture1DArray TextureType; };
1118 template<> struct TexViewTraits<tcu::Texture2DView> { typedef tcu::Texture2D TextureType; };
1119 template<> struct TexViewTraits<tcu::Texture2DArrayView> { typedef tcu::Texture2DArray TextureType; };
1120 template<> struct TexViewTraits<tcu::TextureCubeView> { typedef tcu::TextureCube TextureType; };
1121 template<> struct TexViewTraits<tcu::TextureCubeArrayView> { typedef tcu::TextureCubeArray TextureType; };
1122 template<> struct TexViewTraits<tcu::Texture3DView> { typedef tcu::Texture3D TextureType; };
1124 template<typename TextureViewType>
1125 typename TexViewTraits<TextureViewType>::TextureType* createSkeletonClone (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0);
1127 tcu::TextureFormat getSwizzleTargetFormat (tcu::TextureFormat format)
1129 // Swizzled texture needs to hold all four channels
1130 // \todo [2016-09-21 pyry] We could save some memory by using smaller formats
1131 // when possible (for example U8).
1133 const tcu::TextureChannelClass chnClass = tcu::getTextureChannelClass(format.type);
1135 if (chnClass == tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER)
1136 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::SIGNED_INT32);
1137 else if (chnClass == tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER)
1138 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32);
1140 return tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
1144 tcu::Texture1D* createSkeletonClone<tcu::Texture1DView> (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0)
1146 return new tcu::Texture1D(format, level0.getWidth());
1150 tcu::Texture1DArray* createSkeletonClone<tcu::Texture1DArrayView> (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0)
1152 return new tcu::Texture1DArray(format, level0.getWidth(), level0.getHeight());
1156 tcu::Texture2D* createSkeletonClone<tcu::Texture2DView> (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0)
1158 return new tcu::Texture2D(format, level0.getWidth(), level0.getHeight());
1162 tcu::Texture2DArray* createSkeletonClone<tcu::Texture2DArrayView> (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0)
1164 return new tcu::Texture2DArray(format, level0.getWidth(), level0.getHeight(), level0.getDepth());
1168 tcu::Texture3D* createSkeletonClone<tcu::Texture3DView> (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0)
1170 return new tcu::Texture3D(format, level0.getWidth(), level0.getHeight(), level0.getDepth());
1174 tcu::TextureCubeArray* createSkeletonClone<tcu::TextureCubeArrayView> (tcu::TextureFormat format, const tcu::ConstPixelBufferAccess& level0)
1176 return new tcu::TextureCubeArray(format, level0.getWidth(), level0.getDepth());
1179 template<typename TextureViewType>
1180 MovePtr<typename TexViewTraits<TextureViewType>::TextureType> createSwizzledCopy (const TextureViewType& texture, const vk::VkComponentMapping& swz)
1182 MovePtr<typename TexViewTraits<TextureViewType>::TextureType> copy (createSkeletonClone<TextureViewType>(getSwizzleTargetFormat(texture.getLevel(0).getFormat()), texture.getLevel(0)));
1184 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); ++levelNdx)
1186 copy->allocLevel(levelNdx);
1187 swizzle(texture.getLevel(levelNdx), copy->getLevel(levelNdx), swz);
1194 MovePtr<tcu::TextureCube> createSwizzledCopy (const tcu::TextureCubeView& texture, const vk::VkComponentMapping& swz)
1196 MovePtr<tcu::TextureCube> copy (new tcu::TextureCube(getSwizzleTargetFormat(texture.getLevelFace(0, tcu::CUBEFACE_NEGATIVE_X).getFormat()), texture.getSize()));
1198 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
1200 for (int levelNdx = 0; levelNdx < texture.getNumLevels(); ++levelNdx)
1202 copy->allocLevel((tcu::CubeFace)faceNdx, levelNdx);
1203 swizzle(texture.getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), copy->getLevelFace(levelNdx, (tcu::CubeFace)faceNdx), swz);
1210 template<typename TextureViewType>
1211 bool validateResultImage (const TextureViewType& texture,
1212 const tcu::Sampler& sampler,
1213 const vk::VkComponentMapping& swz,
1214 const tcu::ConstPixelBufferAccess& texCoords,
1215 const tcu::Vec2& lodBounds,
1216 const tcu::LookupPrecision& lookupPrecision,
1217 const tcu::Vec4& lookupScale,
1218 const tcu::Vec4& lookupBias,
1219 const tcu::ConstPixelBufferAccess& result,
1220 const tcu::PixelBufferAccess& errorMask)
1222 if (isIdentitySwizzle(swz))
1223 return validateResultImage(texture, sampler, texCoords, lodBounds, lookupPrecision, lookupScale, lookupBias, result, errorMask);
1226 // There is (currently) no way to handle swizzling inside validation loop
1227 // and thus we need to pre-swizzle the texture.
1228 UniquePtr<typename TexViewTraits<TextureViewType>::TextureType> swizzledTex (createSwizzledCopy(texture, swz));
1230 return validateResultImage(*swizzledTex, sampler, texCoords, lodBounds, lookupPrecision, swizzleScaleBias(lookupScale, swz, 1.0f), swizzleScaleBias(lookupBias, swz, 0.0f), result, errorMask);
1234 vk::VkImageSubresourceRange resolveSubresourceRange (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource)
1236 vk::VkImageSubresourceRange resolved = subresource;
1238 if (subresource.levelCount == VK_REMAINING_MIP_LEVELS)
1239 resolved.levelCount = testTexture.getNumLevels()-subresource.baseMipLevel;
1241 if (subresource.layerCount == VK_REMAINING_ARRAY_LAYERS)
1242 resolved.layerCount = testTexture.getArraySize()-subresource.baseArrayLayer;
1247 MovePtr<tcu::Texture1DView> getTexture1DView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector<tcu::ConstPixelBufferAccess>& levels)
1249 DE_ASSERT(subresource.layerCount == 1);
1251 levels.resize(subresource.levelCount);
1253 for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx)
1255 const tcu::ConstPixelBufferAccess& srcLevel = testTexture.getLevel((int)subresource.baseMipLevel+levelNdx, subresource.baseArrayLayer);
1257 levels[levelNdx] = tcu::getSubregion(srcLevel, 0, 0, 0, srcLevel.getWidth(), 1, 1);
1260 return MovePtr<tcu::Texture1DView>(new tcu::Texture1DView((int)levels.size(), &levels[0]));
1263 MovePtr<tcu::Texture1DArrayView> getTexture1DArrayView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector<tcu::ConstPixelBufferAccess>& levels)
1265 const TestTexture1D* tex1D = dynamic_cast<const TestTexture1D*>(&testTexture);
1266 const TestTexture1DArray* tex1DArray = dynamic_cast<const TestTexture1DArray*>(&testTexture);
1268 DE_ASSERT(!!tex1D != !!tex1DArray);
1269 DE_ASSERT(tex1DArray || subresource.baseArrayLayer == 0);
1271 levels.resize(subresource.levelCount);
1273 for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx)
1275 const tcu::ConstPixelBufferAccess& srcLevel = tex1D ? tex1D->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx)
1276 : tex1DArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx);
1278 levels[levelNdx] = tcu::getSubregion(srcLevel, 0, (int)subresource.baseArrayLayer, 0, srcLevel.getWidth(), (int)subresource.layerCount, 1);
1281 return MovePtr<tcu::Texture1DArrayView>(new tcu::Texture1DArrayView((int)levels.size(), &levels[0]));
1284 MovePtr<tcu::Texture2DView> getTexture2DView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector<tcu::ConstPixelBufferAccess>& levels)
1286 const TestTexture2D* tex2D = dynamic_cast<const TestTexture2D*>(&testTexture);
1287 const TestTexture2DArray* tex2DArray = dynamic_cast<const TestTexture2DArray*>(&testTexture);
1289 DE_ASSERT(subresource.layerCount == 1);
1290 DE_ASSERT(!!tex2D != !!tex2DArray);
1291 DE_ASSERT(tex2DArray || subresource.baseArrayLayer == 0);
1293 levels.resize(subresource.levelCount);
1295 for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx)
1297 const tcu::ConstPixelBufferAccess& srcLevel = tex2D ? tex2D->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx)
1298 : tex2DArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx);
1300 levels[levelNdx] = tcu::getSubregion(srcLevel, 0, 0, (int)subresource.baseArrayLayer, srcLevel.getWidth(), srcLevel.getHeight(), 1);
1303 return MovePtr<tcu::Texture2DView>(new tcu::Texture2DView((int)levels.size(), &levels[0]));
1306 MovePtr<tcu::Texture2DArrayView> getTexture2DArrayView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector<tcu::ConstPixelBufferAccess>& levels)
1308 const TestTexture2D* tex2D = dynamic_cast<const TestTexture2D*>(&testTexture);
1309 const TestTexture2DArray* tex2DArray = dynamic_cast<const TestTexture2DArray*>(&testTexture);
1311 DE_ASSERT(!!tex2D != !!tex2DArray);
1312 DE_ASSERT(tex2DArray || subresource.baseArrayLayer == 0);
1314 levels.resize(subresource.levelCount);
1316 for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx)
1318 const tcu::ConstPixelBufferAccess& srcLevel = tex2D ? tex2D->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx)
1319 : tex2DArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx);
1321 levels[levelNdx] = tcu::getSubregion(srcLevel, 0, 0, (int)subresource.baseArrayLayer, srcLevel.getWidth(), srcLevel.getHeight(), (int)subresource.layerCount);
1324 return MovePtr<tcu::Texture2DArrayView>(new tcu::Texture2DArrayView((int)levels.size(), &levels[0]));
1327 MovePtr<tcu::TextureCubeView> getTextureCubeView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector<tcu::ConstPixelBufferAccess>& levels)
1329 const static tcu::CubeFace s_faceMap[tcu::CUBEFACE_LAST] =
1331 tcu::CUBEFACE_POSITIVE_X,
1332 tcu::CUBEFACE_NEGATIVE_X,
1333 tcu::CUBEFACE_POSITIVE_Y,
1334 tcu::CUBEFACE_NEGATIVE_Y,
1335 tcu::CUBEFACE_POSITIVE_Z,
1336 tcu::CUBEFACE_NEGATIVE_Z
1339 const TestTextureCube* texCube = dynamic_cast<const TestTextureCube*>(&testTexture);
1340 const TestTextureCubeArray* texCubeArray = dynamic_cast<const TestTextureCubeArray*>(&testTexture);
1342 DE_ASSERT(!!texCube != !!texCubeArray);
1343 DE_ASSERT(subresource.layerCount == 6);
1344 DE_ASSERT(texCubeArray || subresource.baseArrayLayer == 0);
1346 levels.resize(subresource.levelCount*tcu::CUBEFACE_LAST);
1348 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
1350 for (int levelNdx = 0; levelNdx < (int)subresource.levelCount; ++levelNdx)
1352 const tcu::ConstPixelBufferAccess& srcLevel = texCubeArray ? texCubeArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx)
1353 : texCube->getTexture().getLevelFace(levelNdx, s_faceMap[faceNdx]);
1355 levels[faceNdx*subresource.levelCount + levelNdx] = tcu::getSubregion(srcLevel, 0, 0, (int)subresource.baseArrayLayer + (texCubeArray ? faceNdx : 0), srcLevel.getWidth(), srcLevel.getHeight(), 1);
1360 const tcu::ConstPixelBufferAccess* reordered[tcu::CUBEFACE_LAST];
1362 for (int faceNdx = 0; faceNdx < tcu::CUBEFACE_LAST; ++faceNdx)
1363 reordered[s_faceMap[faceNdx]] = &levels[faceNdx*subresource.levelCount];
1365 return MovePtr<tcu::TextureCubeView>(new tcu::TextureCubeView((int)subresource.levelCount, reordered));
1369 MovePtr<tcu::TextureCubeArrayView> getTextureCubeArrayView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector<tcu::ConstPixelBufferAccess>& levels)
1371 const TestTextureCubeArray* texCubeArray = dynamic_cast<const TestTextureCubeArray*>(&testTexture);
1373 DE_ASSERT(texCubeArray);
1374 DE_ASSERT(subresource.layerCount%6 == 0);
1376 levels.resize(subresource.levelCount);
1378 for (int levelNdx = 0; levelNdx < (int)subresource.levelCount; ++levelNdx)
1380 const tcu::ConstPixelBufferAccess& srcLevel = texCubeArray->getTexture().getLevel((int)subresource.baseMipLevel+levelNdx);
1382 levels[levelNdx] = tcu::getSubregion(srcLevel, 0, 0, (int)subresource.baseArrayLayer, srcLevel.getWidth(), srcLevel.getHeight(), (int)subresource.layerCount);
1385 return MovePtr<tcu::TextureCubeArrayView>(new tcu::TextureCubeArrayView((int)levels.size(), &levels[0]));
1388 MovePtr<tcu::Texture3DView> getTexture3DView (const TestTexture& testTexture, const vk::VkImageSubresourceRange& subresource, std::vector<tcu::ConstPixelBufferAccess>& levels)
1390 DE_ASSERT(subresource.baseArrayLayer == 0 && subresource.layerCount == 1);
1392 levels.resize(subresource.levelCount);
1394 for (int levelNdx = 0; levelNdx < (int)levels.size(); ++levelNdx)
1395 levels[levelNdx] = testTexture.getLevel((int)subresource.baseMipLevel+levelNdx, subresource.baseArrayLayer);
1397 return MovePtr<tcu::Texture3DView>(new tcu::Texture3DView((int)levels.size(), &levels[0]));
1400 bool validateResultImage (const TestTexture& texture,
1401 const VkImageViewType imageViewType,
1402 const VkImageSubresourceRange& subresource,
1403 const tcu::Sampler& sampler,
1404 const vk::VkComponentMapping& componentMapping,
1405 const tcu::ConstPixelBufferAccess& coordAccess,
1406 const tcu::Vec2& lodBounds,
1407 const tcu::LookupPrecision& lookupPrecision,
1408 const tcu::Vec4& lookupScale,
1409 const tcu::Vec4& lookupBias,
1410 const tcu::ConstPixelBufferAccess& resultAccess,
1411 const tcu::PixelBufferAccess& errorAccess)
1413 std::vector<tcu::ConstPixelBufferAccess> levels;
1415 switch (imageViewType)
1417 case VK_IMAGE_VIEW_TYPE_1D:
1419 UniquePtr<tcu::Texture1DView> texView(getTexture1DView(texture, subresource, levels));
1421 return validateResultImage(*texView, sampler, componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess);
1424 case VK_IMAGE_VIEW_TYPE_1D_ARRAY:
1426 UniquePtr<tcu::Texture1DArrayView> texView(getTexture1DArrayView(texture, subresource, levels));
1428 return validateResultImage(*texView, sampler, componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess);
1431 case VK_IMAGE_VIEW_TYPE_2D:
1433 UniquePtr<tcu::Texture2DView> texView(getTexture2DView(texture, subresource, levels));
1435 return validateResultImage(*texView, sampler, componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess);
1438 case VK_IMAGE_VIEW_TYPE_2D_ARRAY:
1440 UniquePtr<tcu::Texture2DArrayView> texView(getTexture2DArrayView(texture, subresource, levels));
1442 return validateResultImage(*texView, sampler, componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess);
1445 case VK_IMAGE_VIEW_TYPE_CUBE:
1447 UniquePtr<tcu::TextureCubeView> texView(getTextureCubeView(texture, subresource, levels));
1449 return validateResultImage(*texView, sampler, componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess);
1452 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY:
1454 UniquePtr<tcu::TextureCubeArrayView> texView(getTextureCubeArrayView(texture, subresource, levels));
1456 return validateResultImage(*texView, sampler, componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess);
1459 case VK_IMAGE_VIEW_TYPE_3D:
1461 UniquePtr<tcu::Texture3DView> texView(getTexture3DView(texture, subresource, levels));
1463 return validateResultImage(*texView, sampler, componentMapping, coordAccess, lodBounds, lookupPrecision, lookupScale, lookupBias, resultAccess, errorAccess);
1474 tcu::TestStatus ImageSamplingInstance::verifyImage (void)
1476 const VkPhysicalDeviceLimits& limits = m_context.getDeviceProperties().limits;
1477 // \note Color buffer is used to capture coordinates - not sampled texture values
1478 const tcu::TextureFormat colorFormat (tcu::TextureFormat::RGBA, tcu::TextureFormat::FLOAT);
1479 const tcu::TextureFormat depthStencilFormat; // Undefined depth/stencil format.
1480 const CoordinateCaptureProgram coordCaptureProgram;
1481 const rr::Program rrProgram = coordCaptureProgram.getReferenceProgram();
1482 ReferenceRenderer refRenderer (m_renderSize.x(), m_renderSize.y(), 1, colorFormat, depthStencilFormat, &rrProgram);
1483 const bool useStencilAspect = (m_subresourceRange.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT);
1485 bool compareOkAll = true;
1487 tcu::Vec4 lookupScale (1.0f);
1488 tcu::Vec4 lookupBias (0.0f);
1490 getLookupScaleBias(m_imageFormat, lookupScale, lookupBias, useStencilAspect);
1492 // Render out coordinates
1494 const rr::RenderState renderState(refRenderer.getViewportState(), m_context.getDeviceProperties().limits.subPixelPrecisionBits);
1495 refRenderer.draw(renderState, rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
1500 const tcu::Sampler sampler = mapVkSampler(m_samplerParams);
1501 const float referenceLod = de::clamp(m_samplerParams.mipLodBias + m_samplerLod, m_samplerParams.minLod, m_samplerParams.maxLod);
1502 const float lodError = 1.0f / static_cast<float>((1u << limits.mipmapPrecisionBits) - 1u);
1503 const tcu::Vec2 lodBounds (referenceLod - lodError, referenceLod + lodError);
1504 const vk::VkImageSubresourceRange subresource = resolveSubresourceRange(*m_texture, m_subresourceRange);
1506 const tcu::ConstPixelBufferAccess coordAccess = refRenderer.getAccess();
1507 tcu::TextureLevel errorMask (tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNORM_INT8), (int)m_renderSize.x(), (int)m_renderSize.y());
1508 const tcu::PixelBufferAccess errorAccess = errorMask.getAccess();
1510 const bool isNearestOnly = (m_samplerParams.minFilter == VK_FILTER_NEAREST && m_samplerParams.magFilter == VK_FILTER_NEAREST);
1512 tcu::LookupPrecision lookupPrecision;
1514 // Set precision requirements - very low for these tests as
1515 // the point of the test is not to validate accuracy.
1516 lookupPrecision.coordBits = tcu::IVec3(17, 17, 17);
1517 lookupPrecision.uvwBits = tcu::IVec3(5, 5, 5);
1518 lookupPrecision.colorMask = m_componentMask;
1519 lookupPrecision.colorThreshold = tcu::computeFixedPointThreshold(max((tcu::IVec4(8, 8, 8, 8) - (isNearestOnly ? 1 : 2)), tcu::IVec4(0))) / swizzleScaleBias(lookupScale, m_componentMapping, 1.0f);
1521 if (tcu::isSRGB(m_texture->getTextureFormat()))
1522 lookupPrecision.colorThreshold += tcu::Vec4(4.f / 255.f);
1524 de::MovePtr<TestTexture> textureCopy;
1525 TestTexture* texture = DE_NULL;
1527 if (isCombinedDepthStencilType(m_texture->getTextureFormat().type))
1529 // Verification loop does not support reading from combined depth stencil texture levels.
1530 // Get rid of stencil component.
1532 tcu::TextureFormat::ChannelOrder channelOrder = tcu::TextureFormat::CHANNELORDER_LAST;
1533 tcu::TextureFormat::ChannelType channelType = tcu::TextureFormat::CHANNELTYPE_LAST;
1535 if (subresource.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT)
1537 channelOrder = tcu::TextureFormat::S;
1538 channelType = tcu::TextureFormat::UNSIGNED_INT8;
1542 channelOrder = tcu::TextureFormat::D;
1544 switch (m_texture->getTextureFormat().type)
1546 case tcu::TextureFormat::UNSIGNED_INT_16_8_8:
1547 channelType = tcu::TextureFormat::UNORM_INT16;
1549 case tcu::TextureFormat::UNSIGNED_INT_24_8:
1550 case tcu::TextureFormat::UNSIGNED_INT_24_8_REV:
1551 channelType = tcu::TextureFormat::UNORM_INT24;
1553 case tcu::TextureFormat::FLOAT_UNSIGNED_INT_24_8_REV:
1554 channelType = tcu::TextureFormat::FLOAT;
1557 DE_FATAL("Unhandled texture format type in switch");
1561 textureCopy = m_texture->copy(tcu::TextureFormat(channelOrder, channelType));
1562 texture = textureCopy.get();
1566 texture = m_texture.get();
1569 for (int imgNdx = 0; imgNdx < m_imageCount; ++imgNdx)
1571 // Read back result image
1572 UniquePtr<tcu::TextureLevel> result (readColorAttachment(m_context.getDeviceInterface(),
1573 m_context.getDevice(),
1574 m_context.getUniversalQueue(),
1575 m_context.getUniversalQueueFamilyIndex(),
1576 m_context.getDefaultAllocator(),
1577 **m_colorImages[imgNdx],
1580 const tcu::ConstPixelBufferAccess resultAccess = result->getAccess();
1581 bool compareOk = validateResultImage(*texture,
1594 m_context.getTestContext().getLog()
1595 << tcu::TestLog::Image("Result", "Result Image", resultAccess)
1596 << tcu::TestLog::Image("ErrorMask", "Error Mask", errorAccess);
1598 compareOkAll = compareOkAll && compareOk;
1603 return tcu::TestStatus::pass("Result image matches reference");
1605 return tcu::TestStatus::fail("Image mismatch");