1 /*-------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
4 *
5 * Copyright (c) 2017 Google Inc.
6 *
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
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
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.
18 *
19 *//*!
20 * \file
21 * \brief Tests sparse render target.
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktRenderPassSparseRenderTargetTests.hpp"
25 #include "vktRenderPassTestsUtil.hpp"
26
27 #include "vktTestCaseUtil.hpp"
28 #include "vktTestGroupUtil.hpp"
29
30 #include "vkDefs.hpp"
31 #include "vkImageUtil.hpp"
32 #include "vkMemUtil.hpp"
33 #include "vkPrograms.hpp"
34 #include "vkQueryUtil.hpp"
35 #include "vkRef.hpp"
36 #include "vkRefUtil.hpp"
37 #include "vkTypeUtil.hpp"
38 #include "vkCmdUtil.hpp"
39 #include "vkObjUtil.hpp"
40
41 #include "tcuImageCompare.hpp"
42 #include "tcuResultCollector.hpp"
43 #include "tcuTextureUtil.hpp"
44
45 #include "deUniquePtr.hpp"
46 #include "deSharedPtr.hpp"
47
48 using namespace vk;
49
50 using tcu::UVec4;
51 using tcu::Vec4;
52
53 using tcu::ConstPixelBufferAccess;
54 using tcu::PixelBufferAccess;
55
56 using tcu::TestLog;
57
58 using std::string;
59 using std::vector;
60
61 namespace vkt
62 {
63 namespace
64 {
65 using namespace renderpass;
66
createBufferMemory(const DeviceInterface & vk,VkDevice device,Allocator & allocator,VkBuffer buffer)67 de::MovePtr<Allocation> createBufferMemory (const DeviceInterface& vk,
68 VkDevice device,
69 Allocator& allocator,
70 VkBuffer buffer)
71 {
72 de::MovePtr<Allocation> allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), MemoryRequirement::HostVisible));
73 VK_CHECK(vk.bindBufferMemory(device, buffer, allocation->getMemory(), allocation->getOffset()));
74 return allocation;
75 }
76
createSparseImageAndMemory(const DeviceInterface & vk,VkDevice device,const VkPhysicalDevice physicalDevice,const InstanceInterface & instance,Allocator & allocator,vector<de::SharedPtr<Allocation>> & allocations,deUint32 universalQueueFamilyIndex,VkQueue sparseQueue,deUint32 sparseQueueFamilyIndex,const VkSemaphore & bindSemaphore,VkFormat format,deUint32 width,deUint32 height)77 Move<VkImage> createSparseImageAndMemory (const DeviceInterface& vk,
78 VkDevice device,
79 const VkPhysicalDevice physicalDevice,
80 const InstanceInterface& instance,
81 Allocator& allocator,
82 vector<de::SharedPtr<Allocation> >& allocations,
83 deUint32 universalQueueFamilyIndex,
84 VkQueue sparseQueue,
85 deUint32 sparseQueueFamilyIndex,
86 const VkSemaphore& bindSemaphore,
87 VkFormat format,
88 deUint32 width,
89 deUint32 height)
90 {
91 deUint32 queueFamilyIndices[] = {universalQueueFamilyIndex, sparseQueueFamilyIndex};
92 const VkSharingMode sharingMode = universalQueueFamilyIndex != sparseQueueFamilyIndex ? VK_SHARING_MODE_CONCURRENT : VK_SHARING_MODE_EXCLUSIVE;
93
94 const VkExtent3D imageExtent =
95 {
96 width,
97 height,
98 1u
99 };
100
101 const VkImageCreateInfo imageCreateInfo =
102 {
103 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO,
104 DE_NULL,
105 VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT,
106 VK_IMAGE_TYPE_2D,
107 format,
108 imageExtent,
109 1u,
110 1u,
111 VK_SAMPLE_COUNT_1_BIT,
112 VK_IMAGE_TILING_OPTIMAL,
113 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT,
114 sharingMode,
115 sharingMode == VK_SHARING_MODE_CONCURRENT ? 2u : 1u,
116 queueFamilyIndices,
117 VK_IMAGE_LAYOUT_UNDEFINED
118 };
119
120 Move<VkImage> destImage = createImage(vk, device, &imageCreateInfo);
121
122 allocateAndBindSparseImage(vk, device, physicalDevice, instance, imageCreateInfo, bindSemaphore, sparseQueue, allocator, allocations, mapVkFormat(format), *destImage);
123
124 return destImage;
125 }
126
createImageView(const DeviceInterface & vk,VkDevice device,VkImageViewCreateFlags flags,VkImage image,VkImageViewType viewType,VkFormat format,VkComponentMapping components,VkImageSubresourceRange subresourceRange)127 Move<VkImageView> createImageView (const DeviceInterface& vk,
128 VkDevice device,
129 VkImageViewCreateFlags flags,
130 VkImage image,
131 VkImageViewType viewType,
132 VkFormat format,
133 VkComponentMapping components,
134 VkImageSubresourceRange subresourceRange)
135 {
136 const VkImageViewCreateInfo pCreateInfo =
137 {
138 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
139 DE_NULL,
140 flags,
141 image,
142 viewType,
143 format,
144 components,
145 subresourceRange,
146 };
147
148 return createImageView(vk, device, &pCreateInfo);
149 }
150
createImageView(const DeviceInterface & vkd,VkDevice device,VkImage image,VkFormat format,VkImageAspectFlags aspect)151 Move<VkImageView> createImageView (const DeviceInterface& vkd,
152 VkDevice device,
153 VkImage image,
154 VkFormat format,
155 VkImageAspectFlags aspect)
156 {
157 const VkImageSubresourceRange range =
158 {
159 aspect,
160 0u,
161 1u,
162 0u,
163 1u
164 };
165
166 return createImageView(vkd, device, 0u, image, VK_IMAGE_VIEW_TYPE_2D, format, makeComponentMappingRGBA(), range);
167 }
168
createBuffer(const DeviceInterface & vkd,VkDevice device,VkFormat format,deUint32 width,deUint32 height)169 Move<VkBuffer> createBuffer (const DeviceInterface& vkd,
170 VkDevice device,
171 VkFormat format,
172 deUint32 width,
173 deUint32 height)
174 {
175 const VkBufferUsageFlags bufferUsage (VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT);
176 const VkDeviceSize pixelSize = mapVkFormat(format).getPixelSize();
177 const VkBufferCreateInfo createInfo =
178 {
179 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
180 DE_NULL,
181 0u,
182
183 width * height * pixelSize,
184 bufferUsage,
185
186 VK_SHARING_MODE_EXCLUSIVE,
187 0u,
188 DE_NULL
189 };
190
191 return createBuffer(vkd, device, &createInfo);
192 }
193
194 template<typename AttachmentDesc, typename AttachmentRef, typename SubpassDesc, typename SubpassDep, typename RenderPassCreateInfo>
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat dstFormat)195 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
196 VkDevice device,
197 VkFormat dstFormat)
198 {
199 const AttachmentRef dstAttachmentRef // VkAttachmentReference || VkAttachmentReference2KHR
200 (
201 // || VkStructureType sType;
202 DE_NULL, // || const void* pNext;
203 0u, // deUint32 attachment; || deUint32 attachment;
204 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout layout; || VkImageLayout layout;
205 0u // || VkImageAspectFlags aspectMask;
206 );
207 const AttachmentDesc dstAttachment // VkAttachmentDescription || VkAttachmentDescription2KHR
208 (
209 // || VkStructureType sType;
210 DE_NULL, // || const void* pNext;
211 0u, // VkAttachmentDescriptionFlags flags; || VkAttachmentDescriptionFlags flags;
212 dstFormat, // VkFormat format; || VkFormat format;
213 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples; || VkSampleCountFlagBits samples;
214 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp loadOp; || VkAttachmentLoadOp loadOp;
215 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp; || VkAttachmentStoreOp storeOp;
216 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp; || VkAttachmentLoadOp stencilLoadOp;
217 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp; || VkAttachmentStoreOp stencilStoreOp;
218 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout; || VkImageLayout initialLayout;
219 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout; || VkImageLayout finalLayout;
220 );
221 const SubpassDesc subpass // VkSubpassDescription || VkSubpassDescription2KHR
222 (
223 // || VkStructureType sType;
224 DE_NULL, // || const void* pNext;
225 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags; || VkSubpassDescriptionFlags flags;
226 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint; || VkPipelineBindPoint pipelineBindPoint;
227 0u, // || deUint32 viewMask;
228 0u, // deUint32 inputAttachmentCount; || deUint32 inputAttachmentCount;
229 DE_NULL, // const VkAttachmentReference* pInputAttachments; || const VkAttachmentReference2KHR* pInputAttachments;
230 1u, // deUint32 colorAttachmentCount; || deUint32 colorAttachmentCount;
231 &dstAttachmentRef, // const VkAttachmentReference* pColorAttachments; || const VkAttachmentReference2KHR* pColorAttachments;
232 DE_NULL, // const VkAttachmentReference* pResolveAttachments; || const VkAttachmentReference2KHR* pResolveAttachments;
233 DE_NULL, // const VkAttachmentReference* pDepthStencilAttachment; || const VkAttachmentReference2KHR* pDepthStencilAttachment;
234 0u, // deUint32 preserveAttachmentCount; || deUint32 preserveAttachmentCount;
235 DE_NULL // const deUint32* pPreserveAttachments; || const deUint32* pPreserveAttachments;
236 );
237 const RenderPassCreateInfo renderPassCreator // VkRenderPassCreateInfo || VkRenderPassCreateInfo2KHR
238 (
239 // VkStructureType sType; || VkStructureType sType;
240 DE_NULL, // const void* pNext; || const void* pNext;
241 (VkRenderPassCreateFlags)0u, // VkRenderPassCreateFlags flags; || VkRenderPassCreateFlags flags;
242 1u, // deUint32 attachmentCount; || deUint32 attachmentCount;
243 &dstAttachment, // const VkAttachmentDescription* pAttachments; || const VkAttachmentDescription2KHR* pAttachments;
244 1u, // deUint32 subpassCount; || deUint32 subpassCount;
245 &subpass, // const VkSubpassDescription* pSubpasses; || const VkSubpassDescription2KHR* pSubpasses;
246 0u, // deUint32 dependencyCount; || deUint32 dependencyCount;
247 DE_NULL, // const VkSubpassDependency* pDependencies; || const VkSubpassDependency2KHR* pDependencies;
248 0u, // || deUint32 correlatedViewMaskCount;
249 DE_NULL // || const deUint32* pCorrelatedViewMasks;
250 );
251
252 return renderPassCreator.createRenderPass(vkd, device);
253 }
254
createRenderPass(const DeviceInterface & vkd,VkDevice device,VkFormat dstFormat,const RenderPassType renderPassType)255 Move<VkRenderPass> createRenderPass (const DeviceInterface& vkd,
256 VkDevice device,
257 VkFormat dstFormat,
258 const RenderPassType renderPassType)
259 {
260 switch (renderPassType)
261 {
262 case RENDERPASS_TYPE_LEGACY:
263 return createRenderPass<AttachmentDescription1, AttachmentReference1, SubpassDescription1, SubpassDependency1, RenderPassCreateInfo1>(vkd, device, dstFormat);
264 case RENDERPASS_TYPE_RENDERPASS2:
265 return createRenderPass<AttachmentDescription2, AttachmentReference2, SubpassDescription2, SubpassDependency2, RenderPassCreateInfo2>(vkd, device, dstFormat);
266 default:
267 TCU_THROW(InternalError, "Impossible");
268 }
269 }
270
createFramebuffer(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkImageView dstImageView,deUint32 width,deUint32 height)271 Move<VkFramebuffer> createFramebuffer (const DeviceInterface& vkd,
272 VkDevice device,
273 VkRenderPass renderPass,
274 VkImageView dstImageView,
275 deUint32 width,
276 deUint32 height)
277 {
278 const VkFramebufferCreateInfo createInfo =
279 {
280 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO,
281 DE_NULL,
282 0u,
283
284 renderPass,
285 1u,
286 &dstImageView,
287
288 width,
289 height,
290 1u
291 };
292
293 return createFramebuffer(vkd, device, &createInfo);
294 }
295
createRenderPipelineLayout(const DeviceInterface & vkd,VkDevice device)296 Move<VkPipelineLayout> createRenderPipelineLayout (const DeviceInterface& vkd,
297 VkDevice device)
298 {
299 const VkPipelineLayoutCreateInfo createInfo =
300 {
301 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
302 DE_NULL,
303 (vk::VkPipelineLayoutCreateFlags)0,
304
305 0u,
306 DE_NULL,
307
308 0u,
309 DE_NULL
310 };
311
312 return createPipelineLayout(vkd, device, &createInfo);
313 }
314
createRenderPipeline(const DeviceInterface & vkd,VkDevice device,VkRenderPass renderPass,VkPipelineLayout pipelineLayout,const BinaryCollection & binaryCollection,deUint32 width,deUint32 height)315 Move<VkPipeline> createRenderPipeline (const DeviceInterface& vkd,
316 VkDevice device,
317 VkRenderPass renderPass,
318 VkPipelineLayout pipelineLayout,
319 const BinaryCollection& binaryCollection,
320 deUint32 width,
321 deUint32 height)
322 {
323 const Unique<VkShaderModule> vertexShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-vert"), 0u));
324 const Unique<VkShaderModule> fragmentShaderModule (createShaderModule(vkd, device, binaryCollection.get("quad-frag"), 0u));
325
326 const VkPipelineVertexInputStateCreateInfo vertexInputState =
327 {
328 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
329 DE_NULL,
330 (VkPipelineVertexInputStateCreateFlags)0u,
331
332 0u,
333 DE_NULL,
334
335 0u,
336 DE_NULL
337 };
338
339 const std::vector<VkViewport> viewports (1, makeViewport(tcu::UVec2(width, height)));
340 const std::vector<VkRect2D> scissors (1, makeRect2D(tcu::UVec2(width, height)));
341
342 return makeGraphicsPipeline(vkd, // const DeviceInterface& vk
343 device, // const VkDevice device
344 pipelineLayout, // const VkPipelineLayout pipelineLayout
345 *vertexShaderModule, // const VkShaderModule vertexShaderModule
346 DE_NULL, // const VkShaderModule tessellationControlShaderModule
347 DE_NULL, // const VkShaderModule tessellationEvalShaderModule
348 DE_NULL, // const VkShaderModule geometryShaderModule
349 *fragmentShaderModule, // const VkShaderModule fragmentShaderModule
350 renderPass, // const VkRenderPass renderPass
351 viewports, // const std::vector<VkViewport>& viewports
352 scissors, // const std::vector<VkRect2D>& scissors
353 VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, // const VkPrimitiveTopology topology
354 0u, // const deUint32 subpass
355 0u, // const deUint32 patchControlPoints
356 &vertexInputState); // const VkPipelineVertexInputStateCreateInfo* vertexInputStateCreateInfo
357 }
358
359 struct TestConfig
360 {
TestConfigvkt::__anone8d174220111::TestConfig361 TestConfig (VkFormat format_,
362 RenderPassType renderPassType_)
363 : format (format_)
364 , renderPassType (renderPassType_)
365 {
366 }
367
368 VkFormat format;
369 RenderPassType renderPassType;
370 };
371
372 class SparseRenderTargetTestInstance : public TestInstance
373 {
374 public:
375 SparseRenderTargetTestInstance (Context& context, TestConfig testConfig);
376 ~SparseRenderTargetTestInstance (void);
377
378 tcu::TestStatus iterate (void);
379
380 template<typename RenderpassSubpass>
381 tcu::TestStatus iterateInternal (void);
382
383 private:
384 const bool m_extensionSupported;
385 const RenderPassType m_renderPassType;
386
387 const deUint32 m_width;
388 const deUint32 m_height;
389 const VkFormat m_format;
390
391 vector<de::SharedPtr<Allocation> > m_allocations;
392
393 const Unique<VkSemaphore> m_bindSemaphore;
394
395 const Unique<VkImage> m_dstImage;
396 const Unique<VkImageView> m_dstImageView;
397
398 const Unique<VkBuffer> m_dstBuffer;
399 const de::UniquePtr<Allocation> m_dstBufferMemory;
400
401 const Unique<VkRenderPass> m_renderPass;
402 const Unique<VkFramebuffer> m_framebuffer;
403
404 const Unique<VkPipelineLayout> m_renderPipelineLayout;
405 const Unique<VkPipeline> m_renderPipeline;
406
407 const Unique<VkCommandPool> m_commandPool;
408 tcu::ResultCollector m_resultCollector;
409 };
410
SparseRenderTargetTestInstance(Context & context,TestConfig testConfig)411 SparseRenderTargetTestInstance::SparseRenderTargetTestInstance (Context& context, TestConfig testConfig)
412 : TestInstance (context)
413 , m_extensionSupported ((testConfig.renderPassType == RENDERPASS_TYPE_RENDERPASS2) && context.requireDeviceExtension("VK_KHR_create_renderpass2"))
414 , m_renderPassType (testConfig.renderPassType)
415 , m_width (32u)
416 , m_height (32u)
417 , m_format (testConfig.format)
418 , m_bindSemaphore (createSemaphore(context.getDeviceInterface(), context.getDevice()))
419 , 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))
420 , m_dstImageView (createImageView(context.getDeviceInterface(), context.getDevice(), *m_dstImage, m_format, VK_IMAGE_ASPECT_COLOR_BIT))
421 , m_dstBuffer (createBuffer(context.getDeviceInterface(), context.getDevice(), m_format, m_width, m_height))
422 , m_dstBufferMemory (createBufferMemory(context.getDeviceInterface(), context.getDevice(), context.getDefaultAllocator(), *m_dstBuffer))
423 , m_renderPass (createRenderPass(context.getDeviceInterface(), context.getDevice(), m_format, testConfig.renderPassType))
424 , m_framebuffer (createFramebuffer(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_dstImageView, m_width, m_height))
425 , m_renderPipelineLayout (createRenderPipelineLayout(context.getDeviceInterface(), context.getDevice()))
426 , m_renderPipeline (createRenderPipeline(context.getDeviceInterface(), context.getDevice(), *m_renderPass, *m_renderPipelineLayout, context.getBinaryCollection(), m_width, m_height))
427 , m_commandPool (createCommandPool(context.getDeviceInterface(), context.getDevice(), VK_COMMAND_POOL_CREATE_TRANSIENT_BIT, context.getUniversalQueueFamilyIndex()))
428 {
429 }
430
~SparseRenderTargetTestInstance(void)431 SparseRenderTargetTestInstance::~SparseRenderTargetTestInstance (void)
432 {
433 }
434
iterate(void)435 tcu::TestStatus SparseRenderTargetTestInstance::iterate (void)
436 {
437 switch (m_renderPassType)
438 {
439 case RENDERPASS_TYPE_LEGACY:
440 return iterateInternal<RenderpassSubpass1>();
441 case RENDERPASS_TYPE_RENDERPASS2:
442 return iterateInternal<RenderpassSubpass2>();
443 default:
444 TCU_THROW(InternalError, "Impossible");
445 }
446 }
447
448 template<typename RenderpassSubpass>
iterateInternal(void)449 tcu::TestStatus SparseRenderTargetTestInstance::iterateInternal (void)
450
451 {
452 const DeviceInterface& vkd (m_context.getDeviceInterface());
453 const Unique<VkCommandBuffer> commandBuffer (allocateCommandBuffer(vkd, m_context.getDevice(), *m_commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
454 const typename RenderpassSubpass::SubpassBeginInfo subpassBeginInfo (DE_NULL, VK_SUBPASS_CONTENTS_INLINE);
455 const typename RenderpassSubpass::SubpassEndInfo subpassEndInfo (DE_NULL);
456
457 beginCommandBuffer(vkd, *commandBuffer);
458
459 {
460 const VkRenderPassBeginInfo beginInfo =
461 {
462 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO,
463 DE_NULL,
464
465 *m_renderPass,
466 *m_framebuffer,
467
468 {
469 { 0u, 0u },
470 { m_width, m_height }
471 },
472
473 0u,
474 DE_NULL
475 };
476 RenderpassSubpass::cmdBeginRenderPass(vkd, *commandBuffer, &beginInfo, &subpassBeginInfo);
477 }
478
479 vkd.cmdBindPipeline(*commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, *m_renderPipeline);
480 vkd.cmdDraw(*commandBuffer, 6u, 1u, 0u, 0u);
481 RenderpassSubpass::cmdEndRenderPass(vkd, *commandBuffer, &subpassEndInfo);
482
483 copyImageToBuffer(vkd, *commandBuffer, *m_dstImage, *m_dstBuffer, tcu::IVec2(m_width, m_height));
484
485 endCommandBuffer(vkd, *commandBuffer);
486
487 submitCommandsAndWait(vkd, m_context.getDevice(), m_context.getUniversalQueue(), *commandBuffer);
488
489 {
490 const tcu::TextureFormat format (mapVkFormat(m_format));
491 const void* const ptr (m_dstBufferMemory->getHostPtr());
492 const tcu::ConstPixelBufferAccess access (format, m_width, m_height, 1, ptr);
493 tcu::TextureLevel reference (format, m_width, m_height);
494 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(format.type));
495
496 switch (channelClass)
497 {
498 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
499 {
500 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
501 const UVec4 color (1u << (bits.x()-1), 1u << (bits.y()-2), 1u << (bits.z()-3), 0xffffffff);
502
503 for (deUint32 y = 0; y < m_height; y++)
504 for (deUint32 x = 0; x < m_width; x++)
505 {
506 reference.getAccess().setPixel(color, x, y);
507 }
508
509 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
510 m_resultCollector.fail("Compare failed.");
511 }
512 break;
513
514 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
515 {
516 const UVec4 bits (tcu::getTextureFormatBitDepth(format).cast<deUint32>());
517 const UVec4 color (1u << (bits.x()-2), 1u << (bits.y()-3), 1u << (bits.z()-4), 0xffffffff);
518
519 for (deUint32 y = 0; y < m_height; y++)
520 for (deUint32 x = 0; x < m_width; x++)
521 {
522 reference.getAccess().setPixel(color, x, y);
523 }
524
525 if (!tcu::intThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, UVec4(0u), tcu::COMPARE_LOG_ON_ERROR))
526 m_resultCollector.fail("Compare failed.");
527 }
528 break;
529
530 case tcu::TEXTURECHANNELCLASS_UNSIGNED_FIXED_POINT:
531 case tcu::TEXTURECHANNELCLASS_SIGNED_FIXED_POINT:
532 {
533 const tcu::TextureFormatInfo info (tcu::getTextureFormatInfo(format));
534 const Vec4 maxValue (info.valueMax);
535 const Vec4 color (maxValue.x() / 2.0f, maxValue.y() / 4.0f, maxValue.z() / 8.0f, maxValue.w());
536
537 for (deUint32 y = 0; y < m_height; y++)
538 for (deUint32 x = 0; x < m_width; x++)
539 {
540 if (tcu::isSRGB(format))
541 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
542 else
543 reference.getAccess().setPixel(color, x, y);
544 }
545
546 {
547 // Allow error of 4 times the minimum presentable difference
548 const Vec4 threshold (4.0f * 1.0f / ((UVec4(1u) << tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>()) - 1u).cast<float>());
549
550 if (!tcu::floatThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
551 m_resultCollector.fail("Compare failed.");
552 }
553 }
554 break;
555
556 case tcu::TEXTURECHANNELCLASS_FLOATING_POINT:
557 {
558 const Vec4 color(0.5f, 0.25f, 0.125f, 1.0f);
559
560 for (deUint32 y = 0; y < m_height; y++)
561 for (deUint32 x = 0; x < m_width; x++)
562 {
563 if (tcu::isSRGB(format))
564 reference.getAccess().setPixel(tcu::linearToSRGB(color), x, y);
565 else
566 reference.getAccess().setPixel(color, x, y);
567 }
568
569 {
570 // Convert target format ulps to float ulps and allow 64ulp differences
571 const UVec4 threshold (64u * (UVec4(1u) << (UVec4(23) - tcu::getTextureFormatMantissaBitDepth(format).cast<deUint32>())));
572
573 if (!tcu::floatUlpThresholdCompare(m_context.getTestContext().getLog(), "", "", reference.getAccess(), access, threshold, tcu::COMPARE_LOG_ON_ERROR))
574 m_resultCollector.fail("Compare failed.");
575 }
576 }
577 break;
578
579 default:
580 DE_FATAL("Unknown channel class");
581 }
582 }
583
584 return tcu::TestStatus(m_resultCollector.getResult(), m_resultCollector.getMessage());
585 }
586
587 struct Programs
588 {
initvkt::__anone8d174220111::Programs589 void init (vk::SourceCollections& dst, TestConfig testConfig) const
590 {
591 std::ostringstream fragmentShader;
592 const VkFormat format (testConfig.format);
593 const tcu::TextureFormat texFormat (mapVkFormat(format));
594 const UVec4 bits (tcu::getTextureFormatBitDepth(texFormat).cast<deUint32>());
595 const tcu::TextureChannelClass channelClass (tcu::getTextureChannelClass(texFormat.type));
596
597 dst.glslSources.add("quad-vert") << glu::VertexSource(
598 "#version 450\n"
599 "out gl_PerVertex {\n"
600 "\tvec4 gl_Position;\n"
601 "};\n"
602 "highp float;\n"
603 "void main (void)\n"
604 "{\n"
605 " gl_Position = vec4(((gl_VertexIndex + 2) / 3) % 2 == 0 ? -1.0 : 1.0,\n"
606 " ((gl_VertexIndex + 1) / 3) % 2 == 0 ? -1.0 : 1.0, 0.0, 1.0);\n"
607 "}\n");
608
609 switch (channelClass)
610 {
611 case tcu::TEXTURECHANNELCLASS_UNSIGNED_INTEGER:
612 {
613 fragmentShader <<
614 "#version 450\n"
615 "layout(location = 0) out highp uvec4 o_color;\n"
616 "void main (void)\n"
617 "{\n"
618 " o_color = uvec4(" << de::toString(1u << (bits.x()-1)) << ", " << de::toString(1u << (bits.y()-2)) << ", " << de::toString(1u << (bits.z()-3)) << ", 0xffffffff);"
619 "}\n";
620 }
621 break;
622
623 case tcu::TEXTURECHANNELCLASS_SIGNED_INTEGER:
624 {
625 fragmentShader <<
626 "#version 450\n"
627 "layout(location = 0) out highp ivec4 o_color;\n"
628 "void main (void)\n"
629 "{\n"
630 " o_color = ivec4(" << de::toString(1u << (bits.x()-2)) << ", " << de::toString(1u << (bits.y()-3)) << ", " << de::toString(1u << (bits.z()-4)) << ", 0xffffffff);"
631 "}\n";
632 }
633 break;
634
635 default:
636 {
637 fragmentShader <<
638 "#version 450\n"
639 "layout(location = 0) out highp vec4 o_color;\n"
640 "void main (void)\n"
641 "{\n"
642 " o_color = vec4(0.5, 0.25, 0.125, 1.0);\n"
643 "}\n";
644 }
645 break;
646 };
647
648 dst.glslSources.add("quad-frag") << glu::FragmentSource(fragmentShader.str());
649 }
650 };
651
formatToName(VkFormat format)652 std::string formatToName (VkFormat format)
653 {
654 const std::string formatStr = de::toString(format);
655 const std::string prefix = "VK_FORMAT_";
656
657 DE_ASSERT(formatStr.substr(0, prefix.length()) == prefix);
658
659 return de::toLower(formatStr.substr(prefix.length()));
660 }
661
initTests(tcu::TestCaseGroup * group,const RenderPassType renderPassType)662 void initTests (tcu::TestCaseGroup* group, const RenderPassType renderPassType)
663 {
664 static const VkFormat formats[] =
665 {
666 VK_FORMAT_R5G6B5_UNORM_PACK16,
667 VK_FORMAT_R8_UNORM,
668 VK_FORMAT_R8_SNORM,
669 VK_FORMAT_R8_UINT,
670 VK_FORMAT_R8_SINT,
671 VK_FORMAT_R8G8_UNORM,
672 VK_FORMAT_R8G8_SNORM,
673 VK_FORMAT_R8G8_UINT,
674 VK_FORMAT_R8G8_SINT,
675 VK_FORMAT_R8G8B8A8_UNORM,
676 VK_FORMAT_R8G8B8A8_SNORM,
677 VK_FORMAT_R8G8B8A8_UINT,
678 VK_FORMAT_R8G8B8A8_SINT,
679 VK_FORMAT_R8G8B8A8_SRGB,
680 VK_FORMAT_A8B8G8R8_UNORM_PACK32,
681 VK_FORMAT_A8B8G8R8_SNORM_PACK32,
682 VK_FORMAT_A8B8G8R8_UINT_PACK32,
683 VK_FORMAT_A8B8G8R8_SINT_PACK32,
684 VK_FORMAT_A8B8G8R8_SRGB_PACK32,
685 VK_FORMAT_B8G8R8A8_UNORM,
686 VK_FORMAT_B8G8R8A8_SRGB,
687 VK_FORMAT_A2R10G10B10_UNORM_PACK32,
688 VK_FORMAT_A2B10G10R10_UNORM_PACK32,
689 VK_FORMAT_A2B10G10R10_UINT_PACK32,
690 VK_FORMAT_R16_UNORM,
691 VK_FORMAT_R16_SNORM,
692 VK_FORMAT_R16_UINT,
693 VK_FORMAT_R16_SINT,
694 VK_FORMAT_R16_SFLOAT,
695 VK_FORMAT_R16G16_UNORM,
696 VK_FORMAT_R16G16_SNORM,
697 VK_FORMAT_R16G16_UINT,
698 VK_FORMAT_R16G16_SINT,
699 VK_FORMAT_R16G16_SFLOAT,
700 VK_FORMAT_R16G16B16A16_UNORM,
701 VK_FORMAT_R16G16B16A16_SNORM,
702 VK_FORMAT_R16G16B16A16_UINT,
703 VK_FORMAT_R16G16B16A16_SINT,
704 VK_FORMAT_R16G16B16A16_SFLOAT,
705 VK_FORMAT_R32_UINT,
706 VK_FORMAT_R32_SINT,
707 VK_FORMAT_R32_SFLOAT,
708 VK_FORMAT_R32G32_UINT,
709 VK_FORMAT_R32G32_SINT,
710 VK_FORMAT_R32G32_SFLOAT,
711 VK_FORMAT_R32G32B32A32_UINT,
712 VK_FORMAT_R32G32B32A32_SINT,
713 VK_FORMAT_R32G32B32A32_SFLOAT
714 };
715
716 tcu::TestContext& testCtx (group->getTestContext());
717
718 for (size_t formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
719 {
720 const VkFormat format (formats[formatNdx]);
721 const TestConfig testConfig (format, renderPassType);
722 string testName (formatToName(format));
723
724 group->addChild(new InstanceFactory1<SparseRenderTargetTestInstance, TestConfig, Programs>(testCtx, tcu::NODETYPE_SELF_VALIDATE, testName.c_str(), testName.c_str(), testConfig));
725 }
726 }
727
728 } // anonymous
729
createRenderPassSparseRenderTargetTests(tcu::TestContext & testCtx)730 tcu::TestCaseGroup* createRenderPassSparseRenderTargetTests (tcu::TestContext& testCtx)
731 {
732 return createTestGroup(testCtx, "sparserendertarget", "Sparse render target tests", initTests, RENDERPASS_TYPE_LEGACY);
733 }
734
createRenderPass2SparseRenderTargetTests(tcu::TestContext & testCtx)735 tcu::TestCaseGroup* createRenderPass2SparseRenderTargetTests (tcu::TestContext& testCtx)
736 {
737 return createTestGroup(testCtx, "sparserendertarget", "Sparse render target tests", initTests, RENDERPASS_TYPE_RENDERPASS2);
738 }
739 } // vkt
740