1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 The Khronos Group Inc.
6 * Copyright (c) 2017 Google Inc.
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.
21 * \file vktSparseResourcesImageAlignedMipSize.cpp
22 * \brief Aligned mip size tests.
23 *//*--------------------------------------------------------------------*/
25 #include "vktSparseResourcesBufferSparseBinding.hpp"
26 #include "vktSparseResourcesTestsUtil.hpp"
27 #include "vktSparseResourcesBase.hpp"
28 #include "vktTestCaseUtil.hpp"
32 #include "vkRefUtil.hpp"
33 #include "vkPlatform.hpp"
34 #include "vkPrograms.hpp"
35 #include "vkMemUtil.hpp"
36 #include "vkBuilderUtil.hpp"
37 #include "vkImageUtil.hpp"
38 #include "vkQueryUtil.hpp"
39 #include "vkTypeUtil.hpp"
41 #include "deUniquePtr.hpp"
42 #include "deStringUtil.hpp"
56 class ImageAlignedMipSizeCase : public TestCase
59 ImageAlignedMipSizeCase (tcu::TestContext& testCtx,
60 const std::string& name,
61 const std::string& description,
62 const ImageType imageType,
63 const tcu::UVec3& imageSize,
64 const tcu::TextureFormat& format);
66 void initPrograms (SourceCollections& sourceCollections) const {DE_UNREF(sourceCollections);};
67 TestInstance* createInstance (Context& context) const;
70 const ImageType m_imageType;
71 const tcu::UVec3 m_imageSize;
72 const tcu::TextureFormat m_format;
75 ImageAlignedMipSizeCase::ImageAlignedMipSizeCase (tcu::TestContext& testCtx,
76 const std::string& name,
77 const std::string& description,
78 const ImageType imageType,
79 const tcu::UVec3& imageSize,
80 const tcu::TextureFormat& format)
81 : TestCase (testCtx, name, description)
82 , m_imageType (imageType)
83 , m_imageSize (imageSize)
88 class ImageAlignedMipSizeInstance : public SparseResourcesBaseInstance
91 ImageAlignedMipSizeInstance(Context& context,
92 const ImageType imageType,
93 const tcu::UVec3& imageSize,
94 const tcu::TextureFormat& format);
96 tcu::TestStatus iterate (void);
99 const ImageType m_imageType;
100 const tcu::UVec3 m_imageSize;
101 const tcu::TextureFormat m_format;
104 ImageAlignedMipSizeInstance::ImageAlignedMipSizeInstance (Context& context,
105 const ImageType imageType,
106 const tcu::UVec3& imageSize,
107 const tcu::TextureFormat& format)
108 : SparseResourcesBaseInstance (context)
109 , m_imageType (imageType)
110 , m_imageSize (imageSize)
115 tcu::TestStatus ImageAlignedMipSizeInstance::iterate (void)
117 const InstanceInterface& instance = m_context.getInstanceInterface();
118 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
119 const VkPhysicalDeviceProperties physicalDeviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
120 VkImageCreateInfo imageCreateInfo;
121 VkSparseImageMemoryRequirements aspectRequirements;
122 VkExtent3D imageGranularity;
123 const VkPhysicalDeviceSparseProperties sparseProperties = physicalDeviceProperties.sparseProperties;
124 VkImageFormatProperties imageFormatProperties;
126 // Check the image size does not exceed device limits
127 if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
128 TCU_THROW(NotSupportedError, "Image size not supported for device");
130 // Check if device supports sparse operations for image type
131 if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
132 TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
134 imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
135 imageCreateInfo.pNext = DE_NULL;
136 imageCreateInfo.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
137 imageCreateInfo.imageType = mapImageType(m_imageType);
138 imageCreateInfo.format = mapTextureFormat(m_format);
139 imageCreateInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageSize));
140 imageCreateInfo.arrayLayers = getNumLayers(m_imageType, m_imageSize);
141 imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
142 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
143 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
144 imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
145 VK_IMAGE_USAGE_STORAGE_BIT;
146 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
147 imageCreateInfo.queueFamilyIndexCount = 0u;
148 imageCreateInfo.pQueueFamilyIndices = DE_NULL;
150 if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
152 imageCreateInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
155 imageFormatProperties = getPhysicalDeviceImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags);
157 imageCreateInfo.mipLevels = getImageMaxMipLevels(imageFormatProperties, imageCreateInfo.extent);
159 // Check if device supports sparse operations for image format
160 if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageCreateInfo))
161 TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
164 QueueRequirementsVec queueRequirements;
165 queueRequirements.push_back(QueueRequirements(VK_QUEUE_SPARSE_BINDING_BIT, 1u));
167 createDeviceSupportingQueues(queueRequirements);
171 const DeviceInterface& deviceInterface = getDeviceInterface();
173 // Create sparse image
174 const Unique<VkImage> sparseImage (createImage(deviceInterface, getDevice(), &imageCreateInfo));
176 // Get sparse image sparse memory requirements
177 const std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *sparseImage);
179 DE_ASSERT(sparseMemoryRequirements.size() != 0);
181 const deUint32 colorAspectIndex = getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_COLOR_BIT);
183 if (colorAspectIndex == NO_MATCH_FOUND)
184 TCU_THROW(NotSupportedError, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT");
186 aspectRequirements = sparseMemoryRequirements[colorAspectIndex];
187 imageGranularity = aspectRequirements.formatProperties.imageGranularity;
190 if (sparseProperties.residencyAlignedMipSize)
197 extent = mipLevelExtents(imageCreateInfo.extent, lod);
198 if (extent.width % imageGranularity.width != 0
199 || extent.height % imageGranularity.height != 0
200 || extent.depth % imageGranularity.depth != 0)
207 while (extent.width != 1 || extent.height != 1 || extent.depth != 1);
209 if (lod != aspectRequirements.imageMipTailFirstLod)
210 return tcu::TestStatus::fail("Unexpected first LOD for mip tail.");
212 return tcu::TestStatus::pass("pass");
214 else if (aspectRequirements.formatProperties.flags & VK_SPARSE_IMAGE_FORMAT_ALIGNED_MIP_SIZE_BIT)
216 return tcu::TestStatus::fail("Aligned mip size flag doesn't match in device and image properties.");
220 return tcu::TestStatus::pass("Aligned mip size not enabled.");
224 TestInstance* ImageAlignedMipSizeCase::createInstance (Context& context) const
226 return new ImageAlignedMipSizeInstance(context, m_imageType, m_imageSize, m_format);
231 tcu::TestCaseGroup* createImageAlignedMipSizeTests (tcu::TestContext& testCtx)
233 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "aligned_mip_size", "Aligned mip size"));
235 struct ImageParameters
238 tcu::UVec3 imageSize;
241 static const ImageParameters imageParametersArray[] =
243 { IMAGE_TYPE_2D, tcu::UVec3(512u, 256u, 1u) },
244 { IMAGE_TYPE_2D_ARRAY, tcu::UVec3(512u, 256u, 6u) },
245 { IMAGE_TYPE_CUBE, tcu::UVec3(256u, 256u, 1u) },
246 { IMAGE_TYPE_CUBE_ARRAY, tcu::UVec3(256u, 256u, 6u) },
247 { IMAGE_TYPE_3D, tcu::UVec3(512u, 256u, 16u) }
250 static const tcu::TextureFormat formats[] =
252 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT32),
253 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT16),
254 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT8),
255 tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::SIGNED_INT32),
256 tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::SIGNED_INT16),
257 tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::SIGNED_INT8),
258 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
259 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
260 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
263 for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
265 const ImageType imageType = imageParametersArray[imageTypeNdx].imageType;
266 de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
268 for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
270 const tcu::TextureFormat& format = formats[formatNdx];
271 const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSize;
272 const std::string name = getShaderImageFormatQualifier(format);
274 imageTypeGroup->addChild(new ImageAlignedMipSizeCase(testCtx, name.c_str(), "", imageType, imageSize, format));
276 testGroup->addChild(imageTypeGroup.release());
279 return testGroup.release();