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 vktSparseResourcesImageBlockShapes.cpp
22 * \brief Standard block shape 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 ImageBlockShapesCase : public TestCase
59 ImageBlockShapesCase (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,
67 void initPrograms (SourceCollections& sourceCollections) const {DE_UNREF(sourceCollections);};
68 TestInstance* createInstance (Context& context) const;
71 const ImageType m_imageType;
72 const tcu::UVec3 m_imageSize;
73 const tcu::TextureFormat m_format;
74 const deUint32 m_numSamples;
77 ImageBlockShapesCase::ImageBlockShapesCase (tcu::TestContext& testCtx,
78 const std::string& name,
79 const std::string& description,
80 const ImageType imageType,
81 const tcu::UVec3& imageSize,
82 const tcu::TextureFormat& format,
84 : TestCase (testCtx, name, description)
85 , m_imageType (imageType)
86 , m_imageSize (imageSize)
88 , m_numSamples (numSamples)
92 class ImageBlockShapesInstance : public SparseResourcesBaseInstance
95 ImageBlockShapesInstance(Context& context,
96 const ImageType imageType,
97 const tcu::UVec3& imageSize,
98 const tcu::TextureFormat& format,
101 tcu::TestStatus iterate (void);
104 const ImageType m_imageType;
105 const tcu::UVec3 m_imageSize;
106 const tcu::TextureFormat m_format;
107 const deUint32 m_numSamples;
110 ImageBlockShapesInstance::ImageBlockShapesInstance (Context& context,
111 const ImageType imageType,
112 const tcu::UVec3& imageSize,
113 const tcu::TextureFormat& format,
115 : SparseResourcesBaseInstance (context)
116 , m_imageType (imageType)
117 , m_imageSize (imageSize)
119 , m_numSamples (numSamples)
123 tcu::TestStatus ImageBlockShapesInstance::iterate (void)
125 const InstanceInterface& instance = m_context.getInstanceInterface();
126 const VkPhysicalDevice physicalDevice = m_context.getPhysicalDevice();
127 const VkPhysicalDeviceProperties physicalDeviceProperties = getPhysicalDeviceProperties(instance, physicalDevice);
128 VkImageCreateInfo imageCreateInfo;
129 VkSparseImageMemoryRequirements aspectRequirements;
130 VkExtent3D imageGranularity;
131 const VkPhysicalDeviceSparseProperties sparseProperties = physicalDeviceProperties.sparseProperties;
132 const deUint32 pixelSize = tcu::getPixelSize(m_format) * 8;
133 VkExtent3D expectedGranularity;
135 // Check the image size does not exceed device limits
136 if (!isImageSizeSupported(instance, physicalDevice, m_imageType, m_imageSize))
137 TCU_THROW(NotSupportedError, "Image size not supported for device");
139 // Check if device supports sparse operations for image type
140 if (!checkSparseSupportForImageType(instance, physicalDevice, m_imageType))
141 TCU_THROW(NotSupportedError, "Sparse residency for image type is not supported");
143 imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
144 imageCreateInfo.pNext = DE_NULL;
145 imageCreateInfo.flags = VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_SPARSE_BINDING_BIT;
146 imageCreateInfo.imageType = mapImageType(m_imageType);
147 imageCreateInfo.format = mapTextureFormat(m_format);
148 imageCreateInfo.extent = makeExtent3D(getLayerSize(m_imageType, m_imageSize));
149 imageCreateInfo.mipLevels = 1u;
150 imageCreateInfo.arrayLayers = getNumLayers(m_imageType, m_imageSize);
151 imageCreateInfo.samples = static_cast<VkSampleCountFlagBits>(m_numSamples);
152 imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
153 imageCreateInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
154 imageCreateInfo.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
155 VK_IMAGE_USAGE_STORAGE_BIT;
156 imageCreateInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
157 imageCreateInfo.queueFamilyIndexCount = 0u;
158 imageCreateInfo.pQueueFamilyIndices = DE_NULL;
160 if (m_imageType == IMAGE_TYPE_CUBE || m_imageType == IMAGE_TYPE_CUBE_ARRAY)
162 imageCreateInfo.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
165 // Check the format supports given number of samples
166 const VkImageFormatProperties formatProperties = getPhysicalDeviceImageFormatProperties(instance, physicalDevice, imageCreateInfo.format, imageCreateInfo.imageType, imageCreateInfo.tiling, imageCreateInfo.usage, imageCreateInfo.flags);
168 if (!(formatProperties.sampleCounts & imageCreateInfo.samples))
169 TCU_THROW(NotSupportedError, "The image format does not support the number of samples specified");
171 // Check if device supports sparse operations for image format
172 if (!checkSparseSupportForImageFormat(instance, physicalDevice, imageCreateInfo))
173 TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
176 QueueRequirementsVec queueRequirements;
177 queueRequirements.push_back(QueueRequirements(VK_QUEUE_SPARSE_BINDING_BIT, 1u));
179 createDeviceSupportingQueues(queueRequirements);
183 const DeviceInterface& deviceInterface = getDeviceInterface();
185 // Create sparse image
186 const Unique<VkImage> sparseImage (createImage(deviceInterface, getDevice(), &imageCreateInfo));
188 // Get sparse image sparse memory requirements
189 const std::vector<VkSparseImageMemoryRequirements> sparseMemoryRequirements = getImageSparseMemoryRequirements(deviceInterface, getDevice(), *sparseImage);
191 DE_ASSERT(sparseMemoryRequirements.size() != 0);
193 const deUint32 colorAspectIndex = getSparseAspectRequirementsIndex(sparseMemoryRequirements, VK_IMAGE_ASPECT_COLOR_BIT);
195 if (colorAspectIndex == NO_MATCH_FOUND)
196 TCU_THROW(NotSupportedError, "Not supported image aspect - the test supports currently only VK_IMAGE_ASPECT_COLOR_BIT");
198 aspectRequirements = sparseMemoryRequirements[colorAspectIndex];
199 imageGranularity = aspectRequirements.formatProperties.imageGranularity;
202 if (m_imageType == IMAGE_TYPE_3D)
204 if (!sparseProperties.residencyStandard3DBlockShape)
205 return tcu::TestStatus::pass("Pass (residencyStandard3DBlockShape disabled)");
210 expectedGranularity.width = 64;
211 expectedGranularity.height = 32;
212 expectedGranularity.depth = 32;
215 expectedGranularity.width = 32;
216 expectedGranularity.height = 32;
217 expectedGranularity.depth = 32;
220 expectedGranularity.width = 32;
221 expectedGranularity.height = 32;
222 expectedGranularity.depth = 16;
225 expectedGranularity.width = 32;
226 expectedGranularity.height = 16;
227 expectedGranularity.depth = 16;
230 DE_ASSERT(pixelSize == 128);
231 expectedGranularity.width = 16;
232 expectedGranularity.height = 16;
233 expectedGranularity.depth = 16;
237 else if (m_numSamples == 2)
239 if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
240 return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
242 expectedGranularity.depth = 1;
247 expectedGranularity.width = 128;
248 expectedGranularity.height = 256;
251 expectedGranularity.width = 128;
252 expectedGranularity.height = 128;
255 expectedGranularity.width = 64;
256 expectedGranularity.height = 128;
259 expectedGranularity.width = 64;
260 expectedGranularity.height = 64;
263 DE_ASSERT(pixelSize == 128);
264 expectedGranularity.width = 32;
265 expectedGranularity.height = 64;
269 else if (m_numSamples == 4)
271 if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
272 return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
274 expectedGranularity.depth = 1;
279 expectedGranularity.width = 128;
280 expectedGranularity.height = 128;
283 expectedGranularity.width = 128;
284 expectedGranularity.height = 64;
287 expectedGranularity.width = 64;
288 expectedGranularity.height = 64;
291 expectedGranularity.width = 64;
292 expectedGranularity.height = 32;
295 DE_ASSERT(pixelSize == 128);
296 expectedGranularity.width = 32;
297 expectedGranularity.height = 32;
301 else if (m_numSamples == 8)
303 if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
304 return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
306 expectedGranularity.depth = 1;
311 expectedGranularity.width = 64;
312 expectedGranularity.height = 128;
315 expectedGranularity.width = 64;
316 expectedGranularity.height = 64;
319 expectedGranularity.width = 32;
320 expectedGranularity.height = 64;
323 expectedGranularity.width = 32;
324 expectedGranularity.height = 32;
327 DE_ASSERT(pixelSize == 128);
328 expectedGranularity.width = 16;
329 expectedGranularity.height = 32;
333 else if (m_numSamples == 16)
335 if (!sparseProperties.residencyStandard2DMultisampleBlockShape)
336 return tcu::TestStatus::pass("Pass (residencyStandard2DMultisampleBlockShape disabled)");
338 expectedGranularity.depth = 1;
343 expectedGranularity.width = 64;
344 expectedGranularity.height = 64;
347 expectedGranularity.width = 64;
348 expectedGranularity.height = 32;
351 expectedGranularity.width = 32;
352 expectedGranularity.height = 32;
355 expectedGranularity.width = 32;
356 expectedGranularity.height = 16;
359 DE_ASSERT(pixelSize == 128);
360 expectedGranularity.width = 16;
361 expectedGranularity.height = 16;
367 DE_ASSERT(m_numSamples == 1);
369 if (!sparseProperties.residencyStandard2DBlockShape)
370 return tcu::TestStatus::pass("Pass (residencyStandard2DBlockShape disabled)");
372 expectedGranularity.depth = 1;
377 expectedGranularity.width = 256;
378 expectedGranularity.height = 256;
381 expectedGranularity.width = 256;
382 expectedGranularity.height = 128;
385 expectedGranularity.width = 128;
386 expectedGranularity.height = 128;
389 expectedGranularity.width = 128;
390 expectedGranularity.height = 64;
393 DE_ASSERT(pixelSize == 128);
394 expectedGranularity.width = 64;
395 expectedGranularity.height = 64;
400 if (imageGranularity.width == expectedGranularity.width
401 && imageGranularity.height == expectedGranularity.height
402 && imageGranularity.depth == expectedGranularity.depth)
404 return tcu::TestStatus::pass("Passed");
408 return tcu::TestStatus::fail("Non-standard block shape used");
412 TestInstance* ImageBlockShapesCase::createInstance (Context& context) const
414 return new ImageBlockShapesInstance(context, m_imageType, m_imageSize, m_format, m_numSamples);
419 tcu::TestCaseGroup* createImageBlockShapesTests (tcu::TestContext& testCtx)
421 de::MovePtr<tcu::TestCaseGroup> testGroup(new tcu::TestCaseGroup(testCtx, "image_block_shapes", "Standard block shape"));
423 struct ImageParameters
426 tcu::UVec3 imageSize;
429 static const ImageParameters imageParametersArray[] =
431 { IMAGE_TYPE_2D, tcu::UVec3(512u, 256u, 1u) },
432 { IMAGE_TYPE_2D_ARRAY, tcu::UVec3(512u, 256u, 6u) },
433 { IMAGE_TYPE_CUBE, tcu::UVec3(256u, 256u, 1u) },
434 { IMAGE_TYPE_CUBE_ARRAY, tcu::UVec3(256u, 256u, 6u) },
435 { IMAGE_TYPE_3D, tcu::UVec3(512u, 256u, 16u) }
438 static const tcu::TextureFormat formats[] =
440 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT32),
441 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT16),
442 tcu::TextureFormat(tcu::TextureFormat::R, tcu::TextureFormat::SIGNED_INT8),
443 tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::SIGNED_INT32),
444 tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::SIGNED_INT16),
445 tcu::TextureFormat(tcu::TextureFormat::RG, tcu::TextureFormat::SIGNED_INT8),
446 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT32),
447 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT16),
448 tcu::TextureFormat(tcu::TextureFormat::RGBA, tcu::TextureFormat::UNSIGNED_INT8)
451 static const deUint32 sampleCounts[] = { 1u, 2u, 4u, 8u, 16u };
453 for (deInt32 imageTypeNdx = 0; imageTypeNdx < DE_LENGTH_OF_ARRAY(imageParametersArray); ++imageTypeNdx)
455 const ImageType imageType = imageParametersArray[imageTypeNdx].imageType;
456 de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
458 for (deInt32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); ++formatNdx)
460 const tcu::TextureFormat& format = formats[formatNdx];
461 de::MovePtr<tcu::TestCaseGroup> formatGroup(new tcu::TestCaseGroup(testCtx, getShaderImageFormatQualifier(format).c_str(), ""));
463 for (deInt32 sampleCountNdx = 0; sampleCountNdx < DE_LENGTH_OF_ARRAY(sampleCounts); ++sampleCountNdx)
465 const tcu::UVec3 imageSize = imageParametersArray[imageTypeNdx].imageSize;
466 const deUint32 sampleCount = sampleCounts[sampleCountNdx];
467 const std::string name = std::string("samples_") + de::toString(sampleCount);
469 formatGroup->addChild(new ImageBlockShapesCase(testCtx, name.c_str(), "", imageType, imageSize, format, sampleCount));
471 imageTypeGroup->addChild(formatGroup.release());
473 testGroup->addChild(imageTypeGroup.release());
476 return testGroup.release();