1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2017 Google Inc.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * \brief Tests sparse render target.
22 *//*--------------------------------------------------------------------*/
24 #include "vktRenderPassSparseRenderTargetTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkQueryUtil.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
41 #include "tcuImageCompare.hpp"
42 #include "tcuResultCollector.hpp"
43 #include "tcuTextureUtil.hpp"
45 #include "deUniquePtr.hpp"
46 #include "deSharedPtr.hpp"
53 using tcu::ConstPixelBufferAccess;
54 using tcu::PixelBufferAccess;
65 using namespace renderpass;
67 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
72 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
73 VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
77 Move<VkImage> createSparseImageAndMemory (const DeviceInterface& vk,
79 const VkPhysicalDevice physicalDevice,
80 const InstanceInterface& instance,
82 vector<de::SharedPtr<Allocation> >& allocations,
83 deUint32 universalQueueFamilyIndex,
85 deUint32 sparseQueueFamilyIndex,
86 const VkSemaphore& bindSemaphore,
91 deUint32 queueFamilyIndices[] = {universalQueueFamilyIndex, sparseQueueFamilyIndex};
92 const VkSharingMode sharingMode = universalQueueFamilyIndex != sparseQueueFamilyIndex ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
94 const VkExtent3D imageExtent =
101 const VkImageCreateInfo imageCreateInfo =
103 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
105 VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
111 VK_SAMPLE_COUNT_1_BIT,
112 VK_IMAGE_TILING_OPTIMAL,
113 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
115 sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u,
117 VK_IMAGE_LAYOUT_UNDEFINED
120 if (!checkSparseImageFormatSupport(physicalDevice, instance, imageCreateInfo))
121 TCU_THROW(NotSupportedError, "The image format does not support sparse operations");
123 Move<VkImage> destImage = createImage(vk, device, &imageCreateInfo);
124 allocateAndBindSparseImage(vk, device, physicalDevice, instance, imageCreateInfo, bindSemaphore, sparseQueue, allocator, allocations, mapVkFormat(format), *destImage);
129 Move<VkImageView> createImageView (const DeviceInterface& vk,
131 VkImageViewCreateFlags flags,
133 VkImageViewType viewType,
135 VkComponentMapping components,
136 VkImageSubresourceRange subresourceRange)
138 const VkImageViewCreateInfo pCreateInfo =
140 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
150 return createImageView(vk, device, &pCreateInfo);
153 Move<VkImageView> createImageView (const DeviceInterface& vkd,
157 VkImageAspectFlags aspect)
159 const VkImageSubresourceRange range =
168 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
171 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
177 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
178 const VkDeviceSize pixelSize = mapVkFormat(format).getPixelSize();
179 const VkBufferCreateInfo createInfo =
181 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
185 width * height * pixelSize,
188 VK_SHARING_MODE_EXCLUSIVE,
193 return createBuffer(vkd, device, &createInfo);
196 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
197 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
201 const AttachmentRef dstAttachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
203 // || VkStructureType sType;
204 DE_NULL, // || const void* pNext;
205 0u, // deUint32 attachment; || deUint32 attachment;
206 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
207 0u // || VkImageAspectFlags aspectMask;
209 const AttachmentDesc dstAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
211 // || VkStructureType sType;
212 DE_NULL, // || const void* pNext;
213 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
214 dstFormat, // VkFormat format; || VkFormat format;
215 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
216 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
217 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
218 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
219 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
220 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
221 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
223 const SubpassDesc subpass // VkSubpassDescription || VkSubpassDescription2KHR
225 // || VkStructureType sType;
226 DE_NULL, // || const void* pNext;
227 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
228 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
229 0u, // || deUint32 viewMask;
230 0u, // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
231 DE_NULL, // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
232 1u, // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
233 &dstAttachmentRef, // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
234 DE_NULL, // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
235 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
236 0u, // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
237 DE_NULL // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
239 const RenderPassCreateInfo renderPassCreator // VkRenderPassCreateInfo || VkRenderPassCreateInfo2KHR
241 // VkStructureType sType; || VkStructureType sType;
242 DE_NULL, // const void* pNext; || const void* pNext;
243 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; || VkRenderPassCreateFlags flags;
244 1u, // deUint32 attachmentCount; || deUint32 attachmentCount;
245 &dstAttachment, // const VkAttachmentDescription* pAttachments; || const VkAttachmentDescription2KHR* pAttachments;
246 1u, // deUint32 subpassCount; || deUint32 subpassCount;
247 &subpass, // const VkSubpassDescription* pSubpasses; || const VkSubpassDescription2KHR* pSubpasses;
248 0u, // deUint32 dependencyCount; || deUint32 dependencyCount;
249 DE_NULL, // const VkSubpassDependency* pDependencies; || const VkSubpassDependency2KHR* pDependencies;
250 0u, // || deUint32 correlatedViewMaskCount;
251 DE_NULL // || const deUint32* pCorrelatedViewMasks;
254 return renderPassCreator.createRenderPass(vkd, device);
257 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
260 const RenderingType renderingType)
262 switch (renderingType)
264 case RENDERING_TYPE_RENDERPASS_LEGACY:
265 return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, dstFormat);
266 case RENDERING_TYPE_RENDERPASS2:
267 return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, dstFormat);
268 case RENDERING_TYPE_DYNAMIC_RENDERING:
269 return Move<VkRenderPass>();
271 TCU_THROW(InternalError, "Impossible");
275 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
277 VkRenderPass renderPass,
278 VkImageView dstImageView,
282 // when RenderPass was not created then we are testing dynamic rendering
283 // and we can't create framebuffer without valid RenderPass object
285 return Move<VkFramebuffer>();
287 const VkFramebufferCreateInfo createInfo =
289 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
302 return createFramebuffer(vkd, device, &createInfo);
305 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
308 const VkPipelineLayoutCreateInfo createInfo =
310 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
312 (vk::VkPipelineLayoutCreateFlags)0,
321 return createPipelineLayout(vkd, device, &createInfo);
324 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
326 VkRenderPass renderPass,
328 VkPipelineLayout pipelineLayout,
329 const BinaryCollection& binaryCollection,
333 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
334 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
336 const VkPipelineVertexInputStateCreateInfo vertexInputState =
338 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
340 (VkPipelineVertexInputStateCreateFlags)0u,
349 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(width, height)));
350 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(width, height)));
352 VkPipelineRenderingCreateInfoKHR* pNext = DE_NULL;
353 VkPipelineRenderingCreateInfoKHR renderingCreateInfo
355 VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO_KHR,
363 if (renderPass == DE_NULL)
364 pNext = &renderingCreateInfo;
366 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
367 device, // const VkDevice device
368 pipelineLayout, // const VkPipelineLayout pipelineLayout
369 *vertexShaderModule, // const VkShaderModule vertexShaderModule
370 DE_NULL, // const VkShaderModule tessellationControlShaderModule
371 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
372 DE_NULL, // const VkShaderModule geometryShaderModule
373 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
374 renderPass, // const VkRenderPass renderPass
375 viewports, // const std::vector<VkViewport>& viewports
376 scissors, // const std::vector<VkRect2D>& scissors
377 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
378 0u, // const deUint32 subpass
379 0u, // const deUint32 patchControlPoints
380 &vertexInputState, // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
381 DE_NULL, // const VkPipelineRasterizationStateCreateInfo* rasterizationStateCreateInfo
382 DE_NULL, // const VkPipelineMultisampleStateCreateInfo* multisampleStateCreateInfo
383 DE_NULL, // const VkPipelineDepthStencilStateCreateInfo* depthStencilStateCreateInfo
384 DE_NULL, // const VkPipelineColorBlendStateCreateInfo* colorBlendStateCreateInfo
385 DE_NULL, // const VkPipelineDynamicStateCreateInfo* dynamicStateCreateInfo
386 pNext); // const void* pNext
391 TestConfig (VkFormat format_,
392 RenderingType renderingType_)
394 , renderingType (renderingType_)
399 RenderingType renderingType;
402 class SparseRenderTargetTestInstance : public TestInstance
405 SparseRenderTargetTestInstance (Context& context, TestConfig testConfig);
406 ~SparseRenderTargetTestInstance (void);
408 tcu::TestStatus iterate (void);
410 template<typename RenderpassSubpass>
411 tcu::TestStatus iterateInternal (void);
414 const RenderingType m_renderingType;
416 const deUint32 m_width;
417 const deUint32 m_height;
418 const VkFormat m_format;
420 vector<de::SharedPtr<Allocation> > m_allocations;
422 const Unique<VkSemaphore> m_bindSemaphore;
424 const Unique<VkImage> m_dstImage;
425 const Unique<VkImageView> m_dstImageView;
427 const Unique<VkBuffer> m_dstBuffer;
428 const de::UniquePtr<Allocation> m_dstBufferMemory;
430 const Unique<VkRenderPass> m_renderPass;
431 const Unique<VkFramebuffer> m_framebuffer;
433 const Unique<VkPipelineLayout> m_renderPipelineLayout;
434 const Unique<VkPipeline> m_renderPipeline;
436 const Unique<VkCommandPool> m_commandPool;
437 tcu::ResultCollector m_resultCollector;
440 SparseRenderTargetTestInstance::SparseRenderTargetTestInstance (Context& context, TestConfig testConfig)
441 : TestInstance (context)
442 , m_renderingType (testConfig.renderingType)
445 , m_format (testConfig.format)
446 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice()))
447 , m_dstImage (createSparseImageAndMemory(context.getDeviceInterface(), context.getDevice(), context.getPhysicalDevice(), context.getInstanceInterface(), context.getDefaultAllocator(), m_allocations, context.getUniversalQueueFamilyIndex(), context.getSparseQueue(), context.getSparseQueueFamilyIndex(), *m_bindSemaphore, m_format, m_width, m_height))
448 , m_dstImageView (createImageView(context.getDeviceInterface(), context.getDevice(), *m_dstImage, m_format, VK_IMAGE_ASPECT_COLOR_BIT))
449 , m_dstBuffer (createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
450 , m_dstBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
451 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_format, testConfig.renderingType))
452 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_dstImageView, m_width, m_height))
453 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
454 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, testConfig.format, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height))
455 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
459 SparseRenderTargetTestInstance::~SparseRenderTargetTestInstance (void)
463 tcu::TestStatus SparseRenderTargetTestInstance::iterate (void)
465 switch (m_renderingType)
467 case RENDERING_TYPE_RENDERPASS_LEGACY:
468 return iterateInternal<RenderpassSubpass1>();
469 case RENDERING_TYPE_RENDERPASS2:
470 case RENDERING_TYPE_DYNAMIC_RENDERING:
471 return iterateInternal<RenderpassSubpass2>();
473 TCU_THROW(InternalError, "Impossible");
477 template<typename RenderpassSubpass>
478 tcu::TestStatus SparseRenderTargetTestInstance::iterateInternal (void)
480 const DeviceInterface& vkd (m_context.getDeviceInterface());
481 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
483 beginCommandBuffer(vkd, *commandBuffer);
485 VkRect2D renderArea = makeRect2D(m_width, m_height);
486 if (m_renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
488 std::vector<VkImageMemoryBarrier> barriers;
490 const VkImageMemoryBarrier barrier =
492 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER,
496 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
498 VK_IMAGE_LAYOUT_UNDEFINED,
499 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
501 VK_QUEUE_FAMILY_IGNORED,
502 VK_QUEUE_FAMILY_IGNORED,
506 VK_IMAGE_ASPECT_COLOR_BIT,
514 vkd.cmdPipelineBarrier(*commandBuffer, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT, 0u, 0u, DE_NULL, 0u, DE_NULL, 1u, &barrier);
516 const VkClearValue clearValue = makeClearValueColor({ 0.0f, 0.0f, 0.0f, 1.0f });
517 beginRendering(vkd, *commandBuffer, *m_dstImageView, renderArea, clearValue, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, VK_ATTACHMENT_LOAD_OP_DONT_CARE);
521 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo(DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
522 const VkRenderPassBeginInfo beginInfo =
524 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
532 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
535 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
536 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
538 if (m_renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
539 vkd.cmdEndRendering(*commandBuffer);
542 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo(DE_NULL);
543 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
546 copyImageToBuffer(vkd, *commandBuffer, *m_dstImage, *m_dstBuffer, tcu::IVec2(m_width, m_height));
548 endCommandBuffer(vkd, *commandBuffer);
550 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
553 const tcu::TextureFormat format (mapVkFormat(m_format));
554 const void* const ptr (m_dstBufferMemory->getHostPtr());
555 const tcu::ConstPixelBufferAccess access (format, m_width, m_height, 1, ptr);
556 tcu::TextureLevel reference (format, m_width, m_height);
557 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
559 switch (channelClass)
561 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
563 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
564 const UVec4 color (1u << (bits.x()-1), 1u << (bits.y()-2), 1u << (bits.z()-3), 0xffffffff);
566 for (deUint32 y = 0; y < m_height; y++)
567 for (deUint32 x = 0; x < m_width; x++)
569 reference.getAccess().setPixel(color, x, y);
572 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
573 m_resultCollector.fail("Compare failed.");
577 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
579 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
580 const UVec4 color (1u << (bits.x()-2), 1u << (bits.y()-3), 1u << (bits.z()-4), 0xffffffff);
582 for (deUint32 y = 0; y < m_height; y++)
583 for (deUint32 x = 0; x < m_width; x++)
585 reference.getAccess().setPixel(color, x, y);
588 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
589 m_resultCollector.fail("Compare failed.");
593 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
594 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
596 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
597 const Vec4 maxValue (info.valueMax);
598 const Vec4 color (maxValue.x() / 2.0f, maxValue.y() / 4.0f, maxValue.z() / 8.0f, maxValue.w());
600 for (deUint32 y = 0; y < m_height; y++)
601 for (deUint32 x = 0; x < m_width; x++)
603 if (tcu::isSRGB(format))
604 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
606 reference.getAccess().setPixel(color, x, y);
610 // Allow error of 4 times the minimum presentable difference
611 const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
613 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
614 m_resultCollector.fail("Compare failed.");
619 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
621 const Vec4 color(0.5f, 0.25f, 0.125f, 1.0f);
623 for (deUint32 y = 0; y < m_height; y++)
624 for (deUint32 x = 0; x < m_width; x++)
626 if (tcu::isSRGB(format))
627 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
629 reference.getAccess().setPixel(color, x, y);
633 // Convert target format ulps to float ulps and allow 64ulp differences
634 const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
636 if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
637 m_resultCollector.fail("Compare failed.");
643 DE_FATAL("Unknown channel class");
647 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
652 void init (vk::SourceCollections& dst, TestConfig testConfig) const
654 std::ostringstream fragmentShader;
655 const VkFormat format (testConfig.format);
656 const tcu::TextureFormat texFormat (mapVkFormat(format));
657 const UVec4 bits (tcu::getTextureFormatBitDepth(texFormat).cast<deUint32>());
658 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(texFormat.type));
660 dst.glslSources.add("quad-vert") << glu::VertexSource(
662 "out gl_PerVertex {\n"
663 "\tvec4 gl_Position;\n"
668 " gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
669 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
672 switch (channelClass)
674 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
678 "layout(location = 0) out highp uvec4 o_color;\n"
681 " o_color = uvec4(" << de::toString(1u << (bits.x()-1)) << ", " << de::toString(1u << (bits.y()-2)) << ", " << de::toString(1u << (bits.z()-3)) << ", 0xffffffff);"
686 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
690 "layout(location = 0) out highp ivec4 o_color;\n"
693 " o_color = ivec4(" << de::toString(1u << (bits.x()-2)) << ", " << de::toString(1u << (bits.y()-3)) << ", " << de::toString(1u << (bits.z()-4)) << ", 0xffffffff);"
702 "layout(location = 0) out highp vec4 o_color;\n"
705 " o_color = vec4(0.5, 0.25, 0.125, 1.0);\n"
711 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
715 std::string formatToName (VkFormat format)
717 const std::string formatStr = de::toString(format);
718 const std::string prefix = "VK_FORMAT_";
720 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
722 return de::toLower(formatStr.substr(prefix.length()));
725 template<class TestConfigType>
726 void checkSupport(Context& context, TestConfigType config)
728 if (config.renderingType == RENDERING_TYPE_RENDERPASS2)
729 context.requireDeviceFunctionality("VK_KHR_create_renderpass2");
731 if (config.renderingType == RENDERING_TYPE_DYNAMIC_RENDERING)
732 context.requireDeviceFunctionality("VK_KHR_dynamic_rendering");
735 void initTests (tcu::TestCaseGroup* group, const RenderingType renderingType)
737 static const VkFormat formats[] =
739 VK_FORMAT_R5G6B5_UNORM_PACK16,
744 VK_FORMAT_R8G8_UNORM,
745 VK_FORMAT_R8G8_SNORM,
748 VK_FORMAT_R8G8B8A8_UNORM,
749 VK_FORMAT_R8G8B8A8_SNORM,
750 VK_FORMAT_R8G8B8A8_UINT,
751 VK_FORMAT_R8G8B8A8_SINT,
752 VK_FORMAT_R8G8B8A8_SRGB,
753 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
754 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
755 VK_FORMAT_A8B8G8R8_UINT_PACK32,
756 VK_FORMAT_A8B8G8R8_SINT_PACK32,
757 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
758 VK_FORMAT_B8G8R8A8_UNORM,
759 VK_FORMAT_B8G8R8A8_SRGB,
760 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
761 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
762 VK_FORMAT_A2B10G10R10_UINT_PACK32,
767 VK_FORMAT_R16_SFLOAT,
768 VK_FORMAT_R16G16_UNORM,
769 VK_FORMAT_R16G16_SNORM,
770 VK_FORMAT_R16G16_UINT,
771 VK_FORMAT_R16G16_SINT,
772 VK_FORMAT_R16G16_SFLOAT,
773 VK_FORMAT_R16G16B16A16_UNORM,
774 VK_FORMAT_R16G16B16A16_SNORM,
775 VK_FORMAT_R16G16B16A16_UINT,
776 VK_FORMAT_R16G16B16A16_SINT,
777 VK_FORMAT_R16G16B16A16_SFLOAT,
780 VK_FORMAT_R32_SFLOAT,
781 VK_FORMAT_R32G32_UINT,
782 VK_FORMAT_R32G32_SINT,
783 VK_FORMAT_R32G32_SFLOAT,
784 VK_FORMAT_R32G32B32A32_UINT,
785 VK_FORMAT_R32G32B32A32_SINT,
786 VK_FORMAT_R32G32B32A32_SFLOAT,
787 VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16
790 tcu::TestContext& testCtx (group->getTestContext());
792 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
794 const VkFormat format (formats[formatNdx]);
795 const TestConfig testConfig (format, renderingType);
796 string testName (formatToName(format));
798 group->addChild(new InstanceFactory1WithSupport<SparseRenderTargetTestInstance, TestConfig, FunctionSupport1<TestConfig>, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig, typename FunctionSupport1<TestConfig>::Args(checkSupport, testConfig)));
804 tcu::TestCaseGroup* createRenderPassSparseRenderTargetTests (tcu::TestContext& testCtx)
806 return createTestGroup(testCtx, "sparserendertarget", "Sparse render target tests", initTests, RENDERING_TYPE_RENDERPASS_LEGACY);
809 tcu::TestCaseGroup* createRenderPass2SparseRenderTargetTests (tcu::TestContext& testCtx)
811 return createTestGroup(testCtx, "sparserendertarget", "Sparse render target tests", initTests, RENDERING_TYPE_RENDERPASS2);
814 tcu::TestCaseGroup* createDynamicRenderingSparseRenderTargetTests(tcu::TestContext& testCtx)
816 return createTestGroup(testCtx, "sparserendertarget", "Sparse render target tests", initTests, RENDERING_TYPE_DYNAMIC_RENDERING);