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 "tcuImageCompare.hpp"
46 static VkImageType getCompatibleImageType (VkImageViewType viewType)
50 case VK_IMAGE_VIEW_TYPE_1D: return VK_IMAGE_TYPE_1D;
51 case VK_IMAGE_VIEW_TYPE_1D_ARRAY: return VK_IMAGE_TYPE_1D;
52 case VK_IMAGE_VIEW_TYPE_2D: return VK_IMAGE_TYPE_2D;
53 case VK_IMAGE_VIEW_TYPE_2D_ARRAY: return VK_IMAGE_TYPE_2D;
54 case VK_IMAGE_VIEW_TYPE_3D: return VK_IMAGE_TYPE_3D;
55 case VK_IMAGE_VIEW_TYPE_CUBE: return VK_IMAGE_TYPE_2D;
56 case VK_IMAGE_VIEW_TYPE_CUBE_ARRAY: return VK_IMAGE_TYPE_2D;
62 return VK_IMAGE_TYPE_1D;
65 template<typename TcuFormatType>
66 static MovePtr<TestTexture> createTestTexture (const TcuFormatType format, VkImageViewType viewType, const tcu::IVec3& size, int layerCount)
68 MovePtr<TestTexture> texture;
69 const VkImageType imageType = getCompatibleImageType(viewType);
73 case VK_IMAGE_TYPE_1D:
75 texture = MovePtr<TestTexture>(new TestTexture1D(format, size.x()));
77 texture = MovePtr<TestTexture>(new TestTexture1DArray(format, size.x(), layerCount));
81 case VK_IMAGE_TYPE_2D:
84 texture = MovePtr<TestTexture>(new TestTexture2D(format, size.x(), size.y()));
88 if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
90 if (layerCount == tcu::CUBEFACE_LAST)
92 texture = MovePtr<TestTexture>(new TestTextureCube(format, size.x()));
96 DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
98 texture = MovePtr<TestTexture>(new TestTextureCubeArray(format, size.x(), layerCount));
103 texture = MovePtr<TestTexture>(new TestTexture2DArray(format, size.x(), size.y(), layerCount));
109 case VK_IMAGE_TYPE_3D:
110 texture = MovePtr<TestTexture>(new TestTexture3D(format, size.x(), size.y(), size.z()));
120 template<typename TcuTextureType>
121 static void copySubresourceRange (TcuTextureType& dest, const TcuTextureType& src, const VkImageSubresourceRange& subresourceRange)
123 DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
124 DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
126 for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
128 const tcu::ConstPixelBufferAccess srcLevel (src.getLevel(subresourceRange.baseMipLevel + levelNdx));
129 const deUint32 srcLayerOffset = subresourceRange.baseArrayLayer * srcLevel.getWidth() * srcLevel.getHeight() * srcLevel.getFormat().getPixelSize();
130 const tcu::ConstPixelBufferAccess srcLevelLayers (srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), subresourceRange.layerCount, (deUint8*)srcLevel.getDataPtr() + srcLayerOffset);
132 if (dest.isLevelEmpty(levelNdx))
133 dest.allocLevel(levelNdx);
135 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
140 void copySubresourceRange<tcu::Texture1DArray> (tcu::Texture1DArray& dest, const tcu::Texture1DArray& src, const VkImageSubresourceRange& subresourceRange)
142 DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
143 DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
145 DE_ASSERT(subresourceRange.layerCount == (deUint32)dest.getNumLayers());
146 DE_ASSERT(subresourceRange.baseArrayLayer + subresourceRange.layerCount <= (deUint32)src.getNumLayers());
148 for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
150 const tcu::ConstPixelBufferAccess srcLevel (src.getLevel(subresourceRange.baseMipLevel + levelNdx));
151 const deUint32 srcLayerOffset = subresourceRange.baseArrayLayer * srcLevel.getWidth() * srcLevel.getFormat().getPixelSize();
152 const tcu::ConstPixelBufferAccess srcLevelLayers (srcLevel.getFormat(), srcLevel.getWidth(), subresourceRange.layerCount, 1, (deUint8*)srcLevel.getDataPtr() + srcLayerOffset);
154 if (dest.isLevelEmpty(levelNdx))
155 dest.allocLevel(levelNdx);
157 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
162 void copySubresourceRange<tcu::Texture3D>(tcu::Texture3D& dest, const tcu::Texture3D& src, const VkImageSubresourceRange& subresourceRange)
164 DE_ASSERT(subresourceRange.levelCount <= (deUint32)dest.getNumLevels());
165 DE_ASSERT(subresourceRange.baseMipLevel + subresourceRange.levelCount <= (deUint32)src.getNumLevels());
167 for (int levelNdx = 0; levelNdx < dest.getNumLevels(); levelNdx++)
169 const tcu::ConstPixelBufferAccess srcLevel(src.getLevel(subresourceRange.baseMipLevel + levelNdx));
170 const tcu::ConstPixelBufferAccess srcLevelLayers(srcLevel.getFormat(), srcLevel.getWidth(), srcLevel.getHeight(), srcLevel.getDepth(), (deUint8*)srcLevel.getDataPtr());
172 if (dest.isLevelEmpty(levelNdx))
173 dest.allocLevel(levelNdx);
175 tcu::copy(dest.getLevel(levelNdx), srcLevelLayers);
179 static MovePtr<Program> createRefProgram(const tcu::TextureFormat& renderTargetFormat,
180 const tcu::Sampler& sampler,
182 const tcu::UVec4& componentMapping,
183 const TestTexture& testTexture,
184 VkImageViewType viewType,
186 const VkImageSubresourceRange& subresource)
188 MovePtr<Program> program;
189 const VkImageType imageType = getCompatibleImageType(viewType);
190 tcu::Vec4 lookupScale (1.0f);
191 tcu::Vec4 lookupBias (0.0f);
193 if (!testTexture.isCompressed())
195 const tcu::TextureFormatInfo fmtInfo = tcu::getTextureFormatInfo(testTexture.getLevel(0, 0).getFormat());
197 // Needed to normalize various formats to 0..1 range for writing into RT
198 lookupScale = fmtInfo.lookupScale;
199 lookupBias = fmtInfo.lookupBias;
201 // else: All supported compressed formats are fine with no normalization.
202 // ASTC LDR blocks decompress to f16 so querying normalization parameters
203 // based on uncompressed formats would actually lead to massive precision loss
204 // and complete lack of coverage in case of R8G8B8A8_UNORM RT.
208 case VK_IMAGE_TYPE_1D:
211 const tcu::Texture1D& texture = dynamic_cast<const TestTexture1D&>(testTexture).getTexture();
212 program = MovePtr<Program>(new SamplerProgram<tcu::Texture1D>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
216 const tcu::Texture1DArray& texture = dynamic_cast<const TestTexture1DArray&>(testTexture).getTexture();
218 if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getNumLayers())
220 // Not all texture levels and layers are needed. Create new sub-texture.
221 const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel);
222 tcu::Texture1DArray textureView (texture.getFormat(), baseLevel.getWidth(), subresource.layerCount);
224 copySubresourceRange(textureView, texture, subresource);
226 program = MovePtr<Program>(new SamplerProgram<tcu::Texture1DArray>(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
230 program = MovePtr<Program>(new SamplerProgram<tcu::Texture1DArray>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
235 case VK_IMAGE_TYPE_2D:
238 const tcu::Texture2D& texture = dynamic_cast<const TestTexture2D&>(testTexture).getTexture();
239 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2D>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
243 if (viewType == VK_IMAGE_VIEW_TYPE_CUBE || viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
245 if (layerCount == tcu::CUBEFACE_LAST)
247 const tcu::TextureCube& texture = dynamic_cast<const TestTextureCube&>(testTexture).getTexture();
248 program = MovePtr<Program>(new SamplerProgram<tcu::TextureCube>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
252 DE_ASSERT(layerCount % tcu::CUBEFACE_LAST == 0);
254 const tcu::TextureCubeArray& texture = dynamic_cast<const TestTextureCubeArray&>(testTexture).getTexture();
256 if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getDepth())
258 DE_ASSERT(subresource.baseArrayLayer + subresource.layerCount <= (deUint32)texture.getDepth());
260 // Not all texture levels and layers are needed. Create new sub-texture.
261 const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel);
262 tcu::TextureCubeArray textureView (texture.getFormat(), baseLevel.getWidth(), subresource.layerCount);
264 copySubresourceRange(textureView, texture, subresource);
266 program = MovePtr<Program>(new SamplerProgram<tcu::TextureCubeArray>(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
270 // Use all array layers
271 program = MovePtr<Program>(new SamplerProgram<tcu::TextureCubeArray>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
277 const tcu::Texture2DArray& texture = dynamic_cast<const TestTexture2DArray&>(testTexture).getTexture();
279 if (subresource.baseMipLevel > 0 || subresource.layerCount < (deUint32)texture.getNumLayers())
281 DE_ASSERT(subresource.baseArrayLayer + subresource.layerCount <= (deUint32)texture.getNumLayers());
283 // Not all texture levels and layers are needed. Create new sub-texture.
284 const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel);
285 tcu::Texture2DArray textureView (texture.getFormat(), baseLevel.getWidth(), baseLevel.getHeight(), subresource.layerCount);
287 copySubresourceRange(textureView, texture, subresource);
289 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2DArray>(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
293 // Use all array layers
294 program = MovePtr<Program>(new SamplerProgram<tcu::Texture2DArray>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
300 case VK_IMAGE_TYPE_3D:
302 const tcu::Texture3D& texture = dynamic_cast<const TestTexture3D&>(testTexture).getTexture();
304 if (subresource.baseMipLevel > 0)
306 // Not all texture levels are needed. Create new sub-texture.
307 const tcu::ConstPixelBufferAccess baseLevel = texture.getLevel(subresource.baseMipLevel);
308 tcu::Texture3D textureView(texture.getFormat(), baseLevel.getWidth(), baseLevel.getHeight(), baseLevel.getDepth());
310 copySubresourceRange(textureView, texture, subresource);
312 program = MovePtr<Program>(new SamplerProgram<tcu::Texture3D>(renderTargetFormat, textureView, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
316 program = MovePtr<Program>(new SamplerProgram<tcu::Texture3D>(renderTargetFormat, texture, sampler, samplerLod, lookupScale, lookupBias, componentMapping));
330 ImageSamplingInstance::ImageSamplingInstance (Context& context,
331 const tcu::UVec2& renderSize,
332 VkImageViewType imageViewType,
333 VkFormat imageFormat,
334 const tcu::IVec3& imageSize,
336 const VkComponentMapping& componentMapping,
337 const VkImageSubresourceRange& subresourceRange,
338 const VkSamplerCreateInfo& samplerParams,
340 const std::vector<Vertex4Tex4>& vertices)
341 : vkt::TestInstance (context)
342 , m_imageViewType (imageViewType)
343 , m_imageSize (imageSize)
344 , m_layerCount (layerCount)
345 , m_componentMapping (componentMapping)
346 , m_subresourceRange (subresourceRange)
347 , m_samplerParams (samplerParams)
348 , m_samplerLod (samplerLod)
349 , m_renderSize (renderSize)
350 , m_colorFormat (VK_FORMAT_R8G8B8A8_UNORM)
351 , m_vertices (vertices)
353 const DeviceInterface& vk = context.getDeviceInterface();
354 const VkDevice vkDevice = context.getDevice();
355 const VkQueue queue = context.getUniversalQueue();
356 const deUint32 queueFamilyIndex = context.getUniversalQueueFamilyIndex();
357 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(context.getInstanceInterface(), context.getPhysicalDevice()));
358 const VkComponentMapping componentMappingRGBA = { VK_COMPONENT_SWIZZLE_R, VK_COMPONENT_SWIZZLE_G, VK_COMPONENT_SWIZZLE_B, VK_COMPONENT_SWIZZLE_A };
360 if (!isSupportedSamplableFormat(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat))
361 throw tcu::NotSupportedError(std::string("Unsupported format for sampling: ") + getFormatName(imageFormat));
363 if ((samplerParams.minFilter == VK_FILTER_LINEAR ||
364 samplerParams.magFilter == VK_FILTER_LINEAR ||
365 samplerParams.mipmapMode == VK_SAMPLER_MIPMAP_MODE_LINEAR) &&
366 !isLinearFilteringSupported(context.getInstanceInterface(), context.getPhysicalDevice(), imageFormat, VK_IMAGE_TILING_OPTIMAL))
367 throw tcu::NotSupportedError(std::string("Unsupported format for linear filtering: ") + getFormatName(imageFormat));
369 if (isCompressedFormat(imageFormat) && imageViewType == VK_IMAGE_VIEW_TYPE_3D)
371 // \todo [2016-01-22 pyry] Mandate VK_ERROR_FORMAT_NOT_SUPPORTED
374 const VkImageFormatProperties formatProperties = getPhysicalDeviceImageFormatProperties(context.getInstanceInterface(),
375 context.getPhysicalDevice(),
378 VK_IMAGE_TILING_OPTIMAL,
379 VK_IMAGE_USAGE_SAMPLED_BIT,
380 (VkImageCreateFlags)0);
382 if (formatProperties.maxExtent.width == 0 &&
383 formatProperties.maxExtent.height == 0 &&
384 formatProperties.maxExtent.depth == 0)
385 TCU_THROW(NotSupportedError, "3D compressed format not supported");
389 TCU_THROW(NotSupportedError, "3D compressed format not supported");
393 // Create texture image, view and sampler
395 VkImageCreateFlags imageFlags = 0u;
397 if (m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE || m_imageViewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
398 imageFlags = VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
400 // Initialize texture data
401 if (isCompressedFormat(imageFormat))
402 m_texture = createTestTexture(mapVkCompressedFormat(imageFormat), imageViewType, imageSize, layerCount);
404 m_texture = createTestTexture(mapVkFormat(imageFormat), imageViewType, imageSize, layerCount);
406 const VkImageCreateInfo imageParams =
408 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
409 DE_NULL, // const void* pNext;
410 imageFlags, // VkImageCreateFlags flags;
411 getCompatibleImageType(m_imageViewType), // VkImageType imageType;
412 imageFormat, // VkFormat format;
413 { // VkExtent3D extent;
414 (deUint32)m_imageSize.x(),
415 (deUint32)m_imageSize.y(),
416 (deUint32)m_imageSize.z()
418 (deUint32)m_texture->getNumLevels(), // deUint32 mipLevels;
419 (deUint32)m_layerCount, // deUint32 arrayLayers;
420 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
421 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
422 VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT, // VkImageUsageFlags usage;
423 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
424 1u, // deUint32 queueFamilyIndexCount;
425 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
426 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
429 m_image = createImage(vk, vkDevice, &imageParams);
430 m_imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_image), MemoryRequirement::Any);
431 VK_CHECK(vk.bindImageMemory(vkDevice, *m_image, m_imageAlloc->getMemory(), m_imageAlloc->getOffset()));
433 // Upload texture data
434 uploadTestTexture(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_texture, *m_image);
436 // Create image view and sampler
437 const VkImageViewCreateInfo imageViewParams =
439 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
440 DE_NULL, // const void* pNext;
441 0u, // VkImageViewCreateFlags flags;
442 *m_image, // VkImage image;
443 m_imageViewType, // VkImageViewType viewType;
444 imageFormat, // VkFormat format;
445 m_componentMapping, // VkComponentMapping components;
446 m_subresourceRange, // VkImageSubresourceRange subresourceRange;
449 m_imageView = createImageView(vk, vkDevice, &imageViewParams);
450 m_sampler = createSampler(vk, vkDevice, &m_samplerParams);
453 // Create descriptor set for combined image and sampler
455 DescriptorPoolBuilder descriptorPoolBuilder;
456 descriptorPoolBuilder.addType(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1u);
457 m_descriptorPool = descriptorPoolBuilder.build(vk, vkDevice, VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, 1u);
459 DescriptorSetLayoutBuilder setLayoutBuilder;
460 setLayoutBuilder.addSingleBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT);
461 m_descriptorSetLayout = setLayoutBuilder.build(vk, vkDevice);
463 const VkDescriptorSetAllocateInfo descriptorSetAllocateInfo =
465 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
466 DE_NULL, // const void* pNext;
467 *m_descriptorPool, // VkDescriptorPool descriptorPool;
468 1u, // deUint32 setLayoutCount;
469 &m_descriptorSetLayout.get() // const VkDescriptorSetLayout* pSetLayouts;
472 m_descriptorSet = allocateDescriptorSet(vk, vkDevice, &descriptorSetAllocateInfo);
474 const VkDescriptorImageInfo descriptorImageInfo =
476 *m_sampler, // VkSampler sampler;
477 *m_imageView, // VkImageView imageView;
478 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL // VkImageLayout imageLayout;
481 DescriptorSetUpdateBuilder setUpdateBuilder;
482 setUpdateBuilder.writeSingle(*m_descriptorSet, DescriptorSetUpdateBuilder::Location::binding(0), VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, &descriptorImageInfo);
483 setUpdateBuilder.update(vk, vkDevice);
486 // Create color image and view
488 const VkImageCreateInfo colorImageParams =
490 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
491 DE_NULL, // const void* pNext;
492 0u, // VkImageCreateFlags flags;
493 VK_IMAGE_TYPE_2D, // VkImageType imageType;
494 m_colorFormat, // VkFormat format;
495 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y(), 1u }, // VkExtent3D extent;
496 1u, // deUint32 mipLevels;
497 1u, // deUint32 arrayLayers;
498 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
499 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
500 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT, // VkImageUsageFlags usage;
501 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
502 1u, // deUint32 queueFamilyIndexCount;
503 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
504 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout initialLayout;
507 m_colorImage = createImage(vk, vkDevice, &colorImageParams);
508 m_colorImageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, vkDevice, *m_colorImage), MemoryRequirement::Any);
509 VK_CHECK(vk.bindImageMemory(vkDevice, *m_colorImage, m_colorImageAlloc->getMemory(), m_colorImageAlloc->getOffset()));
511 const VkImageViewCreateInfo colorAttachmentViewParams =
513 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
514 DE_NULL, // const void* pNext;
515 0u, // VkImageViewCreateFlags flags;
516 *m_colorImage, // VkImage image;
517 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
518 m_colorFormat, // VkFormat format;
519 componentMappingRGBA, // VkComponentMapping components;
520 { VK_IMAGE_ASPECT_COLOR_BIT, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
523 m_colorAttachmentView = createImageView(vk, vkDevice, &colorAttachmentViewParams);
526 // Create render pass
528 const VkAttachmentDescription colorAttachmentDescription =
530 0u, // VkAttachmentDescriptionFlags flags;
531 m_colorFormat, // VkFormat format;
532 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
533 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
534 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
535 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
536 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
537 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
538 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
541 const VkAttachmentReference colorAttachmentReference =
543 0u, // deUint32 attachment;
544 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
547 const VkSubpassDescription subpassDescription =
549 0u, // VkSubpassDescriptionFlags flags;
550 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
551 0u, // deUint32 inputAttachmentCount;
552 DE_NULL, // const VkAttachmentReference* pInputAttachments;
553 1u, // deUint32 colorAttachmentCount;
554 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
555 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
556 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment;
557 0u, // deUint32 preserveAttachmentCount;
558 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
561 const VkRenderPassCreateInfo renderPassParams =
563 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
564 DE_NULL, // const void* pNext;
565 0u, // VkRenderPassCreateFlags flags;
566 1u, // deUint32 attachmentCount;
567 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
568 1u, // deUint32 subpassCount;
569 &subpassDescription, // const VkSubpassDescription* pSubpasses;
570 0u, // deUint32 dependencyCount;
571 DE_NULL // const VkSubpassDependency* pDependencies;
574 m_renderPass = createRenderPass(vk, vkDevice, &renderPassParams);
577 // Create framebuffer
579 const VkFramebufferCreateInfo framebufferParams =
581 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
582 DE_NULL, // const void* pNext;
583 0u, // VkFramebufferCreateFlags flags;
584 *m_renderPass, // VkRenderPass renderPass;
585 1u, // deUint32 attachmentCount;
586 &m_colorAttachmentView.get(), // const VkImageView* pAttachments;
587 (deUint32)m_renderSize.x(), // deUint32 width;
588 (deUint32)m_renderSize.y(), // deUint32 height;
589 1u // deUint32 layers;
592 m_framebuffer = createFramebuffer(vk, vkDevice, &framebufferParams);
595 // Create pipeline layout
597 const VkPipelineLayoutCreateInfo pipelineLayoutParams =
599 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
600 DE_NULL, // const void* pNext;
601 0u, // VkPipelineLayoutCreateFlags flags;
602 1u, // deUint32 setLayoutCount;
603 &m_descriptorSetLayout.get(), // const VkDescriptorSetLayout* pSetLayouts;
604 0u, // deUint32 pushConstantRangeCount;
605 DE_NULL // const VkPushConstantRange* pPushConstantRanges;
608 m_pipelineLayout = createPipelineLayout(vk, vkDevice, &pipelineLayoutParams);
611 m_vertexShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_vert"), 0);
612 m_fragmentShaderModule = createShaderModule(vk, vkDevice, m_context.getBinaryCollection().get("tex_frag"), 0);
616 const VkPipelineShaderStageCreateInfo shaderStages[2] =
619 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
620 DE_NULL, // const void* pNext;
621 0u, // VkPipelineShaderStageCreateFlags flags;
622 VK_SHADER_STAGE_VERTEX_BIT, // VkShaderStageFlagBits stage;
623 *m_vertexShaderModule, // VkShaderModule module;
624 "main", // const char* pName;
625 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
628 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
629 DE_NULL, // const void* pNext;
630 0u, // VkPipelineShaderStageCreateFlags flags;
631 VK_SHADER_STAGE_FRAGMENT_BIT, // VkShaderStageFlagBits stage;
632 *m_fragmentShaderModule, // VkShaderModule module;
633 "main", // const char* pName;
634 DE_NULL // const VkSpecializationInfo* pSpecializationInfo;
638 const VkVertexInputBindingDescription vertexInputBindingDescription =
640 0u, // deUint32 binding;
641 sizeof(Vertex4Tex4), // deUint32 strideInBytes;
642 VK_VERTEX_INPUT_RATE_VERTEX // VkVertexInputStepRate inputRate;
645 const VkVertexInputAttributeDescription vertexInputAttributeDescriptions[2] =
648 0u, // deUint32 location;
649 0u, // deUint32 binding;
650 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
651 0u // deUint32 offset;
654 1u, // deUint32 location;
655 0u, // deUint32 binding;
656 VK_FORMAT_R32G32B32A32_SFLOAT, // VkFormat format;
657 DE_OFFSET_OF(Vertex4Tex4, texCoord), // deUint32 offset;
661 const VkPipelineVertexInputStateCreateInfo vertexInputStateParams =
663 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
664 DE_NULL, // const void* pNext;
665 0u, // VkPipelineVertexInputStateCreateFlags flags;
666 1u, // deUint32 vertexBindingDescriptionCount;
667 &vertexInputBindingDescription, // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
668 2u, // deUint32 vertexAttributeDescriptionCount;
669 vertexInputAttributeDescriptions // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
672 const VkPipelineInputAssemblyStateCreateInfo inputAssemblyStateParams =
674 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
675 DE_NULL, // const void* pNext;
676 0u, // VkPipelineInputAssemblyStateCreateFlags flags;
677 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // VkPrimitiveTopology topology;
678 false // VkBool32 primitiveRestartEnable;
681 const VkViewport viewport =
685 (float)m_renderSize.x(), // float width;
686 (float)m_renderSize.y(), // float height;
687 0.0f, // float minDepth;
688 1.0f // float maxDepth;
691 const VkRect2D scissor = { { 0, 0 }, { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() } };
693 const VkPipelineViewportStateCreateInfo viewportStateParams =
695 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
696 DE_NULL, // const void* pNext;
697 0u, // VkPipelineViewportStateCreateFlags flags;
698 1u, // deUint32 viewportCount;
699 &viewport, // const VkViewport* pViewports;
700 1u, // deUint32 scissorCount;
701 &scissor // const VkRect2D* pScissors;
704 const VkPipelineRasterizationStateCreateInfo rasterStateParams =
706 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
707 DE_NULL, // const void* pNext;
708 0u, // VkPipelineRasterizationStateCreateFlags flags;
709 false, // VkBool32 depthClampEnable;
710 false, // VkBool32 rasterizerDiscardEnable;
711 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
712 VK_CULL_MODE_NONE, // VkCullModeFlags cullMode;
713 VK_FRONT_FACE_COUNTER_CLOCKWISE, // VkFrontFace frontFace;
714 false, // VkBool32 depthBiasEnable;
715 0.0f, // float depthBiasConstantFactor;
716 0.0f, // float depthBiasClamp;
717 0.0f, // float depthBiasSlopeFactor;
718 1.0f // float lineWidth;
721 const VkPipelineColorBlendAttachmentState colorBlendAttachmentState =
723 false, // VkBool32 blendEnable;
724 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcColorBlendFactor;
725 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstColorBlendFactor;
726 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
727 VK_BLEND_FACTOR_ONE, // VkBlendFactor srcAlphaBlendFactor;
728 VK_BLEND_FACTOR_ZERO, // VkBlendFactor dstAlphaBlendFactor;
729 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
730 VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | // VkColorComponentFlags colorWriteMask;
731 VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT
734 const VkPipelineColorBlendStateCreateInfo colorBlendStateParams =
736 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
737 DE_NULL, // const void* pNext;
738 0u, // VkPipelineColorBlendStateCreateFlags flags;
739 false, // VkBool32 logicOpEnable;
740 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
741 1u, // deUint32 attachmentCount;
742 &colorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
743 { 0.0f, 0.0f, 0.0f, 0.0f } // float blendConstants[4];
746 const VkPipelineMultisampleStateCreateInfo multisampleStateParams =
748 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
749 DE_NULL, // const void* pNext;
750 0u, // VkPipelineMultisampleStateCreateFlags flags;
751 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
752 false, // VkBool32 sampleShadingEnable;
753 0.0f, // float minSampleShading;
754 DE_NULL, // const VkSampleMask* pSampleMask;
755 false, // VkBool32 alphaToCoverageEnable;
756 false // VkBool32 alphaToOneEnable;
759 VkPipelineDepthStencilStateCreateInfo depthStencilStateParams =
761 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
762 DE_NULL, // const void* pNext;
763 0u, // VkPipelineDepthStencilStateCreateFlags flags;
764 false, // VkBool32 depthTestEnable;
765 false, // VkBool32 depthWriteEnable;
766 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
767 false, // VkBool32 depthBoundsTestEnable;
768 false, // VkBool32 stencilTestEnable;
769 { // VkStencilOpState front;
770 VK_STENCIL_OP_ZERO, // VkStencilOp failOp;
771 VK_STENCIL_OP_ZERO, // VkStencilOp passOp;
772 VK_STENCIL_OP_ZERO, // VkStencilOp depthFailOp;
773 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
774 0u, // deUint32 compareMask;
775 0u, // deUint32 writeMask;
776 0u // deUint32 reference;
778 { // VkStencilOpState back;
779 VK_STENCIL_OP_ZERO, // VkStencilOp failOp;
780 VK_STENCIL_OP_ZERO, // VkStencilOp passOp;
781 VK_STENCIL_OP_ZERO, // VkStencilOp depthFailOp;
782 VK_COMPARE_OP_NEVER, // VkCompareOp compareOp;
783 0u, // deUint32 compareMask;
784 0u, // deUint32 writeMask;
785 0u // deUint32 reference;
787 -1.0f, // float minDepthBounds;
788 +1.0f // float maxDepthBounds;
791 const VkGraphicsPipelineCreateInfo graphicsPipelineParams =
793 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
794 DE_NULL, // const void* pNext;
795 0u, // VkPipelineCreateFlags flags;
796 2u, // deUint32 stageCount;
797 shaderStages, // const VkPipelineShaderStageCreateInfo* pStages;
798 &vertexInputStateParams, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
799 &inputAssemblyStateParams, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
800 DE_NULL, // const VkPipelineTessellationStateCreateInfo* pTessellationState;
801 &viewportStateParams, // const VkPipelineViewportStateCreateInfo* pViewportState;
802 &rasterStateParams, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
803 &multisampleStateParams, // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
804 &depthStencilStateParams, // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
805 &colorBlendStateParams, // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
806 (const VkPipelineDynamicStateCreateInfo*)DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
807 *m_pipelineLayout, // VkPipelineLayout layout;
808 *m_renderPass, // VkRenderPass renderPass;
809 0u, // deUint32 subpass;
810 0u, // VkPipeline basePipelineHandle;
811 0u // deInt32 basePipelineIndex;
814 m_graphicsPipeline = createGraphicsPipeline(vk, vkDevice, DE_NULL, &graphicsPipelineParams);
817 // Create vertex buffer
819 const VkDeviceSize vertexBufferSize = (VkDeviceSize)(m_vertices.size() * sizeof(Vertex4Tex4));
820 const VkBufferCreateInfo vertexBufferParams =
822 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
823 DE_NULL, // const void* pNext;
824 0u, // VkBufferCreateFlags flags;
825 vertexBufferSize, // VkDeviceSize size;
826 VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, // VkBufferUsageFlags usage;
827 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
828 1u, // deUint32 queueFamilyIndexCount;
829 &queueFamilyIndex // const deUint32* pQueueFamilyIndices;
832 DE_ASSERT(vertexBufferSize > 0);
834 m_vertexBuffer = createBuffer(vk, vkDevice, &vertexBufferParams);
835 m_vertexBufferAlloc = memAlloc.allocate(getBufferMemoryRequirements(vk, vkDevice, *m_vertexBuffer), MemoryRequirement::HostVisible);
837 VK_CHECK(vk.bindBufferMemory(vkDevice, *m_vertexBuffer, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset()));
839 // Load vertices into vertex buffer
840 deMemcpy(m_vertexBufferAlloc->getHostPtr(), &m_vertices[0], (size_t)vertexBufferSize);
841 flushMappedMemoryRange(vk, vkDevice, m_vertexBufferAlloc->getMemory(), m_vertexBufferAlloc->getOffset(), vertexBufferParams.size);
844 // Create command pool
846 const VkCommandPoolCreateInfo cmdPoolParams =
848 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
849 DE_NULL, // const void* pNext;
850 VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, // VkCommandPoolCreateFlags flags;
851 queueFamilyIndex // deUint32 queueFamilyIndex;
854 m_cmdPool = createCommandPool(vk, vkDevice, &cmdPoolParams);
857 // Create command buffer
859 const VkCommandBufferAllocateInfo cmdBufferAllocateInfo =
861 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
862 DE_NULL, // const void* pNext;
863 *m_cmdPool, // VkCommandPool commandPool;
864 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
865 1u, // deUint32 bufferCount;
868 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
870 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
871 DE_NULL, // const void* pNext;
872 0u, // VkCommandBufferUsageFlags flags;
873 (const VkCommandBufferInheritanceInfo*)DE_NULL,
876 const VkClearValue attachmentClearValue = defaultClearValue(m_colorFormat);
878 const VkRenderPassBeginInfo renderPassBeginInfo =
880 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
881 DE_NULL, // const void* pNext;
882 *m_renderPass, // VkRenderPass renderPass;
883 *m_framebuffer, // VkFramebuffer framebuffer;
886 { (deUint32)m_renderSize.x(), (deUint32)m_renderSize.y() }
887 }, // VkRect2D renderArea;
888 1, // deUint32 clearValueCount;
889 &attachmentClearValue // const VkClearValue* pClearValues;
892 m_cmdBuffer = allocateCommandBuffer(vk, vkDevice, &cmdBufferAllocateInfo);
894 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
895 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
897 vk.cmdBindPipeline(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_graphicsPipeline);
899 vk.cmdBindDescriptorSets(*m_cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_pipelineLayout, 0, 1, &m_descriptorSet.get(), 0, DE_NULL);
901 const VkDeviceSize vertexBufferOffset = 0;
902 vk.cmdBindVertexBuffers(*m_cmdBuffer, 0, 1, &m_vertexBuffer.get(), &vertexBufferOffset);
903 vk.cmdDraw(*m_cmdBuffer, (deUint32)m_vertices.size(), 1, 0, 0);
905 vk.cmdEndRenderPass(*m_cmdBuffer);
906 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
911 const VkFenceCreateInfo fenceParams =
913 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
914 DE_NULL, // const void* pNext;
915 0u // VkFenceCreateFlags flags;
918 m_fence = createFence(vk, vkDevice, &fenceParams);
922 ImageSamplingInstance::~ImageSamplingInstance (void)
926 tcu::TestStatus ImageSamplingInstance::iterate (void)
928 const DeviceInterface& vk = m_context.getDeviceInterface();
929 const VkDevice vkDevice = m_context.getDevice();
930 const VkQueue queue = m_context.getUniversalQueue();
931 const VkSubmitInfo submitInfo =
933 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
934 DE_NULL, // const void* pNext;
935 0u, // deUint32 waitSemaphoreCount;
936 DE_NULL, // const VkSemaphore* pWaitSemaphores;
938 1u, // deUint32 commandBufferCount;
939 &m_cmdBuffer.get(), // const VkCommandBuffer* pCommandBuffers;
940 0u, // deUint32 signalSemaphoreCount;
941 DE_NULL // const VkSemaphore* pSignalSemaphores;
944 VK_CHECK(vk.resetFences(vkDevice, 1, &m_fence.get()));
945 VK_CHECK(vk.queueSubmit(queue, 1, &submitInfo, *m_fence));
946 VK_CHECK(vk.waitForFences(vkDevice, 1, &m_fence.get(), true, ~(0ull) /* infinity */));
948 return verifyImage();
951 tcu::TestStatus ImageSamplingInstance::verifyImage (void)
953 const tcu::TextureFormat colorFormat = mapVkFormat(m_colorFormat);
954 const tcu::TextureFormat depthStencilFormat = tcu::TextureFormat(); // Undefined depth/stencil format.
955 const tcu::Sampler sampler = mapVkSampler(m_samplerParams);
956 const tcu::UVec4 componentMapping = mapVkComponentMapping(m_componentMapping);
959 MovePtr<Program> program;
960 MovePtr<ReferenceRenderer> refRenderer;
962 // Set up LOD of reference sampler
963 samplerLod = de::max(m_samplerParams.minLod, de::min(m_samplerParams.maxLod, m_samplerParams.mipLodBias + m_samplerLod));
965 // Create reference program that uses image subresource range
966 program = createRefProgram(colorFormat, sampler, samplerLod, componentMapping, *m_texture, m_imageViewType, m_layerCount, m_subresourceRange);
967 const rr::Program referenceProgram = program->getReferenceProgram();
969 // Render reference image
970 refRenderer = MovePtr<ReferenceRenderer>(new ReferenceRenderer(m_renderSize.x(), m_renderSize.y(), 1, colorFormat, depthStencilFormat, &referenceProgram));
971 const rr::RenderState renderState(refRenderer->getViewportState());
972 refRenderer->draw(renderState, rr::PRIMITIVETYPE_TRIANGLES, m_vertices);
974 // Compare result with reference image
976 const DeviceInterface& vk = m_context.getDeviceInterface();
977 const VkDevice vkDevice = m_context.getDevice();
978 const VkQueue queue = m_context.getUniversalQueue();
979 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
980 SimpleAllocator memAlloc (vk, vkDevice, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
981 MovePtr<tcu::TextureLevel> result = readColorAttachment(vk, vkDevice, queue, queueFamilyIndex, memAlloc, *m_colorImage, m_colorFormat, m_renderSize);
983 compareOk = tcu::intThresholdPositionDeviationCompare(m_context.getTestContext().getLog(),
986 refRenderer->getAccess(),
988 tcu::UVec4(4, 4, 4, 4),
991 tcu::COMPARE_LOG_RESULT);
995 return tcu::TestStatus::pass("Result image matches reference");
997 return tcu::TestStatus::fail("Image mismatch");