1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2015 The Khronos Group Inc.
6 * Copyright (c) 2015 Samsung Electronics Co., 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 Vulkan Get Render Area Granularity Tests
23 *//*--------------------------------------------------------------------*/
25 #include "vktApiGranularityTests.hpp"
27 #include "deRandom.hpp"
28 #include "deSharedPtr.hpp"
29 #include "deStringUtil.hpp"
30 #include "deUniquePtr.hpp"
32 #include "vkImageUtil.hpp"
33 #include "vkMemUtil.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkRefUtil.hpp"
36 #include "vktTestCase.hpp"
38 #include "tcuTestLog.hpp"
39 #include "tcuTextureUtil.hpp"
56 AttachmentInfo (const VkFormat vkFormat,
58 const deUint32 height,
63 extent.height = height;
67 ~AttachmentInfo (void)
74 typedef de::SharedPtr<Allocation> AllocationSp;
75 typedef de::SharedPtr<Unique<VkImage> > VkImageSp;
76 typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp;
78 class GranularityInstance : public vkt::TestInstance
81 GranularityInstance (Context& context,
82 const std::vector<AttachmentInfo>& attachments,
83 const bool useRenderPass);
84 virtual ~GranularityInstance (void);
85 void checkFormatSupport (const VkFormat format);
86 void initAttachmentDescriptions (void);
87 void initImages (void);
88 void initRenderPass (void);
89 void beginRenderPass (void);
90 void endRenderPass (void);
91 virtual tcu::TestStatus iterate (void);
93 const std::vector<AttachmentInfo> m_attachments;
94 const bool m_useRenderPass;
96 Move<VkRenderPass> m_renderPass;
97 Move<VkFramebuffer> m_frameBuffer;
98 Move<VkCommandPool> m_cmdPool;
99 Move<VkCommandBuffer> m_cmdBuffer;
100 std::vector<VkAttachmentDescription> m_attachmentDescriptions;
101 std::vector<VkImageSp> m_images;
102 std::vector<AllocationSp> m_imageAllocs;
103 std::vector<VkImageViewSp> m_imageViews;
106 GranularityInstance::GranularityInstance (Context& context,
107 const std::vector<AttachmentInfo>& attachments,
108 const bool useRenderPass)
109 : vkt::TestInstance (context)
110 , m_attachments (attachments)
111 , m_useRenderPass (useRenderPass)
113 initAttachmentDescriptions();
116 GranularityInstance::~GranularityInstance (void)
120 void GranularityInstance::checkFormatSupport (const VkFormat format)
122 VkImageFormatProperties properties;
124 VkResult result = m_context.getInstanceInterface().getPhysicalDeviceImageFormatProperties(m_context.getPhysicalDevice(),
125 format, VK_IMAGE_TYPE_2D,
126 VK_IMAGE_TILING_OPTIMAL,
127 VK_IMAGE_USAGE_SAMPLED_BIT,
131 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED)
132 TCU_THROW(NotSupportedError, "Format not supported");
135 void GranularityInstance::initAttachmentDescriptions (void)
137 VkAttachmentDescription attachmentDescription =
139 0u, // VkAttachmentDescriptionFlags flags;
140 VK_FORMAT_UNDEFINED, // VkFormat format;
141 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
142 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp;
143 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp storeOp;
144 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
145 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
146 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
147 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout finalLayout;
150 for (std::vector<AttachmentInfo>::const_iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
152 checkFormatSupport(it->format);
153 attachmentDescription.format = it->format;
154 m_attachmentDescriptions.push_back(attachmentDescription);
158 void GranularityInstance::initImages (void)
160 const DeviceInterface& vk = m_context.getDeviceInterface();
161 const VkDevice device = m_context.getDevice();
162 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
163 SimpleAllocator memAlloc (vk, device, getPhysicalDeviceMemoryProperties(m_context.getInstanceInterface(), m_context.getPhysicalDevice()));
165 for (std::vector<AttachmentInfo>::const_iterator it = m_attachments.begin(); it != m_attachments.end(); ++it)
167 const VkImageCreateInfo imageInfo =
169 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
170 DE_NULL, // const void* pNext;
171 0u, // VkImageCreateFlags flags;
172 VK_IMAGE_TYPE_2D, // VkImageType imageType;
173 it->format, // VkFormat format;
174 it->extent, // VkExtent3D extent;
175 1u, // deUint32 mipLevels;
176 1u, // deUint32 arrayLayers;
177 VK_SAMPLE_COUNT_1_BIT, // deUint32 samples;
178 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
179 VK_IMAGE_USAGE_SAMPLED_BIT, // VkImageUsageFlags usage;
180 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
181 1u, // deUint32 queueFamilyCount;
182 &queueFamilyIndex, // const deUint32* pQueueFamilyIndices;
183 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
187 Move<VkImage> image = createImage(vk, device, &imageInfo);
188 de::MovePtr<Allocation> imageAlloc = memAlloc.allocate(getImageMemoryRequirements(vk, device, *image), MemoryRequirement::Any);
189 VK_CHECK(vk.bindImageMemory(device, *image, imageAlloc->getMemory(), imageAlloc->getOffset()));
191 VkImageAspectFlags aspectFlags = 0;
192 const tcu::TextureFormat tcuFormat = mapVkFormat(it->format);
194 if (tcu::hasDepthComponent(tcuFormat.order))
195 aspectFlags |= VK_IMAGE_ASPECT_DEPTH_BIT;
197 if (tcu::hasStencilComponent(tcuFormat.order))
198 aspectFlags |= VK_IMAGE_ASPECT_STENCIL_BIT;
201 aspectFlags = VK_IMAGE_ASPECT_COLOR_BIT;
203 VkFormatProperties formatProperties;
204 m_context.getInstanceInterface().getPhysicalDeviceFormatProperties(m_context.getPhysicalDevice(),
205 it->format, &formatProperties);
207 if ((formatProperties.optimalTilingFeatures & (VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT |
208 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)) == 0)
209 throw tcu::NotSupportedError("Format not supported as attachment");
211 const VkImageViewCreateInfo createInfo =
213 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
214 DE_NULL, // const void* pNext;
215 0, // VkImageViewCreateFlags flags;
216 *image, // VkImage image;
217 VK_IMAGE_VIEW_TYPE_2D, // VkImageViewType viewType;
218 it->format, // VkFormat format;
220 VK_COMPONENT_SWIZZLE_R,
221 VK_COMPONENT_SWIZZLE_G,
222 VK_COMPONENT_SWIZZLE_B,
223 VK_COMPONENT_SWIZZLE_A
224 }, // VkComponentMapping components;
225 { aspectFlags, 0u, 1u, 0u, 1u } // VkImageSubresourceRange subresourceRange;
228 // Create the Image View
229 Move<VkImageView> imageView = createImageView(vk, device, &createInfo);
231 // To prevent object free
232 m_images.push_back(VkImageSp(new Unique<VkImage>(image)));
233 m_imageAllocs.push_back(AllocationSp(imageAlloc.release()));
234 m_imageViews.push_back(VkImageViewSp(new Unique<VkImageView>(imageView)));
238 void GranularityInstance::initRenderPass (void)
240 const DeviceInterface& vk = m_context.getDeviceInterface();
241 const VkDevice device = m_context.getDevice();
242 const deUint32 queueFamilyIndex = m_context.getUniversalQueueFamilyIndex();
244 { // Create RenderPass
245 const VkSubpassDescription subpassDesc =
247 (VkSubpassDescriptionFlags)0u, // VkSubpassDescriptionFlags flags;
248 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
249 0u, // deUint32 inputCount;
250 DE_NULL, // const VkAttachmentReference* pInputAttachments;
251 0u, // deUint32 colorCount;
252 DE_NULL, // const VkAttachmentReference* pColorAttachments;
253 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
254 DE_NULL, // VkAttachmentReference depthStencilAttachment;
255 0u, // deUint32 preserveCount;
256 DE_NULL // const VkAttachmentReference* pPreserveAttachments;
259 const VkRenderPassCreateInfo renderPassParams =
261 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
262 DE_NULL, // const void* pNext;
263 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
264 (deUint32)m_attachmentDescriptions.size(), // deUint32 attachmentCount;
265 &m_attachmentDescriptions[0], // const VkAttachmentDescription* pAttachments;
266 1u, // deUint32 subpassCount;
267 &subpassDesc, // const VkSubpassDescription* pSubpasses;
268 0u, // deUint32 dependencyCount;
269 DE_NULL // const VkSubpassDependency* pDependencies;
272 m_renderPass = createRenderPass(vk, device, &renderPassParams);
277 { // Create Framebuffer
278 std::vector<VkImageView> imageViews;
280 for (std::vector<VkImageViewSp>::const_iterator it = m_imageViews.begin(); it != m_imageViews.end(); ++it)
281 imageViews.push_back(it->get()->get());
283 const VkFramebufferCreateInfo framebufferParams =
285 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
286 DE_NULL, // const void* pNext;
287 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
288 *m_renderPass, // VkRenderPass renderPass;
289 (deUint32)imageViews.size(), // deUint32 attachmentCount;
290 &imageViews[0], // const VkImageView* pAttachments;
291 1, // deUint32 width;
292 1, // deUint32 height;
293 1 // deUint32 layers;
296 m_frameBuffer = createFramebuffer(vk, device, &framebufferParams);
299 m_cmdPool = createCommandPool(vk, device, VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, queueFamilyIndex);
301 // Create CommandBuffer
302 m_cmdBuffer = allocateCommandBuffer(vk, device, *m_cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY);
304 { // Begin CommandBuffer
305 const VkCommandBufferBeginInfo cmdBufferBeginInfo =
307 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
308 DE_NULL, // const void* pNext;
309 0u, // VkCmdBufferOptimizeFlags flags;
310 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
313 VK_CHECK(vk.beginCommandBuffer(*m_cmdBuffer, &cmdBufferBeginInfo));
317 void GranularityInstance::beginRenderPass (void)
319 const DeviceInterface& vk = m_context.getDeviceInterface();
321 const VkRect2D renderArea =
323 { 0, 0 }, // VkOffset2D offset;
324 { 1, 1 } // VkExtent2D extent;
327 const VkRenderPassBeginInfo renderPassBeginInfo =
329 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
330 DE_NULL, // const void* pNext;
331 *m_renderPass, // VkRenderPass renderPass;
332 *m_frameBuffer, // VkFramebuffer framebuffer;
333 renderArea, // VkRect2D renderArea;
334 0u, // uint32_t clearValueCount;
335 DE_NULL // const VkClearValue* pClearValues;
338 vk.cmdBeginRenderPass(*m_cmdBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
341 void GranularityInstance::endRenderPass (void)
343 const DeviceInterface& vk = m_context.getDeviceInterface();
345 vk.cmdEndRenderPass(*m_cmdBuffer);
346 VK_CHECK(vk.endCommandBuffer(*m_cmdBuffer));
349 tcu::TestStatus GranularityInstance::iterate (void)
351 const DeviceInterface& vk = m_context.getDeviceInterface();
352 const VkDevice device = m_context.getDevice();
353 tcu::TestLog& log = m_context.getTestContext().getLog();
357 VkExtent2D prePassGranularity = { ~0u, ~0u };
358 vk.getRenderAreaGranularity(device, *m_renderPass, &prePassGranularity);
363 VkExtent2D granularity = { 0u, 0u };
364 vk.getRenderAreaGranularity(device, *m_renderPass, &granularity);
365 TCU_CHECK(granularity.width >= 1 && granularity.height >= 1);
366 TCU_CHECK(prePassGranularity.width == granularity.width && prePassGranularity.height == granularity.height);
367 TCU_CHECK(granularity.width <= m_context.getDeviceProperties().limits.maxFramebufferWidth && granularity.height <= m_context.getDeviceProperties().limits.maxFramebufferHeight);
372 log << tcu::TestLog::Message << "Horizontal granularity: " << granularity.width << " Vertical granularity: " << granularity.height << tcu::TestLog::EndMessage;
373 return tcu::TestStatus::pass("Granularity test");
376 class GranularityCase : public vkt::TestCase
379 GranularityCase (tcu::TestContext& testCtx,
380 const std::string& name,
381 const std::string& description,
382 const std::vector<AttachmentInfo>& attachments,
383 const bool useRenderPass);
384 virtual ~GranularityCase (void);
386 virtual TestInstance* createInstance (Context& context) const;
388 const std::vector<AttachmentInfo> m_attachments;
389 const bool m_useRenderPass;
392 GranularityCase::GranularityCase (tcu::TestContext& testCtx,
393 const std::string& name,
394 const std::string& description,
395 const std::vector<AttachmentInfo>& attachments,
396 const bool useRenderPass = false)
397 : vkt::TestCase (testCtx, name, description)
398 , m_attachments (attachments)
399 , m_useRenderPass (useRenderPass)
403 GranularityCase::~GranularityCase (void)
407 TestInstance* GranularityCase::createInstance (Context& context) const
409 return new GranularityInstance(context, m_attachments, m_useRenderPass);
414 tcu::TestCaseGroup* createGranularityQueryTests (tcu::TestContext& testCtx)
416 de::MovePtr<tcu::TestCaseGroup> group (new tcu::TestCaseGroup(testCtx, "granularity", "Granularity query tests"));
418 de::MovePtr<tcu::TestCaseGroup> single (new tcu::TestCaseGroup(testCtx, "single", "Single texture granularity tests."));
419 de::MovePtr<tcu::TestCaseGroup> multi (new tcu::TestCaseGroup(testCtx, "multi", "Multiple textures with same format granularity tests."));
420 de::MovePtr<tcu::TestCaseGroup> random (new tcu::TestCaseGroup(testCtx, "random", "Multiple textures with a guaranteed format occurence."));
421 de::MovePtr<tcu::TestCaseGroup> inRenderPass (new tcu::TestCaseGroup(testCtx, "in_render_pass", "Single texture granularity tests, inside render pass"));
424 const char* description = "Granularity case.";
426 const VkFormat mandatoryFormats[] =
428 VK_FORMAT_B4G4R4A4_UNORM_PACK16,
429 VK_FORMAT_R5G6B5_UNORM_PACK16,
430 VK_FORMAT_A1R5G5B5_UNORM_PACK16,
435 VK_FORMAT_R8G8_UNORM,
436 VK_FORMAT_R8G8_SNORM,
439 VK_FORMAT_R8G8B8A8_UNORM,
440 VK_FORMAT_R8G8B8A8_SNORM,
441 VK_FORMAT_R8G8B8A8_UINT,
442 VK_FORMAT_R8G8B8A8_SINT,
443 VK_FORMAT_R8G8B8A8_SRGB,
444 VK_FORMAT_B8G8R8A8_UNORM,
445 VK_FORMAT_B8G8R8A8_SRGB,
446 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
447 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
448 VK_FORMAT_A8B8G8R8_UINT_PACK32,
449 VK_FORMAT_A8B8G8R8_SINT_PACK32,
450 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
451 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
452 VK_FORMAT_A2B10G10R10_UINT_PACK32,
455 VK_FORMAT_R16_SFLOAT,
456 VK_FORMAT_R16G16_UINT,
457 VK_FORMAT_R16G16_SINT,
458 VK_FORMAT_R16G16_SFLOAT,
459 VK_FORMAT_R16G16B16A16_UINT,
460 VK_FORMAT_R16G16B16A16_SINT,
461 VK_FORMAT_R16G16B16A16_SFLOAT,
464 VK_FORMAT_R32_SFLOAT,
465 VK_FORMAT_R32G32_UINT,
466 VK_FORMAT_R32G32_SINT,
467 VK_FORMAT_R32G32_SFLOAT,
468 VK_FORMAT_R32G32B32A32_UINT,
469 VK_FORMAT_R32G32B32A32_SINT,
470 VK_FORMAT_R32G32B32A32_SFLOAT,
471 VK_FORMAT_B10G11R11_UFLOAT_PACK32,
472 VK_FORMAT_E5B9G9R9_UFLOAT_PACK32,
474 VK_FORMAT_D32_SFLOAT,
477 const deUint32 maxDimension = 500;
478 const deUint32 minIteration = 2;
479 const deUint32 maxIteration = 10;
481 for (deUint32 formatIdx = 1; formatIdx <= VK_FORMAT_D32_SFLOAT_S8_UINT; ++formatIdx)
483 VkFormat format = VkFormat(formatIdx);
484 std::string name = de::toLower(getFormatName(format)).substr(10);
487 std::vector<AttachmentInfo> attachments;
488 attachments.push_back(AttachmentInfo(format, rnd.getInt(1, maxDimension), rnd.getInt(1, maxDimension), 1));
489 single->addChild(new GranularityCase(testCtx, name.c_str(), description, attachments));
493 std::vector<AttachmentInfo> attachments;
494 deUint32 iterations = rnd.getInt(minIteration, maxIteration);
495 for (deUint32 idx = 0; idx < iterations; ++idx)
496 attachments.push_back(AttachmentInfo(VkFormat(formatIdx), rnd.getInt(1, maxDimension), rnd.getInt(1, maxDimension), 1));
497 multi->addChild(new GranularityCase(testCtx, name.c_str(), description, attachments));
501 std::vector<AttachmentInfo> attachments;
502 deUint32 iterations = rnd.getInt(minIteration, maxIteration);
503 attachments.push_back(AttachmentInfo(VkFormat(formatIdx), rnd.getInt(1, maxDimension), rnd.getInt(1, maxDimension), 1));
504 for (deUint32 idx = 0; idx < iterations; ++idx)
505 attachments.push_back(AttachmentInfo(mandatoryFormats[rnd.getInt(0, DE_LENGTH_OF_ARRAY(mandatoryFormats) - 1)], rnd.getInt(1, maxDimension), rnd.getInt(1, maxDimension), 1));
506 random->addChild(new GranularityCase(testCtx, name.c_str(), description, attachments));
510 std::vector<AttachmentInfo> attachments;
511 attachments.push_back(AttachmentInfo(format, rnd.getInt(1, maxDimension), rnd.getInt(1, maxDimension), 1));
512 inRenderPass->addChild(new GranularityCase(testCtx, name.c_str(), description, attachments, true));
516 group->addChild(single.release());
517 group->addChild(multi.release());
518 group->addChild(random.release());
519 group->addChild(inRenderPass.release());
521 return group.release();